Version Description
- BUG: Fixed the Stripe webhook to work on new orders that are storing the subscription id instead of the customer id in the subscription_transaction_id field. (Thanks, nickd32 on GitHub)
- BUG: Fixed issue where the name and email address of customers was not being sent to Stripe if existing members checked out while the "show billing address" option was set to false.
- BUG: Fixed bug where users who checked out with the Braintree Payments gateway could checkout again using their on file credit card if an invalid credit card was entered at checkout the second time. (Thanks, patternsinthecloud)
- BUG: Updated the 2Checkout PHP API library and fixed some issues with 2Checkout integration.
- BUG: Fixed issue where custom roles had to have pmpro_membershiplevels capability to view other PMPro-related dashboard pages. (Thanks, squarelines)
- ENHANCEMENT: Added the ability to order levels on the Levels page by drag and drop in the WordPress admin.
- ENHANCEMENT: Now hiding tabs in the PMPro settings if a user doesn't have access to that tab (but does have access to other tabs).
- ENHANCEMENT: Converted all files to unix format and removed trailing whitespace. This has no functional change on the plugin, but helps developers who are contributing. (Thanks, meths on GitHub)
- ENHANCEMENT: New Danish translation. (Thanks, Morten Stenbk and Frederik Hermund)
Download this release
Release Info
Developer | strangerstudios |
Plugin | Paid Memberships Pro |
Version | 1.8.4 |
Comparing to | |
See all releases |
Code changes from version 1.8.3.1 to 1.8.4
- adminpages/addons.php +142 -142
- adminpages/addons/hide-admin-bar-from-non-admins.php +31 -31
- adminpages/addons/pmpro-addon-packages.php +30 -30
- adminpages/addons/pmpro-affiliates.php +30 -30
- adminpages/addons/pmpro-aweber.php +31 -31
- adminpages/addons/pmpro-bbpress.php +31 -31
- adminpages/addons/pmpro-constant-contact.php +31 -31
- adminpages/addons/pmpro-disable-emails.php +28 -28
- adminpages/addons/pmpro-email-templates.php +31 -31
- adminpages/addons/pmpro-expiration.php +30 -30
- adminpages/addons/pmpro-freeaddress.php +30 -30
- adminpages/addons/pmpro-infusionsoft.php +31 -31
- adminpages/addons/pmpro-level-cost-text.php +30 -30
- adminpages/addons/pmpro-mailchimp.php +31 -31
- adminpages/addons/pmpro-network-subsite.php +31 -31
- adminpages/addons/pmpro-network.php +31 -31
- adminpages/addons/pmpro-post-affiliate-pro.php +31 -31
- adminpages/addons/pmpro-register-helper.php +31 -31
- adminpages/addons/pmpro-require-code-to-register.php +28 -28
- adminpages/addons/pmpro-series.php +30 -30
- adminpages/addons/pmpro-shipping.php +31 -31
- adminpages/addons/pmpro-user-pages.php +30 -30
- adminpages/addons/pmpro-woocommerce.php +31 -31
- adminpages/addons/pmpro-wp-affiliate.php +31 -31
- adminpages/addons/tml.php +32 -32
- adminpages/addons/wp-bouncer.php +31 -31
- adminpages/admin_footer.php +1 -1
- adminpages/admin_header.php +173 -156
- adminpages/advancedsettings.php +79 -79
- adminpages/dashboard.php +27 -27
- adminpages/discountcodes.php +665 -665
- adminpages/emailsettings.php +181 -181
- adminpages/functions.php +255 -255
- adminpages/membershiplevels.php +673 -594
- adminpages/memberslist-csv.php +41 -41
- adminpages/memberslist.php +58 -58
- adminpages/orders-csv.php +75 -75
- adminpages/orders.php +2 -2
- adminpages/pagesettings.php +260 -257
- adminpages/paymentsettings.php +244 -244
- adminpages/reports.php +61 -61
- adminpages/reports/login.php +419 -419
- adminpages/reports/memberships.php +660 -660
- adminpages/reports/sales.php +406 -406
- classes/class.memberorder.php +3 -3
- classes/class.mimetype.php +238 -238
- classes/class.pmproemail.php +815 -815
- classes/gateways/class.pmprogateway.php +220 -220
- classes/gateways/class.pmprogateway_authorizenet.php +224 -224
- classes/gateways/class.pmprogateway_braintree.php +824 -824
- classes/gateways/class.pmprogateway_check.php +340 -340
- classes/gateways/class.pmprogateway_cybersource.php +884 -884
- classes/gateways/class.pmprogateway_payflowpro.php +175 -175
- classes/gateways/class.pmprogateway_paypal.php +178 -178
- classes/gateways/class.pmprogateway_paypalexpress.php +243 -243
- classes/gateways/class.pmprogateway_paypalstandard.php +537 -537
- classes/gateways/class.pmprogateway_stripe.php +1616 -1616
- classes/gateways/class.pmprogateway_twocheckout.php +83 -30
- css/admin.css +117 -113
- css/frontend.css +177 -177
- css/print.css +3 -3
- email/billing.html +3 -3
- email/billing_admin.html +4 -4
- email/billing_failure.html +2 -2
- email/billing_failure_admin.html +10 -10
- email/cancel_admin.html +1 -1
- email/checkout_freetrial.html +2 -2
- email/checkout_freetrial_admin.html +2 -2
- email/checkout_paid.html +2 -2
- email/checkout_paid_admin.html +2 -2
- email/checkout_trial.html +2 -2
- email/checkout_trial_admin.html +2 -2
- email/credit_card_expiring.html +12 -12
- email/invoice.html +2 -2
- email/membership_expired.html +6 -6
- email/membership_expiring.html +5 -5
- includes/adminpages.php +272 -268
- includes/cleanup.php +39 -39
- includes/content.php +357 -458
adminpages/addons.php
CHANGED
@@ -1,142 +1,142 @@
|
|
1 |
-
<?php
|
2 |
-
//only admins can get this
|
3 |
-
if(!function_exists("current_user_can") || (!current_user_can("manage_options") && !current_user_can("pmpro_addons")))
|
4 |
-
{
|
5 |
-
die(__("You do not have permissions to perform this action.", "pmpro"));
|
6 |
-
}
|
7 |
-
|
8 |
-
global $wpdb, $msg, $msgt, $pmpro_addons;
|
9 |
-
|
10 |
-
/*
|
11 |
-
Addon lists
|
12 |
-
*/
|
13 |
-
$pmpro_addon_lists = array(
|
14 |
-
'repo' => array('Plugins in the WordPress Repository', 'These official PMPro plugins are available in the WordPress repository and can be installed through Plugins --> Add New.'),
|
15 |
-
'thirdparty' => array('Third-party Integration', 'These official PMPro plugins integrate with specific third-party tools and software.'),
|
16 |
-
'recommended' => array('Recommended Plugins', 'These plugins are not developed by the PMPro team, but are recommended for sites running PMPro.'),
|
17 |
-
'github' => array('Plugins on GitHub', 'These official PMPro plugins must be downloaded from GitHub and installed through Plugins --> Add New --> Upload, then activated. These plugins cannot be automatically updated and may require more developer input.'),
|
18 |
-
'gists' => array('Code Gists', 'These are bits of code that generally must be added to your active theme\'s functions.php file or included in a custom plugin. Most gists require customization and are recommended for developers only.')
|
19 |
-
);
|
20 |
-
|
21 |
-
/*
|
22 |
-
Function to add an addon
|
23 |
-
*/
|
24 |
-
function pmpro_add_addon($list, $addon)
|
25 |
-
{
|
26 |
-
global $pmpro_addons;
|
27 |
-
|
28 |
-
//make sure we have the base array
|
29 |
-
if(empty($pmpro_addons))
|
30 |
-
$pmpro_addons = array();
|
31 |
-
|
32 |
-
//make sure we have an array for the list
|
33 |
-
if(empty($pmpro_addons[$list]))
|
34 |
-
$pmpro_addons[$list] = array();
|
35 |
-
|
36 |
-
//add addon to list
|
37 |
-
$pmpro_addons[$list][] = $addon;
|
38 |
-
}
|
39 |
-
|
40 |
-
/*
|
41 |
-
Load All Addons
|
42 |
-
*/
|
43 |
-
$pmpro_addons_dir = dirname(__FILE__) . "/../adminpages/addons/";
|
44 |
-
$cwd = getcwd();
|
45 |
-
chdir($pmpro_addons_dir);
|
46 |
-
$count = 0;
|
47 |
-
foreach (glob("*.php") as $filename)
|
48 |
-
{
|
49 |
-
$count++;
|
50 |
-
require_once($filename);
|
51 |
-
}
|
52 |
-
chdir($cwd);
|
53 |
-
|
54 |
-
require_once(dirname(__FILE__) . "/admin_header.php");
|
55 |
-
?>
|
56 |
-
|
57 |
-
<h2>Add Ons</h2>
|
58 |
-
<ul id="addon-filters" class="subsubsub">
|
59 |
-
<li id="addon-filters-all"><a href="javascript:void(0);" class="current all tab">All</a> <span>(<?php echo $count;?>)</span></li>
|
60 |
-
<?php foreach($pmpro_addon_lists as $list => $list_info) { ?>
|
61 |
-
<li id="addon-filters-<?php echo $list;?>"> | <a href="javascript:void(0);>" class="tab"><?php echo $list_info[0];?></a> <span>(<?php echo count($pmpro_addons[$list]);?>)</span></li>
|
62 |
-
<?php } ?>
|
63 |
-
</ul>
|
64 |
-
|
65 |
-
<?php foreach($pmpro_addon_lists as $list => $list_info) { ?>
|
66 |
-
<div id="pmpro-<?php echo $list;?>" class="pmpro-addon-list widgets-holder-wrap">
|
67 |
-
|
68 |
-
<h3 class="section-title"><?php echo $list_info[0];?></h3>
|
69 |
-
<p class="description"><?php echo $list_info[1];?></p>
|
70 |
-
<br class="clear" />
|
71 |
-
|
72 |
-
<div id="addons-list-<?php echo $list;?>" class="addon-list">
|
73 |
-
|
74 |
-
<?php foreach($pmpro_addons[$list] as $slug => $addon) { ?>
|
75 |
-
<div id="addon-<?php echo $slug;?>" class="widget <?php if($addon['enabled']) echo "enabled"; else echo "disabled";?>">
|
76 |
-
<div class="widget-top">
|
77 |
-
<div class="widget-title">
|
78 |
-
<h4>
|
79 |
-
<span class="status-label"><?php if($addon['enabled']) echo __("Enabled", "pmpro"); else echo __("Disabled", "pmpro");?></span>
|
80 |
-
<span class="title"><?php echo $addon['title'];?></span>
|
81 |
-
<span class="version pmpro_tag-grey"><?php echo $addon['version'];?></span>
|
82 |
-
<span class="in-widget-title"></span>
|
83 |
-
</h4>
|
84 |
-
</div> <!-- end widget-title -->
|
85 |
-
</div> <!-- end widget-top -->
|
86 |
-
<div class="widget-inside">
|
87 |
-
<?php call_user_func($addon['widget'], $addon);?>
|
88 |
-
</div> <!-- end addon-inside -->
|
89 |
-
</div> <!-- end widget -->
|
90 |
-
<?php } ?>
|
91 |
-
|
92 |
-
<br class="clear" />
|
93 |
-
</div> <!-- end addon-list -->
|
94 |
-
|
95 |
-
</div> <!-- end pmpro-<?php echo $list;?> -->
|
96 |
-
<?php } ?>
|
97 |
-
|
98 |
-
<script>
|
99 |
-
//tabs
|
100 |
-
jQuery(document).ready(function() {
|
101 |
-
jQuery('#addon-filters a.tab').click(function() {
|
102 |
-
//which tab?
|
103 |
-
var tab = jQuery(this).parent().attr('id').replace('addon-filters-', '');
|
104 |
-
|
105 |
-
//un select tabs
|
106 |
-
jQuery('#addon-filters a.tab').removeClass('current');
|
107 |
-
|
108 |
-
//select this tab
|
109 |
-
jQuery('#addon-filters-'+tab+' a').addClass('current');
|
110 |
-
|
111 |
-
//show all?
|
112 |
-
if(tab == 'all')
|
113 |
-
jQuery('div.pmpro-addon-list').show();
|
114 |
-
else
|
115 |
-
{
|
116 |
-
//hide all
|
117 |
-
jQuery('div.pmpro-addon-list').hide();
|
118 |
-
|
119 |
-
//show this one
|
120 |
-
jQuery('#pmpro-'+tab).show();
|
121 |
-
}
|
122 |
-
});
|
123 |
-
});
|
124 |
-
|
125 |
-
//resize addon boxes
|
126 |
-
jQuery(document).ready(function() {
|
127 |
-
jQuery('.addon-list').each(function() {
|
128 |
-
//what's the tallest p in the list?
|
129 |
-
var tallest = 32;
|
130 |
-
jQuery(this).find('div.info p').each(function() {
|
131 |
-
tallest = Math.max(tallest, jQuery(this).height());
|
132 |
-
});
|
133 |
-
|
134 |
-
//set all p's to match
|
135 |
-
jQuery(this).find('div.info p').css('height', tallest);
|
136 |
-
});
|
137 |
-
});
|
138 |
-
</script>
|
139 |
-
|
140 |
-
<?php
|
141 |
-
require_once(dirname(__FILE__) . "/admin_footer.php");
|
142 |
-
?>
|
1 |
+
<?php
|
2 |
+
//only admins can get this
|
3 |
+
if(!function_exists("current_user_can") || (!current_user_can("manage_options") && !current_user_can("pmpro_addons")))
|
4 |
+
{
|
5 |
+
die(__("You do not have permissions to perform this action.", "pmpro"));
|
6 |
+
}
|
7 |
+
|
8 |
+
global $wpdb, $msg, $msgt, $pmpro_addons;
|
9 |
+
|
10 |
+
/*
|
11 |
+
Addon lists
|
12 |
+
*/
|
13 |
+
$pmpro_addon_lists = array(
|
14 |
+
'repo' => array('Plugins in the WordPress Repository', 'These official PMPro plugins are available in the WordPress repository and can be installed through Plugins --> Add New.'),
|
15 |
+
'thirdparty' => array('Third-party Integration', 'These official PMPro plugins integrate with specific third-party tools and software.'),
|
16 |
+
'recommended' => array('Recommended Plugins', 'These plugins are not developed by the PMPro team, but are recommended for sites running PMPro.'),
|
17 |
+
'github' => array('Plugins on GitHub', 'These official PMPro plugins must be downloaded from GitHub and installed through Plugins --> Add New --> Upload, then activated. These plugins cannot be automatically updated and may require more developer input.'),
|
18 |
+
'gists' => array('Code Gists', 'These are bits of code that generally must be added to your active theme\'s functions.php file or included in a custom plugin. Most gists require customization and are recommended for developers only.')
|
19 |
+
);
|
20 |
+
|
21 |
+
/*
|
22 |
+
Function to add an addon
|
23 |
+
*/
|
24 |
+
function pmpro_add_addon($list, $addon)
|
25 |
+
{
|
26 |
+
global $pmpro_addons;
|
27 |
+
|
28 |
+
//make sure we have the base array
|
29 |
+
if(empty($pmpro_addons))
|
30 |
+
$pmpro_addons = array();
|
31 |
+
|
32 |
+
//make sure we have an array for the list
|
33 |
+
if(empty($pmpro_addons[$list]))
|
34 |
+
$pmpro_addons[$list] = array();
|
35 |
+
|
36 |
+
//add addon to list
|
37 |
+
$pmpro_addons[$list][] = $addon;
|
38 |
+
}
|
39 |
+
|
40 |
+
/*
|
41 |
+
Load All Addons
|
42 |
+
*/
|
43 |
+
$pmpro_addons_dir = dirname(__FILE__) . "/../adminpages/addons/";
|
44 |
+
$cwd = getcwd();
|
45 |
+
chdir($pmpro_addons_dir);
|
46 |
+
$count = 0;
|
47 |
+
foreach (glob("*.php") as $filename)
|
48 |
+
{
|
49 |
+
$count++;
|
50 |
+
require_once($filename);
|
51 |
+
}
|
52 |
+
chdir($cwd);
|
53 |
+
|
54 |
+
require_once(dirname(__FILE__) . "/admin_header.php");
|
55 |
+
?>
|
56 |
+
|
57 |
+
<h2>Add Ons</h2>
|
58 |
+
<ul id="addon-filters" class="subsubsub">
|
59 |
+
<li id="addon-filters-all"><a href="javascript:void(0);" class="current all tab">All</a> <span>(<?php echo $count;?>)</span></li>
|
60 |
+
<?php foreach($pmpro_addon_lists as $list => $list_info) { ?>
|
61 |
+
<li id="addon-filters-<?php echo $list;?>"> | <a href="javascript:void(0);>" class="tab"><?php echo $list_info[0];?></a> <span>(<?php echo count($pmpro_addons[$list]);?>)</span></li>
|
62 |
+
<?php } ?>
|
63 |
+
</ul>
|
64 |
+
|
65 |
+
<?php foreach($pmpro_addon_lists as $list => $list_info) { ?>
|
66 |
+
<div id="pmpro-<?php echo $list;?>" class="pmpro-addon-list widgets-holder-wrap">
|
67 |
+
|
68 |
+
<h3 class="section-title"><?php echo $list_info[0];?></h3>
|
69 |
+
<p class="description"><?php echo $list_info[1];?></p>
|
70 |
+
<br class="clear" />
|
71 |
+
|
72 |
+
<div id="addons-list-<?php echo $list;?>" class="addon-list">
|
73 |
+
|
74 |
+
<?php foreach($pmpro_addons[$list] as $slug => $addon) { ?>
|
75 |
+
<div id="addon-<?php echo $slug;?>" class="widget <?php if($addon['enabled']) echo "enabled"; else echo "disabled";?>">
|
76 |
+
<div class="widget-top">
|
77 |
+
<div class="widget-title">
|
78 |
+
<h4>
|
79 |
+
<span class="status-label"><?php if($addon['enabled']) echo __("Enabled", "pmpro"); else echo __("Disabled", "pmpro");?></span>
|
80 |
+
<span class="title"><?php echo $addon['title'];?></span>
|
81 |
+
<span class="version pmpro_tag-grey"><?php echo $addon['version'];?></span>
|
82 |
+
<span class="in-widget-title"></span>
|
83 |
+
</h4>
|
84 |
+
</div> <!-- end widget-title -->
|
85 |
+
</div> <!-- end widget-top -->
|
86 |
+
<div class="widget-inside">
|
87 |
+
<?php call_user_func($addon['widget'], $addon);?>
|
88 |
+
</div> <!-- end addon-inside -->
|
89 |
+
</div> <!-- end widget -->
|
90 |
+
<?php } ?>
|
91 |
+
|
92 |
+
<br class="clear" />
|
93 |
+
</div> <!-- end addon-list -->
|
94 |
+
|
95 |
+
</div> <!-- end pmpro-<?php echo $list;?> -->
|
96 |
+
<?php } ?>
|
97 |
+
|
98 |
+
<script>
|
99 |
+
//tabs
|
100 |
+
jQuery(document).ready(function() {
|
101 |
+
jQuery('#addon-filters a.tab').click(function() {
|
102 |
+
//which tab?
|
103 |
+
var tab = jQuery(this).parent().attr('id').replace('addon-filters-', '');
|
104 |
+
|
105 |
+
//un select tabs
|
106 |
+
jQuery('#addon-filters a.tab').removeClass('current');
|
107 |
+
|
108 |
+
//select this tab
|
109 |
+
jQuery('#addon-filters-'+tab+' a').addClass('current');
|
110 |
+
|
111 |
+
//show all?
|
112 |
+
if(tab == 'all')
|
113 |
+
jQuery('div.pmpro-addon-list').show();
|
114 |
+
else
|
115 |
+
{
|
116 |
+
//hide all
|
117 |
+
jQuery('div.pmpro-addon-list').hide();
|
118 |
+
|
119 |
+
//show this one
|
120 |
+
jQuery('#pmpro-'+tab).show();
|
121 |
+
}
|
122 |
+
});
|
123 |
+
});
|
124 |
+
|
125 |
+
//resize addon boxes
|
126 |
+
jQuery(document).ready(function() {
|
127 |
+
jQuery('.addon-list').each(function() {
|
128 |
+
//what's the tallest p in the list?
|
129 |
+
var tallest = 32;
|
130 |
+
jQuery(this).find('div.info p').each(function() {
|
131 |
+
tallest = Math.max(tallest, jQuery(this).height());
|
132 |
+
});
|
133 |
+
|
134 |
+
//set all p's to match
|
135 |
+
jQuery(this).find('div.info p').css('height', tallest);
|
136 |
+
});
|
137 |
+
});
|
138 |
+
</script>
|
139 |
+
|
140 |
+
<?php
|
141 |
+
require_once(dirname(__FILE__) . "/admin_footer.php");
|
142 |
+
?>
|
adminpages/addons/hide-admin-bar-from-non-admins.php
CHANGED
@@ -1,32 +1,32 @@
|
|
1 |
-
<?php
|
2 |
-
/*
|
3 |
-
Addon: Hide Admin Bar From Non-Admins
|
4 |
-
Slug: hide-admin-bar-from-non-admins
|
5 |
-
*/
|
6 |
-
pmpro_add_addon('repo', array(
|
7 |
-
'title' => 'Hide Admin Bar From Non-Admins',
|
8 |
-
'version' => '1.0',
|
9 |
-
'widget' => 'pmpro_addon_hide_admin_bar_from_non_admins_widget',
|
10 |
-
'enabled' => function_exists('habfna_disable_admin_bar')
|
11 |
-
)
|
12 |
-
);
|
13 |
-
|
14 |
-
function pmpro_addon_hide_admin_bar_from_non_admins_widget($addon)
|
15 |
-
{
|
16 |
-
?>
|
17 |
-
<div class="info">
|
18 |
-
<p>Perfect for sites where there is only one admin who needs access to the dashboard and the admin bar. When activated only administrators will see the admin bar.</p>
|
19 |
-
<div class="actions">
|
20 |
-
<form method="post" name="component-actions" action="">
|
21 |
-
<?php if($addon['enabled']) { ?>
|
22 |
-
<a href="<?php echo admin_url("plugins.php");?>" class="button">Enabled</a>
|
23 |
-
<?php } elseif(file_exists(dirname(__FILE__) . "/../../../hide-admin-bar-from-non-admins/hide-admin-bar-from-non-admins.php")) { ?>
|
24 |
-
<a href="<?php echo wp_nonce_url(self_admin_url('plugins.php?action=activate&plugin=hide-admin-bar-from-non-admins/hide-admin-bar-from-non-admins.php'), 'activate-plugin_hide-admin-bar-from-non-admins/hide-admin-bar-from-non-admins.php')?>" class="button button-primary">Activate</a>
|
25 |
-
<?php } else { ?>
|
26 |
-
<a href="<?php echo wp_nonce_url(self_admin_url('update.php?action=install-plugin&plugin=hide-admin-bar-from-non-admins'), 'install-plugin_hide-admin-bar-from-non-admins'); ?>" class="button button-primary">Download</a>
|
27 |
-
<?php } ?>
|
28 |
-
</form>
|
29 |
-
</div>
|
30 |
-
</div> <!-- end info -->
|
31 |
-
<?php
|
32 |
}
|
1 |
+
<?php
|
2 |
+
/*
|
3 |
+
Addon: Hide Admin Bar From Non-Admins
|
4 |
+
Slug: hide-admin-bar-from-non-admins
|
5 |
+
*/
|
6 |
+
pmpro_add_addon('repo', array(
|
7 |
+
'title' => 'Hide Admin Bar From Non-Admins',
|
8 |
+
'version' => '1.0',
|
9 |
+
'widget' => 'pmpro_addon_hide_admin_bar_from_non_admins_widget',
|
10 |
+
'enabled' => function_exists('habfna_disable_admin_bar')
|
11 |
+
)
|
12 |
+
);
|
13 |
+
|
14 |
+
function pmpro_addon_hide_admin_bar_from_non_admins_widget($addon)
|
15 |
+
{
|
16 |
+
?>
|
17 |
+
<div class="info">
|
18 |
+
<p>Perfect for sites where there is only one admin who needs access to the dashboard and the admin bar. When activated only administrators will see the admin bar.</p>
|
19 |
+
<div class="actions">
|
20 |
+
<form method="post" name="component-actions" action="">
|
21 |
+
<?php if($addon['enabled']) { ?>
|
22 |
+
<a href="<?php echo admin_url("plugins.php");?>" class="button">Enabled</a>
|
23 |
+
<?php } elseif(file_exists(dirname(__FILE__) . "/../../../hide-admin-bar-from-non-admins/hide-admin-bar-from-non-admins.php")) { ?>
|
24 |
+
<a href="<?php echo wp_nonce_url(self_admin_url('plugins.php?action=activate&plugin=hide-admin-bar-from-non-admins/hide-admin-bar-from-non-admins.php'), 'activate-plugin_hide-admin-bar-from-non-admins/hide-admin-bar-from-non-admins.php')?>" class="button button-primary">Activate</a>
|
25 |
+
<?php } else { ?>
|
26 |
+
<a href="<?php echo wp_nonce_url(self_admin_url('update.php?action=install-plugin&plugin=hide-admin-bar-from-non-admins'), 'install-plugin_hide-admin-bar-from-non-admins'); ?>" class="button button-primary">Download</a>
|
27 |
+
<?php } ?>
|
28 |
+
</form>
|
29 |
+
</div>
|
30 |
+
</div> <!-- end info -->
|
31 |
+
<?php
|
32 |
}
|
adminpages/addons/pmpro-addon-packages.php
CHANGED
@@ -1,30 +1,30 @@
|
|
1 |
-
<?php
|
2 |
-
/*
|
3 |
-
Addon: PMPro Addon Packages
|
4 |
-
Slug: pmpro-addon-packages
|
5 |
-
*/
|
6 |
-
pmpro_add_addon('github', array(
|
7 |
-
'title' => 'PMPro Addon Packages',
|
8 |
-
'version' => '.4.3',
|
9 |
-
'widget' => 'pmpro_addon_pmpro_addon_packages_widget',
|
10 |
-
'enabled' => function_exists('pmproap_post_meta')
|
11 |
-
)
|
12 |
-
);
|
13 |
-
|
14 |
-
function pmpro_addon_pmpro_addon_packages_widget($addon)
|
15 |
-
{
|
16 |
-
?>
|
17 |
-
<div class="info">
|
18 |
-
<p>Sell access to individual pages or posts for a flat fee. This is a workaround if you would like to allow multiple membership levels per user.</p>
|
19 |
-
<div class="actions">
|
20 |
-
<?php if($addon['enabled']) { ?>
|
21 |
-
<a href="https://github.com/strangerstudios/pmpro-addon-packages/blob/master/readme.txt" class="button">Enabled</a>
|
22 |
-
<?php } elseif(file_exists(dirname(__FILE__) . "/../../../pmpro-addon-packages/pmpro-addon-packages.php")) { ?>
|
23 |
-
<a href="<?php echo wp_nonce_url(self_admin_url('plugins.php?action=activate&plugin=pmpro-addon-packages/pmpro-addon-packages.php'), 'activate-plugin_pmpro-addon-packages/pmpro-addon-packages.php')?>" class="button button-primary">Activate</a>
|
24 |
-
<?php } else { ?>
|
25 |
-
<a href="https://www.paidmembershipspro.com/wp-content/uploads/plugins/pmpro-addon-packages.zip" class="button button-primary">Download</a>
|
26 |
-
<?php } ?>
|
27 |
-
</div>
|
28 |
-
</div> <!-- end info -->
|
29 |
-
<?php
|
30 |
-
}
|
1 |
+
<?php
|
2 |
+
/*
|
3 |
+
Addon: PMPro Addon Packages
|
4 |
+
Slug: pmpro-addon-packages
|
5 |
+
*/
|
6 |
+
pmpro_add_addon('github', array(
|
7 |
+
'title' => 'PMPro Addon Packages',
|
8 |
+
'version' => '.4.3',
|
9 |
+
'widget' => 'pmpro_addon_pmpro_addon_packages_widget',
|
10 |
+
'enabled' => function_exists('pmproap_post_meta')
|
11 |
+
)
|
12 |
+
);
|
13 |
+
|
14 |
+
function pmpro_addon_pmpro_addon_packages_widget($addon)
|
15 |
+
{
|
16 |
+
?>
|
17 |
+
<div class="info">
|
18 |
+
<p>Sell access to individual pages or posts for a flat fee. This is a workaround if you would like to allow multiple membership levels per user.</p>
|
19 |
+
<div class="actions">
|
20 |
+
<?php if($addon['enabled']) { ?>
|
21 |
+
<a href="https://github.com/strangerstudios/pmpro-addon-packages/blob/master/readme.txt" class="button">Enabled</a>
|
22 |
+
<?php } elseif(file_exists(dirname(__FILE__) . "/../../../pmpro-addon-packages/pmpro-addon-packages.php")) { ?>
|
23 |
+
<a href="<?php echo wp_nonce_url(self_admin_url('plugins.php?action=activate&plugin=pmpro-addon-packages/pmpro-addon-packages.php'), 'activate-plugin_pmpro-addon-packages/pmpro-addon-packages.php')?>" class="button button-primary">Activate</a>
|
24 |
+
<?php } else { ?>
|
25 |
+
<a href="https://www.paidmembershipspro.com/wp-content/uploads/plugins/pmpro-addon-packages.zip" class="button button-primary">Download</a>
|
26 |
+
<?php } ?>
|
27 |
+
</div>
|
28 |
+
</div> <!-- end info -->
|
29 |
+
<?php
|
30 |
+
}
|
adminpages/addons/pmpro-affiliates.php
CHANGED
@@ -1,30 +1,30 @@
|
|
1 |
-
<?php
|
2 |
-
/*
|
3 |
-
Addon: PMPro Affiliates
|
4 |
-
Slug: pmpro-affiliates
|
5 |
-
*/
|
6 |
-
pmpro_add_addon('github', array(
|
7 |
-
'title' => 'PMPro Affiliates',
|
8 |
-
'version' => '.2.4',
|
9 |
-
'widget' => 'pmpro_addon_pmpro_affiliates_widget',
|
10 |
-
'enabled' => function_exists('pmpro_affiliates_dependencies')
|
11 |
-
)
|
12 |
-
);
|
13 |
-
|
14 |
-
function pmpro_addon_pmpro_affiliates_widget($addon)
|
15 |
-
{
|
16 |
-
?>
|
17 |
-
<div class="info">
|
18 |
-
<p>Lightweight Affiliate system. Create affiliate accounts and codes; tracks checkouts by affiliate account.</p>
|
19 |
-
<div class="actions">
|
20 |
-
<?php if($addon['enabled']) { ?>
|
21 |
-
<a href="https://github.com/strangerstudios/pmpro-affiliates/blob/master/readme.txt" class="button">Enabled</a>
|
22 |
-
<?php } elseif(file_exists(dirname(__FILE__) . "/../../../pmpro-affiliates/pmpro-affiliates.php")) { ?>
|
23 |
-
<a href="<?php echo wp_nonce_url(self_admin_url('plugins.php?action=activate&plugin=pmpro-affiliates/pmpro-affiliates.php'), 'activate-plugin_pmpro-affiliates/pmpro-affiliates.php')?>" class="button button-primary">Activate</a>
|
24 |
-
<?php } else { ?>
|
25 |
-
<a href="http://www.paidmembershipspro.com/wp-content/uploads/plugins/pmpro-affiliates.zip" class="button button-primary">Download</a>
|
26 |
-
<?php } ?>
|
27 |
-
</div>
|
28 |
-
</div> <!-- end info -->
|
29 |
-
<?php
|
30 |
-
}
|
1 |
+
<?php
|
2 |
+
/*
|
3 |
+
Addon: PMPro Affiliates
|
4 |
+
Slug: pmpro-affiliates
|
5 |
+
*/
|
6 |
+
pmpro_add_addon('github', array(
|
7 |
+
'title' => 'PMPro Affiliates',
|
8 |
+
'version' => '.2.4',
|
9 |
+
'widget' => 'pmpro_addon_pmpro_affiliates_widget',
|
10 |
+
'enabled' => function_exists('pmpro_affiliates_dependencies')
|
11 |
+
)
|
12 |
+
);
|
13 |
+
|
14 |
+
function pmpro_addon_pmpro_affiliates_widget($addon)
|
15 |
+
{
|
16 |
+
?>
|
17 |
+
<div class="info">
|
18 |
+
<p>Lightweight Affiliate system. Create affiliate accounts and codes; tracks checkouts by affiliate account.</p>
|
19 |
+
<div class="actions">
|
20 |
+
<?php if($addon['enabled']) { ?>
|
21 |
+
<a href="https://github.com/strangerstudios/pmpro-affiliates/blob/master/readme.txt" class="button">Enabled</a>
|
22 |
+
<?php } elseif(file_exists(dirname(__FILE__) . "/../../../pmpro-affiliates/pmpro-affiliates.php")) { ?>
|
23 |
+
<a href="<?php echo wp_nonce_url(self_admin_url('plugins.php?action=activate&plugin=pmpro-affiliates/pmpro-affiliates.php'), 'activate-plugin_pmpro-affiliates/pmpro-affiliates.php')?>" class="button button-primary">Activate</a>
|
24 |
+
<?php } else { ?>
|
25 |
+
<a href="http://www.paidmembershipspro.com/wp-content/uploads/plugins/pmpro-affiliates.zip" class="button button-primary">Download</a>
|
26 |
+
<?php } ?>
|
27 |
+
</div>
|
28 |
+
</div> <!-- end info -->
|
29 |
+
<?php
|
30 |
+
}
|
adminpages/addons/pmpro-aweber.php
CHANGED
@@ -1,31 +1,31 @@
|
|
1 |
-
<?php
|
2 |
-
/*
|
3 |
-
Addon: PMPro AWeber Integration
|
4 |
-
Slug: pmpro-aweber
|
5 |
-
*/
|
6 |
-
pmpro_add_addon('thirdparty', array(
|
7 |
-
'title' => 'PMPro AWeber Integration',
|
8 |
-
'version' => '1.0',
|
9 |
-
'widget' => 'pmpro_addon_pmpro_aweber_widget',
|
10 |
-
'enabled' => function_exists('pmproaw_init')
|
11 |
-
)
|
12 |
-
);
|
13 |
-
|
14 |
-
function pmpro_addon_pmpro_aweber_widget($addon)
|
15 |
-
{
|
16 |
-
?>
|
17 |
-
<img class="addon-thumb" src="<?php echo PMPRO_URL?>/adminpages/addons/images/pmpro-aweber.gif" />
|
18 |
-
<div class="info">
|
19 |
-
<p>Integrate User Registrations with AWeber. Adds members to lists based on their membership level. (Note: works without PMPro as well.)</p>
|
20 |
-
<div class="actions">
|
21 |
-
<?php if($addon['enabled']) { ?>
|
22 |
-
<a href="<?php echo admin_url("plugins.php");?>" class="button">Enabled</a>
|
23 |
-
<?php } elseif(file_exists(dirname(__FILE__) . "/../../../pmpro-aweber/pmpro-aweber.php")) { ?>
|
24 |
-
<a href="<?php echo wp_nonce_url(self_admin_url('plugins.php?action=activate&plugin=pmpro-aweber/pmpro-aweber.php'), 'activate-plugin_pmpro-aweber/pmpro-aweber.php')?>" class="button button-primary">Activate</a>
|
25 |
-
<?php } else { ?>
|
26 |
-
<a href="<?php echo wp_nonce_url(self_admin_url('update.php?action=install-plugin&plugin=pmpro-aweber'), 'install-plugin_pmpro-aweber'); ?>" class="button button-primary">Download</a>
|
27 |
-
<?php } ?>
|
28 |
-
</div>
|
29 |
-
</div> <!-- end info -->
|
30 |
-
<?php
|
31 |
-
}
|
1 |
+
<?php
|
2 |
+
/*
|
3 |
+
Addon: PMPro AWeber Integration
|
4 |
+
Slug: pmpro-aweber
|
5 |
+
*/
|
6 |
+
pmpro_add_addon('thirdparty', array(
|
7 |
+
'title' => 'PMPro AWeber Integration',
|
8 |
+
'version' => '1.0',
|
9 |
+
'widget' => 'pmpro_addon_pmpro_aweber_widget',
|
10 |
+
'enabled' => function_exists('pmproaw_init')
|
11 |
+
)
|
12 |
+
);
|
13 |
+
|
14 |
+
function pmpro_addon_pmpro_aweber_widget($addon)
|
15 |
+
{
|
16 |
+
?>
|
17 |
+
<img class="addon-thumb" src="<?php echo PMPRO_URL?>/adminpages/addons/images/pmpro-aweber.gif" />
|
18 |
+
<div class="info">
|
19 |
+
<p>Integrate User Registrations with AWeber. Adds members to lists based on their membership level. (Note: works without PMPro as well.)</p>
|
20 |
+
<div class="actions">
|
21 |
+
<?php if($addon['enabled']) { ?>
|
22 |
+
<a href="<?php echo admin_url("plugins.php");?>" class="button">Enabled</a>
|
23 |
+
<?php } elseif(file_exists(dirname(__FILE__) . "/../../../pmpro-aweber/pmpro-aweber.php")) { ?>
|
24 |
+
<a href="<?php echo wp_nonce_url(self_admin_url('plugins.php?action=activate&plugin=pmpro-aweber/pmpro-aweber.php'), 'activate-plugin_pmpro-aweber/pmpro-aweber.php')?>" class="button button-primary">Activate</a>
|
25 |
+
<?php } else { ?>
|
26 |
+
<a href="<?php echo wp_nonce_url(self_admin_url('update.php?action=install-plugin&plugin=pmpro-aweber'), 'install-plugin_pmpro-aweber'); ?>" class="button button-primary">Download</a>
|
27 |
+
<?php } ?>
|
28 |
+
</div>
|
29 |
+
</div> <!-- end info -->
|
30 |
+
<?php
|
31 |
+
}
|
adminpages/addons/pmpro-bbpress.php
CHANGED
@@ -1,31 +1,31 @@
|
|
1 |
-
<?php
|
2 |
-
/*
|
3 |
-
Addon: PMPro bbPress
|
4 |
-
Slug: pmpro-bbpress
|
5 |
-
*/
|
6 |
-
pmpro_add_addon('repo', array(
|
7 |
-
'title' => 'PMPro bbPress',
|
8 |
-
'version' => '1.0.1',
|
9 |
-
'widget' => 'pmpro_addon_pmpro_bbpress_widget',
|
10 |
-
'enabled' => function_exists('pmprobbp_add_meta_box')
|
11 |
-
)
|
12 |
-
);
|
13 |
-
|
14 |
-
function pmpro_addon_pmpro_bbpress_widget($addon)
|
15 |
-
{
|
16 |
-
?>
|
17 |
-
<img class="addon-thumb" src="<?php echo PMPRO_URL?>/adminpages/addons/images/pmpro-bbpress.jpg" />
|
18 |
-
<div class="info">
|
19 |
-
<p>Locking down bbPress Forums by Membership Level and Forum ID.</p>
|
20 |
-
<div class="actions">
|
21 |
-
<?php if($addon['enabled']) { ?>
|
22 |
-
<a href="<?php echo admin_url("plugins.php");?>" class="button">Enabled</a>
|
23 |
-
<?php } elseif(file_exists(dirname(__FILE__) . "/../../../pmpro-bbpress/pmpro-bbpress.php")) { ?>
|
24 |
-
<a href="<?php echo wp_nonce_url(self_admin_url('plugins.php?action=activate&plugin=pmpro-bbpress/pmpro-bbpress.php'), 'activate-plugin_pmpro-bbpress/pmpro-bbpress.php')?>" class="button button-primary">Activate</a>
|
25 |
-
<?php } else { ?>
|
26 |
-
<a href="<?php echo wp_nonce_url(self_admin_url('update.php?action=install-plugin&plugin=pmpro-bbpress'), 'install-plugin_pmpro-bbpress'); ?>" class="button button-primary">Download</a>
|
27 |
-
<?php } ?>
|
28 |
-
</div>
|
29 |
-
</div> <!-- end info -->
|
30 |
-
<?php
|
31 |
-
}
|
1 |
+
<?php
|
2 |
+
/*
|
3 |
+
Addon: PMPro bbPress
|
4 |
+
Slug: pmpro-bbpress
|
5 |
+
*/
|
6 |
+
pmpro_add_addon('repo', array(
|
7 |
+
'title' => 'PMPro bbPress',
|
8 |
+
'version' => '1.0.1',
|
9 |
+
'widget' => 'pmpro_addon_pmpro_bbpress_widget',
|
10 |
+
'enabled' => function_exists('pmprobbp_add_meta_box')
|
11 |
+
)
|
12 |
+
);
|
13 |
+
|
14 |
+
function pmpro_addon_pmpro_bbpress_widget($addon)
|
15 |
+
{
|
16 |
+
?>
|
17 |
+
<img class="addon-thumb" src="<?php echo PMPRO_URL?>/adminpages/addons/images/pmpro-bbpress.jpg" />
|
18 |
+
<div class="info">
|
19 |
+
<p>Locking down bbPress Forums by Membership Level and Forum ID.</p>
|
20 |
+
<div class="actions">
|
21 |
+
<?php if($addon['enabled']) { ?>
|
22 |
+
<a href="<?php echo admin_url("plugins.php");?>" class="button">Enabled</a>
|
23 |
+
<?php } elseif(file_exists(dirname(__FILE__) . "/../../../pmpro-bbpress/pmpro-bbpress.php")) { ?>
|
24 |
+
<a href="<?php echo wp_nonce_url(self_admin_url('plugins.php?action=activate&plugin=pmpro-bbpress/pmpro-bbpress.php'), 'activate-plugin_pmpro-bbpress/pmpro-bbpress.php')?>" class="button button-primary">Activate</a>
|
25 |
+
<?php } else { ?>
|
26 |
+
<a href="<?php echo wp_nonce_url(self_admin_url('update.php?action=install-plugin&plugin=pmpro-bbpress'), 'install-plugin_pmpro-bbpress'); ?>" class="button button-primary">Download</a>
|
27 |
+
<?php } ?>
|
28 |
+
</div>
|
29 |
+
</div> <!-- end info -->
|
30 |
+
<?php
|
31 |
+
}
|
adminpages/addons/pmpro-constant-contact.php
CHANGED
@@ -1,31 +1,31 @@
|
|
1 |
-
<?php
|
2 |
-
/*
|
3 |
-
Addon: PMPro Constant Contact Integration
|
4 |
-
Slug: pmpro-constant-contact
|
5 |
-
*/
|
6 |
-
pmpro_add_addon('thirdparty', array(
|
7 |
-
'title' => 'PMPro Constant Contact Integration',
|
8 |
-
'version' => '1.0',
|
9 |
-
'widget' => 'pmpro_addon_pmpro_constant_contact_widget',
|
10 |
-
'enabled' => function_exists('pmprocc_init')
|
11 |
-
)
|
12 |
-
);
|
13 |
-
|
14 |
-
function pmpro_addon_pmpro_constant_contact_widget($addon)
|
15 |
-
{
|
16 |
-
?>
|
17 |
-
<img class="addon-thumb" src="<?php echo PMPRO_URL?>/adminpages/addons/images/pmpro-constant-contact.gif" />
|
18 |
-
<div class="info">
|
19 |
-
<p>Integrate User Registrations with Constant Contact . Adds members to lists based on their membership level. (Note: works without PMPro as well.)</p>
|
20 |
-
<div class="actions">
|
21 |
-
<?php if($addon['enabled']) { ?>
|
22 |
-
<a href="<?php echo admin_url("plugins.php");?>" class="button">Enabled</a>
|
23 |
-
<?php } elseif(file_exists(dirname(__FILE__) . "/../../../pmpro-constant-contact/pmpro-constant-contact.php")) { ?>
|
24 |
-
<a href="<?php echo wp_nonce_url(self_admin_url('plugins.php?action=activate&plugin=pmpro-constant-contact/pmpro-constant-contact.php'), 'activate-plugin_pmpro-constant-contact/pmpro-constant-contact.php')?>" class="button button-primary">Activate</a>
|
25 |
-
<?php } else { ?>
|
26 |
-
<a href="<?php echo wp_nonce_url(self_admin_url('update.php?action=install-plugin&plugin=pmpro-constant-contact'), 'install-plugin_pmpro-constant-contact'); ?>" class="button button-primary">Download</a>
|
27 |
-
<?php } ?>
|
28 |
-
</div>
|
29 |
-
</div> <!-- end info -->
|
30 |
-
<?php
|
31 |
-
}
|
1 |
+
<?php
|
2 |
+
/*
|
3 |
+
Addon: PMPro Constant Contact Integration
|
4 |
+
Slug: pmpro-constant-contact
|
5 |
+
*/
|
6 |
+
pmpro_add_addon('thirdparty', array(
|
7 |
+
'title' => 'PMPro Constant Contact Integration',
|
8 |
+
'version' => '1.0',
|
9 |
+
'widget' => 'pmpro_addon_pmpro_constant_contact_widget',
|
10 |
+
'enabled' => function_exists('pmprocc_init')
|
11 |
+
)
|
12 |
+
);
|
13 |
+
|
14 |
+
function pmpro_addon_pmpro_constant_contact_widget($addon)
|
15 |
+
{
|
16 |
+
?>
|
17 |
+
<img class="addon-thumb" src="<?php echo PMPRO_URL?>/adminpages/addons/images/pmpro-constant-contact.gif" />
|
18 |
+
<div class="info">
|
19 |
+
<p>Integrate User Registrations with Constant Contact . Adds members to lists based on their membership level. (Note: works without PMPro as well.)</p>
|
20 |
+
<div class="actions">
|
21 |
+
<?php if($addon['enabled']) { ?>
|
22 |
+
<a href="<?php echo admin_url("plugins.php");?>" class="button">Enabled</a>
|
23 |
+
<?php } elseif(file_exists(dirname(__FILE__) . "/../../../pmpro-constant-contact/pmpro-constant-contact.php")) { ?>
|
24 |
+
<a href="<?php echo wp_nonce_url(self_admin_url('plugins.php?action=activate&plugin=pmpro-constant-contact/pmpro-constant-contact.php'), 'activate-plugin_pmpro-constant-contact/pmpro-constant-contact.php')?>" class="button button-primary">Activate</a>
|
25 |
+
<?php } else { ?>
|
26 |
+
<a href="<?php echo wp_nonce_url(self_admin_url('update.php?action=install-plugin&plugin=pmpro-constant-contact'), 'install-plugin_pmpro-constant-contact'); ?>" class="button button-primary">Download</a>
|
27 |
+
<?php } ?>
|
28 |
+
</div>
|
29 |
+
</div> <!-- end info -->
|
30 |
+
<?php
|
31 |
+
}
|
adminpages/addons/pmpro-disable-emails.php
CHANGED
@@ -1,28 +1,28 @@
|
|
1 |
-
<?php
|
2 |
-
/*
|
3 |
-
Addon: PMPro Disable PMPro Emails
|
4 |
-
Slug: pmpro-disable-emails
|
5 |
-
*/
|
6 |
-
pmpro_add_addon('gists', array(
|
7 |
-
'title' => 'PMPro Disable Emails',
|
8 |
-
'version' => '.1',
|
9 |
-
'widget' => 'pmpro_addon_pmpro_disable_emails_widget',
|
10 |
-
'enabled' => function_exists('dae_pmpro_email_recipient')
|
11 |
-
)
|
12 |
-
);
|
13 |
-
|
14 |
-
function pmpro_addon_pmpro_disable_emails_widget($addon)
|
15 |
-
{
|
16 |
-
?>
|
17 |
-
<div class="info">
|
18 |
-
<p>Disable all or specific emails sent by the PMPro plugin.</p>
|
19 |
-
<div class="actions">
|
20 |
-
<?php if($addon['enabled']) { ?>
|
21 |
-
<a target="_blank" href="https://gist.github.com/strangerstudios/3667545" class="button">Enabled</a>
|
22 |
-
<?php } else { ?>
|
23 |
-
<a target="_blank" href="https://gist.github.com/strangerstudios/3667545" class="button button-primary">View Gist</a>
|
24 |
-
<?php } ?>
|
25 |
-
</div>
|
26 |
-
</div> <!-- end info -->
|
27 |
-
<?php
|
28 |
-
}
|
1 |
+
<?php
|
2 |
+
/*
|
3 |
+
Addon: PMPro Disable PMPro Emails
|
4 |
+
Slug: pmpro-disable-emails
|
5 |
+
*/
|
6 |
+
pmpro_add_addon('gists', array(
|
7 |
+
'title' => 'PMPro Disable Emails',
|
8 |
+
'version' => '.1',
|
9 |
+
'widget' => 'pmpro_addon_pmpro_disable_emails_widget',
|
10 |
+
'enabled' => function_exists('dae_pmpro_email_recipient')
|
11 |
+
)
|
12 |
+
);
|
13 |
+
|
14 |
+
function pmpro_addon_pmpro_disable_emails_widget($addon)
|
15 |
+
{
|
16 |
+
?>
|
17 |
+
<div class="info">
|
18 |
+
<p>Disable all or specific emails sent by the PMPro plugin.</p>
|
19 |
+
<div class="actions">
|
20 |
+
<?php if($addon['enabled']) { ?>
|
21 |
+
<a target="_blank" href="https://gist.github.com/strangerstudios/3667545" class="button">Enabled</a>
|
22 |
+
<?php } else { ?>
|
23 |
+
<a target="_blank" href="https://gist.github.com/strangerstudios/3667545" class="button button-primary">View Gist</a>
|
24 |
+
<?php } ?>
|
25 |
+
</div>
|
26 |
+
</div> <!-- end info -->
|
27 |
+
<?php
|
28 |
+
}
|
adminpages/addons/pmpro-email-templates.php
CHANGED
@@ -1,31 +1,31 @@
|
|
1 |
-
<?php
|
2 |
-
/*
|
3 |
-
Addon: PMPro Email Templates Editor
|
4 |
-
Slug: pmpro-email-templates-addon
|
5 |
-
*/
|
6 |
-
pmpro_add_addon('repo', array(
|
7 |
-
'title' => 'PMPro Email Templates',
|
8 |
-
'version' => '.5.2',
|
9 |
-
'widget' => 'pmpro_addon_email_templates_widget',
|
10 |
-
'enabled' => function_exists('pmproet_scripts')
|
11 |
-
)
|
12 |
-
);
|
13 |
-
|
14 |
-
function pmpro_addon_email_templates_widget($addon)
|
15 |
-
{
|
16 |
-
?>
|
17 |
-
<img class="addon-thumb" src="<?php echo PMPRO_URL?>/adminpages/addons/images/pmpro-email-templates.gif" />
|
18 |
-
<div class="info">
|
19 |
-
<p>Easily edit system-generated Email Templates from the WordPress admin.</p>
|
20 |
-
<div class="actions">
|
21 |
-
<?php if($addon['enabled']) { ?>
|
22 |
-
<a href="http://wordpress.org/plugins/pmpro-email-templates-addon/" class="button">Enabled</a>
|
23 |
-
<?php } elseif(file_exists(dirname(__FILE__) . "/../../../pmpro-email-templates-addon/pmpro-email-templates.php")) { ?>
|
24 |
-
<a href="<?php echo wp_nonce_url(self_admin_url('plugins.php?action=activate&plugin=pmpro-email-templates-addon/pmpro-email-templates.php'), 'activate-plugin_pmpro-email-templates-addon/pmpro-email-templates.php')?>" class="button button-primary">Activate</a>
|
25 |
-
<?php } else { ?>
|
26 |
-
<a href="<?php echo wp_nonce_url(self_admin_url('update.php?action=install-plugin&plugin=pmpro-email-templates-addon'), 'install-plugin_pmpro-email-templates-addon'); ?>" class="button button-primary">Download</a>
|
27 |
-
<?php } ?>
|
28 |
-
</div>
|
29 |
-
</div> <!-- end info -->
|
30 |
-
<?php
|
31 |
-
}
|
1 |
+
<?php
|
2 |
+
/*
|
3 |
+
Addon: PMPro Email Templates Editor
|
4 |
+
Slug: pmpro-email-templates-addon
|
5 |
+
*/
|
6 |
+
pmpro_add_addon('repo', array(
|
7 |
+
'title' => 'PMPro Email Templates',
|
8 |
+
'version' => '.5.2',
|
9 |
+
'widget' => 'pmpro_addon_email_templates_widget',
|
10 |
+
'enabled' => function_exists('pmproet_scripts')
|
11 |
+
)
|
12 |
+
);
|
13 |
+
|
14 |
+
function pmpro_addon_email_templates_widget($addon)
|
15 |
+
{
|
16 |
+
?>
|
17 |
+
<img class="addon-thumb" src="<?php echo PMPRO_URL?>/adminpages/addons/images/pmpro-email-templates.gif" />
|
18 |
+
<div class="info">
|
19 |
+
<p>Easily edit system-generated Email Templates from the WordPress admin.</p>
|
20 |
+
<div class="actions">
|
21 |
+
<?php if($addon['enabled']) { ?>
|
22 |
+
<a href="http://wordpress.org/plugins/pmpro-email-templates-addon/" class="button">Enabled</a>
|
23 |
+
<?php } elseif(file_exists(dirname(__FILE__) . "/../../../pmpro-email-templates-addon/pmpro-email-templates.php")) { ?>
|
24 |
+
<a href="<?php echo wp_nonce_url(self_admin_url('plugins.php?action=activate&plugin=pmpro-email-templates-addon/pmpro-email-templates.php'), 'activate-plugin_pmpro-email-templates-addon/pmpro-email-templates.php')?>" class="button button-primary">Activate</a>
|
25 |
+
<?php } else { ?>
|
26 |
+
<a href="<?php echo wp_nonce_url(self_admin_url('update.php?action=install-plugin&plugin=pmpro-email-templates-addon'), 'install-plugin_pmpro-email-templates-addon'); ?>" class="button button-primary">Download</a>
|
27 |
+
<?php } ?>
|
28 |
+
</div>
|
29 |
+
</div> <!-- end info -->
|
30 |
+
<?php
|
31 |
+
}
|
adminpages/addons/pmpro-expiration.php
CHANGED
@@ -1,30 +1,30 @@
|
|
1 |
-
<?php
|
2 |
-
/*
|
3 |
-
Addon: PMPro Expiration Date
|
4 |
-
Slug: pmpro-expiration
|
5 |
-
*/
|
6 |
-
pmpro_add_addon('github', array(
|
7 |
-
'title' => 'PMPro Set Expiration Dates',
|
8 |
-
'version' => '.1.1',
|
9 |
-
'widget' => 'pmpro_addon_pmpro_expiration_widget',
|
10 |
-
'enabled' => function_exists('pmprosed_pmpro_checkout_level')
|
11 |
-
)
|
12 |
-
);
|
13 |
-
|
14 |
-
function pmpro_addon_pmpro_expiration_widget($addon)
|
15 |
-
{
|
16 |
-
?>
|
17 |
-
<div class="info">
|
18 |
-
<p>Set a specific expiration date (e.g. 2013-12-31) for a PMPro membership level or discount code.</p>
|
19 |
-
<div class="actions">
|
20 |
-
<?php if($addon['enabled']) { ?>
|
21 |
-
<a href="https://github.com/strangerstudios/pmpro-set-expiration-dates/blob/master/readme.txt" class="button">Enabled</a>
|
22 |
-
<?php } elseif(file_exists(dirname(__FILE__) . "/../../../pmpro-set-expiration-dates/pmpro-set-expiration-dates.php")) { ?>
|
23 |
-
<a href="<?php echo wp_nonce_url(self_admin_url('plugins.php?action=activate&plugin=pmpro-set-expiration-dates/pmpro-set-expiration-dates.php'), 'activate-plugin_pmpro-set-expiration-dates/pmpro-set-expiration-dates.php')?>" class="button button-primary">Activate</a>
|
24 |
-
<?php } else { ?>
|
25 |
-
<a href="http://www.paidmembershipspro.com/wp-content/uploads/plugins/pmpro-set-expiration-dates.zip" class="button button-primary">Download</a>
|
26 |
-
<?php } ?>
|
27 |
-
</div>
|
28 |
-
</div> <!-- end info -->
|
29 |
-
<?php
|
30 |
-
}
|
1 |
+
<?php
|
2 |
+
/*
|
3 |
+
Addon: PMPro Expiration Date
|
4 |
+
Slug: pmpro-expiration
|
5 |
+
*/
|
6 |
+
pmpro_add_addon('github', array(
|
7 |
+
'title' => 'PMPro Set Expiration Dates',
|
8 |
+
'version' => '.1.1',
|
9 |
+
'widget' => 'pmpro_addon_pmpro_expiration_widget',
|
10 |
+
'enabled' => function_exists('pmprosed_pmpro_checkout_level')
|
11 |
+
)
|
12 |
+
);
|
13 |
+
|
14 |
+
function pmpro_addon_pmpro_expiration_widget($addon)
|
15 |
+
{
|
16 |
+
?>
|
17 |
+
<div class="info">
|
18 |
+
<p>Set a specific expiration date (e.g. 2013-12-31) for a PMPro membership level or discount code.</p>
|
19 |
+
<div class="actions">
|
20 |
+
<?php if($addon['enabled']) { ?>
|
21 |
+
<a href="https://github.com/strangerstudios/pmpro-set-expiration-dates/blob/master/readme.txt" class="button">Enabled</a>
|
22 |
+
<?php } elseif(file_exists(dirname(__FILE__) . "/../../../pmpro-set-expiration-dates/pmpro-set-expiration-dates.php")) { ?>
|
23 |
+
<a href="<?php echo wp_nonce_url(self_admin_url('plugins.php?action=activate&plugin=pmpro-set-expiration-dates/pmpro-set-expiration-dates.php'), 'activate-plugin_pmpro-set-expiration-dates/pmpro-set-expiration-dates.php')?>" class="button button-primary">Activate</a>
|
24 |
+
<?php } else { ?>
|
25 |
+
<a href="http://www.paidmembershipspro.com/wp-content/uploads/plugins/pmpro-set-expiration-dates.zip" class="button button-primary">Download</a>
|
26 |
+
<?php } ?>
|
27 |
+
</div>
|
28 |
+
</div> <!-- end info -->
|
29 |
+
<?php
|
30 |
+
}
|
adminpages/addons/pmpro-freeaddress.php
CHANGED
@@ -1,30 +1,30 @@
|
|
1 |
-
<?php
|
2 |
-
/*
|
3 |
-
Addon: PMPro Require Name and Address for Free Level
|
4 |
-
Slug: pmpro-freerequire
|
5 |
-
*/
|
6 |
-
pmpro_add_addon('github', array(
|
7 |
-
'title' => 'PMPro Require Name/Address for Free Level',
|
8 |
-
'version' => '.2',
|
9 |
-
'widget' => 'pmpro_addon_pmpro_freerequire_widget',
|
10 |
-
'enabled' => function_exists('my_pmpro_checkout_boxes_require_address')
|
11 |
-
)
|
12 |
-
);
|
13 |
-
|
14 |
-
function pmpro_addon_pmpro_freerequire_widget($addon)
|
15 |
-
{
|
16 |
-
?>
|
17 |
-
<div class="info">
|
18 |
-
<p>Require name/address for free Membership Level checkout.</p>
|
19 |
-
<div class="actions">
|
20 |
-
<?php if($addon['enabled']) { ?>
|
21 |
-
<a href="https://github.com/strangerstudios/pmpro-address-for-free-levels" class="button">Enabled</a>
|
22 |
-
<?php } elseif(file_exists(dirname(__FILE__) . "/../../../pmpro-address-for-free-levels/pmpro-address-for-free-levels.php")) { ?>
|
23 |
-
<a href="<?php echo wp_nonce_url(self_admin_url('plugins.php?action=activate&plugin=pmpro-address-for-free-levels/pmpro-address-for-free-levels.php'), 'activate-plugin_pmpro-address-for-free-levels/pmpro-address-for-free-levels.php')?>" class="button button-primary">Activate</a>
|
24 |
-
<?php } else { ?>
|
25 |
-
<a href="http://www.paidmembershipspro.com/wp-content/uploads/plugins/pmpro-address-for-free-levels.zip" class="button button-primary">Download</a>
|
26 |
-
<?php } ?>
|
27 |
-
</div>
|
28 |
-
</div> <!-- end info -->
|
29 |
-
<?php
|
30 |
-
}
|
1 |
+
<?php
|
2 |
+
/*
|
3 |
+
Addon: PMPro Require Name and Address for Free Level
|
4 |
+
Slug: pmpro-freerequire
|
5 |
+
*/
|
6 |
+
pmpro_add_addon('github', array(
|
7 |
+
'title' => 'PMPro Require Name/Address for Free Level',
|
8 |
+
'version' => '.2',
|
9 |
+
'widget' => 'pmpro_addon_pmpro_freerequire_widget',
|
10 |
+
'enabled' => function_exists('my_pmpro_checkout_boxes_require_address')
|
11 |
+
)
|
12 |
+
);
|
13 |
+
|
14 |
+
function pmpro_addon_pmpro_freerequire_widget($addon)
|
15 |
+
{
|
16 |
+
?>
|
17 |
+
<div class="info">
|
18 |
+
<p>Require name/address for free Membership Level checkout.</p>
|
19 |
+
<div class="actions">
|
20 |
+
<?php if($addon['enabled']) { ?>
|
21 |
+
<a href="https://github.com/strangerstudios/pmpro-address-for-free-levels" class="button">Enabled</a>
|
22 |
+
<?php } elseif(file_exists(dirname(__FILE__) . "/../../../pmpro-address-for-free-levels/pmpro-address-for-free-levels.php")) { ?>
|
23 |
+
<a href="<?php echo wp_nonce_url(self_admin_url('plugins.php?action=activate&plugin=pmpro-address-for-free-levels/pmpro-address-for-free-levels.php'), 'activate-plugin_pmpro-address-for-free-levels/pmpro-address-for-free-levels.php')?>" class="button button-primary">Activate</a>
|
24 |
+
<?php } else { ?>
|
25 |
+
<a href="http://www.paidmembershipspro.com/wp-content/uploads/plugins/pmpro-address-for-free-levels.zip" class="button button-primary">Download</a>
|
26 |
+
<?php } ?>
|
27 |
+
</div>
|
28 |
+
</div> <!-- end info -->
|
29 |
+
<?php
|
30 |
+
}
|
adminpages/addons/pmpro-infusionsoft.php
CHANGED
@@ -1,31 +1,31 @@
|
|
1 |
-
<?php
|
2 |
-
/*
|
3 |
-
Addon: PMPro Infusionsoft Integration
|
4 |
-
Slug: pmpro-infusionsoft
|
5 |
-
*/
|
6 |
-
pmpro_add_addon('thirdparty', array(
|
7 |
-
'title' => 'PMPro Infusionsoft Integration',
|
8 |
-
'version' => '1.2',
|
9 |
-
'widget' => 'pmpro_addon_pmpro_infusionsoft_widget',
|
10 |
-
'enabled' => function_exists('pmprois_init')
|
11 |
-
)
|
12 |
-
);
|
13 |
-
|
14 |
-
function pmpro_addon_pmpro_infusionsoft_widget($addon)
|
15 |
-
{
|
16 |
-
?>
|
17 |
-
<img class="addon-thumb" src="<?php echo PMPRO_URL?>/adminpages/addons/images/pmpro-infusionsoft.jpg" />
|
18 |
-
<div class="info">
|
19 |
-
<p>Integrate with Infusionsoft. Add members to email lists (groups, tags) based on their membership level. (Note: works without PMPro as well.)</p>
|
20 |
-
<div class="actions">
|
21 |
-
<?php if($addon['enabled']) { ?>
|
22 |
-
<a href="<?php echo admin_url("plugins.php");?>" class="button">Enabled</a>
|
23 |
-
<?php } elseif(file_exists(dirname(__FILE__) . "/../../../pmpro-infusionsoft/pmpro-infusionsoft.php")) { ?>
|
24 |
-
<a href="<?php echo wp_nonce_url(self_admin_url('plugins.php?action=activate&plugin=pmpro-infusionsoft/pmpro-infusionsoft.php'), 'activate-plugin_pmpro-infusionsoft/pmpro-infusionsoft.php')?>" class="button button-primary">Activate</a>
|
25 |
-
<?php } else { ?>
|
26 |
-
<a href="<?php echo wp_nonce_url(self_admin_url('update.php?action=install-plugin&plugin=pmpro-infusionsoft'), 'install-plugin_pmpro-infusionsoft'); ?>" class="button button-primary">Download</a>
|
27 |
-
<?php } ?>
|
28 |
-
</div>
|
29 |
-
</div> <!-- end info -->
|
30 |
-
<?php
|
31 |
-
}
|
1 |
+
<?php
|
2 |
+
/*
|
3 |
+
Addon: PMPro Infusionsoft Integration
|
4 |
+
Slug: pmpro-infusionsoft
|
5 |
+
*/
|
6 |
+
pmpro_add_addon('thirdparty', array(
|
7 |
+
'title' => 'PMPro Infusionsoft Integration',
|
8 |
+
'version' => '1.2',
|
9 |
+
'widget' => 'pmpro_addon_pmpro_infusionsoft_widget',
|
10 |
+
'enabled' => function_exists('pmprois_init')
|
11 |
+
)
|
12 |
+
);
|
13 |
+
|
14 |
+
function pmpro_addon_pmpro_infusionsoft_widget($addon)
|
15 |
+
{
|
16 |
+
?>
|
17 |
+
<img class="addon-thumb" src="<?php echo PMPRO_URL?>/adminpages/addons/images/pmpro-infusionsoft.jpg" />
|
18 |
+
<div class="info">
|
19 |
+
<p>Integrate with Infusionsoft. Add members to email lists (groups, tags) based on their membership level. (Note: works without PMPro as well.)</p>
|
20 |
+
<div class="actions">
|
21 |
+
<?php if($addon['enabled']) { ?>
|
22 |
+
<a href="<?php echo admin_url("plugins.php");?>" class="button">Enabled</a>
|
23 |
+
<?php } elseif(file_exists(dirname(__FILE__) . "/../../../pmpro-infusionsoft/pmpro-infusionsoft.php")) { ?>
|
24 |
+
<a href="<?php echo wp_nonce_url(self_admin_url('plugins.php?action=activate&plugin=pmpro-infusionsoft/pmpro-infusionsoft.php'), 'activate-plugin_pmpro-infusionsoft/pmpro-infusionsoft.php')?>" class="button button-primary">Activate</a>
|
25 |
+
<?php } else { ?>
|
26 |
+
<a href="<?php echo wp_nonce_url(self_admin_url('update.php?action=install-plugin&plugin=pmpro-infusionsoft'), 'install-plugin_pmpro-infusionsoft'); ?>" class="button button-primary">Download</a>
|
27 |
+
<?php } ?>
|
28 |
+
</div>
|
29 |
+
</div> <!-- end info -->
|
30 |
+
<?php
|
31 |
+
}
|
adminpages/addons/pmpro-level-cost-text.php
CHANGED
@@ -1,30 +1,30 @@
|
|
1 |
-
<?php
|
2 |
-
/*
|
3 |
-
Addon: PMPro Custom Level Cost Text
|
4 |
-
Slug: pmpro-level-cost-text
|
5 |
-
*/
|
6 |
-
pmpro_add_addon('github', array(
|
7 |
-
'title' => 'PMPro Level Cost Text',
|
8 |
-
'version' => '.2',
|
9 |
-
'widget' => 'pmpro_addon_pmpro_level_cost_text_widget',
|
10 |
-
'enabled' => function_exists('pclct_pmpro_discount_code_after_level_settings')
|
11 |
-
)
|
12 |
-
);
|
13 |
-
|
14 |
-
function pmpro_addon_pmpro_level_cost_text_widget($addon)
|
15 |
-
{
|
16 |
-
?>
|
17 |
-
<div class="info">
|
18 |
-
<p>Adds a "level cost text" field to PMPro Membership Levels and Discount Codes to allow you to override the automatically generated level cost text PMPro provides.</p>
|
19 |
-
<div class="actions">
|
20 |
-
<?php if($addon['enabled']) { ?>
|
21 |
-
<a href="https://github.com/strangerstudios/pmpro-level-cost-text/blob/master/readme.txt" class="button">Enabled</a>
|
22 |
-
<?php } elseif(file_exists(dirname(__FILE__) . "/../../../pmpro-level-cost-text/pmpro-level-cost-text.php")) { ?>
|
23 |
-
<a href="<?php echo wp_nonce_url(self_admin_url('plugins.php?action=activate&plugin=pmpro-level-cost-text/pmpro-level-cost-text.php'), 'activate-plugin_pmpro-level-cost-text/pmpro-level-cost-text.php')?>" class="button button-primary">Activate</a>
|
24 |
-
<?php } else { ?>
|
25 |
-
<a href="http://www.paidmembershipspro.com/wp-content/uploads/plugins/pmpro-level-cost-text.zip" class="button button-primary">Download</a>
|
26 |
-
<?php } ?>
|
27 |
-
</div>
|
28 |
-
</div> <!-- end info -->
|
29 |
-
<?php
|
30 |
-
}
|
1 |
+
<?php
|
2 |
+
/*
|
3 |
+
Addon: PMPro Custom Level Cost Text
|
4 |
+
Slug: pmpro-level-cost-text
|
5 |
+
*/
|
6 |
+
pmpro_add_addon('github', array(
|
7 |
+
'title' => 'PMPro Level Cost Text',
|
8 |
+
'version' => '.2',
|
9 |
+
'widget' => 'pmpro_addon_pmpro_level_cost_text_widget',
|
10 |
+
'enabled' => function_exists('pclct_pmpro_discount_code_after_level_settings')
|
11 |
+
)
|
12 |
+
);
|
13 |
+
|
14 |
+
function pmpro_addon_pmpro_level_cost_text_widget($addon)
|
15 |
+
{
|
16 |
+
?>
|
17 |
+
<div class="info">
|
18 |
+
<p>Adds a "level cost text" field to PMPro Membership Levels and Discount Codes to allow you to override the automatically generated level cost text PMPro provides.</p>
|
19 |
+
<div class="actions">
|
20 |
+
<?php if($addon['enabled']) { ?>
|
21 |
+
<a href="https://github.com/strangerstudios/pmpro-level-cost-text/blob/master/readme.txt" class="button">Enabled</a>
|
22 |
+
<?php } elseif(file_exists(dirname(__FILE__) . "/../../../pmpro-level-cost-text/pmpro-level-cost-text.php")) { ?>
|
23 |
+
<a href="<?php echo wp_nonce_url(self_admin_url('plugins.php?action=activate&plugin=pmpro-level-cost-text/pmpro-level-cost-text.php'), 'activate-plugin_pmpro-level-cost-text/pmpro-level-cost-text.php')?>" class="button button-primary">Activate</a>
|
24 |
+
<?php } else { ?>
|
25 |
+
<a href="http://www.paidmembershipspro.com/wp-content/uploads/plugins/pmpro-level-cost-text.zip" class="button button-primary">Download</a>
|
26 |
+
<?php } ?>
|
27 |
+
</div>
|
28 |
+
</div> <!-- end info -->
|
29 |
+
<?php
|
30 |
+
}
|
adminpages/addons/pmpro-mailchimp.php
CHANGED
@@ -1,31 +1,31 @@
|
|
1 |
-
<?php
|
2 |
-
/*
|
3 |
-
Addon: PMPro MailChimp Integration
|
4 |
-
Slug: pmpro-mailchimp
|
5 |
-
*/
|
6 |
-
pmpro_add_addon('thirdparty', array(
|
7 |
-
'title' => 'PMPro MailChimp Integration',
|
8 |
-
'version' => '1.0',
|
9 |
-
'widget' => 'pmpro_addon_pmpro_mailchimp_widget',
|
10 |
-
'enabled' => function_exists('pmpromc_init')
|
11 |
-
)
|
12 |
-
);
|
13 |
-
|
14 |
-
function pmpro_addon_pmpro_mailchimp_widget($addon)
|
15 |
-
{
|
16 |
-
?>
|
17 |
-
<img class="addon-thumb" src="<?php echo PMPRO_URL?>/adminpages/addons/images/pmpro-mailchimp.jpg" />
|
18 |
-
<div class="info">
|
19 |
-
<p>Integrate User Registrations with Mailchimp. Adds members to lists based on their membership level. (Note: works without PMPro as well.)</p>
|
20 |
-
<div class="actions">
|
21 |
-
<?php if($addon['enabled']) { ?>
|
22 |
-
<a href="<?php echo admin_url("plugins.php");?>" class="button">Enabled</a>
|
23 |
-
<?php } elseif(file_exists(dirname(__FILE__) . "/../../../pmpro-mailchimp/pmpro-mailchimp.php")) { ?>
|
24 |
-
<a href="<?php echo wp_nonce_url(self_admin_url('plugins.php?action=activate&plugin=pmpro-mailchimp/pmpro-mailchimp.php'), 'activate-plugin_pmpro-mailchimp/pmpro-mailchimp.php')?>" class="button button-primary">Activate</a>
|
25 |
-
<?php } else { ?>
|
26 |
-
<a href="<?php echo wp_nonce_url(self_admin_url('update.php?action=install-plugin&plugin=pmpro-mailchimp'), 'install-plugin_pmpro-mailchimp'); ?>" class="button button-primary">Download</a>
|
27 |
-
<?php } ?>
|
28 |
-
</div>
|
29 |
-
</div> <!-- end info -->
|
30 |
-
<?php
|
31 |
-
}
|
1 |
+
<?php
|
2 |
+
/*
|
3 |
+
Addon: PMPro MailChimp Integration
|
4 |
+
Slug: pmpro-mailchimp
|
5 |
+
*/
|
6 |
+
pmpro_add_addon('thirdparty', array(
|
7 |
+
'title' => 'PMPro MailChimp Integration',
|
8 |
+
'version' => '1.0',
|
9 |
+
'widget' => 'pmpro_addon_pmpro_mailchimp_widget',
|
10 |
+
'enabled' => function_exists('pmpromc_init')
|
11 |
+
)
|
12 |
+
);
|
13 |
+
|
14 |
+
function pmpro_addon_pmpro_mailchimp_widget($addon)
|
15 |
+
{
|
16 |
+
?>
|
17 |
+
<img class="addon-thumb" src="<?php echo PMPRO_URL?>/adminpages/addons/images/pmpro-mailchimp.jpg" />
|
18 |
+
<div class="info">
|
19 |
+
<p>Integrate User Registrations with Mailchimp. Adds members to lists based on their membership level. (Note: works without PMPro as well.)</p>
|
20 |
+
<div class="actions">
|
21 |
+
<?php if($addon['enabled']) { ?>
|
22 |
+
<a href="<?php echo admin_url("plugins.php");?>" class="button">Enabled</a>
|
23 |
+
<?php } elseif(file_exists(dirname(__FILE__) . "/../../../pmpro-mailchimp/pmpro-mailchimp.php")) { ?>
|
24 |
+
<a href="<?php echo wp_nonce_url(self_admin_url('plugins.php?action=activate&plugin=pmpro-mailchimp/pmpro-mailchimp.php'), 'activate-plugin_pmpro-mailchimp/pmpro-mailchimp.php')?>" class="button button-primary">Activate</a>
|
25 |
+
<?php } else { ?>
|
26 |
+
<a href="<?php echo wp_nonce_url(self_admin_url('update.php?action=install-plugin&plugin=pmpro-mailchimp'), 'install-plugin_pmpro-mailchimp'); ?>" class="button button-primary">Download</a>
|
27 |
+
<?php } ?>
|
28 |
+
</div>
|
29 |
+
</div> <!-- end info -->
|
30 |
+
<?php
|
31 |
+
}
|
adminpages/addons/pmpro-network-subsite.php
CHANGED
@@ -1,31 +1,31 @@
|
|
1 |
-
<?php
|
2 |
-
/*
|
3 |
-
Addon: PMPro Network
|
4 |
-
Slug: pmpro-network-subsite
|
5 |
-
*/
|
6 |
-
pmpro_add_addon('github', array(
|
7 |
-
'title' => 'PMPro Network Subsite Helper',
|
8 |
-
'version' => '.2',
|
9 |
-
'widget' => 'pmpro_addon_pmpro_network_subsite_widget',
|
10 |
-
'enabled' => function_exists('pmpron_subsite_activated_plugin')
|
11 |
-
)
|
12 |
-
);
|
13 |
-
|
14 |
-
function pmpro_addon_pmpro_network_subsite_widget($addon)
|
15 |
-
{
|
16 |
-
?>
|
17 |
-
<img class="addon-thumb" src="<?php echo PMPRO_URL?>/adminpages/addons/images/pmpro-network.gif" />
|
18 |
-
<div class="info">
|
19 |
-
<p>Have network subsites use membership data from a "main" site to handle access restrictions.</p>
|
20 |
-
<div class="actions">
|
21 |
-
<?php if($addon['enabled']) { ?>
|
22 |
-
<a href="https://github.com/strangerstudios/pmpro-network-subsite" class="button">Enabled</a>
|
23 |
-
<?php } elseif(file_exists(dirname(__FILE__) . "/../../../pmpro-network-subsite/pmpro-network-subsite.php")) { ?>
|
24 |
-
<a href="<?php echo wp_nonce_url(self_admin_url('plugins.php?action=activate&plugin=pmpro-network-subsite/pmpro-network-subsite.php'), 'activate-plugin_pmpro-network-subsite/pmpro-network-subsite.php')?>" class="button button-primary">Activate</a>
|
25 |
-
<?php } else { ?>
|
26 |
-
<a href="http://www.paidmembershipspro.com/wp-content/uploads/plugins/pmpro-network-subsite.zip" class="button button-primary">Download</a>
|
27 |
-
<?php } ?>
|
28 |
-
</div>
|
29 |
-
</div> <!-- end info -->
|
30 |
-
<?php
|
31 |
-
}
|
1 |
+
<?php
|
2 |
+
/*
|
3 |
+
Addon: PMPro Network
|
4 |
+
Slug: pmpro-network-subsite
|
5 |
+
*/
|
6 |
+
pmpro_add_addon('github', array(
|
7 |
+
'title' => 'PMPro Network Subsite Helper',
|
8 |
+
'version' => '.2',
|
9 |
+
'widget' => 'pmpro_addon_pmpro_network_subsite_widget',
|
10 |
+
'enabled' => function_exists('pmpron_subsite_activated_plugin')
|
11 |
+
)
|
12 |
+
);
|
13 |
+
|
14 |
+
function pmpro_addon_pmpro_network_subsite_widget($addon)
|
15 |
+
{
|
16 |
+
?>
|
17 |
+
<img class="addon-thumb" src="<?php echo PMPRO_URL?>/adminpages/addons/images/pmpro-network.gif" />
|
18 |
+
<div class="info">
|
19 |
+
<p>Have network subsites use membership data from a "main" site to handle access restrictions.</p>
|
20 |
+
<div class="actions">
|
21 |
+
<?php if($addon['enabled']) { ?>
|
22 |
+
<a href="https://github.com/strangerstudios/pmpro-network-subsite" class="button">Enabled</a>
|
23 |
+
<?php } elseif(file_exists(dirname(__FILE__) . "/../../../pmpro-network-subsite/pmpro-network-subsite.php")) { ?>
|
24 |
+
<a href="<?php echo wp_nonce_url(self_admin_url('plugins.php?action=activate&plugin=pmpro-network-subsite/pmpro-network-subsite.php'), 'activate-plugin_pmpro-network-subsite/pmpro-network-subsite.php')?>" class="button button-primary">Activate</a>
|
25 |
+
<?php } else { ?>
|
26 |
+
<a href="http://www.paidmembershipspro.com/wp-content/uploads/plugins/pmpro-network-subsite.zip" class="button button-primary">Download</a>
|
27 |
+
<?php } ?>
|
28 |
+
</div>
|
29 |
+
</div> <!-- end info -->
|
30 |
+
<?php
|
31 |
+
}
|
adminpages/addons/pmpro-network.php
CHANGED
@@ -1,31 +1,31 @@
|
|
1 |
-
<?php
|
2 |
-
/*
|
3 |
-
Addon: PMPro Network
|
4 |
-
Slug: pmpro-network
|
5 |
-
*/
|
6 |
-
pmpro_add_addon('github', array(
|
7 |
-
'title' => 'PMPro Network',
|
8 |
-
'version' => '.3.1',
|
9 |
-
'widget' => 'pmpro_addon_pmpro_network_widget',
|
10 |
-
'enabled' => function_exists('pmpron_new_blogs_settings')
|
11 |
-
)
|
12 |
-
);
|
13 |
-
|
14 |
-
function pmpro_addon_pmpro_network_widget($addon)
|
15 |
-
{
|
16 |
-
?>
|
17 |
-
<img class="addon-thumb" src="<?php echo PMPRO_URL?>/adminpages/addons/images/pmpro-network.gif" />
|
18 |
-
<div class="info">
|
19 |
-
<p>Allow users to checkout for a membership to create a site on your WordPress multisite network.</p>
|
20 |
-
<div class="actions">
|
21 |
-
<?php if($addon['enabled']) { ?>
|
22 |
-
<a href="https://github.com/strangerstudios/pmpro-network/blob/master/readme.txt" class="button">Enabled</a>
|
23 |
-
<?php } elseif(file_exists(dirname(__FILE__) . "/../../../pmpro-network/pmpro-network.php")) { ?>
|
24 |
-
<a href="<?php echo wp_nonce_url(self_admin_url('plugins.php?action=activate&plugin=pmpro-network/pmpro-network.php'), 'activate-plugin_pmpro-network/pmpro-network.php')?>" class="button button-primary">Activate</a>
|
25 |
-
<?php } else { ?>
|
26 |
-
<a href="http://www.paidmembershipspro.com/wp-content/uploads/plugins/pmpro-network.zip" class="button button-primary">Download</a>
|
27 |
-
<?php } ?>
|
28 |
-
</div>
|
29 |
-
</div> <!-- end info -->
|
30 |
-
<?php
|
31 |
-
}
|
1 |
+
<?php
|
2 |
+
/*
|
3 |
+
Addon: PMPro Network
|
4 |
+
Slug: pmpro-network
|
5 |
+
*/
|
6 |
+
pmpro_add_addon('github', array(
|
7 |
+
'title' => 'PMPro Network',
|
8 |
+
'version' => '.3.1',
|
9 |
+
'widget' => 'pmpro_addon_pmpro_network_widget',
|
10 |
+
'enabled' => function_exists('pmpron_new_blogs_settings')
|
11 |
+
)
|
12 |
+
);
|
13 |
+
|
14 |
+
function pmpro_addon_pmpro_network_widget($addon)
|
15 |
+
{
|
16 |
+
?>
|
17 |
+
<img class="addon-thumb" src="<?php echo PMPRO_URL?>/adminpages/addons/images/pmpro-network.gif" />
|
18 |
+
<div class="info">
|
19 |
+
<p>Allow users to checkout for a membership to create a site on your WordPress multisite network.</p>
|
20 |
+
<div class="actions">
|
21 |
+
<?php if($addon['enabled']) { ?>
|
22 |
+
<a href="https://github.com/strangerstudios/pmpro-network/blob/master/readme.txt" class="button">Enabled</a>
|
23 |
+
<?php } elseif(file_exists(dirname(__FILE__) . "/../../../pmpro-network/pmpro-network.php")) { ?>
|
24 |
+
<a href="<?php echo wp_nonce_url(self_admin_url('plugins.php?action=activate&plugin=pmpro-network/pmpro-network.php'), 'activate-plugin_pmpro-network/pmpro-network.php')?>" class="button button-primary">Activate</a>
|
25 |
+
<?php } else { ?>
|
26 |
+
<a href="http://www.paidmembershipspro.com/wp-content/uploads/plugins/pmpro-network.zip" class="button button-primary">Download</a>
|
27 |
+
<?php } ?>
|
28 |
+
</div>
|
29 |
+
</div> <!-- end info -->
|
30 |
+
<?php
|
31 |
+
}
|
adminpages/addons/pmpro-post-affiliate-pro.php
CHANGED
@@ -1,31 +1,31 @@
|
|
1 |
-
<?php
|
2 |
-
/*
|
3 |
-
Addon: PMPro Post Affiliate Pro Integration
|
4 |
-
Slug: pmpro-post-affiliate-pro
|
5 |
-
*/
|
6 |
-
pmpro_add_addon('thirdparty', array(
|
7 |
-
'title' => 'PMPro Post Affiliate Pro Integration',
|
8 |
-
'version' => '.2.1.1',
|
9 |
-
'widget' => 'pmpro_addon_pmpro_post_affiliate_pro_widget',
|
10 |
-
'enabled' => function_exists('pap_pmpro_track_sale')
|
11 |
-
)
|
12 |
-
);
|
13 |
-
|
14 |
-
function pmpro_addon_pmpro_post_affiliate_pro_widget($addon)
|
15 |
-
{
|
16 |
-
?>
|
17 |
-
<img class="addon-thumb" src="<?php echo PMPRO_URL?>/adminpages/addons/images/pmpro-post-affiliate-pro.jpg" />
|
18 |
-
<div class="info">
|
19 |
-
<p>Integrate Paid Memberships Pro with the Post Affiliate Pro platform.</p>
|
20 |
-
<div class="actions">
|
21 |
-
<?php if($addon['enabled']) { ?>
|
22 |
-
<a href="https://github.com/strangerstudios/pmpro-post-affiliate-pro/blob/master/readme.txt" class="button">Enabled</a>
|
23 |
-
<?php } elseif(file_exists(dirname(__FILE__) . "/../../../pmpro-post-affiliate-pro/pmpro-post-affiliate-pro.php")) { ?>
|
24 |
-
<a href="<?php echo wp_nonce_url(self_admin_url('plugins.php?action=activate&plugin=pmpro-post-affiliate-pro/pmpro-post-affiliate-pro.php'), 'activate-plugin_pmpro-post-affiliate-pro/pmpro-post-affiliate-pro.php')?>" class="button button-primary">Activate</a>
|
25 |
-
<?php } else { ?>
|
26 |
-
<a href="http://www.paidmembershipspro.com/wp-content/uploads/plugins/pmpro-post-affiliate-pro.zip" class="button button-primary">Download</a>
|
27 |
-
<?php } ?>
|
28 |
-
</div>
|
29 |
-
</div> <!-- end info -->
|
30 |
-
<?php
|
31 |
-
}
|
1 |
+
<?php
|
2 |
+
/*
|
3 |
+
Addon: PMPro Post Affiliate Pro Integration
|
4 |
+
Slug: pmpro-post-affiliate-pro
|
5 |
+
*/
|
6 |
+
pmpro_add_addon('thirdparty', array(
|
7 |
+
'title' => 'PMPro Post Affiliate Pro Integration',
|
8 |
+
'version' => '.2.1.1',
|
9 |
+
'widget' => 'pmpro_addon_pmpro_post_affiliate_pro_widget',
|
10 |
+
'enabled' => function_exists('pap_pmpro_track_sale')
|
11 |
+
)
|
12 |
+
);
|
13 |
+
|
14 |
+
function pmpro_addon_pmpro_post_affiliate_pro_widget($addon)
|
15 |
+
{
|
16 |
+
?>
|
17 |
+
<img class="addon-thumb" src="<?php echo PMPRO_URL?>/adminpages/addons/images/pmpro-post-affiliate-pro.jpg" />
|
18 |
+
<div class="info">
|
19 |
+
<p>Integrate Paid Memberships Pro with the Post Affiliate Pro platform.</p>
|
20 |
+
<div class="actions">
|
21 |
+
<?php if($addon['enabled']) { ?>
|
22 |
+
<a href="https://github.com/strangerstudios/pmpro-post-affiliate-pro/blob/master/readme.txt" class="button">Enabled</a>
|
23 |
+
<?php } elseif(file_exists(dirname(__FILE__) . "/../../../pmpro-post-affiliate-pro/pmpro-post-affiliate-pro.php")) { ?>
|
24 |
+
<a href="<?php echo wp_nonce_url(self_admin_url('plugins.php?action=activate&plugin=pmpro-post-affiliate-pro/pmpro-post-affiliate-pro.php'), 'activate-plugin_pmpro-post-affiliate-pro/pmpro-post-affiliate-pro.php')?>" class="button button-primary">Activate</a>
|
25 |
+
<?php } else { ?>
|
26 |
+
<a href="http://www.paidmembershipspro.com/wp-content/uploads/plugins/pmpro-post-affiliate-pro.zip" class="button button-primary">Download</a>
|
27 |
+
<?php } ?>
|
28 |
+
</div>
|
29 |
+
</div> <!-- end info -->
|
30 |
+
<?php
|
31 |
+
}
|
adminpages/addons/pmpro-register-helper.php
CHANGED
@@ -1,31 +1,31 @@
|
|
1 |
-
<?php
|
2 |
-
/*
|
3 |
-
Addon: PMPro Register Helper
|
4 |
-
Slug: pmpro-register-helper
|
5 |
-
*/
|
6 |
-
pmpro_add_addon('github', array(
|
7 |
-
'title' => 'PMPro Register Helper',
|
8 |
-
'version' => '.5.16.1',
|
9 |
-
'widget' => 'pmpro_addon_pmpro_register_helper_widget',
|
10 |
-
'enabled' => class_exists('PMProRH_Field')
|
11 |
-
)
|
12 |
-
);
|
13 |
-
|
14 |
-
function pmpro_addon_pmpro_register_helper_widget($addon)
|
15 |
-
{
|
16 |
-
?>
|
17 |
-
<img class="addon-thumb" src="<?php echo PMPRO_URL?>/adminpages/addons/images/pmpro-register-helper.gif" />
|
18 |
-
<div class="info">
|
19 |
-
<p>Add additional meta fields to your PMPro checkout page and/or "Your Profile" pages. Support for text, select, multi-select, textarea, hidden, and custom HTML. Loop into existing checkout/profile field sections or add new ones.</p>
|
20 |
-
<div class="actions">
|
21 |
-
<?php if($addon['enabled']) { ?>
|
22 |
-
<a href="https://github.com/strangerstudios/pmpro-register-helper/blob/master/readme.txt" class="button">Enabled</a>
|
23 |
-
<?php } elseif(file_exists(dirname(__FILE__) . "/../../../pmpro-register-helper/pmpro-register-helper.php")) { ?>
|
24 |
-
<a href="<?php echo wp_nonce_url(self_admin_url('plugins.php?action=activate&plugin=pmpro-register-helper/pmpro-register-helper.php'), 'activate-plugin_pmpro-register-helper/pmpro-register-helper.php')?>" class="button button-primary">Activate</a>
|
25 |
-
<?php } else { ?>
|
26 |
-
<a href="http://www.paidmembershipspro.com/wp-content/uploads/plugins/pmpro-register-helper.zip" class="button button-primary">Download</a>
|
27 |
-
<?php } ?>
|
28 |
-
</div>
|
29 |
-
</div> <!-- end info -->
|
30 |
-
<?php
|
31 |
-
}
|
1 |
+
<?php
|
2 |
+
/*
|
3 |
+
Addon: PMPro Register Helper
|
4 |
+
Slug: pmpro-register-helper
|
5 |
+
*/
|
6 |
+
pmpro_add_addon('github', array(
|
7 |
+
'title' => 'PMPro Register Helper',
|
8 |
+
'version' => '.5.16.1',
|
9 |
+
'widget' => 'pmpro_addon_pmpro_register_helper_widget',
|
10 |
+
'enabled' => class_exists('PMProRH_Field')
|
11 |
+
)
|
12 |
+
);
|
13 |
+
|
14 |
+
function pmpro_addon_pmpro_register_helper_widget($addon)
|
15 |
+
{
|
16 |
+
?>
|
17 |
+
<img class="addon-thumb" src="<?php echo PMPRO_URL?>/adminpages/addons/images/pmpro-register-helper.gif" />
|
18 |
+
<div class="info">
|
19 |
+
<p>Add additional meta fields to your PMPro checkout page and/or "Your Profile" pages. Support for text, select, multi-select, textarea, hidden, and custom HTML. Loop into existing checkout/profile field sections or add new ones.</p>
|
20 |
+
<div class="actions">
|
21 |
+
<?php if($addon['enabled']) { ?>
|
22 |
+
<a href="https://github.com/strangerstudios/pmpro-register-helper/blob/master/readme.txt" class="button">Enabled</a>
|
23 |
+
<?php } elseif(file_exists(dirname(__FILE__) . "/../../../pmpro-register-helper/pmpro-register-helper.php")) { ?>
|
24 |
+
<a href="<?php echo wp_nonce_url(self_admin_url('plugins.php?action=activate&plugin=pmpro-register-helper/pmpro-register-helper.php'), 'activate-plugin_pmpro-register-helper/pmpro-register-helper.php')?>" class="button button-primary">Activate</a>
|
25 |
+
<?php } else { ?>
|
26 |
+
<a href="http://www.paidmembershipspro.com/wp-content/uploads/plugins/pmpro-register-helper.zip" class="button button-primary">Download</a>
|
27 |
+
<?php } ?>
|
28 |
+
</div>
|
29 |
+
</div> <!-- end info -->
|
30 |
+
<?php
|
31 |
+
}
|
adminpages/addons/pmpro-require-code-to-register.php
CHANGED
@@ -1,28 +1,28 @@
|
|
1 |
-
<?php
|
2 |
-
/*
|
3 |
-
Addon: PMPro Require Code to Register
|
4 |
-
Slug: pmpro-require-code-to-register
|
5 |
-
*/
|
6 |
-
pmpro_add_addon('gists', array(
|
7 |
-
'title' => 'PMPro Require a Code to Register',
|
8 |
-
'version' => '.1',
|
9 |
-
'widget' => 'pmpro_addon_pmpro_require_code_to_register_widget',
|
10 |
-
'enabled' => function_exists('my_pmpro_registration_checks_require_code_to_register')
|
11 |
-
)
|
12 |
-
);
|
13 |
-
|
14 |
-
function pmpro_addon_pmpro_require_code_to_register_widget($addon)
|
15 |
-
{
|
16 |
-
?>
|
17 |
-
<div class="info">
|
18 |
-
<p>Require a discount code to checkout for a specific level.</p>
|
19 |
-
<div class="actions">
|
20 |
-
<?php if($addon['enabled']) { ?>
|
21 |
-
<a target="_blank" href="https://gist.github.com/strangerstudios/5573829" class="button">Enabled</a>
|
22 |
-
<?php } else { ?>
|
23 |
-
<a target="_blank" href="https://gist.github.com/strangerstudios/5573829" class="button button-primary">View Gist</a>
|
24 |
-
<?php } ?>
|
25 |
-
</div>
|
26 |
-
</div> <!-- end info -->
|
27 |
-
<?php
|
28 |
-
}
|
1 |
+
<?php
|
2 |
+
/*
|
3 |
+
Addon: PMPro Require Code to Register
|
4 |
+
Slug: pmpro-require-code-to-register
|
5 |
+
*/
|
6 |
+
pmpro_add_addon('gists', array(
|
7 |
+
'title' => 'PMPro Require a Code to Register',
|
8 |
+
'version' => '.1',
|
9 |
+
'widget' => 'pmpro_addon_pmpro_require_code_to_register_widget',
|
10 |
+
'enabled' => function_exists('my_pmpro_registration_checks_require_code_to_register')
|
11 |
+
)
|
12 |
+
);
|
13 |
+
|
14 |
+
function pmpro_addon_pmpro_require_code_to_register_widget($addon)
|
15 |
+
{
|
16 |
+
?>
|
17 |
+
<div class="info">
|
18 |
+
<p>Require a discount code to checkout for a specific level.</p>
|
19 |
+
<div class="actions">
|
20 |
+
<?php if($addon['enabled']) { ?>
|
21 |
+
<a target="_blank" href="https://gist.github.com/strangerstudios/5573829" class="button">Enabled</a>
|
22 |
+
<?php } else { ?>
|
23 |
+
<a target="_blank" href="https://gist.github.com/strangerstudios/5573829" class="button button-primary">View Gist</a>
|
24 |
+
<?php } ?>
|
25 |
+
</div>
|
26 |
+
</div> <!-- end info -->
|
27 |
+
<?php
|
28 |
+
}
|
adminpages/addons/pmpro-series.php
CHANGED
@@ -1,31 +1,31 @@
|
|
1 |
-
<?php
|
2 |
-
/*
|
3 |
-
Addon: PMPro Series
|
4 |
-
Slug: pmpro-series
|
5 |
-
*/
|
6 |
-
pmpro_add_addon('github', array(
|
7 |
-
'title' => 'PMPro Series',
|
8 |
-
'version' => '.3',
|
9 |
-
'widget' => 'pmpro_addon_pmpro_series_widget',
|
10 |
-
'enabled' => class_exists("PMProSeries")
|
11 |
-
)
|
12 |
-
);
|
13 |
-
|
14 |
-
function pmpro_addon_pmpro_series_widget($addon)
|
15 |
-
{
|
16 |
-
?>
|
17 |
-
<img class="addon-thumb" src="<?php echo PMPRO_URL?>/adminpages/addons/images/pmpro-series.gif" />
|
18 |
-
<div class="info">
|
19 |
-
<p>"Drip feed" content to your members over the course of their membership. Serializes content by # of days post-registration.</p>
|
20 |
-
<div class="actions">
|
21 |
-
<?php if($addon['enabled']) { ?>
|
22 |
-
<a href="<?php echo admin_url("edit.php?post_type=pmpro_series");?>" class="button">Enabled</a>
|
23 |
-
<?php } elseif(file_exists(dirname(__FILE__) . "/../../../pmpro-series/pmpro-series.php")) { ?>
|
24 |
-
<a href="<?php echo wp_nonce_url(self_admin_url('plugins.php?action=activate&plugin=pmpro-series/pmpro-series.php'), 'activate-plugin_pmpro-series/pmpro-series.php')?>" class="button button-primary">Activate</a>
|
25 |
-
<?php } else { ?>
|
26 |
-
<a href="http://www.paidmembershipspro.com/wp-content/uploads/plugins/pmpro-series.zip" class="button button-primary">Download</a>
|
27 |
-
<?php } ?>
|
28 |
-
</div>
|
29 |
-
</div> <!-- end info -->
|
30 |
-
<?php
|
31 |
}
|
1 |
+
<?php
|
2 |
+
/*
|
3 |
+
Addon: PMPro Series
|
4 |
+
Slug: pmpro-series
|
5 |
+
*/
|
6 |
+
pmpro_add_addon('github', array(
|
7 |
+
'title' => 'PMPro Series',
|
8 |
+
'version' => '.3',
|
9 |
+
'widget' => 'pmpro_addon_pmpro_series_widget',
|
10 |
+
'enabled' => class_exists("PMProSeries")
|
11 |
+
)
|
12 |
+
);
|
13 |
+
|
14 |
+
function pmpro_addon_pmpro_series_widget($addon)
|
15 |
+
{
|
16 |
+
?>
|
17 |
+
<img class="addon-thumb" src="<?php echo PMPRO_URL?>/adminpages/addons/images/pmpro-series.gif" />
|
18 |
+
<div class="info">
|
19 |
+
<p>"Drip feed" content to your members over the course of their membership. Serializes content by # of days post-registration.</p>
|
20 |
+
<div class="actions">
|
21 |
+
<?php if($addon['enabled']) { ?>
|
22 |
+
<a href="<?php echo admin_url("edit.php?post_type=pmpro_series");?>" class="button">Enabled</a>
|
23 |
+
<?php } elseif(file_exists(dirname(__FILE__) . "/../../../pmpro-series/pmpro-series.php")) { ?>
|
24 |
+
<a href="<?php echo wp_nonce_url(self_admin_url('plugins.php?action=activate&plugin=pmpro-series/pmpro-series.php'), 'activate-plugin_pmpro-series/pmpro-series.php')?>" class="button button-primary">Activate</a>
|
25 |
+
<?php } else { ?>
|
26 |
+
<a href="http://www.paidmembershipspro.com/wp-content/uploads/plugins/pmpro-series.zip" class="button button-primary">Download</a>
|
27 |
+
<?php } ?>
|
28 |
+
</div>
|
29 |
+
</div> <!-- end info -->
|
30 |
+
<?php
|
31 |
}
|
adminpages/addons/pmpro-shipping.php
CHANGED
@@ -1,31 +1,31 @@
|
|
1 |
-
<?php
|
2 |
-
/*
|
3 |
-
Addon: PMPro Shipping Add On
|
4 |
-
Slug: pmpro-shipping
|
5 |
-
*/
|
6 |
-
pmpro_add_addon('github', array(
|
7 |
-
'title' => 'PMPro Shipping Add On',
|
8 |
-
'version' => '.2.6',
|
9 |
-
'widget' => 'pmpro_addon_pmpro_shipping_widget',
|
10 |
-
'enabled' => function_exists('pmproship_pmpro_checkout_boxes')
|
11 |
-
)
|
12 |
-
);
|
13 |
-
|
14 |
-
function pmpro_addon_pmpro_shipping_widget($addon)
|
15 |
-
{
|
16 |
-
?>
|
17 |
-
<?php /* <img class="addon-thumb" src="<?php echo PMPRO_URL?>/adminpages/addons/images/pmpro-shipping.jpg" /> */ ?>
|
18 |
-
<div class="info">
|
19 |
-
<p>Adds shipping fields to the checkout page, confirmation page, confirmation emails, member's list and edit user profile pages.</p>
|
20 |
-
<div class="actions">
|
21 |
-
<?php if($addon['enabled']) { ?>
|
22 |
-
<a href="https://github.com/strangerstudios/pmpro-shipping/" class="button">Enabled</a>
|
23 |
-
<?php } elseif(file_exists(dirname(__FILE__) . "/../../../pmpro-shipping/pmpro-shipping.php")) { ?>
|
24 |
-
<a href="<?php echo wp_nonce_url(self_admin_url('plugins.php?action=activate&plugin=pmpro-shipping/pmpro-shipping.php'), 'activate-plugin_pmpro-shipping/pmpro-shipping.php')?>" class="button button-primary">Activate</a>
|
25 |
-
<?php } else { ?>
|
26 |
-
<a href="http://www.paidmembershipspro.com/wp-content/uploads/plugins/pmpro-shipping.zip" class="button button-primary">Download</a>
|
27 |
-
<?php } ?>
|
28 |
-
</div>
|
29 |
-
</div> <!-- end info -->
|
30 |
-
<?php
|
31 |
-
}
|
1 |
+
<?php
|
2 |
+
/*
|
3 |
+
Addon: PMPro Shipping Add On
|
4 |
+
Slug: pmpro-shipping
|
5 |
+
*/
|
6 |
+
pmpro_add_addon('github', array(
|
7 |
+
'title' => 'PMPro Shipping Add On',
|
8 |
+
'version' => '.2.6',
|
9 |
+
'widget' => 'pmpro_addon_pmpro_shipping_widget',
|
10 |
+
'enabled' => function_exists('pmproship_pmpro_checkout_boxes')
|
11 |
+
)
|
12 |
+
);
|
13 |
+
|
14 |
+
function pmpro_addon_pmpro_shipping_widget($addon)
|
15 |
+
{
|
16 |
+
?>
|
17 |
+
<?php /* <img class="addon-thumb" src="<?php echo PMPRO_URL?>/adminpages/addons/images/pmpro-shipping.jpg" /> */ ?>
|
18 |
+
<div class="info">
|
19 |
+
<p>Adds shipping fields to the checkout page, confirmation page, confirmation emails, member's list and edit user profile pages.</p>
|
20 |
+
<div class="actions">
|
21 |
+
<?php if($addon['enabled']) { ?>
|
22 |
+
<a href="https://github.com/strangerstudios/pmpro-shipping/" class="button">Enabled</a>
|
23 |
+
<?php } elseif(file_exists(dirname(__FILE__) . "/../../../pmpro-shipping/pmpro-shipping.php")) { ?>
|
24 |
+
<a href="<?php echo wp_nonce_url(self_admin_url('plugins.php?action=activate&plugin=pmpro-shipping/pmpro-shipping.php'), 'activate-plugin_pmpro-shipping/pmpro-shipping.php')?>" class="button button-primary">Activate</a>
|
25 |
+
<?php } else { ?>
|
26 |
+
<a href="http://www.paidmembershipspro.com/wp-content/uploads/plugins/pmpro-shipping.zip" class="button button-primary">Download</a>
|
27 |
+
<?php } ?>
|
28 |
+
</div>
|
29 |
+
</div> <!-- end info -->
|
30 |
+
<?php
|
31 |
+
}
|
adminpages/addons/pmpro-user-pages.php
CHANGED
@@ -1,30 +1,30 @@
|
|
1 |
-
<?php
|
2 |
-
/*
|
3 |
-
Addon: PMPro User Pages
|
4 |
-
Slug: pmpro-user-pages
|
5 |
-
*/
|
6 |
-
pmpro_add_addon('github', array(
|
7 |
-
'title' => 'PMPro User Pages',
|
8 |
-
'version' => '.3',
|
9 |
-
'widget' => 'pmpro_addon_pmpro_user_pages_widget',
|
10 |
-
'enabled' => function_exists('pmproup_pmpro_after_checkout')
|
11 |
-
)
|
12 |
-
);
|
13 |
-
|
14 |
-
function pmpro_addon_pmpro_user_pages_widget($addon)
|
15 |
-
{
|
16 |
-
?>
|
17 |
-
<div class="info">
|
18 |
-
<p>Creates a unique page for each Member after checkout, giving the Admin access to write customized content for each specific member.</p>
|
19 |
-
<div class="actions">
|
20 |
-
<?php if($addon['enabled']) { ?>
|
21 |
-
<a href="https://github.com/strangerstudios/pmpro-user-pages/blob/master/readme.txt" class="button">Enabled</a>
|
22 |
-
<?php } elseif(file_exists(dirname(__FILE__) . "/../../../pmpro-user-pages/pmpro-user-pages.php")) { ?>
|
23 |
-
<a href="<?php echo wp_nonce_url(self_admin_url('plugins.php?action=activate&plugin=pmpro-user-pages/pmpro-user-pages.php'), 'activate-plugin_pmpro-user-pages/pmpro-user-pages.php')?>" class="button button-primary">Activate</a>
|
24 |
-
<?php } else { ?>
|
25 |
-
<a href="http://www.paidmembershipspro.com/wp-content/uploads/plugins/pmpro-user-pages.zip" class="button button-primary">Download</a>
|
26 |
-
<?php } ?>
|
27 |
-
</div>
|
28 |
-
</div> <!-- end info -->
|
29 |
-
<?php
|
30 |
-
}
|
1 |
+
<?php
|
2 |
+
/*
|
3 |
+
Addon: PMPro User Pages
|
4 |
+
Slug: pmpro-user-pages
|
5 |
+
*/
|
6 |
+
pmpro_add_addon('github', array(
|
7 |
+
'title' => 'PMPro User Pages',
|
8 |
+
'version' => '.3',
|
9 |
+
'widget' => 'pmpro_addon_pmpro_user_pages_widget',
|
10 |
+
'enabled' => function_exists('pmproup_pmpro_after_checkout')
|
11 |
+
)
|
12 |
+
);
|
13 |
+
|
14 |
+
function pmpro_addon_pmpro_user_pages_widget($addon)
|
15 |
+
{
|
16 |
+
?>
|
17 |
+
<div class="info">
|
18 |
+
<p>Creates a unique page for each Member after checkout, giving the Admin access to write customized content for each specific member.</p>
|
19 |
+
<div class="actions">
|
20 |
+
<?php if($addon['enabled']) { ?>
|
21 |
+
<a href="https://github.com/strangerstudios/pmpro-user-pages/blob/master/readme.txt" class="button">Enabled</a>
|
22 |
+
<?php } elseif(file_exists(dirname(__FILE__) . "/../../../pmpro-user-pages/pmpro-user-pages.php")) { ?>
|
23 |
+
<a href="<?php echo wp_nonce_url(self_admin_url('plugins.php?action=activate&plugin=pmpro-user-pages/pmpro-user-pages.php'), 'activate-plugin_pmpro-user-pages/pmpro-user-pages.php')?>" class="button button-primary">Activate</a>
|
24 |
+
<?php } else { ?>
|
25 |
+
<a href="http://www.paidmembershipspro.com/wp-content/uploads/plugins/pmpro-user-pages.zip" class="button button-primary">Download</a>
|
26 |
+
<?php } ?>
|
27 |
+
</div>
|
28 |
+
</div> <!-- end info -->
|
29 |
+
<?php
|
30 |
+
}
|
adminpages/addons/pmpro-woocommerce.php
CHANGED
@@ -1,31 +1,31 @@
|
|
1 |
-
<?php
|
2 |
-
/*
|
3 |
-
Addon: PMPro WooCommerce
|
4 |
-
Slug: pmpro-woocommerce
|
5 |
-
*/
|
6 |
-
pmpro_add_addon('thirdparty', array(
|
7 |
-
'title' => 'PMPro WooCommerce',
|
8 |
-
'version' => '1.2.2',
|
9 |
-
'widget' => 'pmpro_addon_pmpro_woocommerce_widget',
|
10 |
-
'enabled' => function_exists('pmprowoo_add_membership_from_order')
|
11 |
-
)
|
12 |
-
);
|
13 |
-
|
14 |
-
function pmpro_addon_pmpro_woocommerce_widget($addon)
|
15 |
-
{
|
16 |
-
?>
|
17 |
-
<img class="addon-thumb" src="<?php echo PMPRO_URL?>/adminpages/addons/images/pmpro-woocommerce.gif" />
|
18 |
-
<div class="info">
|
19 |
-
<p>Use <a href="http://www.woothemes.com/woocommerce/">WooCommerce</a> to purchase membership levels or set members-only product pricing.</p>
|
20 |
-
<div class="actions">
|
21 |
-
<?php if($addon['enabled']) { ?>
|
22 |
-
<a href="<?php echo admin_url("plugins.php");?>" class="button">Enabled</a>
|
23 |
-
<?php } elseif(file_exists(dirname(__FILE__) . "/../../../pmpro-woocommerce/pmpro-woocommerce.php")) { ?>
|
24 |
-
<a href="<?php echo wp_nonce_url(self_admin_url('plugins.php?action=activate&plugin=pmpro-woocommerce/pmpro-woocommerce.php'), 'activate-plugin_pmpro-woocommerce/pmpro-woocommerce.php')?>" class="button button-primary">Activate</a>
|
25 |
-
<?php } else { ?>
|
26 |
-
<a href="<?php echo wp_nonce_url(self_admin_url('update.php?action=install-plugin&plugin=pmpro-woocommerce'), 'install-plugin_pmpro-woocommerce'); ?>" class="button button-primary">Download</a>
|
27 |
-
<?php } ?>
|
28 |
-
</div>
|
29 |
-
</div> <!-- end info -->
|
30 |
-
<?php
|
31 |
-
}
|
1 |
+
<?php
|
2 |
+
/*
|
3 |
+
Addon: PMPro WooCommerce
|
4 |
+
Slug: pmpro-woocommerce
|
5 |
+
*/
|
6 |
+
pmpro_add_addon('thirdparty', array(
|
7 |
+
'title' => 'PMPro WooCommerce',
|
8 |
+
'version' => '1.2.2',
|
9 |
+
'widget' => 'pmpro_addon_pmpro_woocommerce_widget',
|
10 |
+
'enabled' => function_exists('pmprowoo_add_membership_from_order')
|
11 |
+
)
|
12 |
+
);
|
13 |
+
|
14 |
+
function pmpro_addon_pmpro_woocommerce_widget($addon)
|
15 |
+
{
|
16 |
+
?>
|
17 |
+
<img class="addon-thumb" src="<?php echo PMPRO_URL?>/adminpages/addons/images/pmpro-woocommerce.gif" />
|
18 |
+
<div class="info">
|
19 |
+
<p>Use <a href="http://www.woothemes.com/woocommerce/">WooCommerce</a> to purchase membership levels or set members-only product pricing.</p>
|
20 |
+
<div class="actions">
|
21 |
+
<?php if($addon['enabled']) { ?>
|
22 |
+
<a href="<?php echo admin_url("plugins.php");?>" class="button">Enabled</a>
|
23 |
+
<?php } elseif(file_exists(dirname(__FILE__) . "/../../../pmpro-woocommerce/pmpro-woocommerce.php")) { ?>
|
24 |
+
<a href="<?php echo wp_nonce_url(self_admin_url('plugins.php?action=activate&plugin=pmpro-woocommerce/pmpro-woocommerce.php'), 'activate-plugin_pmpro-woocommerce/pmpro-woocommerce.php')?>" class="button button-primary">Activate</a>
|
25 |
+
<?php } else { ?>
|
26 |
+
<a href="<?php echo wp_nonce_url(self_admin_url('update.php?action=install-plugin&plugin=pmpro-woocommerce'), 'install-plugin_pmpro-woocommerce'); ?>" class="button button-primary">Download</a>
|
27 |
+
<?php } ?>
|
28 |
+
</div>
|
29 |
+
</div> <!-- end info -->
|
30 |
+
<?php
|
31 |
+
}
|
adminpages/addons/pmpro-wp-affiliate.php
CHANGED
@@ -1,31 +1,31 @@
|
|
1 |
-
<?php
|
2 |
-
/*
|
3 |
-
Addon: PMPro WP Affiliate Platform Integration
|
4 |
-
Slug: pmpro-wp-affiliate
|
5 |
-
*/
|
6 |
-
pmpro_add_addon('thirdparty', array(
|
7 |
-
'title' => 'PMPro WP Affiliate Platform Integration',
|
8 |
-
'version' => '.3',
|
9 |
-
'widget' => 'pmpro_addon_pmpro_wp_affiliate_widget',
|
10 |
-
'enabled' => function_exists('wpa_pmpro_after_checkout')
|
11 |
-
)
|
12 |
-
);
|
13 |
-
|
14 |
-
function pmpro_addon_pmpro_wp_affiliate_widget($addon)
|
15 |
-
{
|
16 |
-
?>
|
17 |
-
<img class="addon-thumb" src="<?php echo PMPRO_URL?>/adminpages/addons/images/pmpro-wp-affiliate-platform.jpg" />
|
18 |
-
<div class="info">
|
19 |
-
<p>Process an affiliate via WP Affiliate Platform after a PMPro checkout.</p>
|
20 |
-
<div class="actions">
|
21 |
-
<?php if($addon['enabled']) { ?>
|
22 |
-
<a href="https://github.com/strangerstudios/pmpro-wp-affiliate-platform/" class="button">Enabled</a>
|
23 |
-
<?php } elseif(file_exists(dirname(__FILE__) . "/../../../pmpro-wp-affiliate-platform/pmpro-wp-affiliate-platform.php")) { ?>
|
24 |
-
<a href="<?php echo wp_nonce_url(self_admin_url('plugins.php?action=activate&plugin=pmpro-wp-affiliate-platform/pmpro-wp-affiliate-platform.php'), 'activate-plugin_pmpro-wp-affiliate-platform/pmpro-wp-affiliate-platform.php')?>" class="button button-primary">Activate</a>
|
25 |
-
<?php } else { ?>
|
26 |
-
<a href="http://www.paidmembershipspro.com/wp-content/uploads/plugins/pmpro-wp-affiliate-platform.zip" class="button button-primary">Download</a>
|
27 |
-
<?php } ?>
|
28 |
-
</div>
|
29 |
-
</div> <!-- end info -->
|
30 |
-
<?php
|
31 |
-
}
|
1 |
+
<?php
|
2 |
+
/*
|
3 |
+
Addon: PMPro WP Affiliate Platform Integration
|
4 |
+
Slug: pmpro-wp-affiliate
|
5 |
+
*/
|
6 |
+
pmpro_add_addon('thirdparty', array(
|
7 |
+
'title' => 'PMPro WP Affiliate Platform Integration',
|
8 |
+
'version' => '.3',
|
9 |
+
'widget' => 'pmpro_addon_pmpro_wp_affiliate_widget',
|
10 |
+
'enabled' => function_exists('wpa_pmpro_after_checkout')
|
11 |
+
)
|
12 |
+
);
|
13 |
+
|
14 |
+
function pmpro_addon_pmpro_wp_affiliate_widget($addon)
|
15 |
+
{
|
16 |
+
?>
|
17 |
+
<img class="addon-thumb" src="<?php echo PMPRO_URL?>/adminpages/addons/images/pmpro-wp-affiliate-platform.jpg" />
|
18 |
+
<div class="info">
|
19 |
+
<p>Process an affiliate via WP Affiliate Platform after a PMPro checkout.</p>
|
20 |
+
<div class="actions">
|
21 |
+
<?php if($addon['enabled']) { ?>
|
22 |
+
<a href="https://github.com/strangerstudios/pmpro-wp-affiliate-platform/" class="button">Enabled</a>
|
23 |
+
<?php } elseif(file_exists(dirname(__FILE__) . "/../../../pmpro-wp-affiliate-platform/pmpro-wp-affiliate-platform.php")) { ?>
|
24 |
+
<a href="<?php echo wp_nonce_url(self_admin_url('plugins.php?action=activate&plugin=pmpro-wp-affiliate-platform/pmpro-wp-affiliate-platform.php'), 'activate-plugin_pmpro-wp-affiliate-platform/pmpro-wp-affiliate-platform.php')?>" class="button button-primary">Activate</a>
|
25 |
+
<?php } else { ?>
|
26 |
+
<a href="http://www.paidmembershipspro.com/wp-content/uploads/plugins/pmpro-wp-affiliate-platform.zip" class="button button-primary">Download</a>
|
27 |
+
<?php } ?>
|
28 |
+
</div>
|
29 |
+
</div> <!-- end info -->
|
30 |
+
<?php
|
31 |
+
}
|
adminpages/addons/tml.php
CHANGED
@@ -1,32 +1,32 @@
|
|
1 |
-
<?php
|
2 |
-
/*
|
3 |
-
Addon: Theme My Login
|
4 |
-
Slug: pmpro-tml
|
5 |
-
*/
|
6 |
-
pmpro_add_addon('recommended', array(
|
7 |
-
'title' => 'Theme My Login',
|
8 |
-
'widget' => 'pmpro_addon_tml_widget',
|
9 |
-
'enabled' => class_exists('Theme_My_Login'),
|
10 |
-
'version' => '6.3.10'
|
11 |
-
)
|
12 |
-
);
|
13 |
-
|
14 |
-
function pmpro_addon_tml_widget($addon)
|
15 |
-
{
|
16 |
-
?>
|
17 |
-
<div class="info">
|
18 |
-
<p>This plugin themes the WordPress login, registration and forgot password pages according to your current theme. By <a href="http://www.jfarthing.com/" target="_blank">Jeff Farthing</a></p>
|
19 |
-
<div class="actions">
|
20 |
-
<form method="post" name="component-actions" action="">
|
21 |
-
<?php if($addon['enabled']) { ?>
|
22 |
-
<a href="<?php echo admin_url("plugins.php");?>" class="button">Enabled</a>
|
23 |
-
<?php } elseif(file_exists(dirname(__FILE__) . "/../../../theme-my-login/theme-my-login.php")) { ?>
|
24 |
-
<a href="<?php echo wp_nonce_url(self_admin_url('plugins.php?action=activate&plugin=theme-my-login/theme-my-login.php'), 'activate-plugin_theme-my-login/theme-my-login.php')?>" class="button button-primary">Activate</a>
|
25 |
-
<?php } else { ?>
|
26 |
-
<a href="<?php echo wp_nonce_url(self_admin_url('update.php?action=install-plugin&plugin=theme-my-login'), 'install-plugin_theme-my-login'); ?>" class="button button-primary">Download</a>
|
27 |
-
<?php } ?>
|
28 |
-
</form>
|
29 |
-
</div>
|
30 |
-
</div> <!-- end info -->
|
31 |
-
<?php
|
32 |
-
}
|
1 |
+
<?php
|
2 |
+
/*
|
3 |
+
Addon: Theme My Login
|
4 |
+
Slug: pmpro-tml
|
5 |
+
*/
|
6 |
+
pmpro_add_addon('recommended', array(
|
7 |
+
'title' => 'Theme My Login',
|
8 |
+
'widget' => 'pmpro_addon_tml_widget',
|
9 |
+
'enabled' => class_exists('Theme_My_Login'),
|
10 |
+
'version' => '6.3.10'
|
11 |
+
)
|
12 |
+
);
|
13 |
+
|
14 |
+
function pmpro_addon_tml_widget($addon)
|
15 |
+
{
|
16 |
+
?>
|
17 |
+
<div class="info">
|
18 |
+
<p>This plugin themes the WordPress login, registration and forgot password pages according to your current theme. By <a href="http://www.jfarthing.com/" target="_blank">Jeff Farthing</a></p>
|
19 |
+
<div class="actions">
|
20 |
+
<form method="post" name="component-actions" action="">
|
21 |
+
<?php if($addon['enabled']) { ?>
|
22 |
+
<a href="<?php echo admin_url("plugins.php");?>" class="button">Enabled</a>
|
23 |
+
<?php } elseif(file_exists(dirname(__FILE__) . "/../../../theme-my-login/theme-my-login.php")) { ?>
|
24 |
+
<a href="<?php echo wp_nonce_url(self_admin_url('plugins.php?action=activate&plugin=theme-my-login/theme-my-login.php'), 'activate-plugin_theme-my-login/theme-my-login.php')?>" class="button button-primary">Activate</a>
|
25 |
+
<?php } else { ?>
|
26 |
+
<a href="<?php echo wp_nonce_url(self_admin_url('update.php?action=install-plugin&plugin=theme-my-login'), 'install-plugin_theme-my-login'); ?>" class="button button-primary">Download</a>
|
27 |
+
<?php } ?>
|
28 |
+
</form>
|
29 |
+
</div>
|
30 |
+
</div> <!-- end info -->
|
31 |
+
<?php
|
32 |
+
}
|
adminpages/addons/wp-bouncer.php
CHANGED
@@ -1,31 +1,31 @@
|
|
1 |
-
<?php
|
2 |
-
/*
|
3 |
-
Addon: WP Bouncer
|
4 |
-
Slug: wp-bouncer
|
5 |
-
*/
|
6 |
-
pmpro_add_addon('repo', array(
|
7 |
-
'title' => 'WP Bouncer',
|
8 |
-
'version' => '1.1',
|
9 |
-
'widget' => 'pmpro_addon_wp_bouncer_widget',
|
10 |
-
'enabled' => class_exists('WP_Bouncer')
|
11 |
-
)
|
12 |
-
);
|
13 |
-
|
14 |
-
function pmpro_addon_wp_bouncer_widget($addon)
|
15 |
-
{
|
16 |
-
?>
|
17 |
-
<img class="addon-thumb" src="<?php echo PMPRO_URL?>/adminpages/addons/images/wp-bouncer.gif" />
|
18 |
-
<div class="info">
|
19 |
-
<p>Make sure users are only logged in from one computer or device at a time.</p>
|
20 |
-
<div class="actions">
|
21 |
-
<?php if($addon['enabled']) { ?>
|
22 |
-
<a href="http://wordpress.org/plugins/wp-bouncer/" class="button">Enabled</a>
|
23 |
-
<?php } elseif(file_exists(dirname(__FILE__) . "/../../../wp-bouncer/wp-bouncer.php")) { ?>
|
24 |
-
<a href="<?php echo wp_nonce_url(self_admin_url('plugins.php?action=activate&plugin=wp-bouncer/wp-bouncer.php'), 'activate-plugin_wp-bouncer/wp-bouncer.php')?>" class="button button-primary">Activate</a>
|
25 |
-
<?php } else { ?>
|
26 |
-
<a href="<?php echo wp_nonce_url(self_admin_url('update.php?action=install-plugin&plugin=wp-bouncer'), 'install-plugin_wp-bouncer'); ?>" class="button button-primary">Download</a>
|
27 |
-
<?php } ?>
|
28 |
-
</div>
|
29 |
-
</div> <!-- end info -->
|
30 |
-
<?php
|
31 |
-
}
|
1 |
+
<?php
|
2 |
+
/*
|
3 |
+
Addon: WP Bouncer
|
4 |
+
Slug: wp-bouncer
|
5 |
+
*/
|
6 |
+
pmpro_add_addon('repo', array(
|
7 |
+
'title' => 'WP Bouncer',
|
8 |
+
'version' => '1.1',
|
9 |
+
'widget' => 'pmpro_addon_wp_bouncer_widget',
|
10 |
+
'enabled' => class_exists('WP_Bouncer')
|
11 |
+
)
|
12 |
+
);
|
13 |
+
|
14 |
+
function pmpro_addon_wp_bouncer_widget($addon)
|
15 |
+
{
|
16 |
+
?>
|
17 |
+
<img class="addon-thumb" src="<?php echo PMPRO_URL?>/adminpages/addons/images/wp-bouncer.gif" />
|
18 |
+
<div class="info">
|
19 |
+
<p>Make sure users are only logged in from one computer or device at a time.</p>
|
20 |
+
<div class="actions">
|
21 |
+
<?php if($addon['enabled']) { ?>
|
22 |
+
<a href="http://wordpress.org/plugins/wp-bouncer/" class="button">Enabled</a>
|
23 |
+
<?php } elseif(file_exists(dirname(__FILE__) . "/../../../wp-bouncer/wp-bouncer.php")) { ?>
|
24 |
+
<a href="<?php echo wp_nonce_url(self_admin_url('plugins.php?action=activate&plugin=wp-bouncer/wp-bouncer.php'), 'activate-plugin_wp-bouncer/wp-bouncer.php')?>" class="button button-primary">Activate</a>
|
25 |
+
<?php } else { ?>
|
26 |
+
<a href="<?php echo wp_nonce_url(self_admin_url('update.php?action=install-plugin&plugin=wp-bouncer'), 'install-plugin_wp-bouncer'); ?>" class="button button-primary">Download</a>
|
27 |
+
<?php } ?>
|
28 |
+
</div>
|
29 |
+
</div> <!-- end info -->
|
30 |
+
<?php
|
31 |
+
}
|
adminpages/admin_footer.php
CHANGED
@@ -1,2 +1,2 @@
|
|
1 |
-
<div class="clear"></div>
|
2 |
</div>
|
1 |
+
<div class="clear"></div>
|
2 |
</div>
|
adminpages/admin_header.php
CHANGED
@@ -1,156 +1,173 @@
|
|
1 |
-
<?php
|
2 |
-
require_once(dirname(__FILE__) . "/functions.php");
|
3 |
-
|
4 |
-
if(isset($_REQUEST['page']))
|
5 |
-
$view = $_REQUEST['page'];
|
6 |
-
else
|
7 |
-
$view = "";
|
8 |
-
|
9 |
-
global $pmpro_ready, $msg, $msgt;
|
10 |
-
$pmpro_ready = pmpro_is_ready();
|
11 |
-
if(!$pmpro_ready)
|
12 |
-
{
|
13 |
-
global $pmpro_level_ready, $pmpro_gateway_ready, $pmpro_pages_ready;
|
14 |
-
if(!isset($edit))
|
15 |
-
{
|
16 |
-
if(isset($_REQUEST['edit']))
|
17 |
-
$edit = $_REQUEST['edit'];
|
18 |
-
else
|
19 |
-
$edit = false;
|
20 |
-
}
|
21 |
-
|
22 |
-
if(empty($msg))
|
23 |
-
$msg = -1;
|
24 |
-
if(empty($pmpro_level_ready) && empty($edit))
|
25 |
-
$msgt .= " <a href=\"?page=pmpro-membershiplevels&edit=-1\">" . __("Add a membership level to get started.", "pmpro") . "</a>";
|
26 |
-
elseif($pmpro_level_ready && !$pmpro_pages_ready && $view != "pmpro-pagesettings")
|
27 |
-
$msgt .= " <a href=\"?page=pmpro-pagesettings\">" . __("Setup the membership pages", "pmpro") . "</a>.";
|
28 |
-
elseif($pmpro_level_ready && $pmpro_pages_ready && !$pmpro_gateway_ready && $view != "pmpro-paymentsettings")
|
29 |
-
$msgt .= " <a href=\"?page=pmpro-paymentsettings\">" . __("Setup your SSL certificate and payment gateway", "pmpro") . "</a>.";
|
30 |
-
|
31 |
-
if(empty($msgt))
|
32 |
-
$msg = false;
|
33 |
-
}
|
34 |
-
|
35 |
-
if(!pmpro_checkLevelForStripeCompatibility())
|
36 |
-
{
|
37 |
-
$msg = -1;
|
38 |
-
$msgt = __("The billing details for some of your membership levels is not supported by Stripe.", "pmpro");
|
39 |
-
if($view == "pmpro-membershiplevels" && !empty($_REQUEST['edit']) && $_REQUEST['edit'] > 0)
|
40 |
-
{
|
41 |
-
if(!pmpro_checkLevelForStripeCompatibility($_REQUEST['edit']))
|
42 |
-
{
|
43 |
-
global $pmpro_stripe_error;
|
44 |
-
$pmpro_stripe_error = true;
|
45 |
-
$msg = -1;
|
46 |
-
$msgt = __("The billing details for this level are not supported by Stripe. Please review the notes in the Billing Details section below.", "pmpro");
|
47 |
-
}
|
48 |
-
}
|
49 |
-
elseif($view == "pmpro-membershiplevels")
|
50 |
-
$msgt .= " " . __("The levels with issues are highlighted below.", "pmpro");
|
51 |
-
else
|
52 |
-
$msgt .= " <a href=\"?page=pmpro-membershiplevels\">" . __("Please edit your levels", "pmpro") . "</a>.";
|
53 |
-
}
|
54 |
-
|
55 |
-
if(!pmpro_checkLevelForPayflowCompatibility())
|
56 |
-
{
|
57 |
-
$msg = -1;
|
58 |
-
$msgt = __("The billing details for some of your membership levels is not supported by Payflow.", "pmpro");
|
59 |
-
if($view == "pmpro-membershiplevels" && !empty($_REQUEST['edit']) && $_REQUEST['edit'] > 0)
|
60 |
-
{
|
61 |
-
if(!pmpro_checkLevelForPayflowCompatibility($_REQUEST['edit']))
|
62 |
-
{
|
63 |
-
global $pmpro_payflow_error;
|
64 |
-
$pmpro_payflow_error = true;
|
65 |
-
$msg = -1;
|
66 |
-
$msgt = __("The billing details for this level are not supported by Payflow. Please review the notes in the Billing Details section below.", "pmpro");
|
67 |
-
}
|
68 |
-
}
|
69 |
-
elseif($view == "pmpro-membershiplevels")
|
70 |
-
$msgt .= " " . __("The levels with issues are highlighted below.", "pmpro");
|
71 |
-
else
|
72 |
-
$msgt .= " <a href=\"?page=pmpro-membershiplevels\">" . __("Please edit your levels", "pmpro") . "</a>.";
|
73 |
-
}
|
74 |
-
|
75 |
-
if(!pmpro_checkLevelForBraintreeCompatibility())
|
76 |
-
{
|
77 |
-
$msg = -1;
|
78 |
-
$msgt = __("The billing details for some of your membership levels is not supported by Braintree.", "pmpro");
|
79 |
-
if($view == "pmpro-membershiplevels" && !empty($_REQUEST['edit']) && $_REQUEST['edit'] > 0)
|
80 |
-
{
|
81 |
-
if(!pmpro_checkLevelForBraintreeCompatibility($_REQUEST['edit']))
|
82 |
-
{
|
83 |
-
global $pmpro_braintree_error;
|
84 |
-
$pmpro_braintree_error = true;
|
85 |
-
$msg = -1;
|
86 |
-
$msgt = __("The billing details for this level are not supported by Braintree. Please review the notes in the Billing Details section below.", "pmpro");
|
87 |
-
}
|
88 |
-
}
|
89 |
-
elseif($view == "pmpro-membershiplevels")
|
90 |
-
$msgt .= " " . __("The levels with issues are highlighted below.", "pmpro");
|
91 |
-
else
|
92 |
-
$msgt .= " <a href=\"?page=pmpro-membershiplevels\">" . __("Please edit your levels", "pmpro") . "</a>.";
|
93 |
-
}
|
94 |
-
|
95 |
-
if(!pmpro_checkLevelForTwoCheckoutCompatibility())
|
96 |
-
{
|
97 |
-
$msg = -1;
|
98 |
-
$msgt = __("The billing details for some of your membership levels is not supported by TwoCheckout.", "pmpro");
|
99 |
-
if($view == "pmpro-membershiplevels" && !empty($_REQUEST['edit']) && $_REQUEST['edit'] > 0)
|
100 |
-
{
|
101 |
-
if(!pmpro_checkLevelForTwoCheckoutCompatibility($_REQUEST['edit']))
|
102 |
-
{
|
103 |
-
global $pmpro_twocheckout_error;
|
104 |
-
$pmpro_twocheckout_error = true;
|
105 |
-
|
106 |
-
$msg = -1;
|
107 |
-
$msgt = __("The billing details for this level are not supported by 2Checkout. Please review the notes in the Billing Details section below.", "pmpro");
|
108 |
-
}
|
109 |
-
}
|
110 |
-
elseif($view == "pmpro-membershiplevels")
|
111 |
-
$msgt .= " " . __("The levels with issues are highlighted below.", "pmpro");
|
112 |
-
else
|
113 |
-
$msgt .= " <a href=\"?page=pmpro-membershiplevels\">" . __("Please edit your levels", "pmpro") . "</a>.";
|
114 |
-
}
|
115 |
-
|
116 |
-
if(!empty($msg))
|
117 |
-
{
|
118 |
-
?>
|
119 |
-
<div id="message" class="<?php if($msg > 0) echo "updated fade"; else echo "error"; ?>"><p><?php echo $msgt?></p></div>
|
120 |
-
<?php
|
121 |
-
}
|
122 |
-
|
123 |
-
?>
|
124 |
-
<div class="wrap pmpro_admin">
|
125 |
-
<div class="pmpro_banner">
|
126 |
-
<a class="pmpro_logo" title="Paid Memberships Pro - Membership Plugin for WordPress" target="_blank" href="<?php echo pmpro_https_filter("http://www.paidmembershipspro.com")?>"><img src="<?php echo PMPRO_URL?>/images/Paid-Memberships-Pro.png" width="350" height="75" border="0" alt="Paid Memberships Pro(c) - All Rights Reserved" /></a>
|
127 |
-
<div class="pmpro_meta"><span class="pmpro_tag-grey">v<?php echo PMPRO_VERSION?></span><a target="_blank" class="pmpro_tag-blue" href="<?php echo pmpro_https_filter("http://www.paidmembershipspro.com")?>"><?php _e('Plugin Support', 'pmpro');?></a><a target="_blank" class="pmpro_tag-blue" href="http://www.paidmembershipspro.com/forums/"><?php _e('User Forum', 'pmpro');?></a></div>
|
128 |
-
|
129 |
-
<br style="clear:both;" />
|
130 |
-
</div>
|
131 |
-
|
132 |
-
<div id="pmpro_notifications">
|
133 |
-
</div>
|
134 |
-
<script>
|
135 |
-
jQuery(document).ready(function() {
|
136 |
-
jQuery.get('<?php echo get_admin_url(NULL, "/admin-ajax.php?action=pmpro_notifications"); ?>', function(data) {
|
137 |
-
if(data && data != 'NULL')
|
138 |
-
jQuery('#pmpro_notifications').html(data);
|
139 |
-
});
|
140 |
-
});
|
141 |
-
</script>
|
142 |
-
|
143 |
-
<?php
|
144 |
-
$settings_tabs = array("pmpro-membershiplevels", "pmpro-pagesettings", "pmpro-paymentsettings", "pmpro-emailsettings", "pmpro-advancedsettings", "pmpro-addons");
|
145 |
-
if(in_array($view, $settings_tabs))
|
146 |
-
{
|
147 |
-
?>
|
148 |
-
<h2 class="nav-tab-wrapper">
|
149 |
-
|
150 |
-
|
151 |
-
|
152 |
-
|
153 |
-
|
154 |
-
|
155 |
-
|
156 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
require_once(dirname(__FILE__) . "/functions.php");
|
3 |
+
|
4 |
+
if(isset($_REQUEST['page']))
|
5 |
+
$view = $_REQUEST['page'];
|
6 |
+
else
|
7 |
+
$view = "";
|
8 |
+
|
9 |
+
global $pmpro_ready, $msg, $msgt;
|
10 |
+
$pmpro_ready = pmpro_is_ready();
|
11 |
+
if(!$pmpro_ready)
|
12 |
+
{
|
13 |
+
global $pmpro_level_ready, $pmpro_gateway_ready, $pmpro_pages_ready;
|
14 |
+
if(!isset($edit))
|
15 |
+
{
|
16 |
+
if(isset($_REQUEST['edit']))
|
17 |
+
$edit = $_REQUEST['edit'];
|
18 |
+
else
|
19 |
+
$edit = false;
|
20 |
+
}
|
21 |
+
|
22 |
+
if(empty($msg))
|
23 |
+
$msg = -1;
|
24 |
+
if(empty($pmpro_level_ready) && empty($edit))
|
25 |
+
$msgt .= " <a href=\"?page=pmpro-membershiplevels&edit=-1\">" . __("Add a membership level to get started.", "pmpro") . "</a>";
|
26 |
+
elseif($pmpro_level_ready && !$pmpro_pages_ready && $view != "pmpro-pagesettings")
|
27 |
+
$msgt .= " <a href=\"?page=pmpro-pagesettings\">" . __("Setup the membership pages", "pmpro") . "</a>.";
|
28 |
+
elseif($pmpro_level_ready && $pmpro_pages_ready && !$pmpro_gateway_ready && $view != "pmpro-paymentsettings")
|
29 |
+
$msgt .= " <a href=\"?page=pmpro-paymentsettings\">" . __("Setup your SSL certificate and payment gateway", "pmpro") . "</a>.";
|
30 |
+
|
31 |
+
if(empty($msgt))
|
32 |
+
$msg = false;
|
33 |
+
}
|
34 |
+
|
35 |
+
if(!pmpro_checkLevelForStripeCompatibility())
|
36 |
+
{
|
37 |
+
$msg = -1;
|
38 |
+
$msgt = __("The billing details for some of your membership levels is not supported by Stripe.", "pmpro");
|
39 |
+
if($view == "pmpro-membershiplevels" && !empty($_REQUEST['edit']) && $_REQUEST['edit'] > 0)
|
40 |
+
{
|
41 |
+
if(!pmpro_checkLevelForStripeCompatibility($_REQUEST['edit']))
|
42 |
+
{
|
43 |
+
global $pmpro_stripe_error;
|
44 |
+
$pmpro_stripe_error = true;
|
45 |
+
$msg = -1;
|
46 |
+
$msgt = __("The billing details for this level are not supported by Stripe. Please review the notes in the Billing Details section below.", "pmpro");
|
47 |
+
}
|
48 |
+
}
|
49 |
+
elseif($view == "pmpro-membershiplevels")
|
50 |
+
$msgt .= " " . __("The levels with issues are highlighted below.", "pmpro");
|
51 |
+
else
|
52 |
+
$msgt .= " <a href=\"?page=pmpro-membershiplevels\">" . __("Please edit your levels", "pmpro") . "</a>.";
|
53 |
+
}
|
54 |
+
|
55 |
+
if(!pmpro_checkLevelForPayflowCompatibility())
|
56 |
+
{
|
57 |
+
$msg = -1;
|
58 |
+
$msgt = __("The billing details for some of your membership levels is not supported by Payflow.", "pmpro");
|
59 |
+
if($view == "pmpro-membershiplevels" && !empty($_REQUEST['edit']) && $_REQUEST['edit'] > 0)
|
60 |
+
{
|
61 |
+
if(!pmpro_checkLevelForPayflowCompatibility($_REQUEST['edit']))
|
62 |
+
{
|
63 |
+
global $pmpro_payflow_error;
|
64 |
+
$pmpro_payflow_error = true;
|
65 |
+
$msg = -1;
|
66 |
+
$msgt = __("The billing details for this level are not supported by Payflow. Please review the notes in the Billing Details section below.", "pmpro");
|
67 |
+
}
|
68 |
+
}
|
69 |
+
elseif($view == "pmpro-membershiplevels")
|
70 |
+
$msgt .= " " . __("The levels with issues are highlighted below.", "pmpro");
|
71 |
+
else
|
72 |
+
$msgt .= " <a href=\"?page=pmpro-membershiplevels\">" . __("Please edit your levels", "pmpro") . "</a>.";
|
73 |
+
}
|
74 |
+
|
75 |
+
if(!pmpro_checkLevelForBraintreeCompatibility())
|
76 |
+
{
|
77 |
+
$msg = -1;
|
78 |
+
$msgt = __("The billing details for some of your membership levels is not supported by Braintree.", "pmpro");
|
79 |
+
if($view == "pmpro-membershiplevels" && !empty($_REQUEST['edit']) && $_REQUEST['edit'] > 0)
|
80 |
+
{
|
81 |
+
if(!pmpro_checkLevelForBraintreeCompatibility($_REQUEST['edit']))
|
82 |
+
{
|
83 |
+
global $pmpro_braintree_error;
|
84 |
+
$pmpro_braintree_error = true;
|
85 |
+
$msg = -1;
|
86 |
+
$msgt = __("The billing details for this level are not supported by Braintree. Please review the notes in the Billing Details section below.", "pmpro");
|
87 |
+
}
|
88 |
+
}
|
89 |
+
elseif($view == "pmpro-membershiplevels")
|
90 |
+
$msgt .= " " . __("The levels with issues are highlighted below.", "pmpro");
|
91 |
+
else
|
92 |
+
$msgt .= " <a href=\"?page=pmpro-membershiplevels\">" . __("Please edit your levels", "pmpro") . "</a>.";
|
93 |
+
}
|
94 |
+
|
95 |
+
if(!pmpro_checkLevelForTwoCheckoutCompatibility())
|
96 |
+
{
|
97 |
+
$msg = -1;
|
98 |
+
$msgt = __("The billing details for some of your membership levels is not supported by TwoCheckout.", "pmpro");
|
99 |
+
if($view == "pmpro-membershiplevels" && !empty($_REQUEST['edit']) && $_REQUEST['edit'] > 0)
|
100 |
+
{
|
101 |
+
if(!pmpro_checkLevelForTwoCheckoutCompatibility($_REQUEST['edit']))
|
102 |
+
{
|
103 |
+
global $pmpro_twocheckout_error;
|
104 |
+
$pmpro_twocheckout_error = true;
|
105 |
+
|
106 |
+
$msg = -1;
|
107 |
+
$msgt = __("The billing details for this level are not supported by 2Checkout. Please review the notes in the Billing Details section below.", "pmpro");
|
108 |
+
}
|
109 |
+
}
|
110 |
+
elseif($view == "pmpro-membershiplevels")
|
111 |
+
$msgt .= " " . __("The levels with issues are highlighted below.", "pmpro");
|
112 |
+
else
|
113 |
+
$msgt .= " <a href=\"?page=pmpro-membershiplevels\">" . __("Please edit your levels", "pmpro") . "</a>.";
|
114 |
+
}
|
115 |
+
|
116 |
+
if(!empty($msg))
|
117 |
+
{
|
118 |
+
?>
|
119 |
+
<div id="message" class="<?php if($msg > 0) echo "updated fade"; else echo "error"; ?>"><p><?php echo $msgt?></p></div>
|
120 |
+
<?php
|
121 |
+
}
|
122 |
+
|
123 |
+
?>
|
124 |
+
<div class="wrap pmpro_admin">
|
125 |
+
<div class="pmpro_banner">
|
126 |
+
<a class="pmpro_logo" title="Paid Memberships Pro - Membership Plugin for WordPress" target="_blank" href="<?php echo pmpro_https_filter("http://www.paidmembershipspro.com")?>"><img src="<?php echo PMPRO_URL?>/images/Paid-Memberships-Pro.png" width="350" height="75" border="0" alt="Paid Memberships Pro(c) - All Rights Reserved" /></a>
|
127 |
+
<div class="pmpro_meta"><span class="pmpro_tag-grey">v<?php echo PMPRO_VERSION?></span><a target="_blank" class="pmpro_tag-blue" href="<?php echo pmpro_https_filter("http://www.paidmembershipspro.com")?>"><?php _e('Plugin Support', 'pmpro');?></a><a target="_blank" class="pmpro_tag-blue" href="http://www.paidmembershipspro.com/forums/"><?php _e('User Forum', 'pmpro');?></a></div>
|
128 |
+
|
129 |
+
<br style="clear:both;" />
|
130 |
+
</div>
|
131 |
+
|
132 |
+
<div id="pmpro_notifications">
|
133 |
+
</div>
|
134 |
+
<script>
|
135 |
+
jQuery(document).ready(function() {
|
136 |
+
jQuery.get('<?php echo get_admin_url(NULL, "/admin-ajax.php?action=pmpro_notifications"); ?>', function(data) {
|
137 |
+
if(data && data != 'NULL')
|
138 |
+
jQuery('#pmpro_notifications').html(data);
|
139 |
+
});
|
140 |
+
});
|
141 |
+
</script>
|
142 |
+
|
143 |
+
<?php
|
144 |
+
$settings_tabs = array("pmpro-membershiplevels", "pmpro-pagesettings", "pmpro-paymentsettings", "pmpro-emailsettings", "pmpro-advancedsettings", "pmpro-addons");
|
145 |
+
if(in_array($view, $settings_tabs))
|
146 |
+
{
|
147 |
+
?>
|
148 |
+
<h2 class="nav-tab-wrapper">
|
149 |
+
<?php if(current_user_can('pmpro_membershiplevels')) { ?>
|
150 |
+
<a href="admin.php?page=pmpro-membershiplevels" class="nav-tab<?php if($view == 'pmpro-membershiplevels') { ?> nav-tab-active<?php } ?>"><?php _e('Membership Levels', 'pmpro');?></a>
|
151 |
+
<?php } ?>
|
152 |
+
|
153 |
+
<?php if(current_user_can('pmpro_pagesettings')) { ?>
|
154 |
+
<a href="admin.php?page=pmpro-pagesettings" class="nav-tab<?php if($view == 'pmpro-pagesettings') { ?> nav-tab-active<?php } ?>"><?php _e('Pages', 'pmpro');?></a>
|
155 |
+
<?php } ?>
|
156 |
+
|
157 |
+
<?php if(current_user_can('pmpro_paymentsettings')) { ?>
|
158 |
+
<a href="admin.php?page=pmpro-paymentsettings" class="nav-tab<?php if($view == 'pmpro-paymentsettings') { ?> nav-tab-active<?php } ?>"><?php _e('Payment Gateway & SSL', 'pmpro');?></a>
|
159 |
+
<?php } ?>
|
160 |
+
|
161 |
+
<?php if(current_user_can('pmpro_emailsettings')) { ?>
|
162 |
+
<a href="admin.php?page=pmpro-emailsettings" class="nav-tab<?php if($view == 'pmpro-emailsettings') { ?> nav-tab-active<?php } ?>"><?php _e('Email', 'pmpro');?></a>
|
163 |
+
<?php } ?>
|
164 |
+
|
165 |
+
<?php if(current_user_can('pmpro_advancedsettings')) { ?>
|
166 |
+
<a href="admin.php?page=pmpro-advancedsettings" class="nav-tab<?php if($view == 'pmpro-advancedsettings') { ?> nav-tab-active<?php } ?>"><?php _e('Advanced', 'pmpro');?></a>
|
167 |
+
<?php } ?>
|
168 |
+
|
169 |
+
<?php if(current_user_can('pmpro_addons')) { ?>
|
170 |
+
<a href="admin.php?page=pmpro-addons" class="nav-tab<?php if($view == 'pmpro-addons') { ?> nav-tab-active<?php } ?>"><?php _e('Add Ons', 'pmpro');?></a>
|
171 |
+
<?php } ?>
|
172 |
+
</h2>
|
173 |
+
<?php } ?>
|
adminpages/advancedsettings.php
CHANGED
@@ -3,31 +3,31 @@
|
|
3 |
if(!function_exists("current_user_can") || (!current_user_can("manage_options") && !current_user_can("pmpro_advancedsettings")))
|
4 |
{
|
5 |
die(__("You do not have permissions to perform this action.", "pmpro"));
|
6 |
-
}
|
7 |
-
|
8 |
global $wpdb, $msg, $msgt;
|
9 |
-
|
10 |
-
//get/set settings
|
11 |
if(!empty($_REQUEST['savesettings']))
|
12 |
-
{
|
13 |
//other settings
|
14 |
pmpro_setOption("nonmembertext");
|
15 |
pmpro_setOption("notloggedintext");
|
16 |
-
pmpro_setOption("rsstext");
|
17 |
pmpro_setOption("filterqueries");
|
18 |
pmpro_setOption("showexcerpts");
|
19 |
pmpro_setOption("hideads");
|
20 |
pmpro_setOption("hideadslevels");
|
21 |
-
pmpro_setOption("redirecttosubscription");
|
22 |
-
|
23 |
//captcha
|
24 |
pmpro_setOption("recaptcha");
|
25 |
pmpro_setOption("recaptcha_publickey");
|
26 |
-
pmpro_setOption("recaptcha_privatekey");
|
27 |
-
|
28 |
//tos
|
29 |
-
pmpro_setOption("tospage");
|
30 |
-
|
31 |
//footer link
|
32 |
pmpro_setOption("hide_footer_link");
|
33 |
|
@@ -37,58 +37,58 @@
|
|
37 |
pmpro_setOption($key);
|
38 |
}
|
39 |
}
|
40 |
-
|
41 |
//assume success
|
42 |
$msg = true;
|
43 |
-
$msgt = __("Your advanced settings have been updated.", "pmpro");
|
44 |
}
|
45 |
|
46 |
$nonmembertext = pmpro_getOption("nonmembertext");
|
47 |
$notloggedintext = pmpro_getOption("notloggedintext");
|
48 |
-
$rsstext = pmpro_getOption("rsstext");
|
49 |
$hideads = pmpro_getOption("hideads");
|
50 |
$filterqueries = pmpro_getOption('filterqueries');
|
51 |
$showexcerpts = pmpro_getOption("showexcerpts");
|
52 |
$hideadslevels = pmpro_getOption("hideadslevels");
|
53 |
-
|
54 |
if(is_multisite())
|
55 |
$redirecttosubscription = pmpro_getOption("redirecttosubscription");
|
56 |
-
|
57 |
$recaptcha = pmpro_getOption("recaptcha");
|
58 |
$recaptcha_publickey = pmpro_getOption("recaptcha_publickey");
|
59 |
$recaptcha_privatekey = pmpro_getOption("recaptcha_privatekey");
|
60 |
-
|
61 |
$tospage = pmpro_getOption("tospage");
|
62 |
-
|
63 |
$hide_footer_link = pmpro_getOption("hide_footer_link");
|
64 |
-
|
65 |
//default settings
|
66 |
if(!$nonmembertext)
|
67 |
{
|
68 |
$nonmembertext = sprintf( __( 'This content is for !!levels!! members only. <a href="%s">Register here</a>.', 'pmpro' ), wp_login_url() . "?action=register" );
|
69 |
pmpro_setOption("nonmembertext", $nonmembertext);
|
70 |
-
}
|
71 |
if(!$notloggedintext)
|
72 |
{
|
73 |
$notloggedintext = sprintf( __( 'Please <a href="%s">login</a> to view this content. (<a href="%s">Register here</a>.)', 'pmpro' ), wp_login_url( get_permalink() ), wp_login_url() . "?action=register" );
|
74 |
pmpro_setOption("notloggedintext", $notloggedintext);
|
75 |
-
}
|
76 |
if(!$rsstext)
|
77 |
{
|
78 |
$rsstext = __( 'This content is for members only. Visit the site and log in/register to read.', 'pmpro' );
|
79 |
pmpro_setOption("rsstext", $rsstext);
|
80 |
-
}
|
81 |
-
|
82 |
$levels = $wpdb->get_results( "SELECT * FROM {$wpdb->pmpro_membership_levels}", OBJECT );
|
83 |
-
|
84 |
-
require_once(dirname(__FILE__) . "/admin_header.php");
|
85 |
?>
|
86 |
|
87 |
-
<form action="" method="post" enctype="multipart/form-data">
|
88 |
<h2><?php _e('Advanced Settings', 'pmpro');?></h2>
|
89 |
-
|
90 |
<table class="form-table">
|
91 |
-
<tbody>
|
92 |
<tr>
|
93 |
<th scope="row" valign="top">
|
94 |
<label for="nonmembertext"><?php _e('Message for Logged-in Non-members', 'pmpro');?>:</label>
|
@@ -97,7 +97,7 @@
|
|
97 |
<textarea name="nonmembertext" rows="3" cols="80"><?php echo stripslashes($nonmembertext)?></textarea><br />
|
98 |
<small class="litegray"><?php _e('This message replaces the post content for non-members. Available variables', 'pmpro');?>: !!levels!!, !!referrer!!</small>
|
99 |
</td>
|
100 |
-
</tr>
|
101 |
<tr>
|
102 |
<th scope="row" valign="top">
|
103 |
<label for="notloggedintext"><?php _e('Message for Logged-out Users', 'pmpro');?>:</label>
|
@@ -106,7 +106,7 @@
|
|
106 |
<textarea name="notloggedintext" rows="3" cols="80"><?php echo stripslashes($notloggedintext)?></textarea><br />
|
107 |
<small class="litegray"><?php _e('This message replaces the post content for logged-out visitors.', 'pmpro');?></small>
|
108 |
</td>
|
109 |
-
</tr>
|
110 |
<tr>
|
111 |
<th scope="row" valign="top">
|
112 |
<label for="rsstext"><?php _e('Message for RSS Feed', 'pmpro');?>:</label>
|
@@ -115,8 +115,8 @@
|
|
115 |
<textarea name="rsstext" rows="3" cols="80"><?php echo stripslashes($rsstext)?></textarea><br />
|
116 |
<small class="litegray"><?php _e('This message replaces the post content in RSS feeds.', 'pmpro');?></small>
|
117 |
</td>
|
118 |
-
</tr>
|
119 |
-
|
120 |
<tr>
|
121 |
<th scope="row" valign="top">
|
122 |
<label for="filterqueries"><?php _e("Filter searches and archives?", 'pmpro');?></label>
|
@@ -124,10 +124,10 @@
|
|
124 |
<td>
|
125 |
<select id="filterqueries" name="filterqueries">
|
126 |
<option value="0" <?php if(!$filterqueries) { ?>selected="selected"<?php } ?>><?php _e('No - Non-members will see restricted posts/pages in searches and archives.', 'pmpro');?></option>
|
127 |
-
<option value="1" <?php if($filterqueries == 1) { ?>selected="selected"<?php } ?>><?php _e('Yes - Only members will see restricted posts/pages in searches and archives.', 'pmpro');?></option>
|
128 |
-
</select>
|
129 |
</td>
|
130 |
-
</tr>
|
131 |
<tr>
|
132 |
<th scope="row" valign="top">
|
133 |
<label for="showexcerpts"><?php _e('Show Excerpts to Non-Members?', 'pmpro');?></label>
|
@@ -141,16 +141,16 @@
|
|
141 |
</tr>
|
142 |
<tr>
|
143 |
<th scope="row" valign="top">
|
144 |
-
<label for="hideads"
|
145 |
</th>
|
146 |
<td>
|
147 |
<select id="hideads" name="hideads" onchange="pmpro_updateHideAdsTRs();">
|
148 |
<option value="0" <?php if(!$hideads) { ?>selected="selected"<?php } ?>><?php _e('No', 'pmpro');?></option>
|
149 |
<option value="1" <?php if($hideads == 1) { ?>selected="selected"<?php } ?>><?php _e('Hide Ads From All Members', 'pmpro');?></option>
|
150 |
<option value="2" <?php if($hideads == 2) { ?>selected="selected"<?php } ?>><?php _e('Hide Ads From Certain Members', 'pmpro');?></option>
|
151 |
-
</select>
|
152 |
</td>
|
153 |
-
</tr>
|
154 |
<tr id="hideads_explanation" <?php if($hideads < 2) { ?>style="display: none;"<?php } ?>>
|
155 |
<th scope="row" valign="top"> </th>
|
156 |
<td>
|
@@ -161,42 +161,42 @@ if(pmpro_displayAds())
|
|
161 |
{
|
162 |
//insert ad code here
|
163 |
}
|
164 |
-
</pre>
|
165 |
</td>
|
166 |
-
</tr>
|
167 |
<tr id="hideadslevels_tr" <?php if($hideads != 2) { ?>style="display: none;"<?php } ?>>
|
168 |
<th scope="row" valign="top">
|
169 |
<label for="hideadslevels"><?php _e('Choose Levels to Hide Ads From', 'pmpro');?>:</label>
|
170 |
</th>
|
171 |
<td>
|
172 |
<div class="checkbox_box" <?php if(count($levels) > 5) { ?>style="height: 100px; overflow: auto;"<?php } ?>>
|
173 |
-
<?php
|
174 |
$hideadslevels = pmpro_getOption("hideadslevels");
|
175 |
if(!is_array($hideadslevels))
|
176 |
$hideadslevels = explode(",", $hideadslevels);
|
177 |
-
|
178 |
-
$sqlQuery = "SELECT * FROM $wpdb->pmpro_membership_levels ";
|
179 |
-
$levels = $wpdb->get_results($sqlQuery, OBJECT);
|
180 |
-
foreach($levels as $level)
|
181 |
-
{
|
182 |
?>
|
183 |
<div class="clickable"><input type="checkbox" id="hideadslevels_<?php echo $level->id?>" name="hideadslevels[]" value="<?php echo $level->id?>" <?php if(in_array($level->id, $hideadslevels)) { ?>checked="checked"<?php } ?>> <?php echo $level->name?></div>
|
184 |
-
<?php
|
185 |
-
}
|
186 |
?>
|
187 |
-
</div>
|
188 |
<script>
|
189 |
jQuery('.checkbox_box input').click(function(event) {
|
190 |
event.stopPropagation()
|
191 |
});
|
192 |
|
193 |
-
jQuery('.checkbox_box div.clickable').click(function() {
|
194 |
var checkbox = jQuery(this).find(':checkbox');
|
195 |
checkbox.attr('checked', !checkbox.attr('checked'));
|
196 |
});
|
197 |
</script>
|
198 |
</td>
|
199 |
-
</tr>
|
200 |
<?php if(is_multisite()) { ?>
|
201 |
<tr>
|
202 |
<th scope="row" valign="top">
|
@@ -205,11 +205,11 @@ if(pmpro_displayAds())
|
|
205 |
<td>
|
206 |
<select id="redirecttosubscription" name="redirecttosubscription">
|
207 |
<option value="0" <?php if(!$redirecttosubscription) { ?>selected="selected"<?php } ?>><?php _e('No', 'pmpro');?></option>
|
208 |
-
<option value="1" <?php if($redirecttosubscription == 1) { ?>selected="selected"<?php } ?>><?php _e('Yes', 'pmpro');?></option>
|
209 |
-
</select>
|
210 |
</td>
|
211 |
-
</tr>
|
212 |
-
<?php } ?>
|
213 |
<tr>
|
214 |
<th scope="row" valign="top">
|
215 |
<label for="recaptcha"><?php _e('Use reCAPTCHA?', 'pmpro');?>:</label>
|
@@ -217,20 +217,20 @@ if(pmpro_displayAds())
|
|
217 |
<td>
|
218 |
<select id="recaptcha" name="recaptcha" onchange="pmpro_updateRecaptchaTRs();">
|
219 |
<option value="0" <?php if(!$recaptcha) { ?>selected="selected"<?php } ?>><?php _e('No', 'pmpro');?></option>
|
220 |
-
<option value="1" <?php if($recaptcha == 1) { ?>selected="selected"<?php } ?>><?php _e('Yes - Free memberships only.', 'pmpro');?></option>
|
221 |
<option value="2" <?php if($recaptcha == 2) { ?>selected="selected"<?php } ?>><?php _e('Yes - All memberships.', 'pmpro');?></option>
|
222 |
</select><br />
|
223 |
-
<small><?php _e('A free reCAPTCHA key is required.', 'pmpro');?> <a href="https://www.google.com/recaptcha/admin/create"><?php _e('Click here to signup for reCAPTCHA', 'pmpro');?></a>.</small>
|
224 |
</td>
|
225 |
-
</tr>
|
226 |
<tr id="recaptcha_tr" <?php if(!$recaptcha) { ?>style="display: none;"<?php } ?>>
|
227 |
<th scope="row" valign="top"> </th>
|
228 |
-
<td>
|
229 |
<label for="recaptcha_publickey"><?php _e('reCAPTCHA Public Key', 'pmpro');?>:</label>
|
230 |
<input type="text" name="recaptcha_publickey" size="60" value="<?php echo $recaptcha_publickey?>" />
|
231 |
<br /><br />
|
232 |
<label for="recaptcha_privatekey"><?php _e('reCAPTCHA Private Key', 'pmpro');?>:</label>
|
233 |
-
<input type="text" name="recaptcha_privatekey" size="60" value="<?php echo $recaptcha_privatekey?>" />
|
234 |
</td>
|
235 |
</tr>
|
236 |
<tr>
|
@@ -244,8 +244,8 @@ if(pmpro_displayAds())
|
|
244 |
<br />
|
245 |
<small><?php _e('If yes, create a WordPress page containing your TOS agreement and assign it using the dropdown above.', 'pmpro');?></small>
|
246 |
</td>
|
247 |
-
</tr>
|
248 |
-
|
249 |
<?php /*
|
250 |
<tr>
|
251 |
<th scope="row" valign="top">
|
@@ -254,8 +254,8 @@ if(pmpro_displayAds())
|
|
254 |
<td>
|
255 |
<select id="hide_footer_link" name="hide_footer_link">
|
256 |
<option value="0" <?php if(!$hide_footer_link) { ?>selected="selected"<?php } ?>>No - Leave the link. (Thanks!)</option>
|
257 |
-
<option value="1" <?php if($hide_footer_link == 1) { ?>selected="selected"<?php } ?>>Yes - Hide the link.</option>
|
258 |
-
</select>
|
259 |
</td>
|
260 |
</tr>
|
261 |
*/
|
@@ -329,46 +329,46 @@ if(pmpro_displayAds())
|
|
329 |
function pmpro_updateHideAdsTRs()
|
330 |
{
|
331 |
var hideads = jQuery('#hideads').val();
|
332 |
-
if(hideads == 2)
|
333 |
{
|
334 |
jQuery('#hideadslevels_tr').show();
|
335 |
-
}
|
336 |
else
|
337 |
{
|
338 |
jQuery('#hideadslevels_tr').hide();
|
339 |
}
|
340 |
-
|
341 |
-
if(hideads > 0)
|
342 |
{
|
343 |
jQuery('#hideads_explanation').show();
|
344 |
-
}
|
345 |
else
|
346 |
{
|
347 |
jQuery('#hideads_explanation').hide();
|
348 |
}
|
349 |
}
|
350 |
pmpro_updateHideAdsTRs();
|
351 |
-
|
352 |
function pmpro_updateRecaptchaTRs()
|
353 |
{
|
354 |
var recaptcha = jQuery('#recaptcha').val();
|
355 |
-
if(recaptcha > 0)
|
356 |
{
|
357 |
jQuery('#recaptcha_tr').show();
|
358 |
-
}
|
359 |
else
|
360 |
{
|
361 |
jQuery('#recaptcha_tr').hide();
|
362 |
-
}
|
363 |
}
|
364 |
pmpro_updateRecaptchaTRs();
|
365 |
</script>
|
366 |
-
|
367 |
-
<p class="submit">
|
368 |
-
<input name="savesettings" type="submit" class="button button-primary" value="<?php _e('Save Settings', 'pmpro');?>" />
|
369 |
-
</p>
|
370 |
</form>
|
371 |
|
372 |
<?php
|
373 |
-
require_once(dirname(__FILE__) . "/admin_footer.php");
|
374 |
?>
|
3 |
if(!function_exists("current_user_can") || (!current_user_can("manage_options") && !current_user_can("pmpro_advancedsettings")))
|
4 |
{
|
5 |
die(__("You do not have permissions to perform this action.", "pmpro"));
|
6 |
+
}
|
7 |
+
|
8 |
global $wpdb, $msg, $msgt;
|
9 |
+
|
10 |
+
//get/set settings
|
11 |
if(!empty($_REQUEST['savesettings']))
|
12 |
+
{
|
13 |
//other settings
|
14 |
pmpro_setOption("nonmembertext");
|
15 |
pmpro_setOption("notloggedintext");
|
16 |
+
pmpro_setOption("rsstext");
|
17 |
pmpro_setOption("filterqueries");
|
18 |
pmpro_setOption("showexcerpts");
|
19 |
pmpro_setOption("hideads");
|
20 |
pmpro_setOption("hideadslevels");
|
21 |
+
pmpro_setOption("redirecttosubscription");
|
22 |
+
|
23 |
//captcha
|
24 |
pmpro_setOption("recaptcha");
|
25 |
pmpro_setOption("recaptcha_publickey");
|
26 |
+
pmpro_setOption("recaptcha_privatekey");
|
27 |
+
|
28 |
//tos
|
29 |
+
pmpro_setOption("tospage");
|
30 |
+
|
31 |
//footer link
|
32 |
pmpro_setOption("hide_footer_link");
|
33 |
|
37 |
pmpro_setOption($key);
|
38 |
}
|
39 |
}
|
40 |
+
|
41 |
//assume success
|
42 |
$msg = true;
|
43 |
+
$msgt = __("Your advanced settings have been updated.", "pmpro");
|
44 |
}
|
45 |
|
46 |
$nonmembertext = pmpro_getOption("nonmembertext");
|
47 |
$notloggedintext = pmpro_getOption("notloggedintext");
|
48 |
+
$rsstext = pmpro_getOption("rsstext");
|
49 |
$hideads = pmpro_getOption("hideads");
|
50 |
$filterqueries = pmpro_getOption('filterqueries');
|
51 |
$showexcerpts = pmpro_getOption("showexcerpts");
|
52 |
$hideadslevels = pmpro_getOption("hideadslevels");
|
53 |
+
|
54 |
if(is_multisite())
|
55 |
$redirecttosubscription = pmpro_getOption("redirecttosubscription");
|
56 |
+
|
57 |
$recaptcha = pmpro_getOption("recaptcha");
|
58 |
$recaptcha_publickey = pmpro_getOption("recaptcha_publickey");
|
59 |
$recaptcha_privatekey = pmpro_getOption("recaptcha_privatekey");
|
60 |
+
|
61 |
$tospage = pmpro_getOption("tospage");
|
62 |
+
|
63 |
$hide_footer_link = pmpro_getOption("hide_footer_link");
|
64 |
+
|
65 |
//default settings
|
66 |
if(!$nonmembertext)
|
67 |
{
|
68 |
$nonmembertext = sprintf( __( 'This content is for !!levels!! members only. <a href="%s">Register here</a>.', 'pmpro' ), wp_login_url() . "?action=register" );
|
69 |
pmpro_setOption("nonmembertext", $nonmembertext);
|
70 |
+
}
|
71 |
if(!$notloggedintext)
|
72 |
{
|
73 |
$notloggedintext = sprintf( __( 'Please <a href="%s">login</a> to view this content. (<a href="%s">Register here</a>.)', 'pmpro' ), wp_login_url( get_permalink() ), wp_login_url() . "?action=register" );
|
74 |
pmpro_setOption("notloggedintext", $notloggedintext);
|
75 |
+
}
|
76 |
if(!$rsstext)
|
77 |
{
|
78 |
$rsstext = __( 'This content is for members only. Visit the site and log in/register to read.', 'pmpro' );
|
79 |
pmpro_setOption("rsstext", $rsstext);
|
80 |
+
}
|
81 |
+
|
82 |
$levels = $wpdb->get_results( "SELECT * FROM {$wpdb->pmpro_membership_levels}", OBJECT );
|
83 |
+
|
84 |
+
require_once(dirname(__FILE__) . "/admin_header.php");
|
85 |
?>
|
86 |
|
87 |
+
<form action="" method="post" enctype="multipart/form-data">
|
88 |
<h2><?php _e('Advanced Settings', 'pmpro');?></h2>
|
89 |
+
|
90 |
<table class="form-table">
|
91 |
+
<tbody>
|
92 |
<tr>
|
93 |
<th scope="row" valign="top">
|
94 |
<label for="nonmembertext"><?php _e('Message for Logged-in Non-members', 'pmpro');?>:</label>
|
97 |
<textarea name="nonmembertext" rows="3" cols="80"><?php echo stripslashes($nonmembertext)?></textarea><br />
|
98 |
<small class="litegray"><?php _e('This message replaces the post content for non-members. Available variables', 'pmpro');?>: !!levels!!, !!referrer!!</small>
|
99 |
</td>
|
100 |
+
</tr>
|
101 |
<tr>
|
102 |
<th scope="row" valign="top">
|
103 |
<label for="notloggedintext"><?php _e('Message for Logged-out Users', 'pmpro');?>:</label>
|
106 |
<textarea name="notloggedintext" rows="3" cols="80"><?php echo stripslashes($notloggedintext)?></textarea><br />
|
107 |
<small class="litegray"><?php _e('This message replaces the post content for logged-out visitors.', 'pmpro');?></small>
|
108 |
</td>
|
109 |
+
</tr>
|
110 |
<tr>
|
111 |
<th scope="row" valign="top">
|
112 |
<label for="rsstext"><?php _e('Message for RSS Feed', 'pmpro');?>:</label>
|
115 |
<textarea name="rsstext" rows="3" cols="80"><?php echo stripslashes($rsstext)?></textarea><br />
|
116 |
<small class="litegray"><?php _e('This message replaces the post content in RSS feeds.', 'pmpro');?></small>
|
117 |
</td>
|
118 |
+
</tr>
|
119 |
+
|
120 |
<tr>
|
121 |
<th scope="row" valign="top">
|
122 |
<label for="filterqueries"><?php _e("Filter searches and archives?", 'pmpro');?></label>
|
124 |
<td>
|
125 |
<select id="filterqueries" name="filterqueries">
|
126 |
<option value="0" <?php if(!$filterqueries) { ?>selected="selected"<?php } ?>><?php _e('No - Non-members will see restricted posts/pages in searches and archives.', 'pmpro');?></option>
|
127 |
+
<option value="1" <?php if($filterqueries == 1) { ?>selected="selected"<?php } ?>><?php _e('Yes - Only members will see restricted posts/pages in searches and archives.', 'pmpro');?></option>
|
128 |
+
</select>
|
129 |
</td>
|
130 |
+
</tr>
|
131 |
<tr>
|
132 |
<th scope="row" valign="top">
|
133 |
<label for="showexcerpts"><?php _e('Show Excerpts to Non-Members?', 'pmpro');?></label>
|
141 |
</tr>
|
142 |
<tr>
|
143 |
<th scope="row" valign="top">
|
144 |
+
<label for="hideads"><?php _e("Hide Ads From Members?", 'pmpro');?></label>
|
145 |
</th>
|
146 |
<td>
|
147 |
<select id="hideads" name="hideads" onchange="pmpro_updateHideAdsTRs();">
|
148 |
<option value="0" <?php if(!$hideads) { ?>selected="selected"<?php } ?>><?php _e('No', 'pmpro');?></option>
|
149 |
<option value="1" <?php if($hideads == 1) { ?>selected="selected"<?php } ?>><?php _e('Hide Ads From All Members', 'pmpro');?></option>
|
150 |
<option value="2" <?php if($hideads == 2) { ?>selected="selected"<?php } ?>><?php _e('Hide Ads From Certain Members', 'pmpro');?></option>
|
151 |
+
</select>
|
152 |
</td>
|
153 |
+
</tr>
|
154 |
<tr id="hideads_explanation" <?php if($hideads < 2) { ?>style="display: none;"<?php } ?>>
|
155 |
<th scope="row" valign="top"> </th>
|
156 |
<td>
|
161 |
{
|
162 |
//insert ad code here
|
163 |
}
|
164 |
+
</pre>
|
165 |
</td>
|
166 |
+
</tr>
|
167 |
<tr id="hideadslevels_tr" <?php if($hideads != 2) { ?>style="display: none;"<?php } ?>>
|
168 |
<th scope="row" valign="top">
|
169 |
<label for="hideadslevels"><?php _e('Choose Levels to Hide Ads From', 'pmpro');?>:</label>
|
170 |
</th>
|
171 |
<td>
|
172 |
<div class="checkbox_box" <?php if(count($levels) > 5) { ?>style="height: 100px; overflow: auto;"<?php } ?>>
|
173 |
+
<?php
|
174 |
$hideadslevels = pmpro_getOption("hideadslevels");
|
175 |
if(!is_array($hideadslevels))
|
176 |
$hideadslevels = explode(",", $hideadslevels);
|
177 |
+
|
178 |
+
$sqlQuery = "SELECT * FROM $wpdb->pmpro_membership_levels ";
|
179 |
+
$levels = $wpdb->get_results($sqlQuery, OBJECT);
|
180 |
+
foreach($levels as $level)
|
181 |
+
{
|
182 |
?>
|
183 |
<div class="clickable"><input type="checkbox" id="hideadslevels_<?php echo $level->id?>" name="hideadslevels[]" value="<?php echo $level->id?>" <?php if(in_array($level->id, $hideadslevels)) { ?>checked="checked"<?php } ?>> <?php echo $level->name?></div>
|
184 |
+
<?php
|
185 |
+
}
|
186 |
?>
|
187 |
+
</div>
|
188 |
<script>
|
189 |
jQuery('.checkbox_box input').click(function(event) {
|
190 |
event.stopPropagation()
|
191 |
});
|
192 |
|
193 |
+
jQuery('.checkbox_box div.clickable').click(function() {
|
194 |
var checkbox = jQuery(this).find(':checkbox');
|
195 |
checkbox.attr('checked', !checkbox.attr('checked'));
|
196 |
});
|
197 |
</script>
|
198 |
</td>
|
199 |
+
</tr>
|
200 |
<?php if(is_multisite()) { ?>
|
201 |
<tr>
|
202 |
<th scope="row" valign="top">
|
205 |
<td>
|
206 |
<select id="redirecttosubscription" name="redirecttosubscription">
|
207 |
<option value="0" <?php if(!$redirecttosubscription) { ?>selected="selected"<?php } ?>><?php _e('No', 'pmpro');?></option>
|
208 |
+
<option value="1" <?php if($redirecttosubscription == 1) { ?>selected="selected"<?php } ?>><?php _e('Yes', 'pmpro');?></option>
|
209 |
+
</select>
|
210 |
</td>
|
211 |
+
</tr>
|
212 |
+
<?php } ?>
|
213 |
<tr>
|
214 |
<th scope="row" valign="top">
|
215 |
<label for="recaptcha"><?php _e('Use reCAPTCHA?', 'pmpro');?>:</label>
|
217 |
<td>
|
218 |
<select id="recaptcha" name="recaptcha" onchange="pmpro_updateRecaptchaTRs();">
|
219 |
<option value="0" <?php if(!$recaptcha) { ?>selected="selected"<?php } ?>><?php _e('No', 'pmpro');?></option>
|
220 |
+
<option value="1" <?php if($recaptcha == 1) { ?>selected="selected"<?php } ?>><?php _e('Yes - Free memberships only.', 'pmpro');?></option>
|
221 |
<option value="2" <?php if($recaptcha == 2) { ?>selected="selected"<?php } ?>><?php _e('Yes - All memberships.', 'pmpro');?></option>
|
222 |
</select><br />
|
223 |
+
<small><?php _e('A free reCAPTCHA key is required.', 'pmpro');?> <a href="https://www.google.com/recaptcha/admin/create"><?php _e('Click here to signup for reCAPTCHA', 'pmpro');?></a>.</small>
|
224 |
</td>
|
225 |
+
</tr>
|
226 |
<tr id="recaptcha_tr" <?php if(!$recaptcha) { ?>style="display: none;"<?php } ?>>
|
227 |
<th scope="row" valign="top"> </th>
|
228 |
+
<td>
|
229 |
<label for="recaptcha_publickey"><?php _e('reCAPTCHA Public Key', 'pmpro');?>:</label>
|
230 |
<input type="text" name="recaptcha_publickey" size="60" value="<?php echo $recaptcha_publickey?>" />
|
231 |
<br /><br />
|
232 |
<label for="recaptcha_privatekey"><?php _e('reCAPTCHA Private Key', 'pmpro');?>:</label>
|
233 |
+
<input type="text" name="recaptcha_privatekey" size="60" value="<?php echo $recaptcha_privatekey?>" />
|
234 |
</td>
|
235 |
</tr>
|
236 |
<tr>
|
244 |
<br />
|
245 |
<small><?php _e('If yes, create a WordPress page containing your TOS agreement and assign it using the dropdown above.', 'pmpro');?></small>
|
246 |
</td>
|
247 |
+
</tr>
|
248 |
+
|
249 |
<?php /*
|
250 |
<tr>
|
251 |
<th scope="row" valign="top">
|
254 |
<td>
|
255 |
<select id="hide_footer_link" name="hide_footer_link">
|
256 |
<option value="0" <?php if(!$hide_footer_link) { ?>selected="selected"<?php } ?>>No - Leave the link. (Thanks!)</option>
|
257 |
+
<option value="1" <?php if($hide_footer_link == 1) { ?>selected="selected"<?php } ?>>Yes - Hide the link.</option>
|
258 |
+
</select>
|
259 |
</td>
|
260 |
</tr>
|
261 |
*/
|
329 |
function pmpro_updateHideAdsTRs()
|
330 |
{
|
331 |
var hideads = jQuery('#hideads').val();
|
332 |
+
if(hideads == 2)
|
333 |
{
|
334 |
jQuery('#hideadslevels_tr').show();
|
335 |
+
}
|
336 |
else
|
337 |
{
|
338 |
jQuery('#hideadslevels_tr').hide();
|
339 |
}
|
340 |
+
|
341 |
+
if(hideads > 0)
|
342 |
{
|
343 |
jQuery('#hideads_explanation').show();
|
344 |
+
}
|
345 |
else
|
346 |
{
|
347 |
jQuery('#hideads_explanation').hide();
|
348 |
}
|
349 |
}
|
350 |
pmpro_updateHideAdsTRs();
|
351 |
+
|
352 |
function pmpro_updateRecaptchaTRs()
|
353 |
{
|
354 |
var recaptcha = jQuery('#recaptcha').val();
|
355 |
+
if(recaptcha > 0)
|
356 |
{
|
357 |
jQuery('#recaptcha_tr').show();
|
358 |
+
}
|
359 |
else
|
360 |
{
|
361 |
jQuery('#recaptcha_tr').hide();
|
362 |
+
}
|
363 |
}
|
364 |
pmpro_updateRecaptchaTRs();
|
365 |
</script>
|
366 |
+
|
367 |
+
<p class="submit">
|
368 |
+
<input name="savesettings" type="submit" class="button button-primary" value="<?php _e('Save Settings', 'pmpro');?>" />
|
369 |
+
</p>
|
370 |
</form>
|
371 |
|
372 |
<?php
|
373 |
+
require_once(dirname(__FILE__) . "/admin_footer.php");
|
374 |
?>
|
adminpages/dashboard.php
CHANGED
@@ -1,12 +1,12 @@
|
|
1 |
<?php
|
2 |
/*
|
3 |
-
Much of this code is borroed from yst_plugin_tools.php in the Yoast WordPress SEO plugin. Thanks, Yoast!
|
4 |
*/
|
5 |
-
|
6 |
global $pmpro_feed;
|
7 |
$pmpro_feed = "http://feeds.feedburner.com/PaidMembershipsPro";
|
8 |
-
|
9 |
-
function pmpro_postbox($id, $title, $content)
|
10 |
{
|
11 |
?>
|
12 |
<div id="<?php echo $id; ?>" class="postbox">
|
@@ -17,22 +17,22 @@
|
|
17 |
</div>
|
18 |
</div>
|
19 |
<?php
|
20 |
-
}
|
21 |
-
|
22 |
-
function pmpro_fetch_rss_items( $num )
|
23 |
{
|
24 |
global $pmpro_feed;
|
25 |
-
|
26 |
include_once(ABSPATH . WPINC . '/feed.php');
|
27 |
$rss = fetch_feed( $pmpro_feed );
|
28 |
-
|
29 |
// Bail if feed doesn't work
|
30 |
if ( is_wp_error($rss) )
|
31 |
return false;
|
32 |
-
|
33 |
$rss_items = $rss->get_items( 0, $rss->get_item_quantity( $num ) );
|
34 |
-
|
35 |
-
// If the feed was erroneously
|
36 |
if ( !$rss_items ) {
|
37 |
$md5 = md5( $pmpro_feed );
|
38 |
delete_transient( 'feed_' . $md5 );
|
@@ -40,17 +40,17 @@
|
|
40 |
$rss = fetch_feed( $pmpro_feed );
|
41 |
$rss_items = $rss->get_items( 0, $rss->get_item_quantity( $num ) );
|
42 |
}
|
43 |
-
|
44 |
return $rss_items;
|
45 |
}
|
46 |
-
|
47 |
/**
|
48 |
* Box with latest news from PaidMembershipsPro.com for sidebar
|
49 |
*/
|
50 |
-
function pmpro_news()
|
51 |
{
|
52 |
$rss_items = pmpro_fetch_rss_items( 5 );
|
53 |
-
|
54 |
$content = '<ul>';
|
55 |
if ( !$rss_items ) {
|
56 |
$content .= '<li class="pmpro_news">no news items, feed might be broken...</li>';
|
@@ -60,7 +60,7 @@
|
|
60 |
$content .= '<a class="rsswidget" href="'.esc_url( $item->get_permalink(), $protocolls=null, 'display' ).'">'. esc_html( $item->get_title() ) .'</a> ';
|
61 |
$content .= '</li>';
|
62 |
}
|
63 |
-
}
|
64 |
$content .= '</ul>';
|
65 |
$pmpro_postbox('pmprolatest', 'Recent Updates from PaidMembershipsPro.com', $content);
|
66 |
}
|
@@ -68,12 +68,12 @@
|
|
68 |
/**
|
69 |
* Widget with latest news from PaidMembershipsPro.com for dashbaord
|
70 |
*/
|
71 |
-
function pmpro_db_widget()
|
72 |
{
|
73 |
global $pmpro_feed;
|
74 |
-
|
75 |
$options = get_option('pmpro_pmprodbwidget');
|
76 |
-
|
77 |
$network = '';
|
78 |
if ( function_exists('is_network_admin') && is_network_admin() )
|
79 |
$network = '_network';
|
@@ -81,16 +81,16 @@
|
|
81 |
if (isset($_POST['pmpro_removedbwidget'])) {
|
82 |
$options['removedbwidget'.$network] = true;
|
83 |
update_option('pmpro_pmprodbwidget',$options);
|
84 |
-
}
|
85 |
if ( isset($options['removedbwidget'.$network]) && $options['removedbwidget'.$network] ) {
|
86 |
echo "If you reload, this widget will be gone and never appear again, unless you decide to delete the database option 'pmpro_pmprodbwidget'.";
|
87 |
return;
|
88 |
}
|
89 |
|
90 |
-
$rss_items = pmpro_fetch_rss_items( 3 );
|
91 |
-
|
92 |
echo "<ul>";
|
93 |
-
|
94 |
if ( !$rss_items ) {
|
95 |
echo '<li class="pmpro_news">no news items, feed might be broken...</li>';
|
96 |
} else {
|
@@ -101,7 +101,7 @@
|
|
101 |
echo '<div class="rssSummary">'. esc_html( pmpro_text_limit( strip_tags( $item->get_description() ), 150 ) ).'</div>';
|
102 |
echo '</li>';
|
103 |
}
|
104 |
-
}
|
105 |
|
106 |
echo '</ul>';
|
107 |
echo '<br class="clear"/><div style="margin-top:10px;border-top: 1px solid #ddd; padding-top: 10px; text-align:center;">';
|
@@ -112,7 +112,7 @@
|
|
112 |
echo '</div>';
|
113 |
}
|
114 |
|
115 |
-
function pmpro_widget_setup()
|
116 |
{
|
117 |
$network = '';
|
118 |
if ( function_exists('is_network_admin') && is_network_admin() )
|
@@ -122,6 +122,6 @@
|
|
122 |
if ( !isset($options['removedbwidget'.$network]) || !$options['removedbwidget'.$network] )
|
123 |
wp_add_dashboard_widget( 'pmpro_db_widget' , 'The Latest From PaidMembershipsPro.com' , 'pmpro_db_widget');
|
124 |
}
|
125 |
-
|
126 |
add_action( 'wp_dashboard_setup', 'pmpro_widget_setup');
|
127 |
?>
|
1 |
<?php
|
2 |
/*
|
3 |
+
Much of this code is borroed from yst_plugin_tools.php in the Yoast WordPress SEO plugin. Thanks, Yoast!
|
4 |
*/
|
5 |
+
|
6 |
global $pmpro_feed;
|
7 |
$pmpro_feed = "http://feeds.feedburner.com/PaidMembershipsPro";
|
8 |
+
|
9 |
+
function pmpro_postbox($id, $title, $content)
|
10 |
{
|
11 |
?>
|
12 |
<div id="<?php echo $id; ?>" class="postbox">
|
17 |
</div>
|
18 |
</div>
|
19 |
<?php
|
20 |
+
}
|
21 |
+
|
22 |
+
function pmpro_fetch_rss_items( $num )
|
23 |
{
|
24 |
global $pmpro_feed;
|
25 |
+
|
26 |
include_once(ABSPATH . WPINC . '/feed.php');
|
27 |
$rss = fetch_feed( $pmpro_feed );
|
28 |
+
|
29 |
// Bail if feed doesn't work
|
30 |
if ( is_wp_error($rss) )
|
31 |
return false;
|
32 |
+
|
33 |
$rss_items = $rss->get_items( 0, $rss->get_item_quantity( $num ) );
|
34 |
+
|
35 |
+
// If the feed was erroneously
|
36 |
if ( !$rss_items ) {
|
37 |
$md5 = md5( $pmpro_feed );
|
38 |
delete_transient( 'feed_' . $md5 );
|
40 |
$rss = fetch_feed( $pmpro_feed );
|
41 |
$rss_items = $rss->get_items( 0, $rss->get_item_quantity( $num ) );
|
42 |
}
|
43 |
+
|
44 |
return $rss_items;
|
45 |
}
|
46 |
+
|
47 |
/**
|
48 |
* Box with latest news from PaidMembershipsPro.com for sidebar
|
49 |
*/
|
50 |
+
function pmpro_news()
|
51 |
{
|
52 |
$rss_items = pmpro_fetch_rss_items( 5 );
|
53 |
+
|
54 |
$content = '<ul>';
|
55 |
if ( !$rss_items ) {
|
56 |
$content .= '<li class="pmpro_news">no news items, feed might be broken...</li>';
|
60 |
$content .= '<a class="rsswidget" href="'.esc_url( $item->get_permalink(), $protocolls=null, 'display' ).'">'. esc_html( $item->get_title() ) .'</a> ';
|
61 |
$content .= '</li>';
|
62 |
}
|
63 |
+
}
|
64 |
$content .= '</ul>';
|
65 |
$pmpro_postbox('pmprolatest', 'Recent Updates from PaidMembershipsPro.com', $content);
|
66 |
}
|
68 |
/**
|
69 |
* Widget with latest news from PaidMembershipsPro.com for dashbaord
|
70 |
*/
|
71 |
+
function pmpro_db_widget()
|
72 |
{
|
73 |
global $pmpro_feed;
|
74 |
+
|
75 |
$options = get_option('pmpro_pmprodbwidget');
|
76 |
+
|
77 |
$network = '';
|
78 |
if ( function_exists('is_network_admin') && is_network_admin() )
|
79 |
$network = '_network';
|
81 |
if (isset($_POST['pmpro_removedbwidget'])) {
|
82 |
$options['removedbwidget'.$network] = true;
|
83 |
update_option('pmpro_pmprodbwidget',$options);
|
84 |
+
}
|
85 |
if ( isset($options['removedbwidget'.$network]) && $options['removedbwidget'.$network] ) {
|
86 |
echo "If you reload, this widget will be gone and never appear again, unless you decide to delete the database option 'pmpro_pmprodbwidget'.";
|
87 |
return;
|
88 |
}
|
89 |
|
90 |
+
$rss_items = pmpro_fetch_rss_items( 3 );
|
91 |
+
|
92 |
echo "<ul>";
|
93 |
+
|
94 |
if ( !$rss_items ) {
|
95 |
echo '<li class="pmpro_news">no news items, feed might be broken...</li>';
|
96 |
} else {
|
101 |
echo '<div class="rssSummary">'. esc_html( pmpro_text_limit( strip_tags( $item->get_description() ), 150 ) ).'</div>';
|
102 |
echo '</li>';
|
103 |
}
|
104 |
+
}
|
105 |
|
106 |
echo '</ul>';
|
107 |
echo '<br class="clear"/><div style="margin-top:10px;border-top: 1px solid #ddd; padding-top: 10px; text-align:center;">';
|
112 |
echo '</div>';
|
113 |
}
|
114 |
|
115 |
+
function pmpro_widget_setup()
|
116 |
{
|
117 |
$network = '';
|
118 |
if ( function_exists('is_network_admin') && is_network_admin() )
|
122 |
if ( !isset($options['removedbwidget'.$network]) || !$options['removedbwidget'.$network] )
|
123 |
wp_add_dashboard_widget( 'pmpro_db_widget' , 'The Latest From PaidMembershipsPro.com' , 'pmpro_db_widget');
|
124 |
}
|
125 |
+
|
126 |
add_action( 'wp_dashboard_setup', 'pmpro_widget_setup');
|
127 |
?>
|
adminpages/discountcodes.php
CHANGED
@@ -1,665 +1,665 @@
|
|
1 |
-
<?php
|
2 |
-
//only admins can get this
|
3 |
-
if(!function_exists("current_user_can") || (!current_user_can("manage_options") && !current_user_can("pmpro_discountcodes")))
|
4 |
-
{
|
5 |
-
die(__("You do not have permissions to perform this action.", "pmpro"));
|
6 |
-
}
|
7 |
-
|
8 |
-
//vars
|
9 |
-
global $wpdb, $pmpro_currency_symbol;
|
10 |
-
|
11 |
-
if(isset($_REQUEST['edit']))
|
12 |
-
$edit = $_REQUEST['edit'];
|
13 |
-
else
|
14 |
-
$edit = false;
|
15 |
-
|
16 |
-
if(isset($_REQUEST['delete']))
|
17 |
-
$delete = $_REQUEST['delete'];
|
18 |
-
else
|
19 |
-
$delete = false;
|
20 |
-
|
21 |
-
if(isset($_REQUEST['saveid']))
|
22 |
-
$saveid = $_POST['saveid'];
|
23 |
-
else
|
24 |
-
$saveid = false;
|
25 |
-
|
26 |
-
if($saveid)
|
27 |
-
{
|
28 |
-
//get vars
|
29 |
-
$code = $_POST['code'];
|
30 |
-
$starts_month = $_POST['starts_month'];
|
31 |
-
$starts_day = $_POST['starts_day'];
|
32 |
-
$starts_year = $_POST['starts_year'];
|
33 |
-
$expires_month = $_POST['expires_month'];
|
34 |
-
$expires_day = $_POST['expires_day'];
|
35 |
-
$expires_year = $_POST['expires_year'];
|
36 |
-
$uses = $_POST['uses'];
|
37 |
-
|
38 |
-
//fix up dates
|
39 |
-
$starts = date("Y-m-d", strtotime($starts_month . "/" . $starts_day . "/" . $starts_year, current_time("timestamp")));
|
40 |
-
$expires = date("Y-m-d", strtotime($expires_month . "/" . $expires_day . "/" . $expires_year, current_time("timestamp")));
|
41 |
-
|
42 |
-
//updating or new?
|
43 |
-
if($saveid > 0)
|
44 |
-
{
|
45 |
-
$sqlQuery = "UPDATE $wpdb->pmpro_discount_codes SET code = '" . esc_sql($code) . "', starts = '" . $starts . "', expires = '" . $expires . "', uses = '" . intval($uses) . "' WHERE id = '" . $saveid . "' LIMIT 1";
|
46 |
-
if($wpdb->query($sqlQuery) !== false)
|
47 |
-
{
|
48 |
-
$pmpro_msg = __("Discount code updated successfully.", "pmpro");
|
49 |
-
$pmpro_msgt = "success";
|
50 |
-
$saved = true;
|
51 |
-
$edit = $saveid;
|
52 |
-
}
|
53 |
-
else
|
54 |
-
{
|
55 |
-
$pmpro_msg = __("Error updating discount code. That code may already be in use.", "pmpro");
|
56 |
-
$pmpro_msgt = "error";
|
57 |
-
}
|
58 |
-
}
|
59 |
-
else
|
60 |
-
{
|
61 |
-
$sqlQuery = "INSERT INTO $wpdb->pmpro_discount_codes (code, starts, expires, uses) VALUES('" . esc_sql($code) . "', '" . $starts . "', '" . $expires . "', '" . intval($uses) . "')";
|
62 |
-
if($wpdb->query($sqlQuery) !== false)
|
63 |
-
{
|
64 |
-
$pmpro_msg = __("Discount code added successfully.", "pmpro");
|
65 |
-
$pmpro_msgt = "success";
|
66 |
-
$saved = true;
|
67 |
-
$edit = $wpdb->insert_id;
|
68 |
-
//$saveid = $edit;
|
69 |
-
}
|
70 |
-
else
|
71 |
-
{
|
72 |
-
$pmpro_msg = __("Error adding discount code. That code may already be in use.", "pmpro") . $wpdb->last_error;
|
73 |
-
$pmpro_msgt = "error";
|
74 |
-
}
|
75 |
-
}
|
76 |
-
|
77 |
-
//now add the membership level rows
|
78 |
-
if($saved && $edit > 0)
|
79 |
-
{
|
80 |
-
//get the submitted values
|
81 |
-
$all_levels_a = $_REQUEST['all_levels'];
|
82 |
-
if(!empty($_REQUEST['levels']))
|
83 |
-
$levels_a = $_REQUEST['levels'];
|
84 |
-
else
|
85 |
-
$levels_a = array();
|
86 |
-
$initial_payment_a = $_REQUEST['initial_payment'];
|
87 |
-
if(!empty($_REQUEST['recurring']))
|
88 |
-
$recurring_a = $_REQUEST['recurring'];
|
89 |
-
$billing_amount_a = $_REQUEST['billing_amount'];
|
90 |
-
$cycle_number_a = $_REQUEST['cycle_number'];
|
91 |
-
$cycle_period_a = $_REQUEST['cycle_period'];
|
92 |
-
$billing_limit_a = $_REQUEST['billing_limit'];
|
93 |
-
if(!empty($_REQUEST['custom_trial']))
|
94 |
-
$custom_trial_a = $_REQUEST['custom_trial'];
|
95 |
-
$trial_amount_a = $_REQUEST['trial_amount'];
|
96 |
-
$trial_limit_a = $_REQUEST['trial_limit'];
|
97 |
-
if(!empty($_REQUEST['expiration']))
|
98 |
-
$expiration_a = $_REQUEST['expiration'];
|
99 |
-
$expiration_number_a = $_REQUEST['expiration_number'];
|
100 |
-
$expiration_period_a = $_REQUEST['expiration_period'];
|
101 |
-
|
102 |
-
//clear the old rows
|
103 |
-
$sqlQuery = "DELETE FROM $wpdb->pmpro_discount_codes_levels WHERE code_id = '" . $edit . "'";
|
104 |
-
$wpdb->query($sqlQuery);
|
105 |
-
|
106 |
-
//add a row for each checked level
|
107 |
-
if(!empty($levels_a))
|
108 |
-
{
|
109 |
-
foreach($levels_a as $level_id)
|
110 |
-
{
|
111 |
-
//get the values ready
|
112 |
-
$n = array_search($level_id, $all_levels_a); //this is the key location of this level's values
|
113 |
-
$initial_payment = $initial_payment_a[$n];
|
114 |
-
|
115 |
-
//is this recurring?
|
116 |
-
if(!empty($recurring_a))
|
117 |
-
{
|
118 |
-
if(in_array($level_id, $recurring_a))
|
119 |
-
$recurring = 1;
|
120 |
-
else
|
121 |
-
$recurring = 0;
|
122 |
-
}
|
123 |
-
else
|
124 |
-
$recurring = 0;
|
125 |
-
|
126 |
-
if(!empty($recurring))
|
127 |
-
{
|
128 |
-
$billing_amount = $billing_amount_a[$n];
|
129 |
-
$cycle_number = $cycle_number_a[$n];
|
130 |
-
$cycle_period = $cycle_period_a[$n];
|
131 |
-
$billing_limit = $billing_limit_a[$n];
|
132 |
-
|
133 |
-
//custom trial
|
134 |
-
if(!empty($custom_trial_a))
|
135 |
-
{
|
136 |
-
if(in_array($level_id, $custom_trial_a))
|
137 |
-
$custom_trial = 1;
|
138 |
-
else
|
139 |
-
$custom_trial = 0;
|
140 |
-
}
|
141 |
-
else
|
142 |
-
$custom_trial = 0;
|
143 |
-
|
144 |
-
if(!empty($custom_trial))
|
145 |
-
{
|
146 |
-
$trial_amount = $trial_amount_a[$n];
|
147 |
-
$trial_limit = $trial_limit_a[$n];
|
148 |
-
}
|
149 |
-
else
|
150 |
-
{
|
151 |
-
$trial_amount = '';
|
152 |
-
$trial_limit = '';
|
153 |
-
}
|
154 |
-
}
|
155 |
-
else
|
156 |
-
{
|
157 |
-
$billing_amount = '';
|
158 |
-
$cycle_number = '';
|
159 |
-
$cycle_period = 'Month';
|
160 |
-
$billing_limit = '';
|
161 |
-
$custom_trial = 0;
|
162 |
-
$trial_amount = '';
|
163 |
-
$trial_limit = '';
|
164 |
-
}
|
165 |
-
|
166 |
-
if(!empty($expiration_a))
|
167 |
-
{
|
168 |
-
if(in_array($level_id, $expiration_a))
|
169 |
-
$expiration = 1;
|
170 |
-
else
|
171 |
-
$expiration = 0;
|
172 |
-
}
|
173 |
-
else
|
174 |
-
$expiration = 0;
|
175 |
-
|
176 |
-
if(!empty($expiration))
|
177 |
-
{
|
178 |
-
$expiration_number = $expiration_number_a[$n];
|
179 |
-
$expiration_period = $expiration_period_a[$n];
|
180 |
-
}
|
181 |
-
else
|
182 |
-
{
|
183 |
-
$expiration_number = '';
|
184 |
-
$expiration_period = 'Month';
|
185 |
-
}
|
186 |
-
|
187 |
-
//okay, do the insert
|
188 |
-
$sqlQuery = "INSERT INTO $wpdb->pmpro_discount_codes_levels (code_id, level_id, initial_payment, billing_amount, cycle_number, cycle_period, billing_limit, trial_amount, trial_limit, expiration_number, expiration_period) VALUES('" . esc_sql($edit) . "', '" . esc_sql($level_id) . "', '" . (double)esc_sql($initial_payment) . "', '" . (double)esc_sql($billing_amount) . "', '" . intval(esc_sql($cycle_number)) . "', '" . esc_sql($cycle_period) . "', '" . intval(esc_sql($billing_limit)) . "', '" . (double)esc_sql($trial_amount) . "', '" . intval(esc_sql($trial_limit)) . "', '" . intval(esc_sql($expiration_number)) . "', '" . esc_sql($expiration_period) . "')";
|
189 |
-
|
190 |
-
if($wpdb->query($sqlQuery) !== false)
|
191 |
-
{
|
192 |
-
//okay
|
193 |
-
do_action("pmpro_save_discount_code_level", $edit, $level_id);
|
194 |
-
}
|
195 |
-
else
|
196 |
-
{
|
197 |
-
$level_errors[] = sprintf(__("Error saving values for the %s level.", "pmpro"), $wpdb->get_var("SELECT name FROM $wpdb->pmpro_membership_levels WHERE id = '" . $level_id . "' LIMIT 1"));
|
198 |
-
}
|
199 |
-
}
|
200 |
-
}
|
201 |
-
|
202 |
-
//errors?
|
203 |
-
if(!empty($level_errors))
|
204 |
-
{
|
205 |
-
$pmpro_msg = __("There were errors updating the level values: ", "pmpro") . implode(" ", $level_errors);
|
206 |
-
$pmpro_msgt = "error";
|
207 |
-
}
|
208 |
-
else
|
209 |
-
{
|
210 |
-
//all good. set edit = NULL so we go back to the overview page
|
211 |
-
$edit = NULL;
|
212 |
-
|
213 |
-
do_action("pmpro_save_discount_code", $saveid);
|
214 |
-
}
|
215 |
-
}
|
216 |
-
}
|
217 |
-
|
218 |
-
//are we deleting?
|
219 |
-
if(!empty($delete))
|
220 |
-
{
|
221 |
-
//is this a code?
|
222 |
-
$code = $wpdb->get_var("SELECT code FROM $wpdb->pmpro_discount_codes WHERE id = '" . $delete . "' LIMIT 1");
|
223 |
-
if(!empty($code))
|
224 |
-
{
|
225 |
-
//action
|
226 |
-
do_action("pmpro_delete_discount_code", $delete);
|
227 |
-
|
228 |
-
//delete the code levels
|
229 |
-
$r1 = $wpdb->query("DELETE FROM $wpdb->pmpro_discount_codes_levels WHERE code_id = '" . $delete . "'");
|
230 |
-
|
231 |
-
if($r1 !== false)
|
232 |
-
{
|
233 |
-
//delete the code
|
234 |
-
$r2 = $wpdb->query("DELETE FROM $wpdb->pmpro_discount_codes WHERE id = '" . $delete . "' LIMIT 1");
|
235 |
-
|
236 |
-
if($r2 !== false)
|
237 |
-
{
|
238 |
-
$pmpro_msg = sprintf(__("Code %s deleted successfully.", "pmpro"), $code);
|
239 |
-
$pmpro_msgt = "success";
|
240 |
-
}
|
241 |
-
else
|
242 |
-
{
|
243 |
-
$pmpro_msg = __("Error deleting discount code. The code was only partially deleted. Please try again.", "pmpro");
|
244 |
-
$pmpro_msgt = "error";
|
245 |
-
}
|
246 |
-
}
|
247 |
-
else
|
248 |
-
{
|
249 |
-
$pmpro_msg = __("Error deleting code. Please try again.", "pmpro");
|
250 |
-
$pmpro_msgt = "error";
|
251 |
-
}
|
252 |
-
}
|
253 |
-
else
|
254 |
-
{
|
255 |
-
$pmpro_msg = __("Code not found.", "pmpro");
|
256 |
-
$pmpro_msgt = "error";
|
257 |
-
}
|
258 |
-
}
|
259 |
-
|
260 |
-
require_once(dirname(__FILE__) . "/admin_header.php");
|
261 |
-
?>
|
262 |
-
|
263 |
-
<?php if($edit) { ?>
|
264 |
-
|
265 |
-
<h2>
|
266 |
-
<?php
|
267 |
-
if($edit > 0)
|
268 |
-
echo __("Edit Discount Code", "pmpro");
|
269 |
-
else
|
270 |
-
echo __("Add New Discount Code", "pmpro");
|
271 |
-
?>
|
272 |
-
</h2>
|
273 |
-
|
274 |
-
<?php if(!empty($pmpro_msg)) { ?>
|
275 |
-
<div id="message" class="<?php if($pmpro_msgt == "success") echo "updated fade"; else echo "error"; ?>"><p><?php echo $pmpro_msg?></p></div>
|
276 |
-
<?php } ?>
|
277 |
-
|
278 |
-
<div>
|
279 |
-
<?php
|
280 |
-
// get the code...
|
281 |
-
if($edit > 0)
|
282 |
-
{
|
283 |
-
$code = $wpdb->get_row("SELECT *, UNIX_TIMESTAMP(starts) as starts, UNIX_TIMESTAMP(expires) as expires FROM $wpdb->pmpro_discount_codes WHERE id = '" . $edit . "' LIMIT 1", OBJECT);
|
284 |
-
$uses = $wpdb->get_var("SELECT COUNT(*) FROM $wpdb->pmpro_discount_codes_uses WHERE code_id = '" . $code->id . "'");
|
285 |
-
$levels = $wpdb->get_results("SELECT l.id, l.name, cl.initial_payment, cl.billing_amount, cl.cycle_number, cl.cycle_period, cl.billing_limit, cl.trial_amount, cl.trial_limit FROM $wpdb->pmpro_membership_levels l LEFT JOIN $wpdb->pmpro_discount_codes_levels cl ON l.id = cl.level_id WHERE cl.code_id = '" . $code->code . "'");
|
286 |
-
$temp_id = $code->id;
|
287 |
-
}
|
288 |
-
elseif(!empty($copy) && $copy > 0)
|
289 |
-
{
|
290 |
-
$code = $wpdb->get_row("SELECT *, UNIX_TIMESTAMP(starts) as starts, UNIX_TIMESTAMP(expires) as expires FROM $wpdb->pmpro_discount_codes WHERE id = '" . $copy . "' LIMIT 1", OBJECT);
|
291 |
-
$temp_id = $level->id;
|
292 |
-
$level->id = NULL;
|
293 |
-
}
|
294 |
-
|
295 |
-
// didn't find a discount code, let's add a new one...
|
296 |
-
if(empty($code->id)) $edit = -1;
|
297 |
-
|
298 |
-
//defaults for new codes
|
299 |
-
if($edit == -1)
|
300 |
-
{
|
301 |
-
$code = new stdClass();
|
302 |
-
$code->code = pmpro_getDiscountCode();
|
303 |
-
}
|
304 |
-
?>
|
305 |
-
<form action="" method="post">
|
306 |
-
<input name="saveid" type="hidden" value="<?php echo $edit?>" />
|
307 |
-
<table class="form-table">
|
308 |
-
<tbody>
|
309 |
-
<tr>
|
310 |
-
<th scope="row" valign="top"><label><?php _e('ID', 'pmpro');?>:</label></th>
|
311 |
-
<td class="pmpro_lite"><?php if(!empty($code->id)) echo $code->id; else echo __("This will be generated when you save.", "pmpro");?></td>
|
312 |
-
</tr>
|
313 |
-
|
314 |
-
<tr>
|
315 |
-
<th scope="row" valign="top"><label for="code"><?php _e('Code', 'pmpro');?>:</label></th>
|
316 |
-
<td><input name="code" type="text" size="20" value="<?php echo str_replace("\"", """, stripslashes($code->code))?>" /></td>
|
317 |
-
</tr>
|
318 |
-
|
319 |
-
<?php
|
320 |
-
//some vars for the dates
|
321 |
-
$current_day = date("j");
|
322 |
-
if(!empty($code->starts))
|
323 |
-
$selected_starts_day = date("j", $code->starts);
|
324 |
-
else
|
325 |
-
$selected_starts_day = $current_day;
|
326 |
-
if(!empty($code->expires))
|
327 |
-
$selected_expires_day = date("j", $code->expires);
|
328 |
-
else
|
329 |
-
$selected_expires_day = $current_day;
|
330 |
-
|
331 |
-
$current_month = date("M");
|
332 |
-
if(!empty($code->starts))
|
333 |
-
$selected_starts_month = date("m", $code->starts);
|
334 |
-
else
|
335 |
-
$selected_starts_month = date("m");
|
336 |
-
if(!empty($code->expires))
|
337 |
-
$selected_expires_month = date("m", $code->expires);
|
338 |
-
else
|
339 |
-
$selected_expires_month = date("m");
|
340 |
-
|
341 |
-
$current_year = date("Y");
|
342 |
-
if(!empty($code->starts))
|
343 |
-
$selected_starts_year = date("Y", $code->starts);
|
344 |
-
else
|
345 |
-
$selected_starts_year = $current_year;
|
346 |
-
if(!empty($code->expires))
|
347 |
-
$selected_expires_year = date("Y", $code->expires);
|
348 |
-
else
|
349 |
-
$selected_expires_year = (int)$current_year + 1;
|
350 |
-
?>
|
351 |
-
|
352 |
-
<tr>
|
353 |
-
<th scope="row" valign="top"><label for="starts"><?php _e('Start Date', 'pmpro');?>:</label></th>
|
354 |
-
<td>
|
355 |
-
<select name="starts_month">
|
356 |
-
<?php
|
357 |
-
for($i = 1; $i < 13; $i++)
|
358 |
-
{
|
359 |
-
?>
|
360 |
-
<option value="<?php echo $i?>" <?php if($i == $selected_starts_month) { ?>selected="selected"<?php } ?>><?php echo date("M", strtotime($i . "/1/" . $current_year, current_time("timestamp")))?></option>
|
361 |
-
<?php
|
362 |
-
}
|
363 |
-
?>
|
364 |
-
</select>
|
365 |
-
<input name="starts_day" type="text" size="2" value="<?php echo $selected_starts_day?>" />
|
366 |
-
<input name="starts_year" type="text" size="4" value="<?php echo $selected_starts_year?>" />
|
367 |
-
</td>
|
368 |
-
</tr>
|
369 |
-
|
370 |
-
<tr>
|
371 |
-
<th scope="row" valign="top"><label for="expires"><?php _e('Expiration Date', 'pmpro');?>:</label></th>
|
372 |
-
<td>
|
373 |
-
<select name="expires_month">
|
374 |
-
<?php
|
375 |
-
for($i = 1; $i < 13; $i++)
|
376 |
-
{
|
377 |
-
?>
|
378 |
-
<option value="<?php echo $i?>" <?php if($i == $selected_expires_month) { ?>selected="selected"<?php } ?>><?php echo date("M", strtotime($i . "/1/" . $current_year, current_time("timestamp")))?></option>
|
379 |
-
<?php
|
380 |
-
}
|
381 |
-
?>
|
382 |
-
</select>
|
383 |
-
<input name="expires_day" type="text" size="2" value="<?php echo $selected_expires_day?>" />
|
384 |
-
<input name="expires_year" type="text" size="4" value="<?php echo $selected_expires_year?>" />
|
385 |
-
</td>
|
386 |
-
</tr>
|
387 |
-
|
388 |
-
<tr>
|
389 |
-
<th scope="row" valign="top"><label for="uses"><?php _e('Uses', 'pmpro');?>:</label></th>
|
390 |
-
<td>
|
391 |
-
<input name="uses" type="text" size="10" value="<?php if(!empty($code->uses)) echo str_replace("\"", """, stripslashes($code->uses));?>" />
|
392 |
-
<small class="pmpro_lite"><?php _e('Leave blank for unlimited uses.', 'pmpro');?></small>
|
393 |
-
</td>
|
394 |
-
</tr>
|
395 |
-
|
396 |
-
</tbody>
|
397 |
-
</table>
|
398 |
-
|
399 |
-
<?php do_action("pmpro_discount_code_after_settings"); ?>
|
400 |
-
|
401 |
-
<h3><?php _e('Which Levels Will This Code Apply To?', 'pmpro'); ?></h3>
|
402 |
-
|
403 |
-
<div class="pmpro_discount_levels">
|
404 |
-
<?php
|
405 |
-
$levels = $wpdb->get_results("SELECT * FROM $wpdb->pmpro_membership_levels");
|
406 |
-
foreach($levels as $level)
|
407 |
-
{
|
408 |
-
//if this level is already managed for this discount code, use the code values
|
409 |
-
if($edit > 0)
|
410 |
-
{
|
411 |
-
$code_level = $wpdb->get_row("SELECT l.id, cl.*, l.name, l.description, l.allow_signups FROM $wpdb->pmpro_discount_codes_levels cl LEFT JOIN $wpdb->pmpro_membership_levels l ON cl.level_id = l.id WHERE cl.code_id = '" . $edit . "' AND cl.level_id = '" . $level->id . "' LIMIT 1");
|
412 |
-
if($code_level)
|
413 |
-
{
|
414 |
-
$level = $code_level;
|
415 |
-
$level->checked = true;
|
416 |
-
}
|
417 |
-
else
|
418 |
-
$level_checked = false;
|
419 |
-
}
|
420 |
-
else
|
421 |
-
$level_checked = false;
|
422 |
-
?>
|
423 |
-
<div>
|
424 |
-
<input type="hidden" name="all_levels[]" value="<?php echo $level->id?>" />
|
425 |
-
<input type="checkbox" id="levels_<?php echo $level->id;?>" name="levels[]" value="<?php echo $level->id?>" <?php if(!empty($level->checked)) { ?>checked="checked"<?php } ?> onclick="if(jQuery(this).is(':checked')) jQuery(this).next().next().show(); else jQuery(this).next().next().hide();" />
|
426 |
-
<label for="levels_<?php echo $level->id;?>"><?php echo $level->name?></label>
|
427 |
-
<div class="pmpro_discount_levels_pricing level_<?php echo $level->id?>" <?php if(empty($level->checked)) { ?>style="display: none;"<?php } ?>>
|
428 |
-
<table class="form-table">
|
429 |
-
<tbody>
|
430 |
-
<tr>
|
431 |
-
<th scope="row" valign="top"><label for="initial_payment"><?php _e('Initial Payment', 'pmpro');?>:</label></th>
|
432 |
-
<td>
|
433 |
-
<?php
|
434 |
-
if(pmpro_getCurrencyPosition() == "left")
|
435 |
-
echo $pmpro_currency_symbol;
|
436 |
-
?>
|
437 |
-
<input name="initial_payment[]" type="text" size="20" value="<?php echo str_replace("\"", """, stripslashes($level->initial_payment))?>" />
|
438 |
-
<?php
|
439 |
-
if(pmpro_getCurrencyPosition() == "right")
|
440 |
-
echo $pmpro_currency_symbol;
|
441 |
-
?>
|
442 |
-
<small><?php _e('The initial amount collected at registration.', 'pmpro');?></small>
|
443 |
-
</td>
|
444 |
-
</tr>
|
445 |
-
|
446 |
-
<tr>
|
447 |
-
<th scope="row" valign="top"><label><?php _e('Recurring Subscription', 'pmpro');?>:</label></th>
|
448 |
-
<td><input class="recurring_checkbox" id="recurring_<?php echo $level->id;?>" name="recurring[]" type="checkbox" value="<?php echo $level->id?>" <?php if(pmpro_isLevelRecurring($level)) { echo "checked='checked'"; } ?> onclick="if(jQuery(this).attr('checked')) { jQuery(this).parent().parent().siblings('.recurring_info').show(); if(!jQuery('#custom_trial_<?php echo $level->id?>').is(':checked')) jQuery(this).parent().parent().siblings('.trial_info').hide();} else jQuery(this).parent().parent().siblings('.recurring_info').hide();" /> <label for="recurring_<?php echo $level->id;?>"><?php _e('Check if this level has a recurring subscription payment.', 'pmpro');?></label></td>
|
449 |
-
</tr>
|
450 |
-
|
451 |
-
<tr class="recurring_info" <?php if(!pmpro_isLevelRecurring($level)) {?>style="display: none;"<?php } ?>>
|
452 |
-
<th scope="row" valign="top"><label for="billing_amount"><?php _e('Billing Amount', 'pmpro');?>:</label></th>
|
453 |
-
<td>
|
454 |
-
<?php
|
455 |
-
if(pmpro_getCurrencyPosition() == "left")
|
456 |
-
echo $pmpro_currency_symbol;
|
457 |
-
?>
|
458 |
-
<input name="billing_amount[]" type="text" size="20" value="<?php echo str_replace("\"", """, stripslashes($level->billing_amount))?>" />
|
459 |
-
<?php
|
460 |
-
if(pmpro_getCurrencyPosition() == "right")
|
461 |
-
echo $pmpro_currency_symbol;
|
462 |
-
?>
|
463 |
-
<small>per</small>
|
464 |
-
<input name="cycle_number[]" type="text" size="10" value="<?php echo str_replace("\"", """, stripslashes($level->cycle_number))?>" />
|
465 |
-
<select name="cycle_period[]" onchange="updateCyclePeriod();">
|
466 |
-
<?php
|
467 |
-
$cycles = array( __('Day(s)', 'pmpro') => 'Day', __('Week(s)', 'pmpro') => 'Week', __('Month(s)', 'pmpro') => 'Month', __('Year(s)', 'pmpro') => 'Year' );
|
468 |
-
foreach ( $cycles as $name => $value ) {
|
469 |
-
echo "<option value='$value'";
|
470 |
-
if ( $level->cycle_period == $value ) echo " selected='selected'";
|
471 |
-
echo ">$name</option>";
|
472 |
-
}
|
473 |
-
?>
|
474 |
-
</select>
|
475 |
-
<br /><small><?php _e('The amount to be billed one cycle after the initial payment.', 'pmpro');?></small>
|
476 |
-
</td>
|
477 |
-
</tr>
|
478 |
-
|
479 |
-
<tr class="recurring_info" <?php if(!pmpro_isLevelRecurring($level)) {?>style="display: none;"<?php } ?>>
|
480 |
-
<th scope="row" valign="top"><label for="billing_limit"><?php _e('Billing Cycle Limit', 'pmpro');?>:</label></th>
|
481 |
-
<td>
|
482 |
-
<input name="billing_limit[]" type="text" size="20" value="<?php echo $level->billing_limit?>" />
|
483 |
-
<br /><small><?php _e('The <strong>total</strong> number of recurring billing cycles for this level, including the trial period (if applicable) but not including the initial payment. Set to zero if membership is indefinite.', 'pmpro');?></small>
|
484 |
-
</td>
|
485 |
-
</tr>
|
486 |
-
|
487 |
-
<tr class="recurring_info" <?php if (!pmpro_isLevelRecurring($level)) echo "style='display:none;'";?>>
|
488 |
-
<th scope="row" valign="top"><label><?php _e('Custom Trial', 'pmpro');?>:</label></th>
|
489 |
-
<td><input id="custom_trial_<?php echo $level->id?>" id="custom_trial_<?php echo $level->id;?>" name="custom_trial[]" type="checkbox" value="<?php echo $level->id?>" <?php if ( pmpro_isLevelTrial($level) ) { echo "checked='checked'"; } ?> onclick="if(jQuery(this).attr('checked')) jQuery(this).parent().parent().siblings('.trial_info').show(); else jQuery(this).parent().parent().siblings('.trial_info').hide();" /> <label for="custom_trial_<?php echo $level->id;?>"><?php _e('Check to add a custom trial period.', 'pmpro');?></label></td>
|
490 |
-
</tr>
|
491 |
-
|
492 |
-
<tr class="trial_info recurring_info" <?php if (!pmpro_isLevelTrial($level)) echo "style='display:none;'";?>>
|
493 |
-
<th scope="row" valign="top"><label for="trial_amount"><?php _e('Trial Billing Amount', 'pmpro');?>:</label></th>
|
494 |
-
<td>
|
495 |
-
<?php
|
496 |
-
if(pmpro_getCurrencyPosition() == "left")
|
497 |
-
echo $pmpro_currency_symbol;
|
498 |
-
?>
|
499 |
-
<input name="trial_amount[]" type="text" size="20" value="<?php echo str_replace("\"", """, stripslashes($level->trial_amount))?>" />
|
500 |
-
<?php
|
501 |
-
if(pmpro_getCurrencyPosition() == "right")
|
502 |
-
echo $pmpro_currency_symbol;
|
503 |
-
?>
|
504 |
-
<small><?php _e('for the first', 'pmpro');?></small>
|
505 |
-
<input name="trial_limit[]" type="text" size="10" value="<?php echo str_replace("\"", """, stripslashes($level->trial_limit))?>" />
|
506 |
-
<small><?php _e('subscription payments', 'pmpro');?>.</small>
|
507 |
-
</td>
|
508 |
-
</tr>
|
509 |
-
|
510 |
-
<tr>
|
511 |
-
<th scope="row" valign="top"><label><?php _e('Membership Expiration', 'pmpro');?>:</label></th>
|
512 |
-
<td><input id="expiration_<?php echo $level->id;?>" name="expiration[]" type="checkbox" value="<?php echo $level->id?>" <?php if(pmpro_isLevelExpiring($level)) { echo "checked='checked'"; } ?> onclick="if(jQuery(this).is(':checked')) { jQuery(this).parent().parent().siblings('.expiration_info').show(); } else { jQuery(this).parent().parent().siblings('.expiration_info').hide();}" /> <label for="expiration_<?php echo $level->id;?>"><?php _e('Check this to set when membership access expires.', 'pmpro');?></label></td>
|
513 |
-
</tr>
|
514 |
-
|
515 |
-
<tr class="expiration_info" <?php if(!pmpro_isLevelExpiring($level)) {?>style="display: none;"<?php } ?>>
|
516 |
-
<th scope="row" valign="top"><label for="billing_amount"><?php _e('Expires In', 'pmpro');?>:</label></th>
|
517 |
-
<td>
|
518 |
-
<input id="expiration_number" name="expiration_number[]" type="text" size="10" value="<?php echo str_replace("\"", """, stripslashes($level->expiration_number))?>" />
|
519 |
-
<select id="expiration_period" name="expiration_period[]">
|
520 |
-
<?php
|
521 |
-
$cycles = array( __('Day(s)', 'pmpro') => 'Day', __('Week(s)', 'pmpro') => 'Week', __('Month(s)', 'pmpro') => 'Month', __('Year(s)', 'pmpro') => 'Year' );
|
522 |
-
foreach ( $cycles as $name => $value ) {
|
523 |
-
echo "<option value='$value'";
|
524 |
-
if ( $level->expiration_period == $value ) echo " selected='selected'";
|
525 |
-
echo ">$name</option>";
|
526 |
-
}
|
527 |
-
?>
|
528 |
-
</select>
|
529 |
-
<br /><small><?php _e('Set the duration of membership access. Note that the any future payments (recurring subscription, if any) will be cancelled when the membership expires.', 'pmpro');?></small>
|
530 |
-
</td>
|
531 |
-
</tr>
|
532 |
-
</tbody>
|
533 |
-
</table>
|
534 |
-
|
535 |
-
<?php do_action("pmpro_discount_code_after_level_settings", $edit, $level); ?>
|
536 |
-
|
537 |
-
</div>
|
538 |
-
</div>
|
539 |
-
<script>
|
540 |
-
|
541 |
-
</script>
|
542 |
-
<?php
|
543 |
-
}
|
544 |
-
?>
|
545 |
-
</div>
|
546 |
-
|
547 |
-
<p class="submit topborder">
|
548 |
-
<input name="save" type="submit" class="button button-primary" value="Save Code" />
|
549 |
-
<input name="cancel" type="button" class="button button-secondary" value="Cancel" onclick="location.href='<?php echo get_admin_url(NULL, '/admin.php?page=pmpro-discountcodes')?>';" />
|
550 |
-
</p>
|
551 |
-
</form>
|
552 |
-
</div>
|
553 |
-
|
554 |
-
<?php } else { ?>
|
555 |
-
|
556 |
-
<h2>
|
557 |
-
<?php _e('Memberships Discount Codes', 'pmpro');?>
|
558 |
-
<a href="admin.php?page=pmpro-discountcodes&edit=-1" class="add-new-h2"><?php _e('Add New Discount Code', 'pmpro');?></a>
|
559 |
-
</h2>
|
560 |
-
|
561 |
-
<?php if(!empty($pmpro_msg)) { ?>
|
562 |
-
<div id="message" class="<?php if($pmpro_msgt == "success") echo "updated fade"; else echo "error"; ?>"><p><?php echo $pmpro_msg?></p></div>
|
563 |
-
<?php } ?>
|
564 |
-
|
565 |
-
<form id="posts-filter" method="get" action="">
|
566 |
-
<p class="search-box">
|
567 |
-
<label class="screen-reader-text" for="post-search-input"><?php _e('Search Discount Codes', 'pmpro');?>:</label>
|
568 |
-
<input type="hidden" name="page" value="pmpro-discountcodes" />
|
569 |
-
<input id="post-search-input" type="text" value="<?php if(!empty($s)) echo $s;?>" name="s" size="30" />
|
570 |
-
<input class="button" type="submit" value="<?php _e('Search', 'pmpro');?>" id="search-submit "/>
|
571 |
-
</p>
|
572 |
-
</form>
|
573 |
-
|
574 |
-
<br class="clear" />
|
575 |
-
<?php
|
576 |
-
$sqlQuery = "SELECT *, UNIX_TIMESTAMP(starts) as starts, UNIX_TIMESTAMP(expires) as expires FROM $wpdb->pmpro_discount_codes ";
|
577 |
-
if(!empty($s))
|
578 |
-
$sqlQuery .= "WHERE code LIKE '%$s%' ";
|
579 |
-
$sqlQuery .= "ORDER BY id ASC";
|
580 |
-
|
581 |
-
$codes = $wpdb->get_results($sqlQuery, OBJECT);
|
582 |
-
?>
|
583 |
-
<table class="widefat">
|
584 |
-
<thead>
|
585 |
-
<tr>
|
586 |
-
<th><?php _e('ID', 'pmpro');?></th>
|
587 |
-
<th><?php _e('Code', 'pmpro');?></th>
|
588 |
-
<th><?php _e('Starts', 'pmpro');?></th>
|
589 |
-
<th><?php _e('Expires', 'pmpro');?></th>
|
590 |
-
<th><?php _e('Uses', 'pmpro');?></th>
|
591 |
-
<th><?php _e('Levels', 'pmpro');?></th>
|
592 |
-
<?php do_action("pmpro_discountcodes_extra_cols_header", $codes);?>
|
593 |
-
<th></th>
|
594 |
-
<th></th>
|
595 |
-
</tr>
|
596 |
-
</thead>
|
597 |
-
<tbody>
|
598 |
-
<?php
|
599 |
-
if(!$codes)
|
600 |
-
{
|
601 |
-
?>
|
602 |
-
<tr><td colspan="7" class="pmpro_pad20">
|
603 |
-
<p><?php _e('Discount codes allow you to offer your memberships at discounted prices to select customers.', 'pmpro');?> <a href="admin.php?page=pmpro-discountcodes&edit=-1"><?php _e('Create your first discount code now', 'pmpro');?></a>.</p>
|
604 |
-
</td></tr>
|
605 |
-
<?php
|
606 |
-
}
|
607 |
-
else
|
608 |
-
{
|
609 |
-
foreach($codes as $code)
|
610 |
-
{
|
611 |
-
?>
|
612 |
-
<tr<?php if($count++ % 2 == 1) { ?> class="alternate"<?php } ?>>
|
613 |
-
<td><?php echo $code->id?></td>
|
614 |
-
<td>
|
615 |
-
<a href="?page=pmpro-discountcodes&edit=<?php echo $code->id?>"><?php echo $code->code?></a>
|
616 |
-
</td>
|
617 |
-
<td>
|
618 |
-
<?php echo date(get_option('date_format'), $code->starts)?>
|
619 |
-
</td>
|
620 |
-
<td>
|
621 |
-
<?php echo date(get_option('date_format'), $code->expires)?>
|
622 |
-
</td>
|
623 |
-
<td>
|
624 |
-
<?php
|
625 |
-
$uses = $wpdb->get_var("SELECT COUNT(*) FROM $wpdb->pmpro_discount_codes_uses WHERE code_id = '" . $code->id . "'");
|
626 |
-
if($code->uses > 0)
|
627 |
-
echo "<strong>" . (int)$uses . "</strong>/" . $code->uses;
|
628 |
-
else
|
629 |
-
echo "<strong>" . (int)$uses . "</strong>/unlimited";
|
630 |
-
?>
|
631 |
-
</td>
|
632 |
-
<td>
|
633 |
-
<?php
|
634 |
-
$sqlQuery = "SELECT l.id, l.name FROM $wpdb->pmpro_membership_levels l LEFT JOIN $wpdb->pmpro_discount_codes_levels cl ON l.id = cl.level_id WHERE cl.code_id = '" . $code->id . "'";
|
635 |
-
$levels = $wpdb->get_results($sqlQuery);
|
636 |
-
|
637 |
-
$level_names = array();
|
638 |
-
foreach($levels as $level)
|
639 |
-
$level_names[] = "<a target=\"_blank\" href=\"" . pmpro_url("checkout", "?level=" . $level->id . "&discount_code=" . $code->code) . "\">" . $level->name . "</a>";
|
640 |
-
if($level_names)
|
641 |
-
echo implode(", ", $level_names);
|
642 |
-
else
|
643 |
-
echo "None";
|
644 |
-
?>
|
645 |
-
</td>
|
646 |
-
<?php do_action("pmpro_discountcodes_extra_cols_body", $code);?>
|
647 |
-
<td>
|
648 |
-
<a href="?page=pmpro-discountcodes&edit=<?php echo $code->id?>"><?php _e('edit', 'pmpro');?></a>
|
649 |
-
</td>
|
650 |
-
<td>
|
651 |
-
<a href="javascript:askfirst('<?php printf(__('Are you sure you want to delete the %s discount code? The subscriptions for existing users will not change, but new users will not be able to use this code anymore.', 'pmpro'), $code->code);?>', '?page=pmpro-discountcodes&delete=<?php echo $code->id?>'); void(0);"><?php _e('delete', 'pmpro');?></a>
|
652 |
-
</td>
|
653 |
-
</tr>
|
654 |
-
<?php
|
655 |
-
}
|
656 |
-
}
|
657 |
-
?>
|
658 |
-
</tbody>
|
659 |
-
</table>
|
660 |
-
|
661 |
-
<?php } ?>
|
662 |
-
|
663 |
-
<?php
|
664 |
-
require_once(dirname(__FILE__) . "/admin_footer.php");
|
665 |
-
?>
|
1 |
+
<?php
|
2 |
+
//only admins can get this
|
3 |
+
if(!function_exists("current_user_can") || (!current_user_can("manage_options") && !current_user_can("pmpro_discountcodes")))
|
4 |
+
{
|
5 |
+
die(__("You do not have permissions to perform this action.", "pmpro"));
|
6 |
+
}
|
7 |
+
|
8 |
+
//vars
|
9 |
+
global $wpdb, $pmpro_currency_symbol;
|
10 |
+
|
11 |
+
if(isset($_REQUEST['edit']))
|
12 |
+
$edit = $_REQUEST['edit'];
|
13 |
+
else
|
14 |
+
$edit = false;
|
15 |
+
|
16 |
+
if(isset($_REQUEST['delete']))
|
17 |
+
$delete = $_REQUEST['delete'];
|
18 |
+
else
|
19 |
+
$delete = false;
|
20 |
+
|
21 |
+
if(isset($_REQUEST['saveid']))
|
22 |
+
$saveid = $_POST['saveid'];
|
23 |
+
else
|
24 |
+
$saveid = false;
|
25 |
+
|
26 |
+
if($saveid)
|
27 |
+
{
|
28 |
+
//get vars
|
29 |
+
$code = $_POST['code'];
|
30 |
+
$starts_month = $_POST['starts_month'];
|
31 |
+
$starts_day = $_POST['starts_day'];
|
32 |
+
$starts_year = $_POST['starts_year'];
|
33 |
+
$expires_month = $_POST['expires_month'];
|
34 |
+
$expires_day = $_POST['expires_day'];
|
35 |
+
$expires_year = $_POST['expires_year'];
|
36 |
+
$uses = $_POST['uses'];
|
37 |
+
|
38 |
+
//fix up dates
|
39 |
+
$starts = date("Y-m-d", strtotime($starts_month . "/" . $starts_day . "/" . $starts_year, current_time("timestamp")));
|
40 |
+
$expires = date("Y-m-d", strtotime($expires_month . "/" . $expires_day . "/" . $expires_year, current_time("timestamp")));
|
41 |
+
|
42 |
+
//updating or new?
|
43 |
+
if($saveid > 0)
|
44 |
+
{
|
45 |
+
$sqlQuery = "UPDATE $wpdb->pmpro_discount_codes SET code = '" . esc_sql($code) . "', starts = '" . $starts . "', expires = '" . $expires . "', uses = '" . intval($uses) . "' WHERE id = '" . $saveid . "' LIMIT 1";
|
46 |
+
if($wpdb->query($sqlQuery) !== false)
|
47 |
+
{
|
48 |
+
$pmpro_msg = __("Discount code updated successfully.", "pmpro");
|
49 |
+
$pmpro_msgt = "success";
|
50 |
+
$saved = true;
|
51 |
+
$edit = $saveid;
|
52 |
+
}
|
53 |
+
else
|
54 |
+
{
|
55 |
+
$pmpro_msg = __("Error updating discount code. That code may already be in use.", "pmpro");
|
56 |
+
$pmpro_msgt = "error";
|
57 |
+
}
|
58 |
+
}
|
59 |
+
else
|
60 |
+
{
|
61 |
+
$sqlQuery = "INSERT INTO $wpdb->pmpro_discount_codes (code, starts, expires, uses) VALUES('" . esc_sql($code) . "', '" . $starts . "', '" . $expires . "', '" . intval($uses) . "')";
|
62 |
+
if($wpdb->query($sqlQuery) !== false)
|
63 |
+
{
|
64 |
+
$pmpro_msg = __("Discount code added successfully.", "pmpro");
|
65 |
+
$pmpro_msgt = "success";
|
66 |
+
$saved = true;
|
67 |
+
$edit = $wpdb->insert_id;
|
68 |
+
//$saveid = $edit;
|
69 |
+
}
|
70 |
+
else
|
71 |
+
{
|
72 |
+
$pmpro_msg = __("Error adding discount code. That code may already be in use.", "pmpro") . $wpdb->last_error;
|
73 |
+
$pmpro_msgt = "error";
|
74 |
+
}
|
75 |
+
}
|
76 |
+
|
77 |
+
//now add the membership level rows
|
78 |
+
if($saved && $edit > 0)
|
79 |
+
{
|
80 |
+
//get the submitted values
|
81 |
+
$all_levels_a = $_REQUEST['all_levels'];
|
82 |
+
if(!empty($_REQUEST['levels']))
|
83 |
+
$levels_a = $_REQUEST['levels'];
|
84 |
+
else
|
85 |
+
$levels_a = array();
|
86 |
+
$initial_payment_a = $_REQUEST['initial_payment'];
|
87 |
+
if(!empty($_REQUEST['recurring']))
|
88 |
+
$recurring_a = $_REQUEST['recurring'];
|
89 |
+
$billing_amount_a = $_REQUEST['billing_amount'];
|
90 |
+
$cycle_number_a = $_REQUEST['cycle_number'];
|
91 |
+
$cycle_period_a = $_REQUEST['cycle_period'];
|
92 |
+
$billing_limit_a = $_REQUEST['billing_limit'];
|
93 |
+
if(!empty($_REQUEST['custom_trial']))
|
94 |
+
$custom_trial_a = $_REQUEST['custom_trial'];
|
95 |
+
$trial_amount_a = $_REQUEST['trial_amount'];
|
96 |
+
$trial_limit_a = $_REQUEST['trial_limit'];
|
97 |
+
if(!empty($_REQUEST['expiration']))
|
98 |
+
$expiration_a = $_REQUEST['expiration'];
|
99 |
+
$expiration_number_a = $_REQUEST['expiration_number'];
|
100 |
+
$expiration_period_a = $_REQUEST['expiration_period'];
|
101 |
+
|
102 |
+
//clear the old rows
|
103 |
+
$sqlQuery = "DELETE FROM $wpdb->pmpro_discount_codes_levels WHERE code_id = '" . $edit . "'";
|
104 |
+
$wpdb->query($sqlQuery);
|
105 |
+
|
106 |
+
//add a row for each checked level
|
107 |
+
if(!empty($levels_a))
|
108 |
+
{
|
109 |
+
foreach($levels_a as $level_id)
|
110 |
+
{
|
111 |
+
//get the values ready
|
112 |
+
$n = array_search($level_id, $all_levels_a); //this is the key location of this level's values
|
113 |
+
$initial_payment = $initial_payment_a[$n];
|
114 |
+
|
115 |
+
//is this recurring?
|
116 |
+
if(!empty($recurring_a))
|
117 |
+
{
|
118 |
+
if(in_array($level_id, $recurring_a))
|
119 |
+
$recurring = 1;
|
120 |
+
else
|
121 |
+
$recurring = 0;
|
122 |
+
}
|
123 |
+
else
|
124 |
+
$recurring = 0;
|
125 |
+
|
126 |
+
if(!empty($recurring))
|
127 |
+
{
|
128 |
+
$billing_amount = $billing_amount_a[$n];
|
129 |
+
$cycle_number = $cycle_number_a[$n];
|
130 |
+
$cycle_period = $cycle_period_a[$n];
|
131 |
+
$billing_limit = $billing_limit_a[$n];
|
132 |
+
|
133 |
+
//custom trial
|
134 |
+
if(!empty($custom_trial_a))
|
135 |
+
{
|
136 |
+
if(in_array($level_id, $custom_trial_a))
|
137 |
+
$custom_trial = 1;
|
138 |
+
else
|
139 |
+
$custom_trial = 0;
|
140 |
+
}
|
141 |
+
else
|
142 |
+
$custom_trial = 0;
|
143 |
+
|
144 |
+
if(!empty($custom_trial))
|
145 |
+
{
|
146 |
+
$trial_amount = $trial_amount_a[$n];
|
147 |
+
$trial_limit = $trial_limit_a[$n];
|
148 |
+
}
|
149 |
+
else
|
150 |
+
{
|
151 |
+
$trial_amount = '';
|
152 |
+
$trial_limit = '';
|
153 |
+
}
|
154 |
+
}
|
155 |
+
else
|
156 |
+
{
|
157 |
+
$billing_amount = '';
|
158 |
+
$cycle_number = '';
|
159 |
+
$cycle_period = 'Month';
|
160 |
+
$billing_limit = '';
|
161 |
+
$custom_trial = 0;
|
162 |
+
$trial_amount = '';
|
163 |
+
$trial_limit = '';
|
164 |
+
}
|
165 |
+
|
166 |
+
if(!empty($expiration_a))
|
167 |
+
{
|
168 |
+
if(in_array($level_id, $expiration_a))
|
169 |
+
$expiration = 1;
|
170 |
+
else
|
171 |
+
$expiration = 0;
|
172 |
+
}
|
173 |
+
else
|
174 |
+
$expiration = 0;
|
175 |
+
|
176 |
+
if(!empty($expiration))
|
177 |
+
{
|
178 |
+
$expiration_number = $expiration_number_a[$n];
|
179 |
+
$expiration_period = $expiration_period_a[$n];
|
180 |
+
}
|
181 |
+
else
|
182 |
+
{
|
183 |
+
$expiration_number = '';
|
184 |
+
$expiration_period = 'Month';
|
185 |
+
}
|
186 |
+
|
187 |
+
//okay, do the insert
|
188 |
+
$sqlQuery = "INSERT INTO $wpdb->pmpro_discount_codes_levels (code_id, level_id, initial_payment, billing_amount, cycle_number, cycle_period, billing_limit, trial_amount, trial_limit, expiration_number, expiration_period) VALUES('" . esc_sql($edit) . "', '" . esc_sql($level_id) . "', '" . (double)esc_sql($initial_payment) . "', '" . (double)esc_sql($billing_amount) . "', '" . intval(esc_sql($cycle_number)) . "', '" . esc_sql($cycle_period) . "', '" . intval(esc_sql($billing_limit)) . "', '" . (double)esc_sql($trial_amount) . "', '" . intval(esc_sql($trial_limit)) . "', '" . intval(esc_sql($expiration_number)) . "', '" . esc_sql($expiration_period) . "')";
|
189 |
+
|
190 |
+
if($wpdb->query($sqlQuery) !== false)
|
191 |
+
{
|
192 |
+
//okay
|
193 |
+
do_action("pmpro_save_discount_code_level", $edit, $level_id);
|
194 |
+
}
|
195 |
+
else
|
196 |
+
{
|
197 |
+
$level_errors[] = sprintf(__("Error saving values for the %s level.", "pmpro"), $wpdb->get_var("SELECT name FROM $wpdb->pmpro_membership_levels WHERE id = '" . $level_id . "' LIMIT 1"));
|
198 |
+
}
|
199 |
+
}
|
200 |
+
}
|
201 |
+
|
202 |
+
//errors?
|
203 |
+
if(!empty($level_errors))
|
204 |
+
{
|
205 |
+
$pmpro_msg = __("There were errors updating the level values: ", "pmpro") . implode(" ", $level_errors);
|
206 |
+
$pmpro_msgt = "error";
|
207 |
+
}
|
208 |
+
else
|
209 |
+
{
|
210 |
+
//all good. set edit = NULL so we go back to the overview page
|
211 |
+
$edit = NULL;
|
212 |
+
|
213 |
+
do_action("pmpro_save_discount_code", $saveid);
|
214 |
+
}
|
215 |
+
}
|
216 |
+
}
|
217 |
+
|
218 |
+
//are we deleting?
|
219 |
+
if(!empty($delete))
|
220 |
+
{
|
221 |
+
//is this a code?
|
222 |
+
$code = $wpdb->get_var("SELECT code FROM $wpdb->pmpro_discount_codes WHERE id = '" . $delete . "' LIMIT 1");
|
223 |
+
if(!empty($code))
|
224 |
+
{
|
225 |
+
//action
|
226 |
+
do_action("pmpro_delete_discount_code", $delete);
|
227 |
+
|
228 |
+
//delete the code levels
|
229 |
+
$r1 = $wpdb->query("DELETE FROM $wpdb->pmpro_discount_codes_levels WHERE code_id = '" . $delete . "'");
|
230 |
+
|
231 |
+
if($r1 !== false)
|
232 |
+
{
|
233 |
+
//delete the code
|
234 |
+
$r2 = $wpdb->query("DELETE FROM $wpdb->pmpro_discount_codes WHERE id = '" . $delete . "' LIMIT 1");
|
235 |
+
|
236 |
+
if($r2 !== false)
|
237 |
+
{
|
238 |
+
$pmpro_msg = sprintf(__("Code %s deleted successfully.", "pmpro"), $code);
|
239 |
+
$pmpro_msgt = "success";
|
240 |
+
}
|
241 |
+
else
|
242 |
+
{
|
243 |
+
$pmpro_msg = __("Error deleting discount code. The code was only partially deleted. Please try again.", "pmpro");
|
244 |
+
$pmpro_msgt = "error";
|
245 |
+
}
|
246 |
+
}
|
247 |
+
else
|
248 |
+
{
|
249 |
+
$pmpro_msg = __("Error deleting code. Please try again.", "pmpro");
|
250 |
+
$pmpro_msgt = "error";
|
251 |
+
}
|
252 |
+
}
|
253 |
+
else
|
254 |
+
{
|
255 |
+
$pmpro_msg = __("Code not found.", "pmpro");
|
256 |
+
$pmpro_msgt = "error";
|
257 |
+
}
|
258 |
+
}
|
259 |
+
|
260 |
+
require_once(dirname(__FILE__) . "/admin_header.php");
|
261 |
+
?>
|
262 |
+
|
263 |
+
<?php if($edit) { ?>
|
264 |
+
|
265 |
+
<h2>
|
266 |
+
<?php
|
267 |
+
if($edit > 0)
|
268 |
+
echo __("Edit Discount Code", "pmpro");
|
269 |
+
else
|
270 |
+
echo __("Add New Discount Code", "pmpro");
|
271 |
+
?>
|
272 |
+
</h2>
|
273 |
+
|
274 |
+
<?php if(!empty($pmpro_msg)) { ?>
|
275 |
+
<div id="message" class="<?php if($pmpro_msgt == "success") echo "updated fade"; else echo "error"; ?>"><p><?php echo $pmpro_msg?></p></div>
|
276 |
+
<?php } ?>
|
277 |
+
|
278 |
+
<div>
|
279 |
+
<?php
|
280 |
+
// get the code...
|
281 |
+
if($edit > 0)
|
282 |
+
{
|
283 |
+
$code = $wpdb->get_row("SELECT *, UNIX_TIMESTAMP(starts) as starts, UNIX_TIMESTAMP(expires) as expires FROM $wpdb->pmpro_discount_codes WHERE id = '" . $edit . "' LIMIT 1", OBJECT);
|
284 |
+
$uses = $wpdb->get_var("SELECT COUNT(*) FROM $wpdb->pmpro_discount_codes_uses WHERE code_id = '" . $code->id . "'");
|
285 |
+
$levels = $wpdb->get_results("SELECT l.id, l.name, cl.initial_payment, cl.billing_amount, cl.cycle_number, cl.cycle_period, cl.billing_limit, cl.trial_amount, cl.trial_limit FROM $wpdb->pmpro_membership_levels l LEFT JOIN $wpdb->pmpro_discount_codes_levels cl ON l.id = cl.level_id WHERE cl.code_id = '" . $code->code . "'");
|
286 |
+
$temp_id = $code->id;
|
287 |
+
}
|
288 |
+
elseif(!empty($copy) && $copy > 0)
|
289 |
+
{
|
290 |
+
$code = $wpdb->get_row("SELECT *, UNIX_TIMESTAMP(starts) as starts, UNIX_TIMESTAMP(expires) as expires FROM $wpdb->pmpro_discount_codes WHERE id = '" . $copy . "' LIMIT 1", OBJECT);
|
291 |
+
$temp_id = $level->id;
|
292 |
+
$level->id = NULL;
|
293 |
+
}
|
294 |
+
|
295 |
+
// didn't find a discount code, let's add a new one...
|
296 |
+
if(empty($code->id)) $edit = -1;
|
297 |
+
|
298 |
+
//defaults for new codes
|
299 |
+
if($edit == -1)
|
300 |
+
{
|
301 |
+
$code = new stdClass();
|
302 |
+
$code->code = pmpro_getDiscountCode();
|
303 |
+
}
|
304 |
+
?>
|
305 |
+
<form action="" method="post">
|
306 |
+
<input name="saveid" type="hidden" value="<?php echo $edit?>" />
|
307 |
+
<table class="form-table">
|
308 |
+
<tbody>
|
309 |
+
<tr>
|
310 |
+
<th scope="row" valign="top"><label><?php _e('ID', 'pmpro');?>:</label></th>
|
311 |
+
<td class="pmpro_lite"><?php if(!empty($code->id)) echo $code->id; else echo __("This will be generated when you save.", "pmpro");?></td>
|
312 |
+
</tr>
|
313 |
+
|
314 |
+
<tr>
|
315 |
+
<th scope="row" valign="top"><label for="code"><?php _e('Code', 'pmpro');?>:</label></th>
|
316 |
+
<td><input name="code" type="text" size="20" value="<?php echo str_replace("\"", """, stripslashes($code->code))?>" /></td>
|
317 |
+
</tr>
|
318 |
+
|
319 |
+
<?php
|
320 |
+
//some vars for the dates
|
321 |
+
$current_day = date("j");
|
322 |
+
if(!empty($code->starts))
|
323 |
+
$selected_starts_day = date("j", $code->starts);
|
324 |
+
else
|
325 |
+
$selected_starts_day = $current_day;
|
326 |
+
if(!empty($code->expires))
|
327 |
+
$selected_expires_day = date("j", $code->expires);
|
328 |
+
else
|
329 |
+
$selected_expires_day = $current_day;
|
330 |
+
|
331 |
+
$current_month = date("M");
|
332 |
+
if(!empty($code->starts))
|
333 |
+
$selected_starts_month = date("m", $code->starts);
|
334 |
+
else
|
335 |
+
$selected_starts_month = date("m");
|
336 |
+
if(!empty($code->expires))
|
337 |
+
$selected_expires_month = date("m", $code->expires);
|
338 |
+
else
|
339 |
+
$selected_expires_month = date("m");
|
340 |
+
|
341 |
+
$current_year = date("Y");
|
342 |
+
if(!empty($code->starts))
|
343 |
+
$selected_starts_year = date("Y", $code->starts);
|
344 |
+
else
|
345 |
+
$selected_starts_year = $current_year;
|
346 |
+
if(!empty($code->expires))
|
347 |
+
$selected_expires_year = date("Y", $code->expires);
|
348 |
+
else
|
349 |
+
$selected_expires_year = (int)$current_year + 1;
|
350 |
+
?>
|
351 |
+
|
352 |
+
<tr>
|
353 |
+
<th scope="row" valign="top"><label for="starts"><?php _e('Start Date', 'pmpro');?>:</label></th>
|
354 |
+
<td>
|
355 |
+
<select name="starts_month">
|
356 |
+
<?php
|
357 |
+
for($i = 1; $i < 13; $i++)
|
358 |
+
{
|
359 |
+
?>
|
360 |
+
<option value="<?php echo $i?>" <?php if($i == $selected_starts_month) { ?>selected="selected"<?php } ?>><?php echo date("M", strtotime($i . "/1/" . $current_year, current_time("timestamp")))?></option>
|
361 |
+
<?php
|
362 |
+
}
|
363 |
+
?>
|
364 |
+
</select>
|
365 |
+
<input name="starts_day" type="text" size="2" value="<?php echo $selected_starts_day?>" />
|
366 |
+
<input name="starts_year" type="text" size="4" value="<?php echo $selected_starts_year?>" />
|
367 |
+
</td>
|
368 |
+
</tr>
|
369 |
+
|
370 |
+
<tr>
|
371 |
+
<th scope="row" valign="top"><label for="expires"><?php _e('Expiration Date', 'pmpro');?>:</label></th>
|
372 |
+
<td>
|
373 |
+
<select name="expires_month">
|
374 |
+
<?php
|
375 |
+
for($i = 1; $i < 13; $i++)
|
376 |
+
{
|
377 |
+
?>
|
378 |
+
<option value="<?php echo $i?>" <?php if($i == $selected_expires_month) { ?>selected="selected"<?php } ?>><?php echo date("M", strtotime($i . "/1/" . $current_year, current_time("timestamp")))?></option>
|
379 |
+
<?php
|
380 |
+
}
|
381 |
+
?>
|
382 |
+
</select>
|
383 |
+
<input name="expires_day" type="text" size="2" value="<?php echo $selected_expires_day?>" />
|
384 |
+
<input name="expires_year" type="text" size="4" value="<?php echo $selected_expires_year?>" />
|
385 |
+
</td>
|
386 |
+
</tr>
|
387 |
+
|
388 |
+
<tr>
|
389 |
+
<th scope="row" valign="top"><label for="uses"><?php _e('Uses', 'pmpro');?>:</label></th>
|
390 |
+
<td>
|
391 |
+
<input name="uses" type="text" size="10" value="<?php if(!empty($code->uses)) echo str_replace("\"", """, stripslashes($code->uses));?>" />
|
392 |
+
<small class="pmpro_lite"><?php _e('Leave blank for unlimited uses.', 'pmpro');?></small>
|
393 |
+
</td>
|
394 |
+
</tr>
|
395 |
+
|
396 |
+
</tbody>
|
397 |
+
</table>
|
398 |
+
|
399 |
+
<?php do_action("pmpro_discount_code_after_settings"); ?>
|
400 |
+
|
401 |
+
<h3><?php _e('Which Levels Will This Code Apply To?', 'pmpro'); ?></h3>
|
402 |
+
|
403 |
+
<div class="pmpro_discount_levels">
|
404 |
+
<?php
|
405 |
+
$levels = $wpdb->get_results("SELECT * FROM $wpdb->pmpro_membership_levels");
|
406 |
+
foreach($levels as $level)
|
407 |
+
{
|
408 |
+
//if this level is already managed for this discount code, use the code values
|
409 |
+
if($edit > 0)
|
410 |
+
{
|
411 |
+
$code_level = $wpdb->get_row("SELECT l.id, cl.*, l.name, l.description, l.allow_signups FROM $wpdb->pmpro_discount_codes_levels cl LEFT JOIN $wpdb->pmpro_membership_levels l ON cl.level_id = l.id WHERE cl.code_id = '" . $edit . "' AND cl.level_id = '" . $level->id . "' LIMIT 1");
|
412 |
+
if($code_level)
|
413 |
+
{
|
414 |
+
$level = $code_level;
|
415 |
+
$level->checked = true;
|
416 |
+
}
|
417 |
+
else
|
418 |
+
$level_checked = false;
|
419 |
+
}
|
420 |
+
else
|
421 |
+
$level_checked = false;
|
422 |
+
?>
|
423 |
+
<div>
|
424 |
+
<input type="hidden" name="all_levels[]" value="<?php echo $level->id?>" />
|
425 |
+
<input type="checkbox" id="levels_<?php echo $level->id;?>" name="levels[]" value="<?php echo $level->id?>" <?php if(!empty($level->checked)) { ?>checked="checked"<?php } ?> onclick="if(jQuery(this).is(':checked')) jQuery(this).next().next().show(); else jQuery(this).next().next().hide();" />
|
426 |
+
<label for="levels_<?php echo $level->id;?>"><?php echo $level->name?></label>
|
427 |
+
<div class="pmpro_discount_levels_pricing level_<?php echo $level->id?>" <?php if(empty($level->checked)) { ?>style="display: none;"<?php } ?>>
|
428 |
+
<table class="form-table">
|
429 |
+
<tbody>
|
430 |
+
<tr>
|
431 |
+
<th scope="row" valign="top"><label for="initial_payment"><?php _e('Initial Payment', 'pmpro');?>:</label></th>
|
432 |
+
<td>
|
433 |
+
<?php
|
434 |
+
if(pmpro_getCurrencyPosition() == "left")
|
435 |
+
echo $pmpro_currency_symbol;
|
436 |
+
?>
|
437 |
+
<input name="initial_payment[]" type="text" size="20" value="<?php echo str_replace("\"", """, stripslashes($level->initial_payment))?>" />
|
438 |
+
<?php
|
439 |
+
if(pmpro_getCurrencyPosition() == "right")
|
440 |
+
echo $pmpro_currency_symbol;
|
441 |
+
?>
|
442 |
+
<small><?php _e('The initial amount collected at registration.', 'pmpro');?></small>
|
443 |
+
</td>
|
444 |
+
</tr>
|
445 |
+
|
446 |
+
<tr>
|
447 |
+
<th scope="row" valign="top"><label><?php _e('Recurring Subscription', 'pmpro');?>:</label></th>
|
448 |
+
<td><input class="recurring_checkbox" id="recurring_<?php echo $level->id;?>" name="recurring[]" type="checkbox" value="<?php echo $level->id?>" <?php if(pmpro_isLevelRecurring($level)) { echo "checked='checked'"; } ?> onclick="if(jQuery(this).attr('checked')) { jQuery(this).parent().parent().siblings('.recurring_info').show(); if(!jQuery('#custom_trial_<?php echo $level->id?>').is(':checked')) jQuery(this).parent().parent().siblings('.trial_info').hide();} else jQuery(this).parent().parent().siblings('.recurring_info').hide();" /> <label for="recurring_<?php echo $level->id;?>"><?php _e('Check if this level has a recurring subscription payment.', 'pmpro');?></label></td>
|
449 |
+
</tr>
|
450 |
+
|
451 |
+
<tr class="recurring_info" <?php if(!pmpro_isLevelRecurring($level)) {?>style="display: none;"<?php } ?>>
|
452 |
+
<th scope="row" valign="top"><label for="billing_amount"><?php _e('Billing Amount', 'pmpro');?>:</label></th>
|
453 |
+
<td>
|
454 |
+
<?php
|
455 |
+
if(pmpro_getCurrencyPosition() == "left")
|
456 |
+
echo $pmpro_currency_symbol;
|
457 |
+
?>
|
458 |
+
<input name="billing_amount[]" type="text" size="20" value="<?php echo str_replace("\"", """, stripslashes($level->billing_amount))?>" />
|
459 |
+
<?php
|
460 |
+
if(pmpro_getCurrencyPosition() == "right")
|
461 |
+
echo $pmpro_currency_symbol;
|
462 |
+
?>
|
463 |
+
<small>per</small>
|
464 |
+
<input name="cycle_number[]" type="text" size="10" value="<?php echo str_replace("\"", """, stripslashes($level->cycle_number))?>" />
|
465 |
+
<select name="cycle_period[]" onchange="updateCyclePeriod();">
|
466 |
+
<?php
|
467 |
+
$cycles = array( __('Day(s)', 'pmpro') => 'Day', __('Week(s)', 'pmpro') => 'Week', __('Month(s)', 'pmpro') => 'Month', __('Year(s)', 'pmpro') => 'Year' );
|
468 |
+
foreach ( $cycles as $name => $value ) {
|
469 |
+
echo "<option value='$value'";
|
470 |
+
if ( $level->cycle_period == $value ) echo " selected='selected'";
|
471 |
+
echo ">$name</option>";
|
472 |
+
}
|
473 |
+
?>
|
474 |
+
</select>
|
475 |
+
<br /><small><?php _e('The amount to be billed one cycle after the initial payment.', 'pmpro');?></small>
|
476 |
+
</td>
|
477 |
+
</tr>
|
478 |
+
|
479 |
+
<tr class="recurring_info" <?php if(!pmpro_isLevelRecurring($level)) {?>style="display: none;"<?php } ?>>
|
480 |
+
<th scope="row" valign="top"><label for="billing_limit"><?php _e('Billing Cycle Limit', 'pmpro');?>:</label></th>
|
481 |
+
<td>
|
482 |
+
<input name="billing_limit[]" type="text" size="20" value="<?php echo $level->billing_limit?>" />
|
483 |
+
<br /><small><?php _e('The <strong>total</strong> number of recurring billing cycles for this level, including the trial period (if applicable) but not including the initial payment. Set to zero if membership is indefinite.', 'pmpro');?></small>
|
484 |
+
</td>
|
485 |
+
</tr>
|
486 |
+
|
487 |
+
<tr class="recurring_info" <?php if (!pmpro_isLevelRecurring($level)) echo "style='display:none;'";?>>
|
488 |
+
<th scope="row" valign="top"><label><?php _e('Custom Trial', 'pmpro');?>:</label></th>
|
489 |
+
<td><input id="custom_trial_<?php echo $level->id?>" id="custom_trial_<?php echo $level->id;?>" name="custom_trial[]" type="checkbox" value="<?php echo $level->id?>" <?php if ( pmpro_isLevelTrial($level) ) { echo "checked='checked'"; } ?> onclick="if(jQuery(this).attr('checked')) jQuery(this).parent().parent().siblings('.trial_info').show(); else jQuery(this).parent().parent().siblings('.trial_info').hide();" /> <label for="custom_trial_<?php echo $level->id;?>"><?php _e('Check to add a custom trial period.', 'pmpro');?></label></td>
|
490 |
+
</tr>
|
491 |
+
|
492 |
+
<tr class="trial_info recurring_info" <?php if (!pmpro_isLevelTrial($level)) echo "style='display:none;'";?>>
|
493 |
+
<th scope="row" valign="top"><label for="trial_amount"><?php _e('Trial Billing Amount', 'pmpro');?>:</label></th>
|
494 |
+
<td>
|
495 |
+
<?php
|
496 |
+
if(pmpro_getCurrencyPosition() == "left")
|
497 |
+
echo $pmpro_currency_symbol;
|
498 |
+
?>
|
499 |
+
<input name="trial_amount[]" type="text" size="20" value="<?php echo str_replace("\"", """, stripslashes($level->trial_amount))?>" />
|
500 |
+
<?php
|
501 |
+
if(pmpro_getCurrencyPosition() == "right")
|
502 |
+
echo $pmpro_currency_symbol;
|
503 |
+
?>
|
504 |
+
<small><?php _e('for the first', 'pmpro');?></small>
|
505 |
+
<input name="trial_limit[]" type="text" size="10" value="<?php echo str_replace("\"", """, stripslashes($level->trial_limit))?>" />
|
506 |
+
<small><?php _e('subscription payments', 'pmpro');?>.</small>
|
507 |
+
</td>
|
508 |
+
</tr>
|
509 |
+
|
510 |
+
<tr>
|
511 |
+
<th scope="row" valign="top"><label><?php _e('Membership Expiration', 'pmpro');?>:</label></th>
|
512 |
+
<td><input id="expiration_<?php echo $level->id;?>" name="expiration[]" type="checkbox" value="<?php echo $level->id?>" <?php if(pmpro_isLevelExpiring($level)) { echo "checked='checked'"; } ?> onclick="if(jQuery(this).is(':checked')) { jQuery(this).parent().parent().siblings('.expiration_info').show(); } else { jQuery(this).parent().parent().siblings('.expiration_info').hide();}" /> <label for="expiration_<?php echo $level->id;?>"><?php _e('Check this to set when membership access expires.', 'pmpro');?></label></td>
|
513 |
+
</tr>
|
514 |
+
|
515 |
+
<tr class="expiration_info" <?php if(!pmpro_isLevelExpiring($level)) {?>style="display: none;"<?php } ?>>
|
516 |
+
<th scope="row" valign="top"><label for="billing_amount"><?php _e('Expires In', 'pmpro');?>:</label></th>
|
517 |
+
<td>
|
518 |
+
<input id="expiration_number" name="expiration_number[]" type="text" size="10" value="<?php echo str_replace("\"", """, stripslashes($level->expiration_number))?>" />
|
519 |
+
<select id="expiration_period" name="expiration_period[]">
|
520 |
+
<?php
|
521 |
+
$cycles = array( __('Day(s)', 'pmpro') => 'Day', __('Week(s)', 'pmpro') => 'Week', __('Month(s)', 'pmpro') => 'Month', __('Year(s)', 'pmpro') => 'Year' );
|
522 |
+
foreach ( $cycles as $name => $value ) {
|
523 |
+
echo "<option value='$value'";
|
524 |
+
if ( $level->expiration_period == $value ) echo " selected='selected'";
|
525 |
+
echo ">$name</option>";
|
526 |
+
}
|
527 |
+
?>
|
528 |
+
</select>
|
529 |
+
<br /><small><?php _e('Set the duration of membership access. Note that the any future payments (recurring subscription, if any) will be cancelled when the membership expires.', 'pmpro');?></small>
|
530 |
+
</td>
|
531 |
+
</tr>
|
532 |
+
</tbody>
|
533 |
+
</table>
|
534 |
+
|
535 |
+
<?php do_action("pmpro_discount_code_after_level_settings", $edit, $level); ?>
|
536 |
+
|
537 |
+
</div>
|
538 |
+
</div>
|
539 |
+
<script>
|
540 |
+
|
541 |
+
</script>
|
542 |
+
<?php
|
543 |
+
}
|
544 |
+
?>
|
545 |
+
</div>
|
546 |
+
|
547 |
+
<p class="submit topborder">
|
548 |
+
<input name="save" type="submit" class="button button-primary" value="Save Code" />
|
549 |
+
<input name="cancel" type="button" class="button button-secondary" value="Cancel" onclick="location.href='<?php echo get_admin_url(NULL, '/admin.php?page=pmpro-discountcodes')?>';" />
|
550 |
+
</p>
|
551 |
+
</form>
|
552 |
+
</div>
|
553 |
+
|
554 |
+
<?php } else { ?>
|
555 |
+
|
556 |
+
<h2>
|
557 |
+
<?php _e('Memberships Discount Codes', 'pmpro');?>
|
558 |
+
<a href="admin.php?page=pmpro-discountcodes&edit=-1" class="add-new-h2"><?php _e('Add New Discount Code', 'pmpro');?></a>
|
559 |
+
</h2>
|
560 |
+
|
561 |
+
<?php if(!empty($pmpro_msg)) { ?>
|
562 |
+
<div id="message" class="<?php if($pmpro_msgt == "success") echo "updated fade"; else echo "error"; ?>"><p><?php echo $pmpro_msg?></p></div>
|
563 |
+
<?php } ?>
|
564 |
+
|
565 |
+
<form id="posts-filter" method="get" action="">
|
566 |
+
<p class="search-box">
|
567 |
+
<label class="screen-reader-text" for="post-search-input"><?php _e('Search Discount Codes', 'pmpro');?>:</label>
|
568 |
+
<input type="hidden" name="page" value="pmpro-discountcodes" />
|
569 |
+
<input id="post-search-input" type="text" value="<?php if(!empty($s)) echo $s;?>" name="s" size="30" />
|
570 |
+
<input class="button" type="submit" value="<?php _e('Search', 'pmpro');?>" id="search-submit "/>
|
571 |
+
</p>
|
572 |
+
</form>
|
573 |
+
|
574 |
+
<br class="clear" />
|
575 |
+
<?php
|
576 |
+
$sqlQuery = "SELECT *, UNIX_TIMESTAMP(starts) as starts, UNIX_TIMESTAMP(expires) as expires FROM $wpdb->pmpro_discount_codes ";
|
577 |
+
if(!empty($s))
|
578 |
+
$sqlQuery .= "WHERE code LIKE '%$s%' ";
|
579 |
+
$sqlQuery .= "ORDER BY id ASC";
|
580 |
+
|
581 |
+
$codes = $wpdb->get_results($sqlQuery, OBJECT);
|
582 |
+
?>
|
583 |
+
<table class="widefat">
|
584 |
+
<thead>
|
585 |
+
<tr>
|
586 |
+
<th><?php _e('ID', 'pmpro');?></th>
|
587 |
+
<th><?php _e('Code', 'pmpro');?></th>
|
588 |
+
<th><?php _e('Starts', 'pmpro');?></th>
|
589 |
+
<th><?php _e('Expires', 'pmpro');?></th>
|
590 |
+
<th><?php _e('Uses', 'pmpro');?></th>
|
591 |
+
<th><?php _e('Levels', 'pmpro');?></th>
|
592 |
+
<?php do_action("pmpro_discountcodes_extra_cols_header", $codes);?>
|
593 |
+
<th></th>
|
594 |
+
<th></th>
|
595 |
+
</tr>
|
596 |
+
</thead>
|
597 |
+
<tbody>
|
598 |
+
<?php
|
599 |
+
if(!$codes)
|
600 |
+
{
|
601 |
+
?>
|
602 |
+
<tr><td colspan="7" class="pmpro_pad20">
|
603 |
+
<p><?php _e('Discount codes allow you to offer your memberships at discounted prices to select customers.', 'pmpro');?> <a href="admin.php?page=pmpro-discountcodes&edit=-1"><?php _e('Create your first discount code now', 'pmpro');?></a>.</p>
|
604 |
+
</td></tr>
|
605 |
+
<?php
|
606 |
+
}
|
607 |
+
else
|
608 |
+
{
|
609 |
+
foreach($codes as $code)
|
610 |
+
{
|
611 |
+
?>
|
612 |
+
<tr<?php if($count++ % 2 == 1) { ?> class="alternate"<?php } ?>>
|
613 |
+
<td><?php echo $code->id?></td>
|
614 |
+
<td>
|
615 |
+
<a href="?page=pmpro-discountcodes&edit=<?php echo $code->id?>"><?php echo $code->code?></a>
|
616 |
+
</td>
|
617 |
+
<td>
|
618 |
+
<?php echo date(get_option('date_format'), $code->starts)?>
|
619 |
+
</td>
|
620 |
+
<td>
|
621 |
+
<?php echo date(get_option('date_format'), $code->expires)?>
|
622 |
+
</td>
|
623 |
+
<td>
|
624 |
+
<?php
|
625 |
+
$uses = $wpdb->get_var("SELECT COUNT(*) FROM $wpdb->pmpro_discount_codes_uses WHERE code_id = '" . $code->id . "'");
|
626 |
+
if($code->uses > 0)
|
627 |
+
echo "<strong>" . (int)$uses . "</strong>/" . $code->uses;
|
628 |
+
else
|
629 |
+
echo "<strong>" . (int)$uses . "</strong>/unlimited";
|
630 |
+
?>
|
631 |
+
</td>
|
632 |
+
<td>
|
633 |
+
<?php
|
634 |
+
$sqlQuery = "SELECT l.id, l.name FROM $wpdb->pmpro_membership_levels l LEFT JOIN $wpdb->pmpro_discount_codes_levels cl ON l.id = cl.level_id WHERE cl.code_id = '" . $code->id . "'";
|
635 |
+
$levels = $wpdb->get_results($sqlQuery);
|
636 |
+
|
637 |
+
$level_names = array();
|
638 |
+
foreach($levels as $level)
|
639 |
+
$level_names[] = "<a target=\"_blank\" href=\"" . pmpro_url("checkout", "?level=" . $level->id . "&discount_code=" . $code->code) . "\">" . $level->name . "</a>";
|
640 |
+
if($level_names)
|
641 |
+
echo implode(", ", $level_names);
|
642 |
+
else
|
643 |
+
echo "None";
|
644 |
+
?>
|
645 |
+
</td>
|
646 |
+
<?php do_action("pmpro_discountcodes_extra_cols_body", $code);?>
|
647 |
+
<td>
|
648 |
+
<a href="?page=pmpro-discountcodes&edit=<?php echo $code->id?>"><?php _e('edit', 'pmpro');?></a>
|
649 |
+
</td>
|
650 |
+
<td>
|
651 |
+
<a href="javascript:askfirst('<?php printf(__('Are you sure you want to delete the %s discount code? The subscriptions for existing users will not change, but new users will not be able to use this code anymore.', 'pmpro'), $code->code);?>', '?page=pmpro-discountcodes&delete=<?php echo $code->id?>'); void(0);"><?php _e('delete', 'pmpro');?></a>
|
652 |
+
</td>
|
653 |
+
</tr>
|
654 |
+
<?php
|
655 |
+
}
|
656 |
+
}
|
657 |
+
?>
|
658 |
+
</tbody>
|
659 |
+
</table>
|
660 |
+
|
661 |
+
<?php } ?>
|
662 |
+
|
663 |
+
<?php
|
664 |
+
require_once(dirname(__FILE__) . "/admin_footer.php");
|
665 |
+
?>
|
adminpages/emailsettings.php
CHANGED
@@ -1,181 +1,181 @@
|
|
1 |
-
<?php
|
2 |
-
//only admins can get this
|
3 |
-
if(!function_exists("current_user_can") || (!current_user_can("manage_options") && !current_user_can("pmpro_emailsettings")))
|
4 |
-
{
|
5 |
-
die(__("You do not have permissions to perform this action.", "pmpro"));
|
6 |
-
}
|
7 |
-
|
8 |
-
global $wpdb, $msg, $msgt;
|
9 |
-
|
10 |
-
//get/set settings
|
11 |
-
global $pmpro_pages;
|
12 |
-
if(!empty($_REQUEST['savesettings']))
|
13 |
-
{
|
14 |
-
//email options
|
15 |
-
pmpro_setOption("from_email");
|
16 |
-
pmpro_setOption("from_name");
|
17 |
-
pmpro_setOption("only_filter_pmpro_emails");
|
18 |
-
|
19 |
-
pmpro_setOption("email_admin_checkout");
|
20 |
-
pmpro_setOption("email_admin_changes");
|
21 |
-
pmpro_setOption("email_admin_cancels");
|
22 |
-
pmpro_setOption("email_admin_billing");
|
23 |
-
|
24 |
-
pmpro_setOption("email_member_notification");
|
25 |
-
|
26 |
-
//assume success
|
27 |
-
$msg = true;
|
28 |
-
$msgt = "Your email settings have been updated.";
|
29 |
-
}
|
30 |
-
|
31 |
-
$from_email = pmpro_getOption("from_email");
|
32 |
-
$from_name = pmpro_getOption("from_name");
|
33 |
-
$only_filter_pmpro_emails = pmpro_getOption("only_filter_pmpro_emails");
|
34 |
-
|
35 |
-
$email_admin_checkout = pmpro_getOption("email_admin_checkout");
|
36 |
-
$email_admin_changes = pmpro_getOption("email_admin_changes");
|
37 |
-
$email_admin_cancels = pmpro_getOption("email_admin_cancels");
|
38 |
-
$email_admin_billing = pmpro_getOption("email_admin_billing");
|
39 |
-
|
40 |
-
$email_member_notification = pmpro_getOption("email_member_notification");
|
41 |
-
|
42 |
-
if(empty($from_email))
|
43 |
-
{
|
44 |
-
$parsed = parse_url(home_url());
|
45 |
-
$hostname = $parsed[host];
|
46 |
-
$hostparts = split("\.", $hostname);
|
47 |
-
$email_domain = $hostparts[count($hostparts) - 2] . "." . $hostparts[count($hostparts) - 1];
|
48 |
-
$from_email = "wordpress@" . $email_domain;
|
49 |
-
pmpro_setOption("from_email", $from_email);
|
50 |
-
}
|
51 |
-
|
52 |
-
if(empty($from_name))
|
53 |
-
{
|
54 |
-
$from_name = "WordPress";
|
55 |
-
pmpro_setOption("from_name", $from_name);
|
56 |
-
}
|
57 |
-
|
58 |
-
// default from email wordpress@sitename
|
59 |
-
$sitename = strtolower( $_SERVER['SERVER_NAME'] );
|
60 |
-
if ( substr( $sitename, 0, 4 ) == 'www.' ) {
|
61 |
-
$sitename = substr( $sitename, 4 );
|
62 |
-
}
|
63 |
-
$default_from_email = 'wordpress@' . $sitename;
|
64 |
-
|
65 |
-
require_once(dirname(__FILE__) . "/admin_header.php");
|
66 |
-
?>
|
67 |
-
|
68 |
-
<form action="" method="post" enctype="multipart/form-data">
|
69 |
-
<h2><?php _e('Email Settings', 'pmpro');?></h2>
|
70 |
-
<p><?php _e('By default, system generated emails are sent from <em><strong>wordpress@yourdomain.com</strong></em>. You can update this from address using the fields below.', 'pmpro');?></p>
|
71 |
-
|
72 |
-
<p><?php _e('To modify the appearance of system generated emails, add the files <em>email_header.html</em> and <em>email_footer.html</em> to your theme\'s directory. This will modify both the WordPress default messages as well as messages generated by Paid Memberships Pro. <a title="Paid Memberships Pro - Member Communications" target="_blank" href="http://www.paidmembershipspro.com/documentation/member-communications/">Click here to learn more about Paid Memberships Pro emails</a>.', 'pmpro');?></p>
|
73 |
-
|
74 |
-
<table class="form-table">
|
75 |
-
<tbody>
|
76 |
-
<tr>
|
77 |
-
<th scope="row" valign="top">
|
78 |
-
<label for="from_email"><?php _e('From Email', 'pmpro');?>:</label>
|
79 |
-
</th>
|
80 |
-
<td>
|
81 |
-
<input type="text" name="from_email" size="60" value="<?php echo esc_attr($from_email);?>" />
|
82 |
-
</td>
|
83 |
-
</tr>
|
84 |
-
<tr>
|
85 |
-
<th scope="row" valign="top">
|
86 |
-
<label for="from_name"><?php _e('From Name', 'pmpro');?>:</label>
|
87 |
-
</th>
|
88 |
-
<td>
|
89 |
-
<input type="text" name="from_name" size="60" value="<?php echo esc_attr($from_name);?>" />
|
90 |
-
</td>
|
91 |
-
</tr>
|
92 |
-
<tr>
|
93 |
-
<th scope="row" valign="top">
|
94 |
-
<label for="only_filter_pmpro_emails"><?php _e('Only Filter PMPro Emails?', 'pmpro');?>:</label>
|
95 |
-
</th>
|
96 |
-
<td>
|
97 |
-
<input type="checkbox" id="only_filter_pmpro_emails" name="only_filter_pmpro_emails" value="1" <?php if(!empty($only_filter_pmpro_emails)) { ?>checked="checked"<?php } ?> />
|
98 |
-
<label for="only_filter_pmpro_emails"><?php _e('If unchecked, all emails from "WordPress <' . $default_from_email . '>" will be filtered to use the above settings.', 'pmpro');?></label>
|
99 |
-
</td>
|
100 |
-
</tr>
|
101 |
-
</tbody>
|
102 |
-
</table>
|
103 |
-
|
104 |
-
<?php /* going to put something like this here in next version
|
105 |
-
<h3><?php _e('Modify System-generated Email Templates', 'pmpro');?>:</h3>
|
106 |
-
<?php
|
107 |
-
if (function_exists('pmproet_scripts'))
|
108 |
-
{
|
109 |
-
_e('You have installed the PMPro Email Templates add on. <a href="' . admin_url('admin.php?page=pmpro-email-templates') . '">Click here to modify email templates</a>');
|
110 |
-
}
|
111 |
-
?>
|
112 |
-
<p><?php _e('To modify the subject line and body content of system generated emails, <a title="Paid Memberships Pro - Email Templates Plugin" target="_blank" href="' . wp_nonce_url(self_admin_url('update.php?action=install-plugin&plugin=pmpro-email-templates-addon'), 'install-plugin_pmpro-email-templates-addon') . '">Install and Activate the PMPro Email Templates add on</a>.', 'pmpro'); ?></p>
|
113 |
-
*/ ?>
|
114 |
-
|
115 |
-
<h3><?php _e('Send the site admin emails', 'pmpro');?>:</h3>
|
116 |
-
|
117 |
-
<table class="form-table">
|
118 |
-
<tbody>
|
119 |
-
<tr>
|
120 |
-
<th scope="row" valign="top">
|
121 |
-
<label for="email_admin_checkout"><?php _e('Checkout', 'pmpro');?>:</label>
|
122 |
-
</th>
|
123 |
-
<td>
|
124 |
-
<input type="checkbox" id="email_admin_checkout" name="email_admin_checkout" value="1" <?php if(!empty($email_admin_checkout)) { ?>checked="checked"<?php } ?> />
|
125 |
-
<label for="email_admin_checkout"><?php _e('when a member checks out.', 'pmpro');?></label>
|
126 |
-
</td>
|
127 |
-
</tr>
|
128 |
-
<tr>
|
129 |
-
<th scope="row" valign="top">
|
130 |
-
<label for="email_admin_changes"><?php _e('Admin Changes', 'pmpro');?>:</label>
|
131 |
-
</th>
|
132 |
-
<td>
|
133 |
-
<input type="checkbox" id="email_admin_changes" name="email_admin_changes" value="1" <?php if(!empty($email_admin_changes)) { ?>checked="checked"<?php } ?> />
|
134 |
-
<label for="email_admin_changes"><?php _e('when an admin changes a user\'s membership level through the dashboard.', 'pmpro');?></label>
|
135 |
-
</td>
|
136 |
-
</tr>
|
137 |
-
<tr>
|
138 |
-
<th scope="row" valign="top">
|
139 |
-
<label for="email_admin_cancels"><?php _e('Cancellation', 'pmpro');?>:</label>
|
140 |
-
</th>
|
141 |
-
<td>
|
142 |
-
<input type="checkbox" id="email_admin_cancels" name="email_admin_cancels" value="1" <?php if(!empty($email_admin_cancels)) { ?>checked="checked"<?php } ?> />
|
143 |
-
<label for="email_admin_cancels"><?php _e('when a user cancels his or her account.', 'pmpro');?></label>
|
144 |
-
</td>
|
145 |
-
</tr>
|
146 |
-
<tr>
|
147 |
-
<th scope="row" valign="top">
|
148 |
-
<label for="email_admin_billing"><?php _e('Bill Updates', 'pmpro');?>:</label>
|
149 |
-
</th>
|
150 |
-
<td>
|
151 |
-
<input type="checkbox" id="email_admin_billing" name="email_admin_billing" value="1" <?php if(!empty($email_admin_billing)) { ?>checked="checked"<?php } ?> />
|
152 |
-
<label for="email_admin_billing"><?php _e('when a user updates his or her billing information.', 'pmpro');?></label>
|
153 |
-
</td>
|
154 |
-
</tr>
|
155 |
-
</tbody>
|
156 |
-
</table>
|
157 |
-
|
158 |
-
<h3><?php _e('Send members emails', 'pmpro');?>:</h3>
|
159 |
-
|
160 |
-
<table class="form-table">
|
161 |
-
<tbody>
|
162 |
-
<tr>
|
163 |
-
<th scope="row" valign="top">
|
164 |
-
<label for="email_member_notification"><?php _e('New Users', 'pmpro');?>:</label>
|
165 |
-
</th>
|
166 |
-
<td>
|
167 |
-
<input type="checkbox" id="email_member_notification" name="email_member_notification" value="1" <?php if(!empty($email_member_notification)) { ?>checked="checked"<?php } ?> />
|
168 |
-
<label for="email_member_notification"><?php _e('Default WP notification email. (Recommended: Leave unchecked. Members will still get an email confirmation from PMPro after checkout.)', 'pmpro');?></label>
|
169 |
-
</td>
|
170 |
-
</tr>
|
171 |
-
</tbody>
|
172 |
-
</table>
|
173 |
-
|
174 |
-
<p class="submit">
|
175 |
-
<input name="savesettings" type="submit" class="button-primary" value="Save Settings" />
|
176 |
-
</p>
|
177 |
-
</form>
|
178 |
-
|
179 |
-
<?php
|
180 |
-
require_once(dirname(__FILE__) . "/admin_footer.php");
|
181 |
-
?>
|
1 |
+
<?php
|
2 |
+
//only admins can get this
|
3 |
+
if(!function_exists("current_user_can") || (!current_user_can("manage_options") && !current_user_can("pmpro_emailsettings")))
|
4 |
+
{
|
5 |
+
die(__("You do not have permissions to perform this action.", "pmpro"));
|
6 |
+
}
|
7 |
+
|
8 |
+
global $wpdb, $msg, $msgt;
|
9 |
+
|
10 |
+
//get/set settings
|
11 |
+
global $pmpro_pages;
|
12 |
+
if(!empty($_REQUEST['savesettings']))
|
13 |
+
{
|
14 |
+
//email options
|
15 |
+
pmpro_setOption("from_email");
|
16 |
+
pmpro_setOption("from_name");
|
17 |
+
pmpro_setOption("only_filter_pmpro_emails");
|
18 |
+
|
19 |
+
pmpro_setOption("email_admin_checkout");
|
20 |
+
pmpro_setOption("email_admin_changes");
|
21 |
+
pmpro_setOption("email_admin_cancels");
|
22 |
+
pmpro_setOption("email_admin_billing");
|
23 |
+
|
24 |
+
pmpro_setOption("email_member_notification");
|
25 |
+
|
26 |
+
//assume success
|
27 |
+
$msg = true;
|
28 |
+
$msgt = "Your email settings have been updated.";
|
29 |
+
}
|
30 |
+
|
31 |
+
$from_email = pmpro_getOption("from_email");
|
32 |
+
$from_name = pmpro_getOption("from_name");
|
33 |
+
$only_filter_pmpro_emails = pmpro_getOption("only_filter_pmpro_emails");
|
34 |
+
|
35 |
+
$email_admin_checkout = pmpro_getOption("email_admin_checkout");
|
36 |
+
$email_admin_changes = pmpro_getOption("email_admin_changes");
|
37 |
+
$email_admin_cancels = pmpro_getOption("email_admin_cancels");
|
38 |
+
$email_admin_billing = pmpro_getOption("email_admin_billing");
|
39 |
+
|
40 |
+
$email_member_notification = pmpro_getOption("email_member_notification");
|
41 |
+
|
42 |
+
if(empty($from_email))
|
43 |
+
{
|
44 |
+
$parsed = parse_url(home_url());
|
45 |
+
$hostname = $parsed[host];
|
46 |
+
$hostparts = split("\.", $hostname);
|
47 |
+
$email_domain = $hostparts[count($hostparts) - 2] . "." . $hostparts[count($hostparts) - 1];
|
48 |
+
$from_email = "wordpress@" . $email_domain;
|
49 |
+
pmpro_setOption("from_email", $from_email);
|
50 |
+
}
|
51 |
+
|
52 |
+
if(empty($from_name))
|
53 |
+
{
|
54 |
+
$from_name = "WordPress";
|
55 |
+
pmpro_setOption("from_name", $from_name);
|
56 |
+
}
|
57 |
+
|
58 |
+
// default from email wordpress@sitename
|
59 |
+
$sitename = strtolower( $_SERVER['SERVER_NAME'] );
|
60 |
+
if ( substr( $sitename, 0, 4 ) == 'www.' ) {
|
61 |
+
$sitename = substr( $sitename, 4 );
|
62 |
+
}
|
63 |
+
$default_from_email = 'wordpress@' . $sitename;
|
64 |
+
|
65 |
+
require_once(dirname(__FILE__) . "/admin_header.php");
|
66 |
+
?>
|
67 |
+
|
68 |
+
<form action="" method="post" enctype="multipart/form-data">
|
69 |
+
<h2><?php _e('Email Settings', 'pmpro');?></h2>
|
70 |
+
<p><?php _e('By default, system generated emails are sent from <em><strong>wordpress@yourdomain.com</strong></em>. You can update this from address using the fields below.', 'pmpro');?></p>
|
71 |
+
|
72 |
+
<p><?php _e('To modify the appearance of system generated emails, add the files <em>email_header.html</em> and <em>email_footer.html</em> to your theme\'s directory. This will modify both the WordPress default messages as well as messages generated by Paid Memberships Pro. <a title="Paid Memberships Pro - Member Communications" target="_blank" href="http://www.paidmembershipspro.com/documentation/member-communications/">Click here to learn more about Paid Memberships Pro emails</a>.', 'pmpro');?></p>
|
73 |
+
|
74 |
+
<table class="form-table">
|
75 |
+
<tbody>
|
76 |
+
<tr>
|
77 |
+
<th scope="row" valign="top">
|
78 |
+
<label for="from_email"><?php _e('From Email', 'pmpro');?>:</label>
|
79 |
+
</th>
|
80 |
+
<td>
|
81 |
+
<input type="text" name="from_email" size="60" value="<?php echo esc_attr($from_email);?>" />
|
82 |
+
</td>
|
83 |
+
</tr>
|
84 |
+
<tr>
|
85 |
+
<th scope="row" valign="top">
|
86 |
+
<label for="from_name"><?php _e('From Name', 'pmpro');?>:</label>
|
87 |
+
</th>
|
88 |
+
<td>
|
89 |
+
<input type="text" name="from_name" size="60" value="<?php echo esc_attr($from_name);?>" />
|
90 |
+
</td>
|
91 |
+
</tr>
|
92 |
+
<tr>
|
93 |
+
<th scope="row" valign="top">
|
94 |
+
<label for="only_filter_pmpro_emails"><?php _e('Only Filter PMPro Emails?', 'pmpro');?>:</label>
|
95 |
+
</th>
|
96 |
+
<td>
|
97 |
+
<input type="checkbox" id="only_filter_pmpro_emails" name="only_filter_pmpro_emails" value="1" <?php if(!empty($only_filter_pmpro_emails)) { ?>checked="checked"<?php } ?> />
|
98 |
+
<label for="only_filter_pmpro_emails"><?php _e('If unchecked, all emails from "WordPress <' . $default_from_email . '>" will be filtered to use the above settings.', 'pmpro');?></label>
|
99 |
+
</td>
|
100 |
+
</tr>
|
101 |
+
</tbody>
|
102 |
+
</table>
|
103 |
+
|
104 |
+
<?php /* going to put something like this here in next version
|
105 |
+
<h3><?php _e('Modify System-generated Email Templates', 'pmpro');?>:</h3>
|
106 |
+
<?php
|
107 |
+
if (function_exists('pmproet_scripts'))
|
108 |
+
{
|
109 |
+
_e('You have installed the PMPro Email Templates add on. <a href="' . admin_url('admin.php?page=pmpro-email-templates') . '">Click here to modify email templates</a>');
|
110 |
+
}
|
111 |
+
?>
|
112 |
+
<p><?php _e('To modify the subject line and body content of system generated emails, <a title="Paid Memberships Pro - Email Templates Plugin" target="_blank" href="' . wp_nonce_url(self_admin_url('update.php?action=install-plugin&plugin=pmpro-email-templates-addon'), 'install-plugin_pmpro-email-templates-addon') . '">Install and Activate the PMPro Email Templates add on</a>.', 'pmpro'); ?></p>
|
113 |
+
*/ ?>
|
114 |
+
|
115 |
+
<h3><?php _e('Send the site admin emails', 'pmpro');?>:</h3>
|
116 |
+
|
117 |
+
<table class="form-table">
|
118 |
+
<tbody>
|
119 |
+
<tr>
|
120 |
+
<th scope="row" valign="top">
|
121 |
+
<label for="email_admin_checkout"><?php _e('Checkout', 'pmpro');?>:</label>
|
122 |
+
</th>
|
123 |
+
<td>
|
124 |
+
<input type="checkbox" id="email_admin_checkout" name="email_admin_checkout" value="1" <?php if(!empty($email_admin_checkout)) { ?>checked="checked"<?php } ?> />
|
125 |
+
<label for="email_admin_checkout"><?php _e('when a member checks out.', 'pmpro');?></label>
|
126 |
+
</td>
|
127 |
+
</tr>
|
128 |
+
<tr>
|
129 |
+
<th scope="row" valign="top">
|
130 |
+
<label for="email_admin_changes"><?php _e('Admin Changes', 'pmpro');?>:</label>
|
131 |
+
</th>
|
132 |
+
<td>
|
133 |
+
<input type="checkbox" id="email_admin_changes" name="email_admin_changes" value="1" <?php if(!empty($email_admin_changes)) { ?>checked="checked"<?php } ?> />
|
134 |
+
<label for="email_admin_changes"><?php _e('when an admin changes a user\'s membership level through the dashboard.', 'pmpro');?></label>
|
135 |
+
</td>
|
136 |
+
</tr>
|
137 |
+
<tr>
|
138 |
+
<th scope="row" valign="top">
|
139 |
+
<label for="email_admin_cancels"><?php _e('Cancellation', 'pmpro');?>:</label>
|
140 |
+
</th>
|
141 |
+
<td>
|
142 |
+
<input type="checkbox" id="email_admin_cancels" name="email_admin_cancels" value="1" <?php if(!empty($email_admin_cancels)) { ?>checked="checked"<?php } ?> />
|
143 |
+
<label for="email_admin_cancels"><?php _e('when a user cancels his or her account.', 'pmpro');?></label>
|
144 |
+
</td>
|
145 |
+
</tr>
|
146 |
+
<tr>
|
147 |
+
<th scope="row" valign="top">
|
148 |
+
<label for="email_admin_billing"><?php _e('Bill Updates', 'pmpro');?>:</label>
|
149 |
+
</th>
|
150 |
+
<td>
|
151 |
+
<input type="checkbox" id="email_admin_billing" name="email_admin_billing" value="1" <?php if(!empty($email_admin_billing)) { ?>checked="checked"<?php } ?> />
|
152 |
+
<label for="email_admin_billing"><?php _e('when a user updates his or her billing information.', 'pmpro');?></label>
|
153 |
+
</td>
|
154 |
+
</tr>
|
155 |
+
</tbody>
|
156 |
+
</table>
|
157 |
+
|
158 |
+
<h3><?php _e('Send members emails', 'pmpro');?>:</h3>
|
159 |
+
|
160 |
+
<table class="form-table">
|
161 |
+
<tbody>
|
162 |
+
<tr>
|
163 |
+
<th scope="row" valign="top">
|
164 |
+
<label for="email_member_notification"><?php _e('New Users', 'pmpro');?>:</label>
|
165 |
+
</th>
|
166 |
+
<td>
|
167 |
+
<input type="checkbox" id="email_member_notification" name="email_member_notification" value="1" <?php if(!empty($email_member_notification)) { ?>checked="checked"<?php } ?> />
|
168 |
+
<label for="email_member_notification"><?php _e('Default WP notification email. (Recommended: Leave unchecked. Members will still get an email confirmation from PMPro after checkout.)', 'pmpro');?></label>
|
169 |
+
</td>
|
170 |
+
</tr>
|
171 |
+
</tbody>
|
172 |
+
</table>
|
173 |
+
|
174 |
+
<p class="submit">
|
175 |
+
<input name="savesettings" type="submit" class="button-primary" value="Save Settings" />
|
176 |
+
</p>
|
177 |
+
</form>
|
178 |
+
|
179 |
+
<?php
|
180 |
+
require_once(dirname(__FILE__) . "/admin_footer.php");
|
181 |
+
?>
|
adminpages/functions.php
CHANGED
@@ -1,256 +1,256 @@
|
|
1 |
-
<?php
|
2 |
-
/****************************************************************
|
3 |
-
|
4 |
-
IMPORTANT. PLEASE READ.
|
5 |
-
|
6 |
-
DO NOT EDIT THIS FILE or any other file in the /wp-content/plugins/paid-memberships-pro/ directory.
|
7 |
-
Doing so could break the PMPro plugin and/or keep you from upgrading this plugin in the future.
|
8 |
-
We regularly release updates to the plugin, including important security fixes and new features.
|
9 |
-
You want to be able to upgrade.
|
10 |
-
|
11 |
-
If you were asked to insert code into "your functions.php file", it was meant that you edit the functions.php
|
12 |
-
in the root folder of your active theme. e.g. /wp-content/themes/twentytwelve/functions.php
|
13 |
-
You can also create a custom plugin to place customization code into. Instructions are here:
|
14 |
-
http://www.paidmembershipspro.com/2012/08/create-a-plugin-for-pmpro-customizations/
|
15 |
-
|
16 |
-
Further documentation for customizing Paid Memberships Pro can be found here:
|
17 |
-
http://www.paidmembershipspro.com/documentation/
|
18 |
-
|
19 |
-
****************************************************************/
|
20 |
-
|
21 |
-
/*
|
22 |
-
Checks if PMPro settings are complete or if there are any errors.
|
23 |
-
*/
|
24 |
-
function pmpro_checkLevelForStripeCompatibility($level = NULL)
|
25 |
-
{
|
26 |
-
$gateway = pmpro_getOption("gateway");
|
27 |
-
if($gateway == "stripe")
|
28 |
-
{
|
29 |
-
global $wpdb;
|
30 |
-
|
31 |
-
//check ALL the levels
|
32 |
-
if(empty($level))
|
33 |
-
{
|
34 |
-
$sqlQuery = "SELECT * FROM $wpdb->pmpro_membership_levels ORDER BY id ASC";
|
35 |
-
$levels = $wpdb->get_results($sqlQuery, OBJECT);
|
36 |
-
if(!empty($levels))
|
37 |
-
{
|
38 |
-
foreach($levels as $level)
|
39 |
-
{
|
40 |
-
/*
|
41 |
-
Stripe currently does not support:
|
42 |
-
* Billing Limits.
|
43 |
-
*/
|
44 |
-
if($level->billing_limit > 0)
|
45 |
-
{
|
46 |
-
return false;
|
47 |
-
}
|
48 |
-
}
|
49 |
-
}
|
50 |
-
}
|
51 |
-
else
|
52 |
-
{
|
53 |
-
//need to look it up?
|
54 |
-
if(is_numeric($level))
|
55 |
-
$level = $wpdb->get_row("SELECT * FROM $wpdb->pmpro_membership_levels WHERE id = '" . esc_sql($level) . "' LIMIT 1");
|
56 |
-
|
57 |
-
//check this level
|
58 |
-
if(($level->cycle_number > 0 && $level->cycle_period == "Day") ||
|
59 |
-
$level->billing_limit > 0)
|
60 |
-
{
|
61 |
-
return false;
|
62 |
-
}
|
63 |
-
}
|
64 |
-
}
|
65 |
-
|
66 |
-
return true;
|
67 |
-
}
|
68 |
-
|
69 |
-
/*
|
70 |
-
Checks if PMPro settings are complete or if there are any errors.
|
71 |
-
*/
|
72 |
-
function pmpro_checkLevelForPayflowCompatibility($level = NULL)
|
73 |
-
{
|
74 |
-
$gateway = pmpro_getOption("gateway");
|
75 |
-
if($gateway == "payflowpro")
|
76 |
-
{
|
77 |
-
global $wpdb;
|
78 |
-
|
79 |
-
//check ALL the levels
|
80 |
-
if(empty($level))
|
81 |
-
{
|
82 |
-
$sqlQuery = "SELECT * FROM $wpdb->pmpro_membership_levels ORDER BY id ASC";
|
83 |
-
$levels = $wpdb->get_results($sqlQuery, OBJECT);
|
84 |
-
if(!empty($levels))
|
85 |
-
{
|
86 |
-
foreach($levels as $level)
|
87 |
-
{
|
88 |
-
/*
|
89 |
-
Payflow currently does not support:
|
90 |
-
* Trial Amounts > 0.
|
91 |
-
* Daily billing periods.
|
92 |
-
*/
|
93 |
-
|
94 |
-
if($level->trial_amount > 0 ||
|
95 |
-
$level->cycle_number > 1)
|
96 |
-
{
|
97 |
-
return false;
|
98 |
-
}
|
99 |
-
}
|
100 |
-
}
|
101 |
-
}
|
102 |
-
else
|
103 |
-
{
|
104 |
-
//need to look it up?
|
105 |
-
if(is_numeric($level))
|
106 |
-
$level = $wpdb->get_row("SELECT * FROM $wpdb->pmpro_membership_levels WHERE id = '" . esc_sql($level) . "' LIMIT 1");
|
107 |
-
|
108 |
-
//check this level
|
109 |
-
if($level->trial_amount > 0 ||
|
110 |
-
$level->cycle_number > 1 ||
|
111 |
-
($level->cycle_number == 1 && $level->cycle_period == "Day"))
|
112 |
-
{
|
113 |
-
return false;
|
114 |
-
}
|
115 |
-
}
|
116 |
-
}
|
117 |
-
|
118 |
-
return true;
|
119 |
-
}
|
120 |
-
|
121 |
-
/*
|
122 |
-
Checks if PMPro settings are complete or if there are any errors.
|
123 |
-
*/
|
124 |
-
function pmpro_checkLevelForBraintreeCompatibility($level = NULL)
|
125 |
-
{
|
126 |
-
$gateway = pmpro_getOption("gateway");
|
127 |
-
if($gateway == "braintree")
|
128 |
-
{
|
129 |
-
global $wpdb;
|
130 |
-
|
131 |
-
//check ALL the levels
|
132 |
-
if(empty($level))
|
133 |
-
{
|
134 |
-
$sqlQuery = "SELECT * FROM $wpdb->pmpro_membership_levels ORDER BY id ASC";
|
135 |
-
$levels = $wpdb->get_results($sqlQuery, OBJECT);
|
136 |
-
if(!empty($levels))
|
137 |
-
{
|
138 |
-
foreach($levels as $level)
|
139 |
-
{
|
140 |
-
/*
|
141 |
-
Braintree currently does not support:
|
142 |
-
* Trial Amounts > 0.
|
143 |
-
* Daily or Weekly billing periods.
|
144 |
-
*/
|
145 |
-
if($level->trial_amount > 0 ||
|
146 |
-
($level->cycle_number > 0 && ($level->cycle_period == "Day" || $level->cycle_period == "Week")))
|
147 |
-
{
|
148 |
-
return false;
|
149 |
-
}
|
150 |
-
}
|
151 |
-
}
|
152 |
-
}
|
153 |
-
else
|
154 |
-
{
|
155 |
-
//need to look it up?
|
156 |
-
if(is_numeric($level))
|
157 |
-
$level = $wpdb->get_row("SELECT * FROM $wpdb->pmpro_membership_levels WHERE id = '" . esc_sql($level) . "' LIMIT 1");
|
158 |
-
|
159 |
-
//check this level
|
160 |
-
if($level->trial_amount > 0 ||
|
161 |
-
($level->cycle_number > 0 && ($level->cycle_period == "Day" || $level->cycle_period == "Week")))
|
162 |
-
{
|
163 |
-
return false;
|
164 |
-
}
|
165 |
-
}
|
166 |
-
}
|
167 |
-
|
168 |
-
return true;
|
169 |
-
}
|
170 |
-
|
171 |
-
/*
|
172 |
-
Checks if PMPro settings are complete or if there are any errors.
|
173 |
-
*/
|
174 |
-
function pmpro_checkLevelForTwoCheckoutCompatibility($level = NULL)
|
175 |
-
{
|
176 |
-
$gateway = pmpro_getOption("gateway");
|
177 |
-
if($gateway == "twocheckout")
|
178 |
-
{
|
179 |
-
global $wpdb;
|
180 |
-
|
181 |
-
//check ALL the levels
|
182 |
-
if(empty($level))
|
183 |
-
{
|
184 |
-
$sqlQuery = "SELECT * FROM $wpdb->pmpro_membership_levels ORDER BY id ASC";
|
185 |
-
$levels = $wpdb->get_results($sqlQuery, OBJECT);
|
186 |
-
if(!empty($levels))
|
187 |
-
{
|
188 |
-
foreach($levels as $level)
|
189 |
-
{
|
190 |
-
/*
|
191 |
-
2Checkout currently does not support:
|
192 |
-
* Trial amounts less than or greater than the absolute value of amonthly recurring amount.
|
193 |
-
*/
|
194 |
-
if(pmpro_isLevelTrial($level))
|
195 |
-
{
|
196 |
-
return false;
|
197 |
-
}
|
198 |
-
}
|
199 |
-
}
|
200 |
-
}
|
201 |
-
else
|
202 |
-
{
|
203 |
-
//need to look it up?
|
204 |
-
if(is_numeric($level))
|
205 |
-
$level = $wpdb->get_row("SELECT * FROM $wpdb->pmpro_membership_levels WHERE id = '" . esc_sql($level) . "' LIMIT 1");
|
206 |
-
|
207 |
-
//check this level
|
208 |
-
if(pmpro_isLevelTrial($level))
|
209 |
-
{
|
210 |
-
return false;
|
211 |
-
}
|
212 |
-
}
|
213 |
-
}
|
214 |
-
|
215 |
-
return true;
|
216 |
-
}
|
217 |
-
|
218 |
-
/**
|
219 |
-
* Get the gateway-related classes for fields on the payment settings page.
|
220 |
-
*
|
221 |
-
* @param string $field The name of the field to check.
|
222 |
-
* @param bool $force If true, it will rebuild the cached results.
|
223 |
-
*
|
224 |
-
* @since 2.0
|
225 |
-
*/
|
226 |
-
function pmpro_getClassesForPaymentSettingsField($field, $force = false)
|
227 |
-
{
|
228 |
-
global $pmpro_gateway_options;
|
229 |
-
$pmpro_gateways = pmpro_gateways();
|
230 |
-
|
231 |
-
//build array of gateways and options
|
232 |
-
if(!isset($pmpro_gateway_options) || $force)
|
233 |
-
{
|
234 |
-
$pmpro_gateway_options = array();
|
235 |
-
|
236 |
-
foreach($pmpro_gateways as $gateway => $label)
|
237 |
-
{
|
238 |
-
//get options
|
239 |
-
if(class_exists('PMProGateway_' . $gateway) && method_exists('PMProGateway_' . $gateway, 'getGatewayOptions'))
|
240 |
-
{
|
241 |
-
$pmpro_gateway_options[$gateway] = call_user_func(array('PMProGateway_' . $gateway, 'getGatewayOptions'));
|
242 |
-
}
|
243 |
-
}
|
244 |
-
}
|
245 |
-
|
246 |
-
//now check where this field shows up
|
247 |
-
$rgateways = array();
|
248 |
-
foreach($pmpro_gateway_options as $gateway => $options)
|
249 |
-
{
|
250 |
-
if(in_array($field, $options))
|
251 |
-
$rgateways[] = "gateway_" . $gateway;
|
252 |
-
}
|
253 |
-
|
254 |
-
//return space separated string
|
255 |
-
return implode(" ", $rgateways);
|
256 |
}
|
1 |
+
<?php
|
2 |
+
/****************************************************************
|
3 |
+
|
4 |
+
IMPORTANT. PLEASE READ.
|
5 |
+
|
6 |
+
DO NOT EDIT THIS FILE or any other file in the /wp-content/plugins/paid-memberships-pro/ directory.
|
7 |
+
Doing so could break the PMPro plugin and/or keep you from upgrading this plugin in the future.
|
8 |
+
We regularly release updates to the plugin, including important security fixes and new features.
|
9 |
+
You want to be able to upgrade.
|
10 |
+
|
11 |
+
If you were asked to insert code into "your functions.php file", it was meant that you edit the functions.php
|
12 |
+
in the root folder of your active theme. e.g. /wp-content/themes/twentytwelve/functions.php
|
13 |
+
You can also create a custom plugin to place customization code into. Instructions are here:
|
14 |
+
http://www.paidmembershipspro.com/2012/08/create-a-plugin-for-pmpro-customizations/
|
15 |
+
|
16 |
+
Further documentation for customizing Paid Memberships Pro can be found here:
|
17 |
+
http://www.paidmembershipspro.com/documentation/
|
18 |
+
|
19 |
+
****************************************************************/
|
20 |
+
|
21 |
+
/*
|
22 |
+
Checks if PMPro settings are complete or if there are any errors.
|
23 |
+
*/
|
24 |
+
function pmpro_checkLevelForStripeCompatibility($level = NULL)
|
25 |
+
{
|
26 |
+
$gateway = pmpro_getOption("gateway");
|
27 |
+
if($gateway == "stripe")
|
28 |
+
{
|
29 |
+
global $wpdb;
|
30 |
+
|
31 |
+
//check ALL the levels
|
32 |
+
if(empty($level))
|
33 |
+
{
|
34 |
+
$sqlQuery = "SELECT * FROM $wpdb->pmpro_membership_levels ORDER BY id ASC";
|
35 |
+
$levels = $wpdb->get_results($sqlQuery, OBJECT);
|
36 |
+
if(!empty($levels))
|
37 |
+
{
|
38 |
+
foreach($levels as $level)
|
39 |
+
{
|
40 |
+
/*
|
41 |
+
Stripe currently does not support:
|
42 |
+
* Billing Limits.
|
43 |
+
*/
|
44 |
+
if($level->billing_limit > 0)
|
45 |
+
{
|
46 |
+
return false;
|
47 |
+
}
|
48 |
+
}
|
49 |
+
}
|
50 |
+
}
|
51 |
+
else
|
52 |
+
{
|
53 |
+
//need to look it up?
|
54 |
+
if(is_numeric($level))
|
55 |
+
$level = $wpdb->get_row("SELECT * FROM $wpdb->pmpro_membership_levels WHERE id = '" . esc_sql($level) . "' LIMIT 1");
|
56 |
+
|
57 |
+
//check this level
|
58 |
+
if(($level->cycle_number > 0 && $level->cycle_period == "Day") ||
|
59 |
+
$level->billing_limit > 0)
|
60 |
+
{
|
61 |
+
return false;
|
62 |
+
}
|
63 |
+
}
|
64 |
+
}
|
65 |
+
|
66 |
+
return true;
|
67 |
+
}
|
68 |
+
|
69 |
+
/*
|
70 |
+
Checks if PMPro settings are complete or if there are any errors.
|
71 |
+
*/
|
72 |
+
function pmpro_checkLevelForPayflowCompatibility($level = NULL)
|
73 |
+
{
|
74 |
+
$gateway = pmpro_getOption("gateway");
|
75 |
+
if($gateway == "payflowpro")
|
76 |
+
{
|
77 |
+
global $wpdb;
|
78 |
+
|
79 |
+
//check ALL the levels
|
80 |
+
if(empty($level))
|
81 |
+
{
|
82 |
+
$sqlQuery = "SELECT * FROM $wpdb->pmpro_membership_levels ORDER BY id ASC";
|
83 |
+
$levels = $wpdb->get_results($sqlQuery, OBJECT);
|
84 |
+
if(!empty($levels))
|
85 |
+
{
|
86 |
+
foreach($levels as $level)
|
87 |
+
{
|
88 |
+
/*
|
89 |
+
Payflow currently does not support:
|
90 |
+
* Trial Amounts > 0.
|
91 |
+
* Daily billing periods.
|
92 |
+
*/
|
93 |
+
|
94 |
+
if($level->trial_amount > 0 ||
|
95 |
+
$level->cycle_number > 1)
|
96 |
+
{
|
97 |
+
return false;
|
98 |
+
}
|
99 |
+
}
|
100 |
+
}
|
101 |
+
}
|
102 |
+
else
|
103 |
+
{
|
104 |
+
//need to look it up?
|
105 |
+
if(is_numeric($level))
|
106 |
+
$level = $wpdb->get_row("SELECT * FROM $wpdb->pmpro_membership_levels WHERE id = '" . esc_sql($level) . "' LIMIT 1");
|
107 |
+
|
108 |
+
//check this level
|
109 |
+
if($level->trial_amount > 0 ||
|
110 |
+
$level->cycle_number > 1 ||
|
111 |
+
($level->cycle_number == 1 && $level->cycle_period == "Day"))
|
112 |
+
{
|
113 |
+
return false;
|
114 |
+
}
|
115 |
+
}
|
116 |
+
}
|
117 |
+
|
118 |
+
return true;
|
119 |
+
}
|
120 |
+
|
121 |
+
/*
|
122 |
+
Checks if PMPro settings are complete or if there are any errors.
|
123 |
+
*/
|
124 |
+
function pmpro_checkLevelForBraintreeCompatibility($level = NULL)
|
125 |
+
{
|
126 |
+
$gateway = pmpro_getOption("gateway");
|
127 |
+
if($gateway == "braintree")
|
128 |
+
{
|
129 |
+
global $wpdb;
|
130 |
+
|
131 |
+
//check ALL the levels
|
132 |
+
if(empty($level))
|
133 |
+
{
|
134 |
+
$sqlQuery = "SELECT * FROM $wpdb->pmpro_membership_levels ORDER BY id ASC";
|
135 |
+
$levels = $wpdb->get_results($sqlQuery, OBJECT);
|
136 |
+
if(!empty($levels))
|
137 |
+
{
|
138 |
+
foreach($levels as $level)
|
139 |
+
{
|
140 |
+
/*
|
141 |
+
Braintree currently does not support:
|
142 |
+
* Trial Amounts > 0.
|
143 |
+
* Daily or Weekly billing periods.
|
144 |
+
*/
|
145 |
+
if($level->trial_amount > 0 ||
|
146 |
+
($level->cycle_number > 0 && ($level->cycle_period == "Day" || $level->cycle_period == "Week")))
|
147 |
+
{
|
148 |
+
return false;
|
149 |
+
}
|
150 |
+
}
|
151 |
+
}
|
152 |
+
}
|
153 |
+
else
|
154 |
+
{
|
155 |
+
//need to look it up?
|
156 |
+
if(is_numeric($level))
|
157 |
+
$level = $wpdb->get_row("SELECT * FROM $wpdb->pmpro_membership_levels WHERE id = '" . esc_sql($level) . "' LIMIT 1");
|
158 |
+
|
159 |
+
//check this level
|
160 |
+
if($level->trial_amount > 0 ||
|
161 |
+
($level->cycle_number > 0 && ($level->cycle_period == "Day" || $level->cycle_period == "Week")))
|
162 |
+
{
|
163 |
+
return false;
|
164 |
+
}
|
165 |
+
}
|
166 |
+
}
|
167 |
+
|
168 |
+
return true;
|
169 |
+
}
|
170 |
+
|
171 |
+
/*
|
172 |
+
Checks if PMPro settings are complete or if there are any errors.
|
173 |
+
*/
|
174 |
+
function pmpro_checkLevelForTwoCheckoutCompatibility($level = NULL)
|
175 |
+
{
|
176 |
+
$gateway = pmpro_getOption("gateway");
|
177 |
+
if($gateway == "twocheckout")
|
178 |
+
{
|
179 |
+
global $wpdb;
|
180 |
+
|
181 |
+
//check ALL the levels
|
182 |
+
if(empty($level))
|
183 |
+
{
|
184 |
+
$sqlQuery = "SELECT * FROM $wpdb->pmpro_membership_levels ORDER BY id ASC";
|
185 |
+
$levels = $wpdb->get_results($sqlQuery, OBJECT);
|
186 |
+
if(!empty($levels))
|
187 |
+
{
|
188 |
+
foreach($levels as $level)
|
189 |
+
{
|
190 |
+
/*
|
191 |
+
2Checkout currently does not support:
|
192 |
+
* Trial amounts less than or greater than the absolute value of amonthly recurring amount.
|
193 |
+
*/
|
194 |
+
if(pmpro_isLevelTrial($level))
|
195 |
+
{
|
196 |
+
return false;
|
197 |
+
}
|
198 |
+
}
|
199 |
+
}
|
200 |
+
}
|
201 |
+
else
|
202 |
+
{
|
203 |
+
//need to look it up?
|
204 |
+
if(is_numeric($level))
|
205 |
+
$level = $wpdb->get_row("SELECT * FROM $wpdb->pmpro_membership_levels WHERE id = '" . esc_sql($level) . "' LIMIT 1");
|
206 |
+
|
207 |
+
//check this level
|
208 |
+
if(pmpro_isLevelTrial($level))
|
209 |
+
{
|
210 |
+
return false;
|
211 |
+
}
|
212 |
+
}
|
213 |
+
}
|
214 |
+
|
215 |
+
return true;
|
216 |
+
}
|
217 |
+
|
218 |
+
/**
|
219 |
+
* Get the gateway-related classes for fields on the payment settings page.
|
220 |
+
*
|
221 |
+
* @param string $field The name of the field to check.
|
222 |
+
* @param bool $force If true, it will rebuild the cached results.
|
223 |
+
*
|
224 |
+
* @since 2.0
|
225 |
+
*/
|
226 |
+
function pmpro_getClassesForPaymentSettingsField($field, $force = false)
|
227 |
+
{
|
228 |
+
global $pmpro_gateway_options;
|
229 |
+
$pmpro_gateways = pmpro_gateways();
|
230 |
+
|
231 |
+
//build array of gateways and options
|
232 |
+
if(!isset($pmpro_gateway_options) || $force)
|
233 |
+
{
|
234 |
+
$pmpro_gateway_options = array();
|
235 |
+
|
236 |
+
foreach($pmpro_gateways as $gateway => $label)
|
237 |
+
{
|
238 |
+
//get options
|
239 |
+
if(class_exists('PMProGateway_' . $gateway) && method_exists('PMProGateway_' . $gateway, 'getGatewayOptions'))
|
240 |
+
{
|
241 |
+
$pmpro_gateway_options[$gateway] = call_user_func(array('PMProGateway_' . $gateway, 'getGatewayOptions'));
|
242 |
+
}
|
243 |
+
}
|
244 |
+
}
|
245 |
+
|
246 |
+
//now check where this field shows up
|
247 |
+
$rgateways = array();
|
248 |
+
foreach($pmpro_gateway_options as $gateway => $options)
|
249 |
+
{
|
250 |
+
if(in_array($field, $options))
|
251 |
+
$rgateways[] = "gateway_" . $gateway;
|
252 |
+
}
|
253 |
+
|
254 |
+
//return space separated string
|
255 |
+
return implode(" ", $rgateways);
|
256 |
}
|
adminpages/membershiplevels.php
CHANGED
@@ -1,594 +1,673 @@
|
|
1 |
-
<?php
|
2 |
-
//only admins can get this
|
3 |
-
if(!function_exists("current_user_can") || (!current_user_can("manage_options") && !current_user_can("pmpro_membershiplevels")))
|
4 |
-
{
|
5 |
-
die(__("You do not have permissions to perform this action.", "pmpro"));
|
6 |
-
}
|
7 |
-
|
8 |
-
global $wpdb, $msg, $msgt, $pmpro_currency_symbol;
|
9 |
-
|
10 |
-
//some vars
|
11 |
-
$gateway = pmpro_getOption("gateway");
|
12 |
-
|
13 |
-
|
14 |
-
|
15 |
-
|
16 |
-
|
17 |
-
$edit =
|
18 |
-
|
19 |
-
$
|
20 |
-
if(isset($_REQUEST['
|
21 |
-
$
|
22 |
-
|
23 |
-
$s =
|
24 |
-
|
25 |
-
|
26 |
-
|
27 |
-
|
28 |
-
$action =
|
29 |
-
|
30 |
-
|
31 |
-
|
32 |
-
|
33 |
-
|
34 |
-
|
35 |
-
if(isset($_REQUEST['
|
36 |
-
$
|
37 |
-
|
38 |
-
|
39 |
-
|
40 |
-
|
41 |
-
|
42 |
-
$
|
43 |
-
$
|
44 |
-
|
45 |
-
|
46 |
-
|
47 |
-
$ml_recurring =
|
48 |
-
|
49 |
-
|
50 |
-
$
|
51 |
-
$
|
52 |
-
|
53 |
-
|
54 |
-
|
55 |
-
$ml_custom_trial =
|
56 |
-
|
57 |
-
|
58 |
-
|
59 |
-
|
60 |
-
|
61 |
-
$ml_expiration =
|
62 |
-
|
63 |
-
|
64 |
-
$
|
65 |
-
|
66 |
-
|
67 |
-
|
68 |
-
|
69 |
-
|
70 |
-
$ml_allow_signups =
|
71 |
-
|
72 |
-
|
73 |
-
|
74 |
-
|
75 |
-
|
76 |
-
|
77 |
-
|
78 |
-
|
79 |
-
|
80 |
-
|
81 |
-
|
82 |
-
|
83 |
-
|
84 |
-
|
85 |
-
|
86 |
-
|
87 |
-
|
88 |
-
|
89 |
-
|
90 |
-
|
91 |
-
|
92 |
-
|
93 |
-
|
94 |
-
|
95 |
-
|
96 |
-
|
97 |
-
|
98 |
-
|
99 |
-
|
100 |
-
|
101 |
-
|
102 |
-
|
103 |
-
|
104 |
-
|
105 |
-
|
106 |
-
|
107 |
-
|
108 |
-
|
109 |
-
|
110 |
-
|
111 |
-
|
112 |
-
|
113 |
-
|
114 |
-
|
115 |
-
|
116 |
-
|
117 |
-
|
118 |
-
$
|
119 |
-
|
120 |
-
|
121 |
-
|
122 |
-
|
123 |
-
|
124 |
-
$
|
125 |
-
|
126 |
-
|
127 |
-
|
128 |
-
|
129 |
-
|
130 |
-
|
131 |
-
|
132 |
-
(
|
133 |
-
|
134 |
-
|
135 |
-
|
136 |
-
|
137 |
-
|
138 |
-
|
139 |
-
$
|
140 |
-
|
141 |
-
$
|
142 |
-
|
143 |
-
|
144 |
-
|
145 |
-
|
146 |
-
|
147 |
-
|
148 |
-
|
149 |
-
|
150 |
-
|
151 |
-
|
152 |
-
|
153 |
-
|
154 |
-
|
155 |
-
|
156 |
-
|
157 |
-
|
158 |
-
|
159 |
-
|
160 |
-
|
161 |
-
|
162 |
-
|
163 |
-
|
164 |
-
|
165 |
-
|
166 |
-
|
167 |
-
|
168 |
-
|
169 |
-
|
170 |
-
|
171 |
-
|
172 |
-
|
173 |
-
|
174 |
-
|
175 |
-
|
176 |
-
|
177 |
-
|
178 |
-
|
179 |
-
|
180 |
-
|
181 |
-
|
182 |
-
$
|
183 |
-
if
|
184 |
-
|
185 |
-
$
|
186 |
-
|
187 |
-
$
|
188 |
-
|
189 |
-
|
190 |
-
|
191 |
-
|
192 |
-
|
193 |
-
|
194 |
-
|
195 |
-
|
196 |
-
|
197 |
-
|
198 |
-
|
199 |
-
|
200 |
-
|
201 |
-
|
202 |
-
|
203 |
-
|
204 |
-
|
205 |
-
|
206 |
-
|
207 |
-
|
208 |
-
|
209 |
-
|
210 |
-
|
211 |
-
|
212 |
-
|
213 |
-
|
214 |
-
|
215 |
-
|
216 |
-
|
217 |
-
|
218 |
-
|
219 |
-
|
220 |
-
|
221 |
-
|
222 |
-
|
223 |
-
|
224 |
-
|
225 |
-
|
226 |
-
echo __("
|
227 |
-
|
228 |
-
|
229 |
-
|
230 |
-
|
231 |
-
|
232 |
-
|
233 |
-
|
234 |
-
|
235 |
-
|
236 |
-
|
237 |
-
|
238 |
-
|
239 |
-
|
240 |
-
|
241 |
-
|
242 |
-
$level->id =
|
243 |
-
|
244 |
-
|
245 |
-
|
246 |
-
|
247 |
-
|
248 |
-
|
249 |
-
|
250 |
-
|
251 |
-
$level
|
252 |
-
$level->
|
253 |
-
$level->
|
254 |
-
$level->
|
255 |
-
$level->
|
256 |
-
$level->
|
257 |
-
$level->
|
258 |
-
$level->
|
259 |
-
$level->
|
260 |
-
$level->
|
261 |
-
$
|
262 |
-
|
263 |
-
|
264 |
-
|
265 |
-
|
266 |
-
|
267 |
-
|
268 |
-
|
269 |
-
|
270 |
-
|
271 |
-
|
272 |
-
|
273 |
-
|
274 |
-
|
275 |
-
|
276 |
-
|
277 |
-
|
278 |
-
|
279 |
-
|
280 |
-
|
281 |
-
|
282 |
-
|
283 |
-
<
|
284 |
-
<
|
285 |
-
|
286 |
-
|
287 |
-
|
288 |
-
|
289 |
-
|
290 |
-
|
291 |
-
|
292 |
-
|
293 |
-
|
294 |
-
|
295 |
-
|
296 |
-
|
297 |
-
|
298 |
-
|
299 |
-
|
300 |
-
|
301 |
-
|
302 |
-
|
303 |
-
|
304 |
-
|
305 |
-
|
306 |
-
|
307 |
-
|
308 |
-
|
309 |
-
|
310 |
-
|
311 |
-
|
312 |
-
|
313 |
-
|
314 |
-
|
315 |
-
|
316 |
-
|
317 |
-
|
318 |
-
|
319 |
-
|
320 |
-
|
321 |
-
|
322 |
-
|
323 |
-
|
324 |
-
|
325 |
-
|
326 |
-
|
327 |
-
|
328 |
-
|
329 |
-
|
330 |
-
|
331 |
-
|
332 |
-
|
333 |
-
|
334 |
-
|
335 |
-
|
336 |
-
|
337 |
-
|
338 |
-
|
339 |
-
|
340 |
-
|
341 |
-
|
342 |
-
|
343 |
-
|
344 |
-
|
345 |
-
|
346 |
-
|
347 |
-
|
348 |
-
|
349 |
-
|
350 |
-
|
351 |
-
|
352 |
-
|
353 |
-
|
354 |
-
|
355 |
-
|
356 |
-
|
357 |
-
|
358 |
-
|
359 |
-
|
360 |
-
|
361 |
-
|
362 |
-
|
363 |
-
|
364 |
-
|
365 |
-
|
366 |
-
|
367 |
-
|
368 |
-
|
369 |
-
|
370 |
-
|
371 |
-
|
372 |
-
<
|
373 |
-
|
374 |
-
|
375 |
-
|
376 |
-
|
377 |
-
|
378 |
-
echo "
|
379 |
-
|
380 |
-
|
381 |
-
|
382 |
-
|
383 |
-
|
384 |
-
|
385 |
-
|
386 |
-
<?php
|
387 |
-
<br /><strong <?php if(!empty($
|
388 |
-
<?php } elseif($gateway == "
|
389 |
-
<br /><strong <?php if(!empty($
|
390 |
-
<?php } ?>
|
391 |
-
|
392 |
-
|
393 |
-
|
394 |
-
<?php
|
395 |
-
<p class="pmpro_message"><strong><?php _e('Note', 'pmpro');?>:</strong> <?php _e('
|
396 |
-
<?php } ?>
|
397 |
-
|
398 |
-
|
399 |
-
|
400 |
-
|
401 |
-
|
402 |
-
|
403 |
-
|
404 |
-
|
405 |
-
|
406 |
-
|
407 |
-
|
408 |
-
<?php
|
409 |
-
|
410 |
-
|
411 |
-
|
412 |
-
|
413 |
-
|
414 |
-
|
415 |
-
|
416 |
-
|
417 |
-
|
418 |
-
<?php if($
|
419 |
-
|
420 |
-
<?php
|
421 |
-
|
422 |
-
|
423 |
-
|
424 |
-
|
425 |
-
|
426 |
-
|
427 |
-
|
428 |
-
|
429 |
-
|
430 |
-
|
431 |
-
|
432 |
-
|
433 |
-
|
434 |
-
|
435 |
-
|
436 |
-
|
437 |
-
|
438 |
-
<small><?php _e('
|
439 |
-
<?php
|
440 |
-
|
441 |
-
|
442 |
-
|
443 |
-
|
444 |
-
|
445 |
-
|
446 |
-
|
447 |
-
|
448 |
-
|
449 |
-
|
450 |
-
|
451 |
-
|
452 |
-
|
453 |
-
|
454 |
-
|
455 |
-
|
456 |
-
|
457 |
-
|
458 |
-
|
459 |
-
|
460 |
-
|
461 |
-
|
462 |
-
|
463 |
-
|
464 |
-
|
465 |
-
|
466 |
-
|
467 |
-
|
468 |
-
|
469 |
-
|
470 |
-
|
471 |
-
|
472 |
-
|
473 |
-
|
474 |
-
|
475 |
-
|
476 |
-
|
477 |
-
|
478 |
-
|
479 |
-
|
480 |
-
|
481 |
-
echo "
|
482 |
-
|
483 |
-
|
484 |
-
|
485 |
-
|
486 |
-
|
487 |
-
|
488 |
-
|
489 |
-
|
490 |
-
|
491 |
-
|
492 |
-
|
493 |
-
|
494 |
-
|
495 |
-
|
496 |
-
|
497 |
-
|
498 |
-
|
499 |
-
|
500 |
-
|
501 |
-
|
502 |
-
|
503 |
-
|
504 |
-
|
505 |
-
|
506 |
-
|
507 |
-
|
508 |
-
|
509 |
-
|
510 |
-
|
511 |
-
|
512 |
-
|
513 |
-
|
514 |
-
|
515 |
-
|
516 |
-
|
517 |
-
|
518 |
-
|
519 |
-
|
520 |
-
|
521 |
-
|
522 |
-
|
523 |
-
|
524 |
-
|
525 |
-
|
526 |
-
|
527 |
-
|
528 |
-
|
529 |
-
|
530 |
-
|
531 |
-
|
532 |
-
|
533 |
-
|
534 |
-
|
535 |
-
|
536 |
-
|
537 |
-
|
538 |
-
|
539 |
-
|
540 |
-
|
541 |
-
|
542 |
-
|
543 |
-
|
544 |
-
|
545 |
-
|
546 |
-
|
547 |
-
|
548 |
-
|
549 |
-
|
550 |
-
|
551 |
-
|
552 |
-
|
553 |
-
|
554 |
-
|
555 |
-
|
556 |
-
|
557 |
-
|
558 |
-
|
559 |
-
|
560 |
-
|
561 |
-
|
562 |
-
|
563 |
-
|
564 |
-
|
565 |
-
|
566 |
-
|
567 |
-
|
568 |
-
|
569 |
-
|
570 |
-
|
571 |
-
|
572 |
-
|
573 |
-
|
574 |
-
|
575 |
-
|
576 |
-
|
577 |
-
|
578 |
-
|
579 |
-
|
580 |
-
|
581 |
-
|
582 |
-
|
583 |
-
|
584 |
-
|
585 |
-
|
586 |
-
|
587 |
-
|
588 |
-
|
589 |
-
|
590 |
-
|
591 |
-
|
592 |
-
|
593 |
-
|
594 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
//only admins can get this
|
3 |
+
if(!function_exists("current_user_can") || (!current_user_can("manage_options") && !current_user_can("pmpro_membershiplevels")))
|
4 |
+
{
|
5 |
+
die(__("You do not have permissions to perform this action.", "pmpro"));
|
6 |
+
}
|
7 |
+
|
8 |
+
global $wpdb, $msg, $msgt, $pmpro_currency_symbol;
|
9 |
+
|
10 |
+
//some vars
|
11 |
+
$gateway = pmpro_getOption("gateway");
|
12 |
+
$pmpro_level_order = pmpro_getOption('level_order');
|
13 |
+
|
14 |
+
global $pmpro_stripe_error, $pmpro_braintree_error, $pmpro_payflow_error, $pmpro_twocheckout_error, $wp_version;
|
15 |
+
|
16 |
+
if(isset($_REQUEST['edit']))
|
17 |
+
$edit = $_REQUEST['edit'];
|
18 |
+
else
|
19 |
+
$edit = false;
|
20 |
+
if(isset($_REQUEST['copy']))
|
21 |
+
$copy = $_REQUEST['copy'];
|
22 |
+
if(isset($_REQUEST['s']))
|
23 |
+
$s = $_REQUEST['s'];
|
24 |
+
else
|
25 |
+
$s = "";
|
26 |
+
|
27 |
+
if(isset($_REQUEST['action']))
|
28 |
+
$action = $_REQUEST['action'];
|
29 |
+
else
|
30 |
+
$action = false;
|
31 |
+
|
32 |
+
if(isset($_REQUEST['saveandnext']))
|
33 |
+
$saveandnext = $_REQUEST['saveandnext'];
|
34 |
+
|
35 |
+
if(isset($_REQUEST['saveid']))
|
36 |
+
$saveid = $_REQUEST['saveid'];
|
37 |
+
if(isset($_REQUEST['deleteid']))
|
38 |
+
$deleteid = $_REQUEST['deleteid'];
|
39 |
+
|
40 |
+
if($action == "save_membershiplevel")
|
41 |
+
{
|
42 |
+
$ml_name = stripslashes($_REQUEST['name']);
|
43 |
+
$ml_description = stripslashes($_REQUEST['description']);
|
44 |
+
$ml_confirmation = stripslashes($_REQUEST['confirmation']);
|
45 |
+
$ml_initial_payment = stripslashes($_REQUEST['initial_payment']);
|
46 |
+
if(!empty($_REQUEST['recurring']))
|
47 |
+
$ml_recurring = 1;
|
48 |
+
else
|
49 |
+
$ml_recurring = 0;
|
50 |
+
$ml_billing_amount = stripslashes($_REQUEST['billing_amount']);
|
51 |
+
$ml_cycle_number = stripslashes($_REQUEST['cycle_number']);
|
52 |
+
$ml_cycle_period = stripslashes($_REQUEST['cycle_period']);
|
53 |
+
$ml_billing_limit = stripslashes($_REQUEST['billing_limit']);
|
54 |
+
if(!empty($_REQUEST['custom_trial']))
|
55 |
+
$ml_custom_trial = 1;
|
56 |
+
else
|
57 |
+
$ml_custom_trial = 0;
|
58 |
+
$ml_trial_amount = stripslashes($_REQUEST['trial_amount']);
|
59 |
+
$ml_trial_limit = stripslashes($_REQUEST['trial_limit']);
|
60 |
+
if(!empty($_REQUEST['expiration']))
|
61 |
+
$ml_expiration = 1;
|
62 |
+
else
|
63 |
+
$ml_expiration = 0;
|
64 |
+
$ml_expiration_number = stripslashes($_REQUEST['expiration_number']);
|
65 |
+
$ml_expiration_period = stripslashes($_REQUEST['expiration_period']);
|
66 |
+
$ml_categories = array();
|
67 |
+
|
68 |
+
//reversing disable to allow here
|
69 |
+
if(empty($_REQUEST['disable_signups']))
|
70 |
+
$ml_allow_signups = 1;
|
71 |
+
else
|
72 |
+
$ml_allow_signups = 0;
|
73 |
+
|
74 |
+
foreach ( $_REQUEST as $key => $value )
|
75 |
+
{
|
76 |
+
if ( $value == 'yes' && preg_match( '/^membershipcategory_(\d+)$/i', $key, $matches ) )
|
77 |
+
{
|
78 |
+
$ml_categories[] = $matches[1];
|
79 |
+
}
|
80 |
+
}
|
81 |
+
|
82 |
+
//clearing out values if checkboxes aren't checked
|
83 |
+
if(empty($ml_recurring))
|
84 |
+
{
|
85 |
+
$ml_billing_amount = $ml_cycle_number = $ml_cycle_period = $ml_billing_limit = $ml_trial_amount = $ml_trial_limit = 0;
|
86 |
+
}
|
87 |
+
elseif(empty($ml_custom_trial))
|
88 |
+
{
|
89 |
+
$ml_trial_amount = $ml_trial_limit = 0;
|
90 |
+
}
|
91 |
+
if(empty($ml_expiration))
|
92 |
+
{
|
93 |
+
$ml_expiration_number = $ml_expiration_period = 0;
|
94 |
+
}
|
95 |
+
|
96 |
+
if($saveid > 0)
|
97 |
+
{
|
98 |
+
$sqlQuery = " UPDATE {$wpdb->pmpro_membership_levels}
|
99 |
+
SET name = '" . esc_sql($ml_name) . "',
|
100 |
+
description = '" . esc_sql($ml_description) . "',
|
101 |
+
confirmation = '" . esc_sql($ml_confirmation) . "',
|
102 |
+
initial_payment = '" . esc_sql($ml_initial_payment) . "',
|
103 |
+
billing_amount = '" . esc_sql($ml_billing_amount) . "',
|
104 |
+
cycle_number = '" . esc_sql($ml_cycle_number) . "',
|
105 |
+
cycle_period = '" . esc_sql($ml_cycle_period) . "',
|
106 |
+
billing_limit = '" . esc_sql($ml_billing_limit) . "',
|
107 |
+
trial_amount = '" . esc_sql($ml_trial_amount) . "',
|
108 |
+
trial_limit = '" . esc_sql($ml_trial_limit) . "',
|
109 |
+
expiration_number = '" . esc_sql($ml_expiration_number) . "',
|
110 |
+
expiration_period = '" . esc_sql($ml_expiration_period) . "',
|
111 |
+
allow_signups = '" . esc_sql($ml_allow_signups) . "'
|
112 |
+
WHERE id = '$saveid' LIMIT 1;";
|
113 |
+
$wpdb->query($sqlQuery);
|
114 |
+
|
115 |
+
pmpro_updateMembershipCategories( $saveid, $ml_categories );
|
116 |
+
if(!mysql_errno())
|
117 |
+
{
|
118 |
+
$edit = false;
|
119 |
+
$msg = 2;
|
120 |
+
$msgt = __("Membership level updated successfully.", "pmpro");
|
121 |
+
}
|
122 |
+
else
|
123 |
+
{
|
124 |
+
$msg = -2;
|
125 |
+
$msg = true;
|
126 |
+
$msgt = __("Error updating membership level.", "pmpro");
|
127 |
+
}
|
128 |
+
}
|
129 |
+
else
|
130 |
+
{
|
131 |
+
$sqlQuery = " INSERT INTO {$wpdb->pmpro_membership_levels}
|
132 |
+
( name, description, confirmation, initial_payment, billing_amount, cycle_number, cycle_period, billing_limit, trial_amount, trial_limit, expiration_number, expiration_period, allow_signups)
|
133 |
+
VALUES
|
134 |
+
( '" . esc_sql($ml_name) . "', '" . esc_sql($ml_description) . "', '" . esc_sql($ml_confirmation) . "', '" . esc_sql($ml_initial_payment) . "', '" . esc_sql($ml_billing_amount) . "', '" . esc_sql($ml_cycle_number) . "', '" . esc_sql($ml_cycle_period) . "', '" . esc_sql($ml_billing_limit) . "', '" . esc_sql($ml_trial_amount) . "', '" . esc_sql($ml_trial_limit) . "', '" . esc_sql($ml_expiration_number) . "', '" . esc_sql($ml_expiration_period) . "', '" . esc_sql($ml_allow_signups) . "' )";
|
135 |
+
$wpdb->query($sqlQuery);
|
136 |
+
if(!mysql_errno())
|
137 |
+
{
|
138 |
+
$saveid = $wpdb->insert_id;
|
139 |
+
pmpro_updateMembershipCategories( $saveid, $ml_categories );
|
140 |
+
|
141 |
+
$edit = false;
|
142 |
+
$msg = 1;
|
143 |
+
$msgt = __("Membership level added successfully.", "pmpro");
|
144 |
+
}
|
145 |
+
else
|
146 |
+
{
|
147 |
+
$msg = -1;
|
148 |
+
$msgt = __("Error adding membership level.", "pmpro");
|
149 |
+
}
|
150 |
+
}
|
151 |
+
|
152 |
+
do_action("pmpro_save_membership_level", $saveid);
|
153 |
+
}
|
154 |
+
elseif($action == "delete_membership_level")
|
155 |
+
{
|
156 |
+
global $wpdb;
|
157 |
+
|
158 |
+
$ml_id = $_REQUEST['deleteid'];
|
159 |
+
|
160 |
+
if($ml_id > 0)
|
161 |
+
{
|
162 |
+
do_action("pmpro_delete_membership_level", $ml_id);
|
163 |
+
|
164 |
+
//remove any categories from the ml
|
165 |
+
$sqlQuery = "DELETE FROM $wpdb->pmpro_memberships_categories WHERE membership_id = '$ml_id'";
|
166 |
+
$r1 = $wpdb->query($sqlQuery);
|
167 |
+
|
168 |
+
//cancel any subscriptions to the ml
|
169 |
+
$r2 = true;
|
170 |
+
$user_ids = $wpdb->get_col("SELECT user_id FROM $wpdb->pmpro_memberships_users WHERE membership_id = '$ml_id' AND status = 'active'");
|
171 |
+
foreach($user_ids as $user_id)
|
172 |
+
{
|
173 |
+
//change there membership level to none. that will handle the cancel
|
174 |
+
if(pmpro_changeMembershipLevel(0, $user_id))
|
175 |
+
{
|
176 |
+
//okay
|
177 |
+
}
|
178 |
+
else
|
179 |
+
{
|
180 |
+
//couldn't delete the subscription
|
181 |
+
//we should probably notify the admin
|
182 |
+
$pmproemail = new PMProEmail();
|
183 |
+
$pmproemail->data = array("body"=>"<p>" . sprintf(__("There was an error canceling the subscription for user with ID=%d. You will want to check your payment gateway to see if their subscription is still active.", "pmpro"), $user_id) . "</p>");
|
184 |
+
$last_order = $wpdb->get_row("SELECT * FROM $wpdb->pmpro_membership_orders WHERE user_id = '" . $user_id . "' ORDER BY timestamp DESC LIMIT 1");
|
185 |
+
if($last_order)
|
186 |
+
$pmproemail->data["body"] .= "<p>" . __("Last Invoice", "pmpro") . ":<br />" . nl2br(var_export($last_order, true)) . "</p>";
|
187 |
+
$pmproemail->sendEmail(get_bloginfo("admin_email"));
|
188 |
+
|
189 |
+
$r2 = false;
|
190 |
+
}
|
191 |
+
}
|
192 |
+
|
193 |
+
//delete the ml
|
194 |
+
$sqlQuery = "DELETE FROM $wpdb->pmpro_membership_levels WHERE id = '$ml_id' LIMIT 1";
|
195 |
+
$r3 = $wpdb->query($sqlQuery);
|
196 |
+
|
197 |
+
if($r1 !== FALSE && $r2 !== FALSE && $r3 !== FALSE)
|
198 |
+
{
|
199 |
+
$msg = 3;
|
200 |
+
$msgt = __("Membership level deleted successfully.", "pmpro");
|
201 |
+
}
|
202 |
+
else
|
203 |
+
{
|
204 |
+
$msg = -3;
|
205 |
+
$msgt = __("Error deleting membership level.", "pmpro");
|
206 |
+
}
|
207 |
+
}
|
208 |
+
else
|
209 |
+
{
|
210 |
+
$msg = -3;
|
211 |
+
$msgt = __("Error deleting membership level.", "pmpro");
|
212 |
+
}
|
213 |
+
}
|
214 |
+
|
215 |
+
require_once(dirname(__FILE__) . "/admin_header.php");
|
216 |
+
?>
|
217 |
+
|
218 |
+
<?php
|
219 |
+
if($edit)
|
220 |
+
{
|
221 |
+
?>
|
222 |
+
|
223 |
+
<h2>
|
224 |
+
<?php
|
225 |
+
if($edit > 0)
|
226 |
+
echo __("Edit Membership Level", "pmpro");
|
227 |
+
else
|
228 |
+
echo __("Add New Membership Level", "pmpro");
|
229 |
+
?>
|
230 |
+
</h2>
|
231 |
+
|
232 |
+
<div>
|
233 |
+
<?php
|
234 |
+
// get the level...
|
235 |
+
if(!empty($edit) && $edit > 0)
|
236 |
+
{
|
237 |
+
$level = $wpdb->get_row("SELECT * FROM $wpdb->pmpro_membership_levels WHERE id = '$edit' LIMIT 1", OBJECT);
|
238 |
+
$temp_id = $level->id;
|
239 |
+
}
|
240 |
+
elseif(!empty($copy) && $copy > 0)
|
241 |
+
{
|
242 |
+
$level = $wpdb->get_row("SELECT * FROM $wpdb->pmpro_membership_levels WHERE id = '$copy' LIMIT 1", OBJECT);
|
243 |
+
$temp_id = $level->id;
|
244 |
+
$level->id = NULL;
|
245 |
+
}
|
246 |
+
else
|
247 |
+
|
248 |
+
// didn't find a membership level, let's add a new one...
|
249 |
+
if(empty($level))
|
250 |
+
{
|
251 |
+
$level = new stdClass();
|
252 |
+
$level->id = NULL;
|
253 |
+
$level->name = NULL;
|
254 |
+
$level->description = NULL;
|
255 |
+
$level->confirmation = NULL;
|
256 |
+
$level->billing_amount = NULL;
|
257 |
+
$level->trial_amount = NULL;
|
258 |
+
$level->initial_payment = NULL;
|
259 |
+
$level->billing_limit = NULL;
|
260 |
+
$level->trial_limit = NULL;
|
261 |
+
$level->expiration_number = NULL;
|
262 |
+
$level->expiration_period = NULL;
|
263 |
+
$edit = -1;
|
264 |
+
}
|
265 |
+
|
266 |
+
//defaults for new levels
|
267 |
+
if(empty($copy) && $edit == -1)
|
268 |
+
{
|
269 |
+
$level->cycle_number = 1;
|
270 |
+
$level->cycle_period = "Month";
|
271 |
+
}
|
272 |
+
|
273 |
+
// grab the categories for the given level...
|
274 |
+
if(!empty($temp_id))
|
275 |
+
$level->categories = $wpdb->get_col("SELECT c.category_id
|
276 |
+
FROM $wpdb->pmpro_memberships_categories c
|
277 |
+
WHERE c.membership_id = '" . $temp_id . "'");
|
278 |
+
if(empty($level->categories))
|
279 |
+
$level->categories = array();
|
280 |
+
|
281 |
+
?>
|
282 |
+
<form action="" method="post" enctype="multipart/form-data">
|
283 |
+
<input name="saveid" type="hidden" value="<?php echo $edit?>" />
|
284 |
+
<input type="hidden" name="action" value="save_membershiplevel" />
|
285 |
+
<table class="form-table">
|
286 |
+
<tbody>
|
287 |
+
<tr>
|
288 |
+
<th scope="row" valign="top"><label><?php _e('ID', 'pmpro');?>:</label></th>
|
289 |
+
<td>
|
290 |
+
<?php echo $level->id?>
|
291 |
+
</td>
|
292 |
+
</tr>
|
293 |
+
|
294 |
+
<tr>
|
295 |
+
<th scope="row" valign="top"><label for="name"><?php _e('Name', 'pmpro');?>:</label></th>
|
296 |
+
<td><input name="name" type="text" size="50" value="<?php echo esc_attr($level->name);?>" /></td>
|
297 |
+
</tr>
|
298 |
+
|
299 |
+
<tr>
|
300 |
+
<th scope="row" valign="top"><label for="description"><?php _e('Description', 'pmpro');?>:</label></th>
|
301 |
+
<td>
|
302 |
+
<div id="poststuff" class="pmpro_description">
|
303 |
+
<?php
|
304 |
+
if(version_compare($wp_version, "3.3") >= 0)
|
305 |
+
wp_editor($level->description, "description", array("textarea_rows"=>5));
|
306 |
+
else
|
307 |
+
{
|
308 |
+
?>
|
309 |
+
<textarea rows="10" cols="80" name="description" id="description"><?php echo esc_textarea($level->description);?></textarea>
|
310 |
+
<?php
|
311 |
+
}
|
312 |
+
?>
|
313 |
+
</div>
|
314 |
+
</td>
|
315 |
+
</tr>
|
316 |
+
|
317 |
+
<tr>
|
318 |
+
<th scope="row" valign="top"><label for="confirmation"><?php _e('Confirmation Message', 'pmpro');?>:</label></th>
|
319 |
+
<td>
|
320 |
+
<div class="pmpro_confirmation">
|
321 |
+
<?php
|
322 |
+
if(version_compare($wp_version, "3.3") >= 0)
|
323 |
+
wp_editor($level->confirmation, "confirmation", array("textarea_rows"=>5));
|
324 |
+
else
|
325 |
+
{
|
326 |
+
?>
|
327 |
+
<textarea rows="10" cols="80" name="confirmation" id="confirmation"><?php echo esc_textarea($level->confirmation);?></textarea>
|
328 |
+
<?php
|
329 |
+
}
|
330 |
+
?>
|
331 |
+
</div>
|
332 |
+
</td>
|
333 |
+
</tr>
|
334 |
+
</tbody>
|
335 |
+
</table>
|
336 |
+
|
337 |
+
<h3 class="topborder"><?php _e('Billing Details', 'pmpro');?></h3>
|
338 |
+
<table class="form-table">
|
339 |
+
<tbody>
|
340 |
+
<tr>
|
341 |
+
<th scope="row" valign="top"><label for="initial_payment"><?php _e('Initial Payment', 'pmpro');?>:</label></th>
|
342 |
+
<td>
|
343 |
+
<?php
|
344 |
+
if(pmpro_getCurrencyPosition() == "left")
|
345 |
+
echo $pmpro_currency_symbol;
|
346 |
+
?>
|
347 |
+
<input name="initial_payment" type="text" size="20" value="<?php echo esc_attr($level->initial_payment);?>" />
|
348 |
+
<?php
|
349 |
+
if(pmpro_getCurrencyPosition() == "right")
|
350 |
+
echo $pmpro_currency_symbol;
|
351 |
+
?>
|
352 |
+
<small><?php _e('The initial amount collected at registration.', 'pmpro');?></small></td>
|
353 |
+
</tr>
|
354 |
+
|
355 |
+
<tr>
|
356 |
+
<th scope="row" valign="top"><label><?php _e('Recurring Subscription', 'pmpro');?>:</label></th>
|
357 |
+
<td><input id="recurring" name="recurring" type="checkbox" value="yes" <?php if(pmpro_isLevelRecurring($level)) { echo "checked='checked'"; } ?> onclick="if(jQuery('#recurring').is(':checked')) { jQuery('.recurring_info').show(); if(jQuery('#custom_trial').is(':checked')) {jQuery('.trial_info').show();} else {jQuery('.trial_info').hide();} } else { jQuery('.recurring_info').hide();}" /> <label for="recurring"><?php _e('Check if this level has a recurring subscription payment.', 'pmpro');?></label></td>
|
358 |
+
</tr>
|
359 |
+
|
360 |
+
<tr class="recurring_info" <?php if(!pmpro_isLevelRecurring($level)) {?>style="display: none;"<?php } ?>>
|
361 |
+
<th scope="row" valign="top"><label for="billing_amount"><?php _e('Billing Amount', 'pmpro');?>:</label></th>
|
362 |
+
<td>
|
363 |
+
<?php
|
364 |
+
if(pmpro_getCurrencyPosition() == "left")
|
365 |
+
echo $pmpro_currency_symbol;
|
366 |
+
?>
|
367 |
+
<input name="billing_amount" type="text" size="20" value="<?php echo esc_attr($level->billing_amount);?>" />
|
368 |
+
<?php
|
369 |
+
if(pmpro_getCurrencyPosition() == "right")
|
370 |
+
echo $pmpro_currency_symbol;
|
371 |
+
?>
|
372 |
+
<small><?php _e('per', 'pmpro');?></small>
|
373 |
+
<input id="cycle_number" name="cycle_number" type="text" size="10" value="<?php echo esc_attr($level->cycle_number);?>" />
|
374 |
+
<select id="cycle_period" name="cycle_period">
|
375 |
+
<?php
|
376 |
+
$cycles = array( __('Day(s)', 'pmpro') => 'Day', __('Week(s)', 'pmpro') => 'Week', __('Month(s)', 'pmpro') => 'Month', __('Year(s)', 'pmpro') => 'Year' );
|
377 |
+
foreach ( $cycles as $name => $value ) {
|
378 |
+
echo "<option value='$value'";
|
379 |
+
if ( $level->cycle_period == $value ) echo " selected='selected'";
|
380 |
+
echo ">$name</option>";
|
381 |
+
}
|
382 |
+
?>
|
383 |
+
</select>
|
384 |
+
<br /><small>
|
385 |
+
<?php _e('The amount to be billed one cycle after the initial payment.', 'pmpro');?>
|
386 |
+
<?php if($gateway == "stripe") { ?>
|
387 |
+
<br /><strong <?php if(!empty($pmpro_stripe_error)) { ?>class="pmpro_red"<?php } ?>><?php _e('Stripe integration currently only supports billing periods of "Week", "Month" or "Year".', 'pmpro');?>
|
388 |
+
<?php } elseif($gateway == "braintree") { ?>
|
389 |
+
<br /><strong <?php if(!empty($pmpro_braintree_error)) { ?>class="pmpro_red"<?php } ?>><?php _e('Braintree integration currently only supports billing periods of "Month" or "Year".', 'pmpro');?>
|
390 |
+
<?php } elseif($gateway == "payflowpro") { ?>
|
391 |
+
<br /><strong <?php if(!empty($pmpro_payflow_error)) { ?>class="pmpro_red"<?php } ?>><?php _e('Payflow integration currently only supports billing frequencies of 1 and billing periods of "Week", "Month" or "Year".', 'pmpro');?>
|
392 |
+
<?php } ?>
|
393 |
+
</small>
|
394 |
+
<?php if($gateway == "braintree" && $edit < 0) { ?>
|
395 |
+
<p class="pmpro_message"><strong><?php _e('Note', 'pmpro');?>:</strong> <?php _e('After saving this level, make note of the ID and create a "Plan" in your Braintree dashboard with the same settings and the "Plan ID" set to <em>pmpro_#</em>, where # is the level ID.', 'pmpro');?></p>
|
396 |
+
<?php } elseif($gateway == "braintree") { ?>
|
397 |
+
<p class="pmpro_message"><strong><?php _e('Note', 'pmpro');?>:</strong> <?php _e('You will need to create a "Plan" in your Braintree dashboard with the same settings and the "Plan ID" set to', 'pmpro');?> <em>pmpro_<?php echo $level->id;?></em>.</p>
|
398 |
+
<?php } ?>
|
399 |
+
</td>
|
400 |
+
</tr>
|
401 |
+
|
402 |
+
<tr class="recurring_info" <?php if(!pmpro_isLevelRecurring($level)) {?>style="display: none;"<?php } ?>>
|
403 |
+
<th scope="row" valign="top"><label for="billing_limit"><?php _e('Billing Cycle Limit', 'pmpro');?>:</label></th>
|
404 |
+
<td>
|
405 |
+
<input name="billing_limit" type="text" size="20" value="<?php echo $level->billing_limit?>" />
|
406 |
+
<br /><small>
|
407 |
+
<?php _e('The <strong>total</strong> number of recurring billing cycles for this level, including the trial period (if applicable) but not including the initial payment. Set to zero if membership is indefinite.', 'pmpro');?>
|
408 |
+
<?php if($gateway == "stripe") { ?>
|
409 |
+
<br /><strong <?php if(!empty($pmpro_stripe_error)) { ?>class="pmpro_red"<?php } ?>><?php _e('Stripe integration currently does not support billing limits. You can still set an expiration date below.', 'pmpro');?></strong>
|
410 |
+
<?php } ?>
|
411 |
+
</small>
|
412 |
+
</td>
|
413 |
+
</tr>
|
414 |
+
|
415 |
+
<tr class="recurring_info" <?php if (!pmpro_isLevelRecurring($level)) echo "style='display:none;'";?>>
|
416 |
+
<th scope="row" valign="top"><label><?php _e('Custom Trial', 'pmpro');?>:</label></th>
|
417 |
+
<td>
|
418 |
+
<input id="custom_trial" name="custom_trial" type="checkbox" value="yes" <?php if ( pmpro_isLevelTrial($level) ) { echo "checked='checked'"; } ?> onclick="jQuery('.trial_info').toggle();" /> <label for="custom_trial"><?php _e('Check to add a custom trial period.', 'pmpro');?></label>
|
419 |
+
|
420 |
+
<?php if($gateway == "twocheckout") { ?>
|
421 |
+
<br /><small><strong <?php if(!empty($pmpro_twocheckout_error)) { ?>class="pmpro_red"<?php } ?>><?php _e('2Checkout integration does not support custom trials. You can do one period trials by setting an initial payment different from the billing amount.', 'pmpro');?></strong></small>
|
422 |
+
<?php } ?>
|
423 |
+
</td>
|
424 |
+
</tr>
|
425 |
+
|
426 |
+
<tr class="trial_info recurring_info" <?php if (!pmpro_isLevelTrial($level)) echo "style='display:none;'";?>>
|
427 |
+
<th scope="row" valign="top"><label for="trial_amount"><?php _e('Trial Billing Amount', 'pmpro');?>:</label></th>
|
428 |
+
<td>
|
429 |
+
<?php
|
430 |
+
if(pmpro_getCurrencyPosition() == "left")
|
431 |
+
echo $pmpro_currency_symbol;
|
432 |
+
?>
|
433 |
+
<input name="trial_amount" type="text" size="20" value="<?php echo esc_attr($level->trial_amount);?>" />
|
434 |
+
<?php
|
435 |
+
if(pmpro_getCurrencyPosition() == "right")
|
436 |
+
echo $pmpro_currency_symbol;
|
437 |
+
?>
|
438 |
+
<small><?php _e('for the first', 'pmpro');?></small>
|
439 |
+
<input name="trial_limit" type="text" size="10" value="<?php echo esc_attr($level->trial_limit);?>" />
|
440 |
+
<small><?php _e('subscription payments', 'pmpro');?>.</small>
|
441 |
+
<?php if($gateway == "stripe") { ?>
|
442 |
+
<br /><small>
|
443 |
+
<strong <?php if(!empty($pmpro_stripe_error)) { ?>class="pmpro_red"<?php } ?>><?php _e('Stripe integration currently does not support trial amounts greater than $0.', 'pmpro');?></strong>
|
444 |
+
</small>
|
445 |
+
<?php } elseif($gateway == "braintree") { ?>
|
446 |
+
<br /><small>
|
447 |
+
<strong <?php if(!empty($pmpro_braintree_error)) { ?>class="pmpro_red"<?php } ?>><?php _e('Braintree integration currently does not support trial amounts greater than $0.', 'pmpro');?></strong>
|
448 |
+
</small>
|
449 |
+
<?php } elseif($gateway == "payflowpro") { ?>
|
450 |
+
<br /><small>
|
451 |
+
<strong <?php if(!empty($pmpro_payflow_error)) { ?>class="pmpro_red"<?php } ?>><?php _e('Payflow integration currently does not support trial amounts greater than $0.', 'pmpro');?></strong>
|
452 |
+
</small>
|
453 |
+
<?php } ?>
|
454 |
+
</td>
|
455 |
+
</tr>
|
456 |
+
|
457 |
+
</tbody>
|
458 |
+
</table>
|
459 |
+
|
460 |
+
<h3 class="topborder"><?php _e('Other Settings', 'pmpro');?></h3>
|
461 |
+
<table class="form-table">
|
462 |
+
<tbody>
|
463 |
+
<tr>
|
464 |
+
<th scope="row" valign="top"><label><?php _e('Disable New Signups', 'pmpro');?>:</label></th>
|
465 |
+
<td><input id="disable_signups" name="disable_signups" type="checkbox" value="yes" <?php if($level->id && !$level->allow_signups) { ?>checked="checked"<?php } ?> /> <label for="disable_signups"><?php _e('Check to hide this level from the membership levels page and disable registration.', 'pmpro');?></label></td>
|
466 |
+
</tr>
|
467 |
+
|
468 |
+
<tr>
|
469 |
+
<th scope="row" valign="top"><label><?php _e('Membership Expiration', 'pmpro');?>:</label></th>
|
470 |
+
<td><input id="expiration" name="expiration" type="checkbox" value="yes" <?php if(pmpro_isLevelExpiring($level)) { echo "checked='checked'"; } ?> onclick="if(jQuery('#expiration').is(':checked')) { jQuery('.expiration_info').show(); } else { jQuery('.expiration_info').hide();}" /> <label for="expiration"><?php _e('Check this to set when membership access expires.', 'pmpro');?></a></td>
|
471 |
+
</tr>
|
472 |
+
|
473 |
+
<tr class="expiration_info" <?php if(!pmpro_isLevelExpiring($level)) {?>style="display: none;"<?php } ?>>
|
474 |
+
<th scope="row" valign="top"><label for="billing_amount"><?php _e('Expires In', 'pmpro');?>:</label></th>
|
475 |
+
<td>
|
476 |
+
<input id="expiration_number" name="expiration_number" type="text" size="10" value="<?php echo esc_attr($level->expiration_number);?>" />
|
477 |
+
<select id="expiration_period" name="expiration_period">
|
478 |
+
<?php
|
479 |
+
$cycles = array( __('Day(s)', 'pmpro') => 'Day', __('Week(s)', 'pmpro') => 'Week', __('Month(s)', 'pmpro') => 'Month', __('Year(s)', 'pmpro') => 'Year' );
|
480 |
+
foreach ( $cycles as $name => $value ) {
|
481 |
+
echo "<option value='$value'";
|
482 |
+
if ( $level->expiration_period == $value ) echo " selected='selected'";
|
483 |
+
echo ">$name</option>";
|
484 |
+
}
|
485 |
+
?>
|
486 |
+
</select>
|
487 |
+
<br /><small><?php _e('Set the duration of membership access. Note that the any future payments (recurring subscription, if any) will be cancelled when the membership expires.', 'pmpro');?></small>
|
488 |
+
</td>
|
489 |
+
</tr>
|
490 |
+
</tbody>
|
491 |
+
</table>
|
492 |
+
|
493 |
+
<?php do_action("pmpro_membership_level_after_other_settings"); ?>
|
494 |
+
|
495 |
+
<h3 class="topborder"><?php _e('Content Settings', 'pmpro');?></h3>
|
496 |
+
<table class="form-table">
|
497 |
+
<tbody>
|
498 |
+
<tr>
|
499 |
+
<th scope="row" valign="top"><label><?php _e('Categories', 'pmpro');?>:</label></th>
|
500 |
+
<td>
|
501 |
+
<?php
|
502 |
+
$categories = get_categories( array( 'hide_empty' => 0 ) );
|
503 |
+
echo "<ul>";
|
504 |
+
foreach ( $categories as $cat )
|
505 |
+
{
|
506 |
+
$checked = in_array( $cat->term_id, $level->categories ) ? "checked='checked'" : '';
|
507 |
+
echo "<li><input id='membershipcategory_{$cat->term_id}' name='membershipcategory_{$cat->term_id}' type='checkbox' value='yes' $checked /> <label for='membershipcategory_{$cat->term_id}'>{$cat->name}</label></li>\n";
|
508 |
+
}
|
509 |
+
echo "</ul>";
|
510 |
+
?>
|
511 |
+
</td>
|
512 |
+
</tr>
|
513 |
+
</tbody>
|
514 |
+
</table>
|
515 |
+
<p class="submit topborder">
|
516 |
+
<input name="save" type="submit" class="button-primary" value="<?php _e('Save Level', 'pmpro'); ?>" />
|
517 |
+
<input name="cancel" type="button" value="<?php _e('Cancel', 'pmpro'); ?>" onclick="location.href='<?php echo get_admin_url(NULL, '/admin.php?page=pmpro-membershiplevels')?>';" />
|
518 |
+
</p>
|
519 |
+
</form>
|
520 |
+
</div>
|
521 |
+
|
522 |
+
<?php
|
523 |
+
}
|
524 |
+
else
|
525 |
+
{
|
526 |
+
?>
|
527 |
+
<script>
|
528 |
+
jQuery(document).ready(function($) {
|
529 |
+
|
530 |
+
// Return a helper with preserved width of cells
|
531 |
+
// from http://www.foliotek.com/devblog/make-table-rows-sortable-using-jquery-ui-sortable/
|
532 |
+
var fixHelper = function(e, ui) {
|
533 |
+
ui.children().each(function() {
|
534 |
+
$(this).width($(this).width());
|
535 |
+
});
|
536 |
+
return ui;
|
537 |
+
};
|
538 |
+
|
539 |
+
$("table.membership-levels tbody").sortable({
|
540 |
+
helper: fixHelper,
|
541 |
+
placeholder: 'testclass',
|
542 |
+
forcePlaceholderSize: true,
|
543 |
+
update: update_level_order
|
544 |
+
});
|
545 |
+
|
546 |
+
function update_level_order(event, ui) {
|
547 |
+
level_order = [];
|
548 |
+
$("table.membership-levels tbody tr").each(function() {
|
549 |
+
$(this).removeClass('alternate');
|
550 |
+
level_order.push(parseInt( $("td:first", this).text()));
|
551 |
+
});
|
552 |
+
|
553 |
+
//update styles
|
554 |
+
$("table.membership-levels tbody tr:odd").each(function() {
|
555 |
+
$(this).addClass('alternate');
|
556 |
+
});
|
557 |
+
|
558 |
+
data = {
|
559 |
+
action: 'pmpro_update_level_order',
|
560 |
+
level_order: level_order
|
561 |
+
};
|
562 |
+
|
563 |
+
$.post(ajaxurl, data, function(response) {
|
564 |
+
});
|
565 |
+
}
|
566 |
+
});
|
567 |
+
</script>
|
568 |
+
|
569 |
+
<h2 class="alignleft"><?php _e('Membership Levels', 'pmpro');?> <a href="admin.php?page=pmpro-membershiplevels&edit=-1" class="add-new-h2"><?php _e('Add New Level', 'pmpro');?></a></h2>
|
570 |
+
<form id="posts-filter" method="get" action="">
|
571 |
+
<p class="search-box">
|
572 |
+
<label class="screen-reader-text" for="post-search-input"><?php _e('Search Levels', 'pmpro');?>:</label>
|
573 |
+
<input type="hidden" name="page" value="pmpro-membershiplevels" />
|
574 |
+
<input id="post-search-input" type="text" value="<?php echo $s?>" name="s" size="30" />
|
575 |
+
<input class="button" type="submit" value="<?php _e('Search Levels', 'pmpro');?>" id="search-submit" />
|
576 |
+
</p>
|
577 |
+
</form>
|
578 |
+
<br class="clear" />
|
579 |
+
<p><?php _e('Drag and drop membership levels to reorder them on the Levels page.', 'pmpro'); ?></p>
|
580 |
+
<table class="widefat membership-levels">
|
581 |
+
<thead>
|
582 |
+
<tr>
|
583 |
+
<th><?php _e('ID', 'pmpro');?></th>
|
584 |
+
<th><?php _e('Name', 'pmpro');?></th>
|
585 |
+
<th><?php _e('Billing Details', 'pmpro');?></th>
|
586 |
+
<th><?php _e('Expiration', 'pmpro');?></th>
|
587 |
+
<th><?php _e('Allow Signups', 'pmpro');?></th>
|
588 |
+
<th></th>
|
589 |
+
</tr>
|
590 |
+
</thead>
|
591 |
+
<tbody>
|
592 |
+
<?php
|
593 |
+
$sqlQuery = "SELECT * FROM $wpdb->pmpro_membership_levels ";
|
594 |
+
if($s)
|
595 |
+
$sqlQuery .= "WHERE name LIKE '%$s%' ";
|
596 |
+
$sqlQuery .= "ORDER BY id ASC";
|
597 |
+
|
598 |
+
$levels = $wpdb->get_results($sqlQuery, OBJECT);
|
599 |
+
|
600 |
+
if(!empty($pmpro_level_order)) {
|
601 |
+
//reorder levels
|
602 |
+
$order = explode(',', $pmpro_level_order);
|
603 |
+
|
604 |
+
//put level ids in their own array
|
605 |
+
$level_ids = array();
|
606 |
+
foreach($levels as $level)
|
607 |
+
$level_ids[] = $level->id;
|
608 |
+
|
609 |
+
//remove levels from order if they are gone
|
610 |
+
foreach($order as $key => $level_id)
|
611 |
+
if(!in_array($level_id, $level_ids))
|
612 |
+
unset($order[$key]);
|
613 |
+
|
614 |
+
//add levels to the end if they aren't in the order array
|
615 |
+
foreach($level_ids as $level_id)
|
616 |
+
if(!in_array($level_id, $order))
|
617 |
+
$order[] = $level_id;
|
618 |
+
|
619 |
+
//remove dupes
|
620 |
+
$order = array_unique($order);
|
621 |
+
|
622 |
+
//save the level order
|
623 |
+
pmpro_setOption('level_order', implode(',', $order));
|
624 |
+
|
625 |
+
//reorder levels here
|
626 |
+
$reordered_levels = array();
|
627 |
+
foreach ($order as $level_id) {
|
628 |
+
foreach ($levels as $level) {
|
629 |
+
if ($level_id == $level->id)
|
630 |
+
$reordered_levels[] = $level;
|
631 |
+
}
|
632 |
+
}
|
633 |
+
}
|
634 |
+
else
|
635 |
+
$reordered_levels = $levels;
|
636 |
+
|
637 |
+
$count = 0;
|
638 |
+
foreach($reordered_levels as $level)
|
639 |
+
{
|
640 |
+
?>
|
641 |
+
<tr class="<?php if($count++ % 2 == 1) { ?>alternate<?php } ?> <?php if(!$level->allow_signups) { ?>pmpro_gray<?php } ?> <?php if(!pmpro_checkLevelForStripeCompatibility($level) || !pmpro_checkLevelForBraintreeCompatibility($level) || !pmpro_checkLevelForPayflowCompatibility($level) || !pmpro_checkLevelForTwoCheckoutCompatibility($level)) { ?>pmpro_error<?php } ?>">
|
642 |
+
<td><?php echo $level->id?></td>
|
643 |
+
<td class="level_name"><a href="admin.php?page=pmpro-membershiplevels&edit=<?php echo $level->id?>"><?php echo $level->name?></a></td>
|
644 |
+
<td>
|
645 |
+
<?php if(pmpro_isLevelFree($level)) { ?>
|
646 |
+
<?php _e('FREE', 'pmpro');?>
|
647 |
+
<?php } else { ?>
|
648 |
+
<?php echo str_replace( 'The price for membership is', '', pmpro_getLevelCost($level)); ?>
|
649 |
+
<?php } ?>
|
650 |
+
</td>
|
651 |
+
<td>
|
652 |
+
<?php if(!pmpro_isLevelExpiring($level)) { ?>
|
653 |
+
--
|
654 |
+
<?php } else { ?>
|
655 |
+
<?php _e('After', 'pmpro');?> <?php echo $level->expiration_number?> <?php echo sornot($level->expiration_period,$level->expiration_number)?>
|
656 |
+
<?php } ?>
|
657 |
+
</td>
|
658 |
+
<td><?php if($level->allow_signups) { ?><a href="<?php echo pmpro_url("checkout", "?level=" . $level->id);?>"><?php _e('Yes', 'pmpro');?></a><?php } else { ?><?php _e('No', 'pmpro');?><?php } ?></td>
|
659 |
+
|
660 |
+
<td><a title="<?php _e('edit','pmpro'); ?>" href="admin.php?page=pmpro-membershiplevels&edit=<?php echo $level->id?>" class="button-primary"><?php _e('edit','pmpro'); ?></a> <a title="<?php _e('copy','pmpro'); ?>" href="admin.php?page=pmpro-membershiplevels©=<?php echo $level->id?>&edit=-1" class="button-secondary"><?php _e('copy','pmpro'); ?></a> <a title="<?php _e('delete','pmpro'); ?>" href="javascript: askfirst('<?php printf(__("Are you sure you want to delete membership level %s? All subscriptions will be cancelled.", "pmpro"), $level->name);?>','admin.php?page=pmpro-membershiplevels&action=delete_membership_level&deleteid=<?php echo $level->id?>'); void(0);" class="button-secondary"><?php _e('delete','pmpro'); ?></a></td>
|
661 |
+
</tr>
|
662 |
+
<?php
|
663 |
+
}
|
664 |
+
?>
|
665 |
+
</tbody>
|
666 |
+
</table>
|
667 |
+
<?php
|
668 |
+
}
|
669 |
+
?>
|
670 |
+
|
671 |
+
<?php
|
672 |
+
require_once(dirname(__FILE__) . "/admin_footer.php");
|
673 |
+
?>
|
adminpages/memberslist-csv.php
CHANGED
@@ -1,38 +1,38 @@
|
|
1 |
-
<?php
|
2 |
//only admins can get this
|
3 |
if(!function_exists("current_user_can") || (!current_user_can("manage_options") && !current_user_can("pmpro_memberslistcsv")))
|
4 |
{
|
5 |
die(__("You do not have permissions to perform this action.", "pmpro"));
|
6 |
-
}
|
7 |
-
|
8 |
-
global $wpdb;
|
9 |
-
|
10 |
-
//get users
|
11 |
if(isset($_REQUEST['s']))
|
12 |
$s = $_REQUEST['s'];
|
13 |
else
|
14 |
$s = "";
|
15 |
-
|
16 |
if(isset($_REQUEST['l']))
|
17 |
$l = $_REQUEST['l'];
|
18 |
else
|
19 |
$l = false;
|
20 |
-
|
21 |
//some vars for the search
|
22 |
if(!empty($_REQUEST['pn']))
|
23 |
$pn = intval($_REQUEST['pn']);
|
24 |
else
|
25 |
$pn = 1;
|
26 |
-
|
27 |
if(!empty($_REQUEST['limit']))
|
28 |
$limit = intval($_REQUEST['limit']);
|
29 |
else
|
30 |
$limit = false;
|
31 |
-
|
32 |
if($limit)
|
33 |
-
{
|
34 |
$end = $pn * $limit;
|
35 |
-
$start = $end - $limit;
|
36 |
}
|
37 |
else
|
38 |
{
|
@@ -105,9 +105,9 @@
|
|
105 |
|
106 |
//get users
|
107 |
$theusers = $wpdb->get_col($sqlQuery);
|
108 |
-
|
109 |
//begin output
|
110 |
-
header("Content-type: text/csv");
|
111 |
if($s && $l == "oldmembers")
|
112 |
header("Content-Disposition: attachment; filename=members_list_expired_" . sanitize_file_name($s) . ".csv");
|
113 |
elseif($s && $l)
|
@@ -118,17 +118,17 @@
|
|
118 |
header("Content-Disposition: attachment; filename=members_list_expired.csv");
|
119 |
else
|
120 |
header("Content-Disposition: attachment; filename=members_list.csv");
|
121 |
-
|
122 |
$heading = "id,username,firstname,lastname,email,billing firstname,billing lastname,address1,address2,city,state,zipcode,country,phone,membership,initial payment,fee,term,discount_code_id,discount_code,joined";
|
123 |
-
|
124 |
if($l == "oldmembers")
|
125 |
$heading .= ",ended";
|
126 |
else
|
127 |
$heading .= ",expires";
|
128 |
-
|
129 |
$heading = apply_filters("pmpro_members_list_csv_heading", $heading);
|
130 |
$csvoutput = $heading;
|
131 |
-
|
132 |
//these are the meta_keys for the fields (arrays are object, property. so e.g. $theuser->ID)
|
133 |
$default_columns = array(
|
134 |
array("theuser", "ID"),
|
@@ -156,7 +156,7 @@
|
|
156 |
|
157 |
//filter
|
158 |
$default_columns = apply_filters("pmpro_members_list_csv_default_columns", $default_columns);
|
159 |
-
|
160 |
//any extra columns
|
161 |
$extra_columns = apply_filters("pmpro_members_list_csv_extra_columns", array());
|
162 |
if(!empty($extra_columns))
|
@@ -166,32 +166,32 @@
|
|
166 |
$csvoutput .= "," . $heading;
|
167 |
}
|
168 |
}
|
169 |
-
|
170 |
-
$csvoutput .= "\n";
|
171 |
-
|
172 |
//output
|
173 |
echo $csvoutput;
|
174 |
$csvoutput = "";
|
175 |
-
|
176 |
if($theusers)
|
177 |
{
|
178 |
foreach($theusers as $user_id)
|
179 |
{
|
180 |
//MULTI: This query will need to be updated to support multiple levels per user. Should probably just dump multiple rows for each membership.
|
181 |
//get meta
|
182 |
-
|
183 |
if($l == "oldmembers")
|
184 |
$theuser = $wpdb->get_row("SELECT u.ID, u.user_login, u.user_email, UNIX_TIMESTAMP(u.user_registered) as joindate, u.user_login, u.user_nicename, u.user_url, u.user_registered, u.user_status, u.display_name, mu.membership_id, mu.initial_payment, mu.billing_amount, mu.cycle_period, UNIX_TIMESTAMP(mu.enddate) as enddate, m.name as membership FROM $wpdb->users u LEFT JOIN $wpdb->usermeta um ON u.ID = um.user_id LEFT JOIN $wpdb->pmpro_memberships_users mu ON u.ID = mu.user_id LEFT JOIN $wpdb->pmpro_membership_levels m ON mu.membership_id = m.id WHERE u.ID = '" . $user_id . "' ORDER BY mu.id DESC LIMIT 1");
|
185 |
else
|
186 |
$theuser = $wpdb->get_row("SELECT u.ID, u.user_login, u.user_email, UNIX_TIMESTAMP(u.user_registered) as joindate, u.user_login, u.user_nicename, u.user_url, u.user_registered, u.user_status, u.display_name, mu.membership_id, mu.initial_payment, mu.billing_amount, mu.cycle_period, UNIX_TIMESTAMP(mu.enddate) as enddate, m.name as membership FROM $wpdb->users u LEFT JOIN $wpdb->usermeta um ON u.ID = um.user_id LEFT JOIN $wpdb->pmpro_memberships_users mu ON u.ID = mu.user_id AND mu.status = 'active' LEFT JOIN $wpdb->pmpro_membership_levels m ON mu.membership_id = m.id WHERE u.ID = '" . $user_id . "' LIMIT 1");
|
187 |
-
|
188 |
-
$sqlQuery = "SELECT meta_key as `key`, meta_value as `value` FROM $wpdb->usermeta WHERE $wpdb->usermeta.user_id = '" . $user_id . "'";
|
189 |
-
$metavalues = pmpro_getMetavalues($sqlQuery);
|
190 |
$theuser->metavalues = $metavalues;
|
191 |
-
$sqlQuery = "SELECT c.id, c.code FROM $wpdb->pmpro_discount_codes_uses cu LEFT JOIN $wpdb->pmpro_discount_codes c ON cu.code_id = c.id WHERE cu.user_id = '" . $theuser->ID . "' ORDER BY c.id DESC LIMIT 1";
|
192 |
$discount_code = $wpdb->get_row($sqlQuery);
|
193 |
-
|
194 |
-
//default columns
|
195 |
if(!empty($default_columns))
|
196 |
{
|
197 |
$count = 0;
|
@@ -201,16 +201,16 @@
|
|
201 |
$count++;
|
202 |
if($count > 1)
|
203 |
$csvoutput .= ",";
|
204 |
-
|
205 |
//checking $object->property. note the double $$
|
206 |
if(!empty($$col[0]->$col[1]))
|
207 |
-
$csvoutput .= pmpro_enclose($$col[0]->$col[1]); //output the value
|
208 |
}
|
209 |
}
|
210 |
-
|
211 |
//joindate and enddate
|
212 |
$csvoutput .= "," . pmpro_enclose(date("Y-m-d", $theuser->joindate)) . ",";
|
213 |
-
|
214 |
if($theuser->membership_id)
|
215 |
{
|
216 |
if($theuser->enddate)
|
@@ -224,8 +224,8 @@
|
|
224 |
}
|
225 |
else
|
226 |
$csvoutput .= "N/A";
|
227 |
-
|
228 |
-
//any extra columns
|
229 |
if(!empty($extra_columns))
|
230 |
{
|
231 |
foreach($extra_columns as $heading => $callback)
|
@@ -233,17 +233,17 @@
|
|
233 |
$csvoutput .= "," . pmpro_enclose(call_user_func($callback, $theuser, $heading));
|
234 |
}
|
235 |
}
|
236 |
-
|
237 |
$csvoutput .= "\n";
|
238 |
-
|
239 |
//output
|
240 |
echo $csvoutput;
|
241 |
-
$csvoutput = "";
|
242 |
}
|
243 |
}
|
244 |
-
|
245 |
print $csvoutput;
|
246 |
-
|
247 |
function pmpro_enclose($s)
|
248 |
{
|
249 |
return "\"" . str_replace("\"", "\\\"", $s) . "\"";
|
1 |
+
<?php
|
2 |
//only admins can get this
|
3 |
if(!function_exists("current_user_can") || (!current_user_can("manage_options") && !current_user_can("pmpro_memberslistcsv")))
|
4 |
{
|
5 |
die(__("You do not have permissions to perform this action.", "pmpro"));
|
6 |
+
}
|
7 |
+
|
8 |
+
global $wpdb;
|
9 |
+
|
10 |
+
//get users
|
11 |
if(isset($_REQUEST['s']))
|
12 |
$s = $_REQUEST['s'];
|
13 |
else
|
14 |
$s = "";
|
15 |
+
|
16 |
if(isset($_REQUEST['l']))
|
17 |
$l = $_REQUEST['l'];
|
18 |
else
|
19 |
$l = false;
|
20 |
+
|
21 |
//some vars for the search
|
22 |
if(!empty($_REQUEST['pn']))
|
23 |
$pn = intval($_REQUEST['pn']);
|
24 |
else
|
25 |
$pn = 1;
|
26 |
+
|
27 |
if(!empty($_REQUEST['limit']))
|
28 |
$limit = intval($_REQUEST['limit']);
|
29 |
else
|
30 |
$limit = false;
|
31 |
+
|
32 |
if($limit)
|
33 |
+
{
|
34 |
$end = $pn * $limit;
|
35 |
+
$start = $end - $limit;
|
36 |
}
|
37 |
else
|
38 |
{
|
105 |
|
106 |
//get users
|
107 |
$theusers = $wpdb->get_col($sqlQuery);
|
108 |
+
|
109 |
//begin output
|
110 |
+
header("Content-type: text/csv");
|
111 |
if($s && $l == "oldmembers")
|
112 |
header("Content-Disposition: attachment; filename=members_list_expired_" . sanitize_file_name($s) . ".csv");
|
113 |
elseif($s && $l)
|
118 |
header("Content-Disposition: attachment; filename=members_list_expired.csv");
|
119 |
else
|
120 |
header("Content-Disposition: attachment; filename=members_list.csv");
|
121 |
+
|
122 |
$heading = "id,username,firstname,lastname,email,billing firstname,billing lastname,address1,address2,city,state,zipcode,country,phone,membership,initial payment,fee,term,discount_code_id,discount_code,joined";
|
123 |
+
|
124 |
if($l == "oldmembers")
|
125 |
$heading .= ",ended";
|
126 |
else
|
127 |
$heading .= ",expires";
|
128 |
+
|
129 |
$heading = apply_filters("pmpro_members_list_csv_heading", $heading);
|
130 |
$csvoutput = $heading;
|
131 |
+
|
132 |
//these are the meta_keys for the fields (arrays are object, property. so e.g. $theuser->ID)
|
133 |
$default_columns = array(
|
134 |
array("theuser", "ID"),
|
156 |
|
157 |
//filter
|
158 |
$default_columns = apply_filters("pmpro_members_list_csv_default_columns", $default_columns);
|
159 |
+
|
160 |
//any extra columns
|
161 |
$extra_columns = apply_filters("pmpro_members_list_csv_extra_columns", array());
|
162 |
if(!empty($extra_columns))
|
166 |
$csvoutput .= "," . $heading;
|
167 |
}
|
168 |
}
|
169 |
+
|
170 |
+
$csvoutput .= "\n";
|
171 |
+
|
172 |
//output
|
173 |
echo $csvoutput;
|
174 |
$csvoutput = "";
|
175 |
+
|
176 |
if($theusers)
|
177 |
{
|
178 |
foreach($theusers as $user_id)
|
179 |
{
|
180 |
//MULTI: This query will need to be updated to support multiple levels per user. Should probably just dump multiple rows for each membership.
|
181 |
//get meta
|
182 |
+
|
183 |
if($l == "oldmembers")
|
184 |
$theuser = $wpdb->get_row("SELECT u.ID, u.user_login, u.user_email, UNIX_TIMESTAMP(u.user_registered) as joindate, u.user_login, u.user_nicename, u.user_url, u.user_registered, u.user_status, u.display_name, mu.membership_id, mu.initial_payment, mu.billing_amount, mu.cycle_period, UNIX_TIMESTAMP(mu.enddate) as enddate, m.name as membership FROM $wpdb->users u LEFT JOIN $wpdb->usermeta um ON u.ID = um.user_id LEFT JOIN $wpdb->pmpro_memberships_users mu ON u.ID = mu.user_id LEFT JOIN $wpdb->pmpro_membership_levels m ON mu.membership_id = m.id WHERE u.ID = '" . $user_id . "' ORDER BY mu.id DESC LIMIT 1");
|
185 |
else
|
186 |
$theuser = $wpdb->get_row("SELECT u.ID, u.user_login, u.user_email, UNIX_TIMESTAMP(u.user_registered) as joindate, u.user_login, u.user_nicename, u.user_url, u.user_registered, u.user_status, u.display_name, mu.membership_id, mu.initial_payment, mu.billing_amount, mu.cycle_period, UNIX_TIMESTAMP(mu.enddate) as enddate, m.name as membership FROM $wpdb->users u LEFT JOIN $wpdb->usermeta um ON u.ID = um.user_id LEFT JOIN $wpdb->pmpro_memberships_users mu ON u.ID = mu.user_id AND mu.status = 'active' LEFT JOIN $wpdb->pmpro_membership_levels m ON mu.membership_id = m.id WHERE u.ID = '" . $user_id . "' LIMIT 1");
|
187 |
+
|
188 |
+
$sqlQuery = "SELECT meta_key as `key`, meta_value as `value` FROM $wpdb->usermeta WHERE $wpdb->usermeta.user_id = '" . $user_id . "'";
|
189 |
+
$metavalues = pmpro_getMetavalues($sqlQuery);
|
190 |
$theuser->metavalues = $metavalues;
|
191 |
+
$sqlQuery = "SELECT c.id, c.code FROM $wpdb->pmpro_discount_codes_uses cu LEFT JOIN $wpdb->pmpro_discount_codes c ON cu.code_id = c.id WHERE cu.user_id = '" . $theuser->ID . "' ORDER BY c.id DESC LIMIT 1";
|
192 |
$discount_code = $wpdb->get_row($sqlQuery);
|
193 |
+
|
194 |
+
//default columns
|
195 |
if(!empty($default_columns))
|
196 |
{
|
197 |
$count = 0;
|
201 |
$count++;
|
202 |
if($count > 1)
|
203 |
$csvoutput .= ",";
|
204 |
+
|
205 |
//checking $object->property. note the double $$
|
206 |
if(!empty($$col[0]->$col[1]))
|
207 |
+
$csvoutput .= pmpro_enclose($$col[0]->$col[1]); //output the value
|
208 |
}
|
209 |
}
|
210 |
+
|
211 |
//joindate and enddate
|
212 |
$csvoutput .= "," . pmpro_enclose(date("Y-m-d", $theuser->joindate)) . ",";
|
213 |
+
|
214 |
if($theuser->membership_id)
|
215 |
{
|
216 |
if($theuser->enddate)
|
224 |
}
|
225 |
else
|
226 |
$csvoutput .= "N/A";
|
227 |
+
|
228 |
+
//any extra columns
|
229 |
if(!empty($extra_columns))
|
230 |
{
|
231 |
foreach($extra_columns as $heading => $callback)
|
233 |
$csvoutput .= "," . pmpro_enclose(call_user_func($callback, $theuser, $heading));
|
234 |
}
|
235 |
}
|
236 |
+
|
237 |
$csvoutput .= "\n";
|
238 |
+
|
239 |
//output
|
240 |
echo $csvoutput;
|
241 |
+
$csvoutput = "";
|
242 |
}
|
243 |
}
|
244 |
+
|
245 |
print $csvoutput;
|
246 |
+
|
247 |
function pmpro_enclose($s)
|
248 |
{
|
249 |
return "\"" . str_replace("\"", "\\\"", $s) . "\"";
|
adminpages/memberslist.php
CHANGED
@@ -3,30 +3,30 @@
|
|
3 |
if(!function_exists("current_user_can") || (!current_user_can("manage_options") && !current_user_can("pmpro_memberslist")))
|
4 |
{
|
5 |
die(__("You do not have permissions to perform this action.", "pmpro"));
|
6 |
-
}
|
7 |
-
|
8 |
//vars
|
9 |
global $wpdb;
|
10 |
if(isset($_REQUEST['s']))
|
11 |
$s = trim($_REQUEST['s']);
|
12 |
else
|
13 |
$s = "";
|
14 |
-
|
15 |
if(isset($_REQUEST['l']))
|
16 |
$l = $_REQUEST['l'];
|
17 |
else
|
18 |
$l = false;
|
19 |
-
|
20 |
-
require_once(dirname(__FILE__) . "/admin_header.php");
|
21 |
?>
|
22 |
|
23 |
-
<form id="posts-filter" method="get" action="">
|
24 |
<h2>
|
25 |
<?php _e('Members List', 'pmpro');?>
|
26 |
<a target="_blank" href="<?php echo admin_url('admin-ajax.php');?>?action=memberslist_csv&s=<?php echo $s?>&l=<?php echo $l?>" class="add-new-h2"><?php _e('Export to CSV', 'pmpro');?></a>
|
27 |
-
</h2>
|
28 |
<ul class="subsubsub">
|
29 |
-
<li>
|
30 |
<?php _e('Show', 'pmpro');?>
|
31 |
<select name="l" onchange="jQuery('#posts-filter').submit();">
|
32 |
<option value="" <?php if(!$l) { ?>selected="selected"<?php } ?>><?php _e('All Levels', 'pmpro');?></option>
|
@@ -41,40 +41,40 @@
|
|
41 |
?>
|
42 |
<option value="cancelled" <?php if($l == "cancelled") { ?>selected="selected"<?php } ?>><?php _e('Cancelled Members', 'pmpro');?></option>
|
43 |
<option value="expired" <?php if($l == "expired") { ?>selected="selected"<?php } ?>><?php _e('Expired Members', 'pmpro');?></option>
|
44 |
-
<option value="oldmembers" <?php if($l == "oldmembers") { ?>selected="selected"<?php } ?>><?php _e('Old Members', 'pmpro');?></option>
|
45 |
-
</select>
|
46 |
</li>
|
47 |
</ul>
|
48 |
<p class="search-box">
|
49 |
<label class="hidden" for="post-search-input"><?php _e('Search Members', 'pmpro');?>:</label>
|
50 |
-
<input type="hidden" name="page" value="pmpro-memberslist" />
|
51 |
<input id="post-search-input" type="text" value="<?php echo $s?>" name="s"/>
|
52 |
<input class="button" type="submit" value="<?php _e('Search Members', 'pmpro');?>"/>
|
53 |
</p>
|
54 |
-
<?php
|
55 |
//some vars for the search
|
56 |
if(isset($_REQUEST['pn']))
|
57 |
$pn = intval($_REQUEST['pn']);
|
58 |
else
|
59 |
$pn = 1;
|
60 |
-
|
61 |
if(isset($_REQUEST['limit']))
|
62 |
$limit = intval($_REQUEST['limit']);
|
63 |
else
|
64 |
$limit = 15;
|
65 |
-
|
66 |
$end = $pn * $limit;
|
67 |
-
$start = $end - $limit;
|
68 |
-
|
69 |
if($s)
|
70 |
{
|
71 |
$sqlQuery = "SELECT SQL_CALC_FOUND_ROWS u.ID, u.user_login, u.user_email, UNIX_TIMESTAMP(u.user_registered) as joindate, mu.membership_id, mu.initial_payment, mu.billing_amount, mu.cycle_period, mu.cycle_number, mu.billing_limit, mu.trial_amount, mu.trial_limit, UNIX_TIMESTAMP(mu.startdate) as startdate, UNIX_TIMESTAMP(mu.enddate) as enddate, m.name as membership FROM $wpdb->users u LEFT JOIN $wpdb->usermeta um ON u.ID = um.user_id LEFT JOIN $wpdb->pmpro_memberships_users mu ON u.ID = mu.user_id LEFT JOIN $wpdb->pmpro_membership_levels m ON mu.membership_id = m.id ";
|
72 |
-
|
73 |
if($l == "oldmembers" || $l == "expired" || $l == "cancelled")
|
74 |
$sqlQuery .= " LEFT JOIN $wpdb->pmpro_memberships_users mu2 ON u.ID = mu2.user_id AND mu2.status = 'active' ";
|
75 |
-
|
76 |
-
$sqlQuery .= " WHERE mu.membership_id > 0 AND (u.user_login LIKE '%" . esc_sql($s) . "%' OR u.user_email LIKE '%" . esc_sql($s) . "%' OR um.meta_value LIKE '%" . esc_sql($s) . "%') ";
|
77 |
-
|
78 |
if($l == "oldmembers")
|
79 |
$sqlQuery .= " AND mu.status <> 'active' AND mu2.status IS NULL ";
|
80 |
elseif($l == "expired")
|
@@ -82,28 +82,28 @@
|
|
82 |
elseif($l == "cancelled")
|
83 |
$sqlQuery .= " AND mu.status IN('cancelled', 'admin_cancelled') AND mu2.status IS NULL ";
|
84 |
elseif($l)
|
85 |
-
$sqlQuery .= " AND mu.status = 'active' AND mu.membership_id = '" . esc_sql($l) . "' ";
|
86 |
else
|
87 |
-
$sqlQuery .= " AND mu.status = 'active' ";
|
88 |
-
|
89 |
$sqlQuery .= "GROUP BY u.ID ";
|
90 |
-
|
91 |
if($l == "oldmembers" || $l == "expired" || $l == "cancelled")
|
92 |
$sqlQuery .= "ORDER BY enddate DESC ";
|
93 |
else
|
94 |
$sqlQuery .= "ORDER BY u.user_registered DESC ";
|
95 |
-
|
96 |
$sqlQuery .= "LIMIT $start, $limit";
|
97 |
}
|
98 |
else
|
99 |
{
|
100 |
$sqlQuery = "SELECT SQL_CALC_FOUND_ROWS u.ID, u.user_login, u.user_email, UNIX_TIMESTAMP(u.user_registered) as joindate, mu.membership_id, mu.initial_payment, mu.billing_amount, mu.cycle_period, mu.cycle_number, mu.billing_limit, mu.trial_amount, mu.trial_limit, UNIX_TIMESTAMP(mu.startdate) as startdate, UNIX_TIMESTAMP(mu.enddate) as enddate, m.name as membership FROM $wpdb->users u LEFT JOIN $wpdb->pmpro_memberships_users mu ON u.ID = mu.user_id LEFT JOIN $wpdb->pmpro_membership_levels m ON mu.membership_id = m.id";
|
101 |
-
|
102 |
if($l == "oldmembers" || $l == "expired" || $l == "cancelled")
|
103 |
$sqlQuery .= " LEFT JOIN $wpdb->pmpro_memberships_users mu2 ON u.ID = mu2.user_id AND mu2.status = 'active' ";
|
104 |
-
|
105 |
$sqlQuery .= " WHERE mu.membership_id > 0 ";
|
106 |
-
|
107 |
if($l == "oldmembers")
|
108 |
$sqlQuery .= " AND mu.status <> 'active' AND mu2.status IS NULL ";
|
109 |
elseif($l == "expired")
|
@@ -115,27 +115,27 @@
|
|
115 |
else
|
116 |
$sqlQuery .= " AND mu.status = 'active' ";
|
117 |
$sqlQuery .= "GROUP BY u.ID ";
|
118 |
-
|
119 |
if($l == "oldmembers" || $l == "expired" || $l == "cancelled")
|
120 |
$sqlQuery .= "ORDER BY enddate DESC ";
|
121 |
else
|
122 |
$sqlQuery .= "ORDER BY u.user_registered DESC ";
|
123 |
-
|
124 |
$sqlQuery .= "LIMIT $start, $limit";
|
125 |
}
|
126 |
-
|
127 |
$sqlQuery = apply_filters("pmpro_members_list_sql", $sqlQuery);
|
128 |
-
|
129 |
$theusers = $wpdb->get_results($sqlQuery);
|
130 |
$totalrows = $wpdb->get_var("SELECT FOUND_ROWS() as found_rows");
|
131 |
-
|
132 |
if($theusers)
|
133 |
{
|
134 |
$calculate_revenue = apply_filters("pmpro_memberslist_calculate_revenue", false);
|
135 |
if($calculate_revenue)
|
136 |
{
|
137 |
$initial_payments = pmpro_calculateInitialPaymentRevenue($s, $l);
|
138 |
-
$recurring_payments = pmpro_calculateRecurringRevenue($s, $l);
|
139 |
?>
|
140 |
<p class="clear"><?php echo strval($totalrows)?> members found. These members have paid <strong>$<?php echo number_format($initial_payments)?> in initial payments</strong> and will generate an estimated <strong>$<?php echo number_format($recurring_payments)?> in revenue over the next year</strong>, or <strong>$<?php echo number_format($recurring_payments/12)?>/month</strong>. <span class="pmpro_lite">(This estimate does not take into account trial periods or billing limits.)</span></p>
|
141 |
<?php
|
@@ -143,10 +143,10 @@
|
|
143 |
else
|
144 |
{
|
145 |
?>
|
146 |
-
<p class="clear"><?php printf(__("%d members found.", "pmpro"), $totalrows);?></span></p>
|
147 |
<?php
|
148 |
}
|
149 |
-
}
|
150 |
?>
|
151 |
<table class="widefat">
|
152 |
<thead>
|
@@ -158,11 +158,11 @@
|
|
158 |
<th><?php _e('Email', 'pmpro');?></th>
|
159 |
<?php do_action("pmpro_memberslist_extra_cols_header", $theusers);?>
|
160 |
<th><?php _e('Billing Address', 'pmpro');?></th>
|
161 |
-
<th><?php _e('Membership', 'pmpro');?></th>
|
162 |
<th><?php _e('Fee', 'pmpro');?></th>
|
163 |
<th><?php _e('Joined', 'pmpro');?></th>
|
164 |
<th>
|
165 |
-
<?php
|
166 |
if($l == "oldmembers")
|
167 |
_e('Ended', 'pmpro');
|
168 |
else
|
@@ -171,13 +171,13 @@
|
|
171 |
</th>
|
172 |
</tr>
|
173 |
</thead>
|
174 |
-
<tbody id="users" class="list:user user-list">
|
175 |
-
<?php
|
176 |
-
$count = 0;
|
177 |
foreach($theusers as $auser)
|
178 |
{
|
179 |
-
//get meta
|
180 |
-
$theuser = get_userdata($auser->ID);
|
181 |
?>
|
182 |
<tr <?php if($count++ % 2 == 0) { ?>class="alternate"<?php } ?>>
|
183 |
<td><?php echo $theuser->ID?></td>
|
@@ -188,11 +188,11 @@
|
|
188 |
$userlink = '<a href="user-edit.php?user_id=' . $theuser->ID . '">' . $theuser->user_login . '</a>';
|
189 |
$userlink = apply_filters("pmpro_members_list_user_link", $userlink, $theuser);
|
190 |
echo $userlink;
|
191 |
-
?>
|
192 |
</strong>
|
193 |
-
<br />
|
194 |
<?php
|
195 |
-
// Set up the hover actions for this user
|
196 |
$actions = apply_filters( 'pmpro_memberslist_user_row_actions', array(), $theuser );
|
197 |
$action_count = count( $actions );
|
198 |
$i = 0;
|
@@ -207,7 +207,7 @@
|
|
207 |
$out .= '</div>';
|
208 |
echo $out;
|
209 |
}
|
210 |
-
?>
|
211 |
</td>
|
212 |
<td><?php echo $theuser->first_name?></td>
|
213 |
<td><?php echo $theuser->last_name?></td>
|
@@ -216,10 +216,10 @@
|
|
216 |
<td>
|
217 |
<?php
|
218 |
echo pmpro_formatAddress(trim($theuser->pmpro_bfirstname . " " . $theuser->pmpro_blastname), $theuser->pmpro_baddress1, $theuser->pmpro_baddress2, $theuser->pmpro_bcity, $theuser->pmpro_bstate, $theuser->pmpro_bzipcode, $theuser->pmpro_bcountry, $theuser->pmpro_bphone);
|
219 |
-
?>
|
220 |
</td>
|
221 |
-
<td><?php echo $auser->membership?></td>
|
222 |
-
<td>
|
223 |
<?php if((float)$auser->initial_payment > 0) { ?>
|
224 |
<?php echo pmpro_formatPrice($auser->initial_payment);?>
|
225 |
<?php } ?>
|
@@ -230,11 +230,11 @@
|
|
230 |
<?php if((float)$auser->initial_payment <= 0 && (float)$auser->billing_amount <= 0) { ?>
|
231 |
-
|
232 |
<?php } ?>
|
233 |
-
</td>
|
234 |
<td><?php echo date(get_option("date_format"), strtotime($theuser->user_registered, current_time("timestamp")))?></td>
|
235 |
<td>
|
236 |
-
<?php
|
237 |
-
if($auser->enddate)
|
238 |
echo apply_filters("pmpro_memberslist_expires_column", date(get_option('date_format'), $auser->enddate), $auser);
|
239 |
else
|
240 |
echo __(apply_filters("pmpro_memberslist_expires_column", "Never", $auser), "pmpro");
|
@@ -243,7 +243,7 @@
|
|
243 |
</tr>
|
244 |
<?php
|
245 |
}
|
246 |
-
|
247 |
if(!$theusers)
|
248 |
{
|
249 |
?>
|
@@ -252,15 +252,15 @@
|
|
252 |
</tr>
|
253 |
<?php
|
254 |
}
|
255 |
-
?>
|
256 |
</tbody>
|
257 |
</table>
|
258 |
</form>
|
259 |
-
|
260 |
<?php
|
261 |
echo pmpro_getPaginationString($pn, $totalrows, $limit, 1, get_admin_url(NULL, "/admin.php?page=pmpro-memberslist&s=" . urlencode($s)), "&l=$l&limit=$limit&pn=");
|
262 |
?>
|
263 |
-
|
264 |
<?php
|
265 |
-
require_once(dirname(__FILE__) . "/admin_footer.php");
|
266 |
?>
|
3 |
if(!function_exists("current_user_can") || (!current_user_can("manage_options") && !current_user_can("pmpro_memberslist")))
|
4 |
{
|
5 |
die(__("You do not have permissions to perform this action.", "pmpro"));
|
6 |
+
}
|
7 |
+
|
8 |
//vars
|
9 |
global $wpdb;
|
10 |
if(isset($_REQUEST['s']))
|
11 |
$s = trim($_REQUEST['s']);
|
12 |
else
|
13 |
$s = "";
|
14 |
+
|
15 |
if(isset($_REQUEST['l']))
|
16 |
$l = $_REQUEST['l'];
|
17 |
else
|
18 |
$l = false;
|
19 |
+
|
20 |
+
require_once(dirname(__FILE__) . "/admin_header.php");
|
21 |
?>
|
22 |
|
23 |
+
<form id="posts-filter" method="get" action="">
|
24 |
<h2>
|
25 |
<?php _e('Members List', 'pmpro');?>
|
26 |
<a target="_blank" href="<?php echo admin_url('admin-ajax.php');?>?action=memberslist_csv&s=<?php echo $s?>&l=<?php echo $l?>" class="add-new-h2"><?php _e('Export to CSV', 'pmpro');?></a>
|
27 |
+
</h2>
|
28 |
<ul class="subsubsub">
|
29 |
+
<li>
|
30 |
<?php _e('Show', 'pmpro');?>
|
31 |
<select name="l" onchange="jQuery('#posts-filter').submit();">
|
32 |
<option value="" <?php if(!$l) { ?>selected="selected"<?php } ?>><?php _e('All Levels', 'pmpro');?></option>
|
41 |
?>
|
42 |
<option value="cancelled" <?php if($l == "cancelled") { ?>selected="selected"<?php } ?>><?php _e('Cancelled Members', 'pmpro');?></option>
|
43 |
<option value="expired" <?php if($l == "expired") { ?>selected="selected"<?php } ?>><?php _e('Expired Members', 'pmpro');?></option>
|
44 |
+
<option value="oldmembers" <?php if($l == "oldmembers") { ?>selected="selected"<?php } ?>><?php _e('Old Members', 'pmpro');?></option>
|
45 |
+
</select>
|
46 |
</li>
|
47 |
</ul>
|
48 |
<p class="search-box">
|
49 |
<label class="hidden" for="post-search-input"><?php _e('Search Members', 'pmpro');?>:</label>
|
50 |
+
<input type="hidden" name="page" value="pmpro-memberslist" />
|
51 |
<input id="post-search-input" type="text" value="<?php echo $s?>" name="s"/>
|
52 |
<input class="button" type="submit" value="<?php _e('Search Members', 'pmpro');?>"/>
|
53 |
</p>
|
54 |
+
<?php
|
55 |
//some vars for the search
|
56 |
if(isset($_REQUEST['pn']))
|
57 |
$pn = intval($_REQUEST['pn']);
|
58 |
else
|
59 |
$pn = 1;
|
60 |
+
|
61 |
if(isset($_REQUEST['limit']))
|
62 |
$limit = intval($_REQUEST['limit']);
|
63 |
else
|
64 |
$limit = 15;
|
65 |
+
|
66 |
$end = $pn * $limit;
|
67 |
+
$start = $end - $limit;
|
68 |
+
|
69 |
if($s)
|
70 |
{
|
71 |
$sqlQuery = "SELECT SQL_CALC_FOUND_ROWS u.ID, u.user_login, u.user_email, UNIX_TIMESTAMP(u.user_registered) as joindate, mu.membership_id, mu.initial_payment, mu.billing_amount, mu.cycle_period, mu.cycle_number, mu.billing_limit, mu.trial_amount, mu.trial_limit, UNIX_TIMESTAMP(mu.startdate) as startdate, UNIX_TIMESTAMP(mu.enddate) as enddate, m.name as membership FROM $wpdb->users u LEFT JOIN $wpdb->usermeta um ON u.ID = um.user_id LEFT JOIN $wpdb->pmpro_memberships_users mu ON u.ID = mu.user_id LEFT JOIN $wpdb->pmpro_membership_levels m ON mu.membership_id = m.id ";
|
72 |
+
|
73 |
if($l == "oldmembers" || $l == "expired" || $l == "cancelled")
|
74 |
$sqlQuery .= " LEFT JOIN $wpdb->pmpro_memberships_users mu2 ON u.ID = mu2.user_id AND mu2.status = 'active' ";
|
75 |
+
|
76 |
+
$sqlQuery .= " WHERE mu.membership_id > 0 AND (u.user_login LIKE '%" . esc_sql($s) . "%' OR u.user_email LIKE '%" . esc_sql($s) . "%' OR um.meta_value LIKE '%" . esc_sql($s) . "%') ";
|
77 |
+
|
78 |
if($l == "oldmembers")
|
79 |
$sqlQuery .= " AND mu.status <> 'active' AND mu2.status IS NULL ";
|
80 |
elseif($l == "expired")
|
82 |
elseif($l == "cancelled")
|
83 |
$sqlQuery .= " AND mu.status IN('cancelled', 'admin_cancelled') AND mu2.status IS NULL ";
|
84 |
elseif($l)
|
85 |
+
$sqlQuery .= " AND mu.status = 'active' AND mu.membership_id = '" . esc_sql($l) . "' ";
|
86 |
else
|
87 |
+
$sqlQuery .= " AND mu.status = 'active' ";
|
88 |
+
|
89 |
$sqlQuery .= "GROUP BY u.ID ";
|
90 |
+
|
91 |
if($l == "oldmembers" || $l == "expired" || $l == "cancelled")
|
92 |
$sqlQuery .= "ORDER BY enddate DESC ";
|
93 |
else
|
94 |
$sqlQuery .= "ORDER BY u.user_registered DESC ";
|
95 |
+
|
96 |
$sqlQuery .= "LIMIT $start, $limit";
|
97 |
}
|
98 |
else
|
99 |
{
|
100 |
$sqlQuery = "SELECT SQL_CALC_FOUND_ROWS u.ID, u.user_login, u.user_email, UNIX_TIMESTAMP(u.user_registered) as joindate, mu.membership_id, mu.initial_payment, mu.billing_amount, mu.cycle_period, mu.cycle_number, mu.billing_limit, mu.trial_amount, mu.trial_limit, UNIX_TIMESTAMP(mu.startdate) as startdate, UNIX_TIMESTAMP(mu.enddate) as enddate, m.name as membership FROM $wpdb->users u LEFT JOIN $wpdb->pmpro_memberships_users mu ON u.ID = mu.user_id LEFT JOIN $wpdb->pmpro_membership_levels m ON mu.membership_id = m.id";
|
101 |
+
|
102 |
if($l == "oldmembers" || $l == "expired" || $l == "cancelled")
|
103 |
$sqlQuery .= " LEFT JOIN $wpdb->pmpro_memberships_users mu2 ON u.ID = mu2.user_id AND mu2.status = 'active' ";
|
104 |
+
|
105 |
$sqlQuery .= " WHERE mu.membership_id > 0 ";
|
106 |
+
|
107 |
if($l == "oldmembers")
|
108 |
$sqlQuery .= " AND mu.status <> 'active' AND mu2.status IS NULL ";
|
109 |
elseif($l == "expired")
|
115 |
else
|
116 |
$sqlQuery .= " AND mu.status = 'active' ";
|
117 |
$sqlQuery .= "GROUP BY u.ID ";
|
118 |
+
|
119 |
if($l == "oldmembers" || $l == "expired" || $l == "cancelled")
|
120 |
$sqlQuery .= "ORDER BY enddate DESC ";
|
121 |
else
|
122 |
$sqlQuery .= "ORDER BY u.user_registered DESC ";
|
123 |
+
|
124 |
$sqlQuery .= "LIMIT $start, $limit";
|
125 |
}
|
126 |
+
|
127 |
$sqlQuery = apply_filters("pmpro_members_list_sql", $sqlQuery);
|
128 |
+
|
129 |
$theusers = $wpdb->get_results($sqlQuery);
|
130 |
$totalrows = $wpdb->get_var("SELECT FOUND_ROWS() as found_rows");
|
131 |
+
|
132 |
if($theusers)
|
133 |
{
|
134 |
$calculate_revenue = apply_filters("pmpro_memberslist_calculate_revenue", false);
|
135 |
if($calculate_revenue)
|
136 |
{
|
137 |
$initial_payments = pmpro_calculateInitialPaymentRevenue($s, $l);
|
138 |
+
$recurring_payments = pmpro_calculateRecurringRevenue($s, $l);
|
139 |
?>
|
140 |
<p class="clear"><?php echo strval($totalrows)?> members found. These members have paid <strong>$<?php echo number_format($initial_payments)?> in initial payments</strong> and will generate an estimated <strong>$<?php echo number_format($recurring_payments)?> in revenue over the next year</strong>, or <strong>$<?php echo number_format($recurring_payments/12)?>/month</strong>. <span class="pmpro_lite">(This estimate does not take into account trial periods or billing limits.)</span></p>
|
141 |
<?php
|
143 |
else
|
144 |
{
|
145 |
?>
|
146 |
+
<p class="clear"><?php printf(__("%d members found.", "pmpro"), $totalrows);?></span></p>
|
147 |
<?php
|
148 |
}
|
149 |
+
}
|
150 |
?>
|
151 |
<table class="widefat">
|
152 |
<thead>
|
158 |
<th><?php _e('Email', 'pmpro');?></th>
|
159 |
<?php do_action("pmpro_memberslist_extra_cols_header", $theusers);?>
|
160 |
<th><?php _e('Billing Address', 'pmpro');?></th>
|
161 |
+
<th><?php _e('Membership', 'pmpro');?></th>
|
162 |
<th><?php _e('Fee', 'pmpro');?></th>
|
163 |
<th><?php _e('Joined', 'pmpro');?></th>
|
164 |
<th>
|
165 |
+
<?php
|
166 |
if($l == "oldmembers")
|
167 |
_e('Ended', 'pmpro');
|
168 |
else
|
171 |
</th>
|
172 |
</tr>
|
173 |
</thead>
|
174 |
+
<tbody id="users" class="list:user user-list">
|
175 |
+
<?php
|
176 |
+
$count = 0;
|
177 |
foreach($theusers as $auser)
|
178 |
{
|
179 |
+
//get meta
|
180 |
+
$theuser = get_userdata($auser->ID);
|
181 |
?>
|
182 |
<tr <?php if($count++ % 2 == 0) { ?>class="alternate"<?php } ?>>
|
183 |
<td><?php echo $theuser->ID?></td>
|
188 |
$userlink = '<a href="user-edit.php?user_id=' . $theuser->ID . '">' . $theuser->user_login . '</a>';
|
189 |
$userlink = apply_filters("pmpro_members_list_user_link", $userlink, $theuser);
|
190 |
echo $userlink;
|
191 |
+
?>
|
192 |
</strong>
|
193 |
+
<br />
|
194 |
<?php
|
195 |
+
// Set up the hover actions for this user
|
196 |
$actions = apply_filters( 'pmpro_memberslist_user_row_actions', array(), $theuser );
|
197 |
$action_count = count( $actions );
|
198 |
$i = 0;
|
207 |
$out .= '</div>';
|
208 |
echo $out;
|
209 |
}
|
210 |
+
?>
|
211 |
</td>
|
212 |
<td><?php echo $theuser->first_name?></td>
|
213 |
<td><?php echo $theuser->last_name?></td>
|
216 |
<td>
|
217 |
<?php
|
218 |
echo pmpro_formatAddress(trim($theuser->pmpro_bfirstname . " " . $theuser->pmpro_blastname), $theuser->pmpro_baddress1, $theuser->pmpro_baddress2, $theuser->pmpro_bcity, $theuser->pmpro_bstate, $theuser->pmpro_bzipcode, $theuser->pmpro_bcountry, $theuser->pmpro_bphone);
|
219 |
+
?>
|
220 |
</td>
|
221 |
+
<td><?php echo $auser->membership?></td>
|
222 |
+
<td>
|
223 |
<?php if((float)$auser->initial_payment > 0) { ?>
|
224 |
<?php echo pmpro_formatPrice($auser->initial_payment);?>
|
225 |
<?php } ?>
|
230 |
<?php if((float)$auser->initial_payment <= 0 && (float)$auser->billing_amount <= 0) { ?>
|
231 |
-
|
232 |
<?php } ?>
|
233 |
+
</td>
|
234 |
<td><?php echo date(get_option("date_format"), strtotime($theuser->user_registered, current_time("timestamp")))?></td>
|
235 |
<td>
|
236 |
+
<?php
|
237 |
+
if($auser->enddate)
|
238 |
echo apply_filters("pmpro_memberslist_expires_column", date(get_option('date_format'), $auser->enddate), $auser);
|
239 |
else
|
240 |
echo __(apply_filters("pmpro_memberslist_expires_column", "Never", $auser), "pmpro");
|
243 |
</tr>
|
244 |
<?php
|
245 |
}
|
246 |
+
|
247 |
if(!$theusers)
|
248 |
{
|
249 |
?>
|
252 |
</tr>
|
253 |
<?php
|
254 |
}
|
255 |
+
?>
|
256 |
</tbody>
|
257 |
</table>
|
258 |
</form>
|
259 |
+
|
260 |
<?php
|
261 |
echo pmpro_getPaginationString($pn, $totalrows, $limit, 1, get_admin_url(NULL, "/admin.php?page=pmpro-memberslist&s=" . urlencode($s)), "&l=$l&limit=$limit&pn=");
|
262 |
?>
|
263 |
+
|
264 |
<?php
|
265 |
+
require_once(dirname(__FILE__) . "/admin_footer.php");
|
266 |
?>
|
adminpages/orders-csv.php
CHANGED
@@ -1,106 +1,106 @@
|
|
1 |
-
<?php
|
2 |
//only admins can get this
|
3 |
if(!function_exists("current_user_can") || (!current_user_can("manage_options") && !current_user_can("pmpro_orderscsv")))
|
4 |
{
|
5 |
die(__("You do not have permissions to perform this action.", "pmpro"));
|
6 |
-
}
|
7 |
-
|
8 |
-
global $wpdb;
|
9 |
-
|
10 |
-
//get users
|
11 |
if(isset($_REQUEST['s']))
|
12 |
$s = $_REQUEST['s'];
|
13 |
else
|
14 |
$s = "";
|
15 |
-
|
16 |
if(isset($_REQUEST['l']))
|
17 |
$l = $_REQUEST['l'];
|
18 |
else
|
19 |
$l = false;
|
20 |
-
|
21 |
if(isset($_REQUEST['start-month']))
|
22 |
$start_month = $_REQUEST['start-month'];
|
23 |
else
|
24 |
$start_month = "1";
|
25 |
-
|
26 |
if(isset($_REQUEST['start-day']))
|
27 |
$start_day = $_REQUEST['start-day'];
|
28 |
else
|
29 |
$start_day = "1";
|
30 |
-
|
31 |
if(isset($_REQUEST['start-year']))
|
32 |
$start_year = $_REQUEST['start-year'];
|
33 |
else
|
34 |
$start_year = date("Y");
|
35 |
-
|
36 |
if(isset($_REQUEST['end-month']))
|
37 |
$end_month = $_REQUEST['end-month'];
|
38 |
else
|
39 |
$end_month = date("n");
|
40 |
-
|
41 |
if(isset($_REQUEST['end-day']))
|
42 |
$end_day = $_REQUEST['end-day'];
|
43 |
else
|
44 |
$end_day = date("j");
|
45 |
-
|
46 |
if(isset($_REQUEST['end-year']))
|
47 |
$end_year = $_REQUEST['end-year'];
|
48 |
else
|
49 |
-
$end_year = date("Y");
|
50 |
-
|
51 |
if(isset($_REQUEST['predefined-date']))
|
52 |
$predefined_date = $_REQUEST['predefined-date'];
|
53 |
else
|
54 |
-
$predefined_date = "This Month";
|
55 |
-
|
56 |
if(isset($_REQUEST['status']))
|
57 |
$status = $_REQUEST['status'];
|
58 |
else
|
59 |
$status = "";
|
60 |
-
|
61 |
if(isset($_REQUEST['filter']))
|
62 |
$filter = sanitize_text_field($_REQUEST['filter']);
|
63 |
else
|
64 |
-
$filter = "all";
|
65 |
-
|
66 |
//some vars for the search
|
67 |
if(!empty($_REQUEST['pn']))
|
68 |
$pn = intval($_REQUEST['pn']);
|
69 |
else
|
70 |
$pn = 1;
|
71 |
-
|
72 |
if(!empty($_REQUEST['limit']))
|
73 |
$limit = intval($_REQUEST['limit']);
|
74 |
else
|
75 |
$limit = false;
|
76 |
-
|
77 |
if($limit)
|
78 |
-
{
|
79 |
$end = $pn * $limit;
|
80 |
-
$start = $end - $limit;
|
81 |
}
|
82 |
else
|
83 |
{
|
84 |
$end = NULL;
|
85 |
$start = NULL;
|
86 |
}
|
87 |
-
|
88 |
//filters
|
89 |
if($filter == "all" || !$filter)
|
90 |
$condition = "1=1";
|
91 |
elseif($filter == "within-a-date-range")
|
92 |
-
{
|
93 |
$start_date = $start_year."-".$start_month."-".$start_day;
|
94 |
$end_date = $end_year."-".$end_month."-".$end_day;
|
95 |
-
|
96 |
//add times to dates
|
97 |
$start_date = $start_date . " 00:00:00";
|
98 |
$end_date = $end_date . " 23:59:59";
|
99 |
-
|
100 |
$condition = "timestamp BETWEEN '".$start_date."' AND '".$end_date."'";
|
101 |
}
|
102 |
elseif($filter == "predefined-date-range")
|
103 |
-
{
|
104 |
if($predefined_date == "Last Month")
|
105 |
{
|
106 |
$start_date = date("Y-m-d", strtotime("first day of last month", current_time("timestamp")));
|
@@ -117,76 +117,76 @@
|
|
117 |
$start_date = date("Y-m-d", strtotime("first day of January $year", current_time("timestamp")));
|
118 |
$end_date = date("Y-m-d", strtotime("last day of December $year", current_time("timestamp")));
|
119 |
}
|
120 |
-
|
121 |
elseif($predefined_date == "Last Year")
|
122 |
{
|
123 |
$year = date('Y') - 1;
|
124 |
$start_date = date("Y-m-d", strtotime("first day of January $year", current_time("timestamp")));
|
125 |
$end_date = date("Y-m-d", strtotime("last day of December $year", current_time("timestamp")));
|
126 |
}
|
127 |
-
|
128 |
//add times to dates
|
129 |
$start_date = $start_date . " 00:00:00";
|
130 |
$end_date = $end_date . " 23:59:59";
|
131 |
-
|
132 |
$condition = "timestamp BETWEEN '".esc_sql($start_date)."' AND '".esc_sql($end_date)."'";
|
133 |
-
}
|
134 |
elseif($filter == "within-a-level")
|
135 |
{
|
136 |
$condition = "membership_id = " . esc_sql($l);
|
137 |
-
}
|
138 |
elseif($filter == "within-a-status")
|
139 |
{
|
140 |
$condition = "status = '" . esc_sql($status) . "' ";
|
141 |
-
}
|
142 |
-
|
143 |
//string search
|
144 |
if($s)
|
145 |
{
|
146 |
$sqlQuery = "SELECT SQL_CALC_FOUND_ROWS o.id FROM $wpdb->pmpro_membership_orders o LEFT JOIN $wpdb->users u ON o.user_id = u.ID LEFT JOIN $wpdb->pmpro_membership_levels l ON o.membership_id = l.id ";
|
147 |
-
|
148 |
$join_with_usermeta = apply_filters("pmpro_orders_search_usermeta", false);
|
149 |
if($join_with_usermeta)
|
150 |
$sqlQuery .= "LEFT JOIN $wpdb->usermeta um ON o.user_id = um.user_id ";
|
151 |
-
|
152 |
$sqlQuery .= "WHERE (1=2 ";
|
153 |
-
|
154 |
$fields = array("o.id", "o.code", "o.billing_name", "o.billing_street", "o.billing_city", "o.billing_state", "o.billing_zip", "o.billing_phone", "o.payment_type", "o.cardtype", "o.accountnumber", "o.status", "o.gateway", "o.gateway_environment", "o.payment_transaction_id", "o.subscription_transaction_id", "u.user_login", "u.user_email", "u.display_name", "l.name");
|
155 |
-
|
156 |
if($join_with_usermeta)
|
157 |
$fields[] = "um.meta_value";
|
158 |
-
|
159 |
$fields = apply_filters("pmpro_orders_search_fields", $fields);
|
160 |
-
|
161 |
foreach($fields as $field)
|
162 |
$sqlQuery .= " OR " . $field . " LIKE '%" . esc_sql($s) . "%' ";
|
163 |
$sqlQuery .= ") ";
|
164 |
-
|
165 |
$sqlQuery .= "AND " . $condition . " ";
|
166 |
-
|
167 |
$sqlQuery .= "GROUP BY o.id ORDER BY o.id DESC, o.timestamp DESC ";
|
168 |
}
|
169 |
else
|
170 |
{
|
171 |
$sqlQuery = "SELECT SQL_CALC_FOUND_ROWS id FROM $wpdb->pmpro_membership_orders WHERE ".$condition." ORDER BY id DESC, timestamp DESC ";
|
172 |
}
|
173 |
-
|
174 |
if(!empty($start) && !empty($limit))
|
175 |
$sqlQuery .= "LIMIT $start, $limit";
|
176 |
-
|
177 |
-
$order_ids = $wpdb->get_col($sqlQuery);
|
178 |
-
|
179 |
//begin output
|
180 |
-
header("Content-type: text/csv");
|
181 |
-
|
182 |
$filename = "orders.csv";
|
183 |
/*
|
184 |
Insert logic here for building filename from $filter and other values.
|
185 |
*/
|
186 |
-
header("Content-Disposition: attachment; filename=$filename;");
|
187 |
-
|
188 |
$csvoutput = "id,user_id,user_login,first_name,last_name,user_email,billing_name,billing_street,billing_city,billing_state,billing_zip,billing_country,billing_phone,membership_id,level_name,subtotal,tax,couponamount,total,payment_type,cardtype,accountnumber,expirationmonth,expirationyear,status,gateway,gateway_environment,payment_transaction_id,subscription_transaction_id,discount_code_id,discount_code,timestamp";
|
189 |
-
|
190 |
//these are the meta_keys for the fields (arrays are object, property. so e.g. $theuser->ID)
|
191 |
$default_columns = array(
|
192 |
array("order", "id"),
|
@@ -205,7 +205,7 @@
|
|
205 |
array("order", "membership_id"),
|
206 |
array("level", "name"),
|
207 |
array("order", "subtotal"),
|
208 |
-
array("order", "tax"),
|
209 |
array("order", "couponamount"),
|
210 |
array("order", "total"),
|
211 |
array("order", "payment_type"),
|
@@ -221,7 +221,7 @@
|
|
221 |
array("discount_code", "id"),
|
222 |
array("discount_code", "code")
|
223 |
);
|
224 |
-
|
225 |
//any extra columns
|
226 |
$extra_columns = apply_filters("pmpro_orders_csv_extra_columns", array());
|
227 |
if(!empty($extra_columns))
|
@@ -231,13 +231,13 @@
|
|
231 |
$csvoutput .= "," . $heading;
|
232 |
}
|
233 |
}
|
234 |
-
|
235 |
-
$csvoutput .= "\n";
|
236 |
-
|
237 |
//output
|
238 |
echo $csvoutput;
|
239 |
$csvoutput = "";
|
240 |
-
|
241 |
if($order_ids)
|
242 |
{
|
243 |
foreach($order_ids as $order_id)
|
@@ -249,8 +249,8 @@
|
|
249 |
$level = $order->getMembershipLevel();
|
250 |
$sqlQuery = "SELECT c.id, c.code FROM $wpdb->pmpro_discount_codes_uses cu LEFT JOIN $wpdb->pmpro_discount_codes c ON cu.code_id = c.id WHERE cu.order_id = '" . $order_id . "' LIMIT 1";
|
251 |
$discount_code = $wpdb->get_row($sqlQuery);
|
252 |
-
|
253 |
-
//default columns
|
254 |
if(!empty($default_columns))
|
255 |
{
|
256 |
$count = 0;
|
@@ -260,19 +260,19 @@
|
|
260 |
$count++;
|
261 |
if($count > 1)
|
262 |
$csvoutput .= ",";
|
263 |
-
|
264 |
-
//checking $object->property. note the double $$
|
265 |
if(!empty($col[2]) && isset($$col[0]->$col[1]->$col[2]))
|
266 |
-
$csvoutput .= pmpro_enclose($$col[0]->$col[1]->$col[2]); //output the value
|
267 |
elseif(!empty($$col[0]->$col[1]))
|
268 |
-
$csvoutput .= pmpro_enclose($$col[0]->$col[1]); //output the value
|
269 |
}
|
270 |
}
|
271 |
-
|
272 |
//timestamp
|
273 |
$csvoutput .= "," . pmpro_enclose(date(get_option("date_format"), $order->timestamp));
|
274 |
-
|
275 |
-
//any extra columns
|
276 |
if(!empty($extra_columns))
|
277 |
{
|
278 |
foreach($extra_columns as $heading => $callback)
|
@@ -280,18 +280,18 @@
|
|
280 |
$csvoutput .= "," . pmpro_enclose(call_user_func($callback, $order));
|
281 |
}
|
282 |
}
|
283 |
-
|
284 |
$csvoutput .= "\n";
|
285 |
-
|
286 |
//output
|
287 |
echo $csvoutput;
|
288 |
-
$csvoutput = "";
|
289 |
}
|
290 |
-
}
|
291 |
-
|
292 |
print $csvoutput;
|
293 |
-
|
294 |
function pmpro_enclose($s)
|
295 |
-
{
|
296 |
return "\"" . str_replace("\"", "\\\"", $s) . "\"";
|
297 |
}
|
1 |
+
<?php
|
2 |
//only admins can get this
|
3 |
if(!function_exists("current_user_can") || (!current_user_can("manage_options") && !current_user_can("pmpro_orderscsv")))
|
4 |
{
|
5 |
die(__("You do not have permissions to perform this action.", "pmpro"));
|
6 |
+
}
|
7 |
+
|
8 |
+
global $wpdb;
|
9 |
+
|
10 |
+
//get users
|
11 |
if(isset($_REQUEST['s']))
|
12 |
$s = $_REQUEST['s'];
|
13 |
else
|
14 |
$s = "";
|
15 |
+
|
16 |
if(isset($_REQUEST['l']))
|
17 |
$l = $_REQUEST['l'];
|
18 |
else
|
19 |
$l = false;
|
20 |
+
|
21 |
if(isset($_REQUEST['start-month']))
|
22 |
$start_month = $_REQUEST['start-month'];
|
23 |
else
|
24 |
$start_month = "1";
|
25 |
+
|
26 |
if(isset($_REQUEST['start-day']))
|
27 |
$start_day = $_REQUEST['start-day'];
|
28 |
else
|
29 |
$start_day = "1";
|
30 |
+
|
31 |
if(isset($_REQUEST['start-year']))
|
32 |
$start_year = $_REQUEST['start-year'];
|
33 |
else
|
34 |
$start_year = date("Y");
|
35 |
+
|
36 |
if(isset($_REQUEST['end-month']))
|
37 |
$end_month = $_REQUEST['end-month'];
|
38 |
else
|
39 |
$end_month = date("n");
|
40 |
+
|
41 |
if(isset($_REQUEST['end-day']))
|
42 |
$end_day = $_REQUEST['end-day'];
|
43 |
else
|
44 |
$end_day = date("j");
|
45 |
+
|
46 |
if(isset($_REQUEST['end-year']))
|
47 |
$end_year = $_REQUEST['end-year'];
|
48 |
else
|
49 |
+
$end_year = date("Y");
|
50 |
+
|
51 |
if(isset($_REQUEST['predefined-date']))
|
52 |
$predefined_date = $_REQUEST['predefined-date'];
|
53 |
else
|
54 |
+
$predefined_date = "This Month";
|
55 |
+
|
56 |
if(isset($_REQUEST['status']))
|
57 |
$status = $_REQUEST['status'];
|
58 |
else
|
59 |
$status = "";
|
60 |
+
|
61 |
if(isset($_REQUEST['filter']))
|
62 |
$filter = sanitize_text_field($_REQUEST['filter']);
|
63 |
else
|
64 |
+
$filter = "all";
|
65 |
+
|
66 |
//some vars for the search
|
67 |
if(!empty($_REQUEST['pn']))
|
68 |
$pn = intval($_REQUEST['pn']);
|
69 |
else
|
70 |
$pn = 1;
|
71 |
+
|
72 |
if(!empty($_REQUEST['limit']))
|
73 |
$limit = intval($_REQUEST['limit']);
|
74 |
else
|
75 |
$limit = false;
|
76 |
+
|
77 |
if($limit)
|
78 |
+
{
|
79 |
$end = $pn * $limit;
|
80 |
+
$start = $end - $limit;
|
81 |
}
|
82 |
else
|
83 |
{
|
84 |
$end = NULL;
|
85 |
$start = NULL;
|
86 |
}
|
87 |
+
|
88 |
//filters
|
89 |
if($filter == "all" || !$filter)
|
90 |
$condition = "1=1";
|
91 |
elseif($filter == "within-a-date-range")
|
92 |
+
{
|
93 |
$start_date = $start_year."-".$start_month."-".$start_day;
|
94 |
$end_date = $end_year."-".$end_month."-".$end_day;
|
95 |
+
|
96 |
//add times to dates
|
97 |
$start_date = $start_date . " 00:00:00";
|
98 |
$end_date = $end_date . " 23:59:59";
|
99 |
+
|
100 |
$condition = "timestamp BETWEEN '".$start_date."' AND '".$end_date."'";
|
101 |
}
|
102 |
elseif($filter == "predefined-date-range")
|
103 |
+
{
|
104 |
if($predefined_date == "Last Month")
|
105 |
{
|
106 |
$start_date = date("Y-m-d", strtotime("first day of last month", current_time("timestamp")));
|
117 |
$start_date = date("Y-m-d", strtotime("first day of January $year", current_time("timestamp")));
|
118 |
$end_date = date("Y-m-d", strtotime("last day of December $year", current_time("timestamp")));
|
119 |
}
|
120 |
+
|
121 |
elseif($predefined_date == "Last Year")
|
122 |
{
|
123 |
$year = date('Y') - 1;
|
124 |
$start_date = date("Y-m-d", strtotime("first day of January $year", current_time("timestamp")));
|
125 |
$end_date = date("Y-m-d", strtotime("last day of December $year", current_time("timestamp")));
|
126 |
}
|
127 |
+
|
128 |
//add times to dates
|
129 |
$start_date = $start_date . " 00:00:00";
|
130 |
$end_date = $end_date . " 23:59:59";
|
131 |
+
|
132 |
$condition = "timestamp BETWEEN '".esc_sql($start_date)."' AND '".esc_sql($end_date)."'";
|
133 |
+
}
|
134 |
elseif($filter == "within-a-level")
|
135 |
{
|
136 |
$condition = "membership_id = " . esc_sql($l);
|
137 |
+
}
|
138 |
elseif($filter == "within-a-status")
|
139 |
{
|
140 |
$condition = "status = '" . esc_sql($status) . "' ";
|
141 |
+
}
|
142 |
+
|
143 |
//string search
|
144 |
if($s)
|
145 |
{
|
146 |
$sqlQuery = "SELECT SQL_CALC_FOUND_ROWS o.id FROM $wpdb->pmpro_membership_orders o LEFT JOIN $wpdb->users u ON o.user_id = u.ID LEFT JOIN $wpdb->pmpro_membership_levels l ON o.membership_id = l.id ";
|
147 |
+
|
148 |
$join_with_usermeta = apply_filters("pmpro_orders_search_usermeta", false);
|
149 |
if($join_with_usermeta)
|
150 |
$sqlQuery .= "LEFT JOIN $wpdb->usermeta um ON o.user_id = um.user_id ";
|
151 |
+
|
152 |
$sqlQuery .= "WHERE (1=2 ";
|
153 |
+
|
154 |
$fields = array("o.id", "o.code", "o.billing_name", "o.billing_street", "o.billing_city", "o.billing_state", "o.billing_zip", "o.billing_phone", "o.payment_type", "o.cardtype", "o.accountnumber", "o.status", "o.gateway", "o.gateway_environment", "o.payment_transaction_id", "o.subscription_transaction_id", "u.user_login", "u.user_email", "u.display_name", "l.name");
|
155 |
+
|
156 |
if($join_with_usermeta)
|
157 |
$fields[] = "um.meta_value";
|
158 |
+
|
159 |
$fields = apply_filters("pmpro_orders_search_fields", $fields);
|
160 |
+
|
161 |
foreach($fields as $field)
|
162 |
$sqlQuery .= " OR " . $field . " LIKE '%" . esc_sql($s) . "%' ";
|
163 |
$sqlQuery .= ") ";
|
164 |
+
|
165 |
$sqlQuery .= "AND " . $condition . " ";
|
166 |
+
|
167 |
$sqlQuery .= "GROUP BY o.id ORDER BY o.id DESC, o.timestamp DESC ";
|
168 |
}
|
169 |
else
|
170 |
{
|
171 |
$sqlQuery = "SELECT SQL_CALC_FOUND_ROWS id FROM $wpdb->pmpro_membership_orders WHERE ".$condition." ORDER BY id DESC, timestamp DESC ";
|
172 |
}
|
173 |
+
|
174 |
if(!empty($start) && !empty($limit))
|
175 |
$sqlQuery .= "LIMIT $start, $limit";
|
176 |
+
|
177 |
+
$order_ids = $wpdb->get_col($sqlQuery);
|
178 |
+
|
179 |
//begin output
|
180 |
+
header("Content-type: text/csv");
|
181 |
+
|
182 |
$filename = "orders.csv";
|
183 |
/*
|
184 |
Insert logic here for building filename from $filter and other values.
|
185 |
*/
|
186 |
+
header("Content-Disposition: attachment; filename=$filename;");
|
187 |
+
|
188 |
$csvoutput = "id,user_id,user_login,first_name,last_name,user_email,billing_name,billing_street,billing_city,billing_state,billing_zip,billing_country,billing_phone,membership_id,level_name,subtotal,tax,couponamount,total,payment_type,cardtype,accountnumber,expirationmonth,expirationyear,status,gateway,gateway_environment,payment_transaction_id,subscription_transaction_id,discount_code_id,discount_code,timestamp";
|
189 |
+
|
190 |
//these are the meta_keys for the fields (arrays are object, property. so e.g. $theuser->ID)
|
191 |
$default_columns = array(
|
192 |
array("order", "id"),
|
205 |
array("order", "membership_id"),
|
206 |
array("level", "name"),
|
207 |
array("order", "subtotal"),
|
208 |
+
array("order", "tax"),
|
209 |
array("order", "couponamount"),
|
210 |
array("order", "total"),
|
211 |
array("order", "payment_type"),
|
221 |
array("discount_code", "id"),
|
222 |
array("discount_code", "code")
|
223 |
);
|
224 |
+
|
225 |
//any extra columns
|
226 |
$extra_columns = apply_filters("pmpro_orders_csv_extra_columns", array());
|
227 |
if(!empty($extra_columns))
|
231 |
$csvoutput .= "," . $heading;
|
232 |
}
|
233 |
}
|
234 |
+
|
235 |
+
$csvoutput .= "\n";
|
236 |
+
|
237 |
//output
|
238 |
echo $csvoutput;
|
239 |
$csvoutput = "";
|
240 |
+
|
241 |
if($order_ids)
|
242 |
{
|
243 |
foreach($order_ids as $order_id)
|
249 |
$level = $order->getMembershipLevel();
|
250 |
$sqlQuery = "SELECT c.id, c.code FROM $wpdb->pmpro_discount_codes_uses cu LEFT JOIN $wpdb->pmpro_discount_codes c ON cu.code_id = c.id WHERE cu.order_id = '" . $order_id . "' LIMIT 1";
|
251 |
$discount_code = $wpdb->get_row($sqlQuery);
|
252 |
+
|
253 |
+
//default columns
|
254 |
if(!empty($default_columns))
|
255 |
{
|
256 |
$count = 0;
|
260 |
$count++;
|
261 |
if($count > 1)
|
262 |
$csvoutput .= ",";
|
263 |
+
|
264 |
+
//checking $object->property. note the double $$
|
265 |
if(!empty($col[2]) && isset($$col[0]->$col[1]->$col[2]))
|
266 |
+
$csvoutput .= pmpro_enclose($$col[0]->$col[1]->$col[2]); //output the value
|
267 |
elseif(!empty($$col[0]->$col[1]))
|
268 |
+
$csvoutput .= pmpro_enclose($$col[0]->$col[1]); //output the value
|
269 |
}
|
270 |
}
|
271 |
+
|
272 |
//timestamp
|
273 |
$csvoutput .= "," . pmpro_enclose(date(get_option("date_format"), $order->timestamp));
|
274 |
+
|
275 |
+
//any extra columns
|
276 |
if(!empty($extra_columns))
|
277 |
{
|
278 |
foreach($extra_columns as $heading => $callback)
|
280 |
$csvoutput .= "," . pmpro_enclose(call_user_func($callback, $order));
|
281 |
}
|
282 |
}
|
283 |
+
|
284 |
$csvoutput .= "\n";
|
285 |
+
|
286 |
//output
|
287 |
echo $csvoutput;
|
288 |
+
$csvoutput = "";
|
289 |
}
|
290 |
+
}
|
291 |
+
|
292 |
print $csvoutput;
|
293 |
+
|
294 |
function pmpro_enclose($s)
|
295 |
+
{
|
296 |
return "\"" . str_replace("\"", "\\\"", $s) . "\"";
|
297 |
}
|
adminpages/orders.php
CHANGED
@@ -932,9 +932,9 @@
|
|
932 |
<?php } else { ?>
|
933 |
[<?php _e('deleted', 'pmpro');?>]
|
934 |
<?php } ?>
|
935 |
-
<br />
|
936 |
<?php
|
937 |
-
// Set up the hover actions for this user
|
938 |
$actions = apply_filters( 'pmpro_orders_user_row_actions', array(), $order->user );
|
939 |
$action_count = count( $actions );
|
940 |
$i = 0;
|
932 |
<?php } else { ?>
|
933 |
[<?php _e('deleted', 'pmpro');?>]
|
934 |
<?php } ?>
|
935 |
+
<br />
|
936 |
<?php
|
937 |
+
// Set up the hover actions for this user
|
938 |
$actions = apply_filters( 'pmpro_orders_user_row_actions', array(), $order->user );
|
939 |
$action_count = count( $actions );
|
940 |
$i = 0;
|
adminpages/pagesettings.php
CHANGED
@@ -1,257 +1,260 @@
|
|
1 |
-
<?php
|
2 |
-
//only admins can get this
|
3 |
-
if(!function_exists("current_user_can") || (!current_user_can("manage_options") && !current_user_can("pmpro_pagesettings")))
|
4 |
-
{
|
5 |
-
die(__("You do not have permissions to perform this action.", "pmpro"));
|
6 |
-
}
|
7 |
-
|
8 |
-
global $wpdb, $msg, $msgt;
|
9 |
-
|
10 |
-
//get/set settings
|
11 |
-
global $pmpro_pages;
|
12 |
-
if(!empty($_REQUEST['savesettings']))
|
13 |
-
{
|
14 |
-
//page ids
|
15 |
-
pmpro_setOption("account_page_id");
|
16 |
-
pmpro_setOption("billing_page_id");
|
17 |
-
pmpro_setOption("cancel_page_id");
|
18 |
-
pmpro_setOption("checkout_page_id");
|
19 |
-
pmpro_setOption("confirmation_page_id");
|
20 |
-
pmpro_setOption("invoice_page_id");
|
21 |
-
pmpro_setOption("levels_page_id");
|
22 |
-
|
23 |
-
//update the pages array
|
24 |
-
$pmpro_pages["account"] = pmpro_getOption("account_page_id");
|
25 |
-
$pmpro_pages["billing"] = pmpro_getOption("billing_page_id");
|
26 |
-
$pmpro_pages["cancel"] = pmpro_getOption("cancel_page_id");
|
27 |
-
$pmpro_pages["checkout"] = pmpro_getOption("checkout_page_id");
|
28 |
-
$pmpro_pages["confirmation"] = pmpro_getOption("confirmation_page_id");
|
29 |
-
$pmpro_pages["invoice"] = pmpro_getOption("invoice_page_id");
|
30 |
-
$pmpro_pages["levels"] = pmpro_getOption("levels_page_id");
|
31 |
-
|
32 |
-
//assume success
|
33 |
-
$msg = true;
|
34 |
-
$msgt = "Your page settings have been updated.";
|
35 |
-
}
|
36 |
-
|
37 |
-
//are we generating pages?
|
38 |
-
if(!empty($_REQUEST['createpages']))
|
39 |
-
{
|
40 |
-
global $pmpro_pages;
|
41 |
-
|
42 |
-
$pages_created = array();
|
43 |
-
|
44 |
-
//check the pages array
|
45 |
-
foreach($pmpro_pages as $pmpro_page_name => $pmpro_page_id)
|
46 |
-
{
|
47 |
-
if(!$pmpro_page_id)
|
48 |
-
{
|
49 |
-
switch ($pmpro_page_name) {
|
50 |
-
case 'account':
|
51 |
-
$pmpro_page_title = __( 'Membership Account', 'pmpro' );
|
52 |
-
break;
|
53 |
-
case 'billing':
|
54 |
-
$pmpro_page_title = __( 'Membership Billing', 'pmpro' );
|
55 |
-
break;
|
56 |
-
case 'cancel':
|
57 |
-
$pmpro_page_title = __( 'Membership Cancel', 'pmpro' );
|
58 |
-
break;
|
59 |
-
case 'checkout':
|
60 |
-
$pmpro_page_title = __( 'Membership Checkout', 'pmpro' );
|
61 |
-
break;
|
62 |
-
case 'confirmation':
|
63 |
-
$pmpro_page_title = __( 'Membership Confirmation', 'pmpro' );
|
64 |
-
break;
|
65 |
-
case 'invoice':
|
66 |
-
$pmpro_page_title = __( 'Membership Invoice', 'pmpro' );
|
67 |
-
break;
|
68 |
-
case 'levels':
|
69 |
-
$pmpro_page_title = __( 'Membership Levels', 'pmpro' );
|
70 |
-
break;
|
71 |
-
|
72 |
-
default:
|
73 |
-
$pmpro_page_title = sprintf( __( 'Membership %s', 'Page title template', 'pmpro' ), ucwords($pmpro_page_name) );
|
74 |
-
break;
|
75 |
-
}
|
76 |
-
|
77 |
-
//no id set. create an array to store the page info
|
78 |
-
$insert = array(
|
79 |
-
'post_title' => $pmpro_page_title,
|
80 |
-
'post_status' => 'publish',
|
81 |
-
'post_type' => 'page',
|
82 |
-
'post_content' => '[pmpro_' . $pmpro_page_name . ']',
|
83 |
-
'comment_status' => 'closed',
|
84 |
-
'ping_status' => 'closed'
|
85 |
-
);
|
86 |
-
|
87 |
-
//make non-account pages a subpage of account
|
88 |
-
if($pmpro_page_name != "account")
|
89 |
-
{
|
90 |
-
$insert['post_parent'] = $pmpro_pages['account'];
|
91 |
-
}
|
92 |
-
|
93 |
-
//create the page
|
94 |
-
$pmpro_pages[$pmpro_page_name] = wp_insert_post( $insert );
|
95 |
-
|
96 |
-
//add besecure post option to pages that need it
|
97 |
-
/* these pages are handling this themselves in the preheader
|
98 |
-
if(in_array($pmpro_page_name, array("billing", "checkout")))
|
99 |
-
update_post_meta($pmpro_pages[$pmpro_page_name], "besecure", 1);
|
100 |
-
*/
|
101 |
-
|
102 |
-
//update the option too
|
103 |
-
pmpro_setOption($pmpro_page_name . "_page_id", $pmpro_pages[$pmpro_page_name]);
|
104 |
-
$pages_created[] = $pmpro_pages[$pmpro_page_name];
|
105 |
-
}
|
106 |
-
}
|
107 |
-
|
108 |
-
if(!empty($pages_created))
|
109 |
-
{
|
110 |
-
$msg = true;
|
111 |
-
$msgt = __("The following pages have been created for you", "pmpro") . ": " . implode(", ", $pages_created) . ".";
|
112 |
-
}
|
113 |
-
}
|
114 |
-
|
115 |
-
require_once(dirname(__FILE__) . "/admin_header.php");
|
116 |
-
?>
|
117 |
-
|
118 |
-
|
119 |
-
<form action="" method="post" enctype="multipart/form-data">
|
120 |
-
<h2><?php _e('Pages', 'pmpro');?></h2>
|
121 |
-
<?php
|
122 |
-
global $pmpro_pages_ready;
|
123 |
-
if($pmpro_pages_ready)
|
124 |
-
{
|
125 |
-
?>
|
126 |
-
<p><?php _e('Manage the WordPress pages assigned to each required Paid Memberships Pro page.', 'pmpro');?></p>
|
127 |
-
<?php
|
128 |
-
}
|
129 |
-
else
|
130 |
-
{
|
131 |
-
?>
|
132 |
-
<p><?php _e('Assign the WordPress pages for each required Paid Memberships Pro page or', 'pmpro');?> <a href="?page=pmpro-pagesettings&createpages=1"><?php _e('click here to let us generate them for you', 'pmpro');?></a>.</p>
|
133 |
-
<?php
|
134 |
-
}
|
135 |
-
?>
|
136 |
-
<table class="form-table">
|
137 |
-
<tbody>
|
138 |
-
<tr>
|
139 |
-
<th scope="row" valign="top">
|
140 |
-
<label for="account_page_id"><?php _e('Account Page', 'pmpro');?>:</label>
|
141 |
-
</th>
|
142 |
-
<td>
|
143 |
-
<?php
|
144 |
-
wp_dropdown_pages(array("name"=>"account_page_id", "show_option_none"=>"-- Choose One --", "selected"=>$pmpro_pages['account']));
|
145 |
-
?>
|
146 |
-
<?php
|
147 |
-
|
148 |
-
|
149 |
-
|
150 |
-
|
151 |
-
|
152 |
-
|
153 |
-
|
154 |
-
|
155 |
-
|
156 |
-
|
157 |
-
<
|
158 |
-
|
159 |
-
|
160 |
-
|
161 |
-
<?php
|
162 |
-
|
163 |
-
|
164 |
-
|
165 |
-
|
166 |
-
|
167 |
-
|
168 |
-
|
169 |
-
|
170 |
-
|
171 |
-
|
172 |
-
<
|
173 |
-
|
174 |
-
|
175 |
-
|
176 |
-
<?php
|
177 |
-
|
178 |
-
|
179 |
-
|
180 |
-
|
181 |
-
|
182 |
-
|
183 |
-
|
184 |
-
|
185 |
-
|
186 |
-
|
187 |
-
|
188 |
-
<
|
189 |
-
|
190 |
-
|
191 |
-
|
192 |
-
<?php
|
193 |
-
|
194 |
-
|
195 |
-
|
196 |
-
|
197 |
-
|
198 |
-
|
199 |
-
|
200 |
-
|
201 |
-
|
202 |
-
|
203 |
-
|
204 |
-
<
|
205 |
-
|
206 |
-
|
207 |
-
|
208 |
-
<?php
|
209 |
-
|
210 |
-
|
211 |
-
|
212 |
-
|
213 |
-
|
214 |
-
|
215 |
-
|
216 |
-
|
217 |
-
|
218 |
-
|
219 |
-
|
220 |
-
<
|
221 |
-
|
222 |
-
|
223 |
-
|
224 |
-
<?php
|
225 |
-
|
226 |
-
|
227 |
-
|
228 |
-
|
229 |
-
|
230 |
-
|
231 |
-
|
232 |
-
|
233 |
-
|
234 |
-
|
235 |
-
|
236 |
-
<
|
237 |
-
|
238 |
-
|
239 |
-
|
240 |
-
<?php
|
241 |
-
|
242 |
-
|
243 |
-
|
244 |
-
|
245 |
-
|
246 |
-
|
247 |
-
|
248 |
-
|
249 |
-
|
250 |
-
|
251 |
-
|
252 |
-
</
|
253 |
-
|
254 |
-
|
255 |
-
|
256 |
-
|
257 |
-
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
//only admins can get this
|
3 |
+
if(!function_exists("current_user_can") || (!current_user_can("manage_options") && !current_user_can("pmpro_pagesettings")))
|
4 |
+
{
|
5 |
+
die(__("You do not have permissions to perform this action.", "pmpro"));
|
6 |
+
}
|
7 |
+
|
8 |
+
global $wpdb, $msg, $msgt;
|
9 |
+
|
10 |
+
//get/set settings
|
11 |
+
global $pmpro_pages;
|
12 |
+
if(!empty($_REQUEST['savesettings']))
|
13 |
+
{
|
14 |
+
//page ids
|
15 |
+
pmpro_setOption("account_page_id");
|
16 |
+
pmpro_setOption("billing_page_id");
|
17 |
+
pmpro_setOption("cancel_page_id");
|
18 |
+
pmpro_setOption("checkout_page_id");
|
19 |
+
pmpro_setOption("confirmation_page_id");
|
20 |
+
pmpro_setOption("invoice_page_id");
|
21 |
+
pmpro_setOption("levels_page_id");
|
22 |
+
|
23 |
+
//update the pages array
|
24 |
+
$pmpro_pages["account"] = pmpro_getOption("account_page_id");
|
25 |
+
$pmpro_pages["billing"] = pmpro_getOption("billing_page_id");
|
26 |
+
$pmpro_pages["cancel"] = pmpro_getOption("cancel_page_id");
|
27 |
+
$pmpro_pages["checkout"] = pmpro_getOption("checkout_page_id");
|
28 |
+
$pmpro_pages["confirmation"] = pmpro_getOption("confirmation_page_id");
|
29 |
+
$pmpro_pages["invoice"] = pmpro_getOption("invoice_page_id");
|
30 |
+
$pmpro_pages["levels"] = pmpro_getOption("levels_page_id");
|
31 |
+
|
32 |
+
//assume success
|
33 |
+
$msg = true;
|
34 |
+
$msgt = "Your page settings have been updated.";
|
35 |
+
}
|
36 |
+
|
37 |
+
//are we generating pages?
|
38 |
+
if(!empty($_REQUEST['createpages']))
|
39 |
+
{
|
40 |
+
global $pmpro_pages;
|
41 |
+
|
42 |
+
$pages_created = array();
|
43 |
+
|
44 |
+
//check the pages array
|
45 |
+
foreach($pmpro_pages as $pmpro_page_name => $pmpro_page_id)
|
46 |
+
{
|
47 |
+
if(!$pmpro_page_id)
|
48 |
+
{
|
49 |
+
switch ($pmpro_page_name) {
|
50 |
+
case 'account':
|
51 |
+
$pmpro_page_title = __( 'Membership Account', 'pmpro' );
|
52 |
+
break;
|
53 |
+
case 'billing':
|
54 |
+
$pmpro_page_title = __( 'Membership Billing', 'pmpro' );
|
55 |
+
break;
|
56 |
+
case 'cancel':
|
57 |
+
$pmpro_page_title = __( 'Membership Cancel', 'pmpro' );
|
58 |
+
break;
|
59 |
+
case 'checkout':
|
60 |
+
$pmpro_page_title = __( 'Membership Checkout', 'pmpro' );
|
61 |
+
break;
|
62 |
+
case 'confirmation':
|
63 |
+
$pmpro_page_title = __( 'Membership Confirmation', 'pmpro' );
|
64 |
+
break;
|
65 |
+
case 'invoice':
|
66 |
+
$pmpro_page_title = __( 'Membership Invoice', 'pmpro' );
|
67 |
+
break;
|
68 |
+
case 'levels':
|
69 |
+
$pmpro_page_title = __( 'Membership Levels', 'pmpro' );
|
70 |
+
break;
|
71 |
+
|
72 |
+
default:
|
73 |
+
$pmpro_page_title = sprintf( __( 'Membership %s', 'Page title template', 'pmpro' ), ucwords($pmpro_page_name) );
|
74 |
+
break;
|
75 |
+
}
|
76 |
+
|
77 |
+
//no id set. create an array to store the page info
|
78 |
+
$insert = array(
|
79 |
+
'post_title' => $pmpro_page_title,
|
80 |
+
'post_status' => 'publish',
|
81 |
+
'post_type' => 'page',
|
82 |
+
'post_content' => '[pmpro_' . $pmpro_page_name . ']',
|
83 |
+
'comment_status' => 'closed',
|
84 |
+
'ping_status' => 'closed'
|
85 |
+
);
|
86 |
+
|
87 |
+
//make non-account pages a subpage of account
|
88 |
+
if($pmpro_page_name != "account")
|
89 |
+
{
|
90 |
+
$insert['post_parent'] = $pmpro_pages['account'];
|
91 |
+
}
|
92 |
+
|
93 |
+
//create the page
|
94 |
+
$pmpro_pages[$pmpro_page_name] = wp_insert_post( $insert );
|
95 |
+
|
96 |
+
//add besecure post option to pages that need it
|
97 |
+
/* these pages are handling this themselves in the preheader
|
98 |
+
if(in_array($pmpro_page_name, array("billing", "checkout")))
|
99 |
+
update_post_meta($pmpro_pages[$pmpro_page_name], "besecure", 1);
|
100 |
+
*/
|
101 |
+
|
102 |
+
//update the option too
|
103 |
+
pmpro_setOption($pmpro_page_name . "_page_id", $pmpro_pages[$pmpro_page_name]);
|
104 |
+
$pages_created[] = $pmpro_pages[$pmpro_page_name];
|
105 |
+
}
|
106 |
+
}
|
107 |
+
|
108 |
+
if(!empty($pages_created))
|
109 |
+
{
|
110 |
+
$msg = true;
|
111 |
+
$msgt = __("The following pages have been created for you", "pmpro") . ": " . implode(", ", $pages_created) . ".";
|
112 |
+
}
|
113 |
+
}
|
114 |
+
|
115 |
+
require_once(dirname(__FILE__) . "/admin_header.php");
|
116 |
+
?>
|
117 |
+
|
118 |
+
|
119 |
+
<form action="" method="post" enctype="multipart/form-data">
|
120 |
+
<h2><?php _e('Pages', 'pmpro');?></h2>
|
121 |
+
<?php
|
122 |
+
global $pmpro_pages_ready;
|
123 |
+
if($pmpro_pages_ready)
|
124 |
+
{
|
125 |
+
?>
|
126 |
+
<p><?php _e('Manage the WordPress pages assigned to each required Paid Memberships Pro page.', 'pmpro');?></p>
|
127 |
+
<?php
|
128 |
+
}
|
129 |
+
else
|
130 |
+
{
|
131 |
+
?>
|
132 |
+
<p><?php _e('Assign the WordPress pages for each required Paid Memberships Pro page or', 'pmpro');?> <a href="?page=pmpro-pagesettings&createpages=1"><?php _e('click here to let us generate them for you', 'pmpro');?></a>.</p>
|
133 |
+
<?php
|
134 |
+
}
|
135 |
+
?>
|
136 |
+
<table class="form-table">
|
137 |
+
<tbody>
|
138 |
+
<tr>
|
139 |
+
<th scope="row" valign="top">
|
140 |
+
<label for="account_page_id"><?php _e('Account Page', 'pmpro');?>:</label>
|
141 |
+
</th>
|
142 |
+
<td>
|
143 |
+
<?php
|
144 |
+
wp_dropdown_pages(array("name"=>"account_page_id", "show_option_none"=>"-- ".__( 'Choose One', 'pmpro' )." --", "selected"=>$pmpro_pages['account']));
|
145 |
+
?>
|
146 |
+
<?php
|
147 |
+
wp_dropdown_pages(array("name"=>"account_page_id", "show_option_none"=>"-- ".__( 'Choose One', 'pmpro' )." --", "selected"=>$pmpro_pages['account']));
|
148 |
+
?>
|
149 |
+
<?php if(!empty($pmpro_pages['account'])) { ?>
|
150 |
+
<a target="_blank" href="post.php?post=<?php echo $pmpro_pages['account'];?>&action=edit" class="button button-secondary pmpro_page_edit"><?php _e('edit page', 'pmpro');?></a>
|
151 |
+
|
152 |
+
<a target="_blank" href="<?php echo get_permalink($pmpro_pages['account']);?>" class="button button-secondary pmpro_page_view"><?php _e('view page', 'pmpro');?></a>
|
153 |
+
<?php } ?>
|
154 |
+
<br /><small class="pmpro_lite"><?php _e('Include the shortcode', 'pmpro');?> [pmpro_account].</small>
|
155 |
+
</td>
|
156 |
+
<tr>
|
157 |
+
<th scope="row" valign="top">
|
158 |
+
<label for="billing_page_id"><?php _e('Billing Information Page', 'pmpro');?>:</label>
|
159 |
+
</th>
|
160 |
+
<td>
|
161 |
+
<?php
|
162 |
+
wp_dropdown_pages(array("name"=>"billing_page_id", "show_option_none"=>"-- ".__( 'Choose One', 'pmpro' )." --", "selected"=>$pmpro_pages['billing']));
|
163 |
+
?>
|
164 |
+
<?php if(!empty($pmpro_pages['billing'])) { ?>
|
165 |
+
<a target="_blank" href="post.php?post=<?php echo $pmpro_pages['billing']?>&action=edit" class="button button-secondary pmpro_page_edit"><?php _e('edit page', 'pmpro');?></a>
|
166 |
+
|
167 |
+
<a target="_blank" href="<?php echo get_permalink($pmpro_pages['billing']);?>" class="button button-secondary pmpro_page_view"><?php _e('view page', 'pmpro');?></a>
|
168 |
+
<?php } ?>
|
169 |
+
<br /><small class="pmpro_lite"><?php _e('Include the shortcode', 'pmpro');?> [pmpro_billing].</small>
|
170 |
+
</td>
|
171 |
+
<tr>
|
172 |
+
<th scope="row" valign="top">
|
173 |
+
<label for="cancel_page_id"><?php _e('Cancel Page', 'pmpro');?>:</label>
|
174 |
+
</th>
|
175 |
+
<td>
|
176 |
+
<?php
|
177 |
+
wp_dropdown_pages(array("name"=>"cancel_page_id", "show_option_none"=>"-- ".__( 'Choose One', 'pmpro' )." --", "selected"=>$pmpro_pages['cancel']));
|
178 |
+
?>
|
179 |
+
<?php if(!empty($pmpro_pages['cancel'])) { ?>
|
180 |
+
<a target="_blank" href="post.php?post=<?php echo $pmpro_pages['cancel']?>&action=edit" class="button button-secondary pmpro_page_edit"><?php _e('edit page', 'pmpro');?></a>
|
181 |
+
|
182 |
+
<a target="_blank" href="<?php echo get_permalink($pmpro_pages['cancel']);?>" class="button button-secondary pmpro_page_view"><?php _e('view page', 'pmpro');?></a>
|
183 |
+
<?php } ?>
|
184 |
+
<br /><small class="pmpro_lite"><?php _e('Include the shortcode', 'pmpro');?> [pmpro_cancel].</small>
|
185 |
+
</td>
|
186 |
+
</tr>
|
187 |
+
<tr>
|
188 |
+
<th scope="row" valign="top">
|
189 |
+
<label for="checkout_page_id"><?php _e('Checkout Page', 'pmpro');?>:</label>
|
190 |
+
</th>
|
191 |
+
<td>
|
192 |
+
<?php
|
193 |
+
wp_dropdown_pages(array("name"=>"checkout_page_id", "show_option_none"=>"-- ".__( 'Choose One', 'pmpro' )." --", "selected"=>$pmpro_pages['checkout']));
|
194 |
+
?>
|
195 |
+
<?php if(!empty($pmpro_pages['checkout'])) { ?>
|
196 |
+
<a target="_blank" href="post.php?post=<?php echo $pmpro_pages['checkout']?>&action=edit" class="button button-secondary pmpro_page_edit"><?php _e('edit page', 'pmpro');?></a>
|
197 |
+
|
198 |
+
<a target="_blank" href="<?php echo get_permalink($pmpro_pages['checkout']);?>" class="button button-secondary pmpro_page_view"><?php _e('view page', 'pmpro');?></a>
|
199 |
+
<?php } ?>
|
200 |
+
<br /><small class="pmpro_lite"><?php _e('Include the shortcode', 'pmpro');?> [pmpro_checkout].</small>
|
201 |
+
</td>
|
202 |
+
</tr>
|
203 |
+
<tr>
|
204 |
+
<th scope="row" valign="top">
|
205 |
+
<label for="confirmation_page_id"><?php _e('Confirmation Page', 'pmpro');?>:</label>
|
206 |
+
</th>
|
207 |
+
<td>
|
208 |
+
<?php
|
209 |
+
wp_dropdown_pages(array("name"=>"confirmation_page_id", "show_option_none"=>"-- ".__( 'Choose One', 'pmpro' )." --", "selected"=>$pmpro_pages['confirmation']));
|
210 |
+
?>
|
211 |
+
<?php if(!empty($pmpro_pages['confirmation'])) { ?>
|
212 |
+
<a target="_blank" href="post.php?post=<?php echo $pmpro_pages['confirmation']?>&action=edit" class="button button-secondary pmpro_page_edit"><?php _e('edit page', 'pmpro');?></a>
|
213 |
+
|
214 |
+
<a target="_blank" href="<?php echo get_permalink($pmpro_pages['confirmation']);?>" class="button button-secondary pmpro_page_view"><?php _e('view page', 'pmpro');?></a>
|
215 |
+
<?php } ?>
|
216 |
+
<br /><small class="pmpro_lite"><?php _e('Include the shortcode', 'pmpro');?> [pmpro_confirmation].</small>
|
217 |
+
</td>
|
218 |
+
</tr>
|
219 |
+
<tr>
|
220 |
+
<th scope="row" valign="top">
|
221 |
+
<label for="invoice_page_id"><?php _e('Invoice Page', 'pmpro');?>:</label>
|
222 |
+
</th>
|
223 |
+
<td>
|
224 |
+
<?php
|
225 |
+
wp_dropdown_pages(array("name"=>"invoice_page_id", "show_option_none"=>"-- ".__( 'Choose One', 'pmpro' )." --", "selected"=>$pmpro_pages['invoice']));
|
226 |
+
?>
|
227 |
+
<?php if(!empty($pmpro_pages['invoice'])) { ?>
|
228 |
+
<a target="_blank" href="post.php?post=<?php echo $pmpro_pages['invoice']?>&action=edit" class="button button-secondary pmpro_page_edit"><?php _e('edit page', 'pmpro');?></a>
|
229 |
+
|
230 |
+
<a target="_blank" href="<?php echo get_permalink($pmpro_pages['invoice']);?>" class="button button-secondary pmpro_page_view"><?php _e('view page', 'pmpro');?></a>
|
231 |
+
<?php } ?>
|
232 |
+
<br /><small class="pmpro_lite"><?php _e('Include the shortcode', 'pmpro');?> [pmpro_invoice].</small>
|
233 |
+
</td>
|
234 |
+
</tr>
|
235 |
+
<tr>
|
236 |
+
<th scope="row" valign="top">
|
237 |
+
<label for="levels_page_id"><?php _e('Levels Page', 'pmpro');?>:</label>
|
238 |
+
</th>
|
239 |
+
<td>
|
240 |
+
<?php
|
241 |
+
wp_dropdown_pages(array("name"=>"levels_page_id", "show_option_none"=>"-- ".__( 'Choose One', 'pmpro' )." --", "selected"=>$pmpro_pages['levels']));
|
242 |
+
?>
|
243 |
+
<?php if(!empty($pmpro_pages['levels'])) { ?>
|
244 |
+
<a target="_blank" href="post.php?post=<?php echo $pmpro_pages['levels']?>&action=edit" class="button button-secondary pmpro_page_edit"><?php _e('edit page', 'pmpro');?></a>
|
245 |
+
|
246 |
+
<a target="_blank" href="<?php echo get_permalink($pmpro_pages['levels']);?>" class="button button-secondary pmpro_page_view"><?php _e('view page', 'pmpro');?></a>
|
247 |
+
<?php } ?>
|
248 |
+
<br /><small class="pmpro_lite"><?php _e('Include the shortcode', 'pmpro');?> [pmpro_levels].</small>
|
249 |
+
</td>
|
250 |
+
</tr>
|
251 |
+
</tbody>
|
252 |
+
</table>
|
253 |
+
<p class="submit">
|
254 |
+
<input name="savesettings" type="submit" class="button button-primary" value="<?php _e('Save Settings', 'pmpro');?>" />
|
255 |
+
</p>
|
256 |
+
</form>
|
257 |
+
|
258 |
+
<?php
|
259 |
+
require_once(dirname(__FILE__) . "/admin_footer.php");
|
260 |
+
?>
|
adminpages/paymentsettings.php
CHANGED
@@ -1,244 +1,244 @@
|
|
1 |
-
<?php
|
2 |
-
//only admins can get this
|
3 |
-
if(!function_exists("current_user_can") || (!current_user_can("manage_options") && !current_user_can("pmpro_paymentsettings")))
|
4 |
-
{
|
5 |
-
die(__("You do not have permissions to perform this action.", "pmpro"));
|
6 |
-
}
|
7 |
-
|
8 |
-
global $wpdb, $pmpro_currency_symbol, $msg, $msgt;
|
9 |
-
|
10 |
-
/*
|
11 |
-
Since 2.0, we let each gateway define what options they have in the class files
|
12 |
-
*/
|
13 |
-
//define options
|
14 |
-
$payment_options = array_unique(apply_filters("pmpro_payment_options", array('gateway')));
|
15 |
-
|
16 |
-
//get/set settings
|
17 |
-
if(!empty($_REQUEST['savesettings']))
|
18 |
-
{
|
19 |
-
/*
|
20 |
-
Save any value that might have been passed in
|
21 |
-
*/
|
22 |
-
foreach($payment_options as $option)
|
23 |
-
pmpro_setOption($option);
|
24 |
-
|
25 |
-
/*
|
26 |
-
Some special case options still worked out here
|
27 |
-
*/
|
28 |
-
//credit cards
|
29 |
-
$pmpro_accepted_credit_cards = array();
|
30 |
-
if(!empty($_REQUEST['creditcards_visa']))
|
31 |
-
$pmpro_accepted_credit_cards[] = "Visa";
|
32 |
-
if(!empty($_REQUEST['creditcards_mastercard']))
|
33 |
-
$pmpro_accepted_credit_cards[] = "Mastercard";
|
34 |
-
if(!empty($_REQUEST['creditcards_amex']))
|
35 |
-
$pmpro_accepted_credit_cards[] = "American Express";
|
36 |
-
if(!empty($_REQUEST['creditcards_discover']))
|
37 |
-
$pmpro_accepted_credit_cards[] = "Discover";
|
38 |
-
if(!empty($_REQUEST['creditcards_dinersclub']))
|
39 |
-
$pmpro_accepted_credit_cards[] = "Diners Club";
|
40 |
-
if(!empty($_REQUEST['creditcards_enroute']))
|
41 |
-
$pmpro_accepted_credit_cards[] = "EnRoute";
|
42 |
-
if(!empty($_REQUEST['creditcards_jcb']))
|
43 |
-
$pmpro_accepted_credit_cards[] = "JCB";
|
44 |
-
|
45 |
-
pmpro_setOption("accepted_credit_cards", implode(",", $pmpro_accepted_credit_cards));
|
46 |
-
|
47 |
-
//assume success
|
48 |
-
$msg = true;
|
49 |
-
$msgt = __("Your payment settings have been updated.", "pmpro");
|
50 |
-
}
|
51 |
-
|
52 |
-
/*
|
53 |
-
Extract values for use later
|
54 |
-
*/
|
55 |
-
$payment_option_values = array();
|
56 |
-
foreach($payment_options as $option)
|
57 |
-
$payment_option_values[$option] = pmpro_getOption($option);
|
58 |
-
extract($payment_option_values);
|
59 |
-
|
60 |
-
/*
|
61 |
-
Some special cases that get worked out here.
|
62 |
-
*/
|
63 |
-
//make sure the tax rate is not > 1
|
64 |
-
$tax_state = pmpro_getOption("tax_state");
|
65 |
-
$tax_rate = pmpro_getOption("tax_rate");
|
66 |
-
if((double)$tax_rate > 1)
|
67 |
-
{
|
68 |
-
//assume the entered X%
|
69 |
-
$tax_rate = $tax_rate / 100;
|
70 |
-
pmpro_setOption("tax_rate", $tax_rate);
|
71 |
-
}
|
72 |
-
|
73 |
-
//accepted credit cards
|
74 |
-
$pmpro_accepted_credit_cards = $payment_option_values['accepted_credit_cards']; //this var has the pmpro_ prefix
|
75 |
-
|
76 |
-
//default settings
|
77 |
-
if(empty($gateway_environment))
|
78 |
-
{
|
79 |
-
$gateway_environment = "sandbox";
|
80 |
-
pmpro_setOption("gateway_environment", $gateway_environment);
|
81 |
-
}
|
82 |
-
if(empty($pmpro_accepted_credit_cards))
|
83 |
-
{
|
84 |
-
$pmpro_accepted_credit_cards = "Visa,Mastercard,American Express,Discover";
|
85 |
-
pmpro_setOption("accepted_credit_cards", $pmpro_accepted_credit_cards);
|
86 |
-
}
|
87 |
-
$pmpro_accepted_credit_cards = explode(",", $pmpro_accepted_credit_cards);
|
88 |
-
|
89 |
-
require_once(dirname(__FILE__) . "/admin_header.php");
|
90 |
-
?>
|
91 |
-
|
92 |
-
<form action="" method="post" enctype="multipart/form-data">
|
93 |
-
<h2><?php _e('Payment Gateway', 'pmpro');?> & <?php _e('SSL Settings', 'pmpro');?></h2>
|
94 |
-
|
95 |
-
<p><?php _e('Learn more about <a title="Paid Memberships Pro - SSL Settings" target="_blank" href="http://www.paidmembershipspro.com/support/initial-plugin-setup/ssl/">SSL</a> or <a title="Paid Memberships Pro - Payment Gateway Settings" target="_blank" href="http://www.paidmembershipspro.com/support/initial-plugin-setup/payment-gateway/">Payment Gateway Settings</a>.', 'pmpro'); ?></p>
|
96 |
-
|
97 |
-
<table class="form-table">
|
98 |
-
<tbody>
|
99 |
-
<tr class="pmpro_settings_divider">
|
100 |
-
<td colspan="2">
|
101 |
-
Choose a Gateway
|
102 |
-
</td>
|
103 |
-
</tr>
|
104 |
-
<tr>
|
105 |
-
<th scope="row" valign="top">
|
106 |
-
<label for="gateway"><?php _e('Payment Gateway', 'pmpro');?>:</label>
|
107 |
-
</th>
|
108 |
-
<td>
|
109 |
-
<select id="gateway" name="gateway" onchange="pmpro_changeGateway(jQuery(this).val());">
|
110 |
-
<?php
|
111 |
-
$pmpro_gateways = pmpro_gateways();
|
112 |
-
foreach($pmpro_gateways as $pmpro_gateway_name => $pmpro_gateway_label)
|
113 |
-
{
|
114 |
-
?>
|
115 |
-
<option value="<?php echo esc_attr($pmpro_gateway_name);?>" <?php selected($gateway, $pmpro_gateway_name);?>><?php echo $pmpro_gateway_label;?></option>
|
116 |
-
<?php
|
117 |
-
}
|
118 |
-
?>
|
119 |
-
</select>
|
120 |
-
</td>
|
121 |
-
</tr>
|
122 |
-
<tr>
|
123 |
-
<th scope="row" valign="top">
|
124 |
-
<label for="gateway_environment"><?php _e('Gateway Environment', 'pmpro');?>:</label>
|
125 |
-
</th>
|
126 |
-
<td>
|
127 |
-
<select name="gateway_environment">
|
128 |
-
<option value="sandbox" <?php selected( $gateway_environment, "sandbox" ); ?>><?php _e('Sandbox/Testing', 'pmpro');?></option>
|
129 |
-
<option value="live" <?php selected( $gateway_environment, "live" ); ?>><?php _e('Live/Production', 'pmpro');?></option>
|
130 |
-
</select>
|
131 |
-
<script>
|
132 |
-
function pmpro_changeGateway(gateway)
|
133 |
-
{
|
134 |
-
//hide all gateway options
|
135 |
-
jQuery('tr.gateway').hide();
|
136 |
-
jQuery('tr.gateway_'+gateway).show();
|
137 |
-
}
|
138 |
-
pmpro_changeGateway(jQuery('#gateway').val());
|
139 |
-
</script>
|
140 |
-
</td>
|
141 |
-
</tr>
|
142 |
-
|
143 |
-
<?php /* Gateway Specific Settings */ ?>
|
144 |
-
<?php do_action('pmpro_payment_option_fields', $payment_option_values, $gateway); ?>
|
145 |
-
|
146 |
-
<tr class="pmpro_settings_divider">
|
147 |
-
<td colspan="2">
|
148 |
-
Currency and Tax Settings
|
149 |
-
</td>
|
150 |
-
</tr>
|
151 |
-
<tr class="gateway gateway_ <?php echo esc_attr(pmpro_getClassesForPaymentSettingsField("currency"));?>" <?php if(!empty($gateway) && $gateway != "paypal" && $gateway != "paypalexpress" && $gateway != "paypalstandard" && $gateway != "braintree" && $gateway != "twocheckout" && $gateway != "cybersource" && $gateway != "payflowpro" && $gateway != "stripe" && $gateway != "authorizenet") { ?>style="display: none;"<?php } ?>>
|
152 |
-
<th scope="row" valign="top">
|
153 |
-
<label for="currency"><?php _e('Currency', 'pmpro');?>:</label>
|
154 |
-
</th>
|
155 |
-
<td>
|
156 |
-
<select name="currency">
|
157 |
-
<?php
|
158 |
-
global $pmpro_currencies;
|
159 |
-
foreach($pmpro_currencies as $ccode => $cdescription)
|
160 |
-
{
|
161 |
-
if(is_array($cdescription))
|
162 |
-
$cdescription = $cdescription['name'];
|
163 |
-
?>
|
164 |
-
<option value="<?php echo $ccode?>" <?php if($currency == $ccode) { ?>selected="selected"<?php } ?>><?php echo $cdescription?></option>
|
165 |
-
<?php
|
166 |
-
}
|
167 |
-
?>
|
168 |
-
</select>
|
169 |
-
<small><?php _e( 'Not all currencies will be supported by every gateway. Please check with your gateway.', 'pmpro' ); ?></small>
|
170 |
-
</td>
|
171 |
-
</tr>
|
172 |
-
<tr class="gateway gateway_ <?php echo esc_attr(pmpro_getClassesForPaymentSettingsField("accepted_credit_cards"));?>" <?php if(!empty($gateway) && $gateway != "authorizenet" && $gateway != "paypal" && $gateway != "stripe" && $gateway != "payflowpro" && $gateway != "braintree" && $gateway != "twocheckout" && $gateway != "cybersource") { ?>style="display: none;"<?php } ?>>
|
173 |
-
<th scope="row" valign="top">
|
174 |
-
<label for="creditcards"><?php _e('Accepted Credit Card Types', 'pmpro');?></label>
|
175 |
-
</th>
|
176 |
-
<td>
|
177 |
-
<input type="checkbox" id="creditcards_visa" name="creditcards_visa" value="1" <?php if(in_array("Visa", $pmpro_accepted_credit_cards)) { ?>checked="checked"<?php } ?> /> <label for="creditcards_visa">Visa</label><br />
|
178 |
-
<input type="checkbox" id="creditcards_mastercard" name="creditcards_mastercard" value="1" <?php if(in_array("Mastercard", $pmpro_accepted_credit_cards)) { ?>checked="checked"<?php } ?> /> <label for="creditcards_mastercard">Mastercard</label><br />
|
179 |
-
<input type="checkbox" id="creditcards_amex" name="creditcards_amex" value="1" <?php if(in_array("American Express", $pmpro_accepted_credit_cards)) { ?>checked="checked"<?php } ?> /> <label for="creditcards_amex">American Express</label><br />
|
180 |
-
<input type="checkbox" id="creditcards_discover" name="creditcards_discover" value="1" <?php if(in_array("Discover", $pmpro_accepted_credit_cards)) { ?>checked="checked"<?php } ?> /> <label for="creditcards_discover">Discover</label><br />
|
181 |
-
<input type="checkbox" id="creditcards_dinersclub" name="creditcards_dinersclub" value="1" <?php if(in_array("Diners Club", $pmpro_accepted_credit_cards)) {?>checked="checked"<?php } ?> /> <label for="creditcards_dinersclub">Diner's Club</label><br />
|
182 |
-
<input type="checkbox" id="creditcards_enroute" name="creditcards_enroute" value="1" <?php if(in_array("EnRoute", $pmpro_accepted_credit_cards)) {?>checked="checked"<?php } ?> /> <label for="creditcards_enroute">EnRoute</label><br />
|
183 |
-
<input type="checkbox" id="creditcards_jcb" name="creditcards_jcb" value="1" <?php if(in_array("JCB", $pmpro_accepted_credit_cards)) {?>checked="checked"<?php } ?> /> <label for="creditcards_jcb">JCB</label><br />
|
184 |
-
</td>
|
185 |
-
</tr>
|
186 |
-
<tr class="gateway gateway_ <?php echo esc_attr(pmpro_getClassesForPaymentSettingsField("tax_rate"));?>" <?php if(!empty($gateway) && $gateway != "stripe" && $gateway != "authorizenet" && $gateway != "paypal" && $gateway != "paypalexpress" && $gateway != "check" && $gateway != "paypalstandard" && $gateway != "payflowpro" && $gateway != "braintree" && $gateway != "twocheckout" && $gateway != "cybersource") { ?>style="display: none;"<?php } ?>>
|
187 |
-
<th scope="row" valign="top">
|
188 |
-
<label for="tax"><?php _e('Sales Tax', 'pmpro');?> <small>(<?php _e('optional', 'pmpro');?>)</small></label>
|
189 |
-
</th>
|
190 |
-
<td>
|
191 |
-
<?php _e('Tax State', 'pmpro');?>:
|
192 |
-
<input type="text" id="tax_state" name="tax_state" size="4" value="<?php echo esc_attr($tax_state)?>" /> <small>(<?php _e('abbreviation, e.g. "PA"', 'pmpro');?>)</small>
|
193 |
-
Tax Rate:
|
194 |
-
<input type="text" id="tax_rate" name="tax_rate" size="10" value="<?php echo esc_attr($tax_rate)?>" /> <small>(<?php _e('decimal, e.g. "0.06"', 'pmpro');?>)</small>
|
195 |
-
<p><small><?php _e('US only. If values are given, tax will be applied for any members ordering from the selected state.<br />For non-US or more complex tax rules, use the <a target="_blank" href="http://www.paidmembershipspro.com/2013/10/non-us-taxes-paid-memberships-pro/">pmpro_tax filter</a>.', 'pmpro');?></small></p>
|
196 |
-
</td>
|
197 |
-
</tr>
|
198 |
-
|
199 |
-
<tr class="pmpro_settings_divider">
|
200 |
-
<td colspan="2">
|
201 |
-
SSL Settings
|
202 |
-
</td>
|
203 |
-
</tr>
|
204 |
-
<tr class="gateway gateway_ <?php echo esc_attr(pmpro_getClassesForPaymentSettingsField("use_ssl"));?>">
|
205 |
-
<th scope="row" valign="top">
|
206 |
-
<label for="use_ssl"><?php _e('Force SSL', 'pmpro');?>:</label>
|
207 |
-
</th>
|
208 |
-
<td>
|
209 |
-
<select id="use_ssl" name="use_ssl">
|
210 |
-
<option value="0" <?php if(empty($use_ssl)) { ?>selected="selected"<?php } ?>><?php _e('No', 'pmpro');?></option>
|
211 |
-
<option value="1" <?php if(!empty($use_ssl) && $use_ssl == 1) { ?>selected="selected"<?php } ?>><?php _e('Yes', 'pmpro');?></option>
|
212 |
-
<option value="2" <?php if(!empty($use_ssl) && $use_ssl == 2) { ?>selected="selected"<?php } ?>><?php _e('Yes (with JavaScript redirects)', 'pmpro');?></option>
|
213 |
-
</select>
|
214 |
-
<small>Recommended: Yes. Try the JavaScript redirects setting if you are having issues with infinite redirect loops.</small>
|
215 |
-
</td>
|
216 |
-
</tr>
|
217 |
-
<tr>
|
218 |
-
<th scope="row" valign="top">
|
219 |
-
<label for="sslseal"><?php _e('SSL Seal Code', 'pmpro');?>:</label>
|
220 |
-
</th>
|
221 |
-
<td>
|
222 |
-
<textarea id="sslseal" name="sslseal" rows="3" cols="80"><?php echo stripslashes(esc_textarea($sslseal))?></textarea>
|
223 |
-
<br /><small>Your <strong><a target="_blank" href="http://www.paidmembershipspro.com/documentation/initial-plugin-setup/ssl/">SSL Certificate</a></strong> must be installed by your web host. Your <strong>SSL Seal</strong> will be a short HTML or JavaScript snippet that can be pasted here.</small>
|
224 |
-
</td>
|
225 |
-
</tr>
|
226 |
-
<tr>
|
227 |
-
<th scope="row" valign="top">
|
228 |
-
<label for="nuclear_HTTPS"><?php _e('Extra HTTPS URL Filter', 'pmpro');?>:</label>
|
229 |
-
</th>
|
230 |
-
<td>
|
231 |
-
<input type="checkbox" id="nuclear_HTTPS" name="nuclear_HTTPS" value="1" <?php if(!empty($nuclear_HTTPS)) { ?>checked="checked"<?php } ?> /> <label for="nuclear_HTTPS"><?php _e('Pass all generated HTML through a URL filter to add HTTPS to URLs used on secure pages. Check this if you are using SSL and have warnings on your checkout pages.', 'pmpro');?></label>
|
232 |
-
</td>
|
233 |
-
</tr>
|
234 |
-
|
235 |
-
</tbody>
|
236 |
-
</table>
|
237 |
-
<p class="submit">
|
238 |
-
<input name="savesettings" type="submit" class="button-primary" value="<?php _e('Save Settings', 'pmpro');?>" />
|
239 |
-
</p>
|
240 |
-
</form>
|
241 |
-
|
242 |
-
<?php
|
243 |
-
require_once(dirname(__FILE__) . "/admin_footer.php");
|
244 |
-
?>
|
1 |
+
<?php
|
2 |
+
//only admins can get this
|
3 |
+
if(!function_exists("current_user_can") || (!current_user_can("manage_options") && !current_user_can("pmpro_paymentsettings")))
|
4 |
+
{
|
5 |
+
die(__("You do not have permissions to perform this action.", "pmpro"));
|
6 |
+
}
|
7 |
+
|
8 |
+
global $wpdb, $pmpro_currency_symbol, $msg, $msgt;
|
9 |
+
|
10 |
+
/*
|
11 |
+
Since 2.0, we let each gateway define what options they have in the class files
|
12 |
+
*/
|
13 |
+
//define options
|
14 |
+
$payment_options = array_unique(apply_filters("pmpro_payment_options", array('gateway')));
|
15 |
+
|
16 |
+
//get/set settings
|
17 |
+
if(!empty($_REQUEST['savesettings']))
|
18 |
+
{
|
19 |
+
/*
|
20 |
+
Save any value that might have been passed in
|
21 |
+
*/
|
22 |
+
foreach($payment_options as $option)
|
23 |
+
pmpro_setOption($option);
|
24 |
+
|
25 |
+
/*
|
26 |
+
Some special case options still worked out here
|
27 |
+
*/
|
28 |
+
//credit cards
|
29 |
+
$pmpro_accepted_credit_cards = array();
|
30 |
+
if(!empty($_REQUEST['creditcards_visa']))
|
31 |
+
$pmpro_accepted_credit_cards[] = "Visa";
|
32 |
+
if(!empty($_REQUEST['creditcards_mastercard']))
|
33 |
+
$pmpro_accepted_credit_cards[] = "Mastercard";
|
34 |
+
if(!empty($_REQUEST['creditcards_amex']))
|
35 |
+
$pmpro_accepted_credit_cards[] = "American Express";
|
36 |
+
if(!empty($_REQUEST['creditcards_discover']))
|
37 |
+
$pmpro_accepted_credit_cards[] = "Discover";
|
38 |
+
if(!empty($_REQUEST['creditcards_dinersclub']))
|
39 |
+
$pmpro_accepted_credit_cards[] = "Diners Club";
|
40 |
+
if(!empty($_REQUEST['creditcards_enroute']))
|
41 |
+
$pmpro_accepted_credit_cards[] = "EnRoute";
|
42 |
+
if(!empty($_REQUEST['creditcards_jcb']))
|
43 |
+
$pmpro_accepted_credit_cards[] = "JCB";
|
44 |
+
|
45 |
+
pmpro_setOption("accepted_credit_cards", implode(",", $pmpro_accepted_credit_cards));
|
46 |
+
|
47 |
+
//assume success
|
48 |
+
$msg = true;
|
49 |
+
$msgt = __("Your payment settings have been updated.", "pmpro");
|
50 |
+
}
|
51 |
+
|
52 |
+
/*
|
53 |
+
Extract values for use later
|
54 |
+
*/
|
55 |
+
$payment_option_values = array();
|
56 |
+
foreach($payment_options as $option)
|
57 |
+
$payment_option_values[$option] = pmpro_getOption($option);
|
58 |
+
extract($payment_option_values);
|
59 |
+
|
60 |
+
/*
|
61 |
+
Some special cases that get worked out here.
|
62 |
+
*/
|
63 |
+
//make sure the tax rate is not > 1
|
64 |
+
$tax_state = pmpro_getOption("tax_state");
|
65 |
+
$tax_rate = pmpro_getOption("tax_rate");
|
66 |
+
if((double)$tax_rate > 1)
|
67 |
+
{
|
68 |
+
//assume the entered X%
|
69 |
+
$tax_rate = $tax_rate / 100;
|
70 |
+
pmpro_setOption("tax_rate", $tax_rate);
|
71 |
+
}
|
72 |
+
|
73 |
+
//accepted credit cards
|
74 |
+
$pmpro_accepted_credit_cards = $payment_option_values['accepted_credit_cards']; //this var has the pmpro_ prefix
|
75 |
+
|
76 |
+
//default settings
|
77 |
+
if(empty($gateway_environment))
|
78 |
+
{
|
79 |
+
$gateway_environment = "sandbox";
|
80 |
+
pmpro_setOption("gateway_environment", $gateway_environment);
|
81 |
+
}
|
82 |
+
if(empty($pmpro_accepted_credit_cards))
|
83 |
+
{
|
84 |
+
$pmpro_accepted_credit_cards = "Visa,Mastercard,American Express,Discover";
|
85 |
+
pmpro_setOption("accepted_credit_cards", $pmpro_accepted_credit_cards);
|
86 |
+
}
|
87 |
+
$pmpro_accepted_credit_cards = explode(",", $pmpro_accepted_credit_cards);
|
88 |
+
|
89 |
+
require_once(dirname(__FILE__) . "/admin_header.php");
|
90 |
+
?>
|
91 |
+
|
92 |
+
<form action="" method="post" enctype="multipart/form-data">
|
93 |
+
<h2><?php _e('Payment Gateway', 'pmpro');?> & <?php _e('SSL Settings', 'pmpro');?></h2>
|
94 |
+
|
95 |
+
<p><?php _e('Learn more about <a title="Paid Memberships Pro - SSL Settings" target="_blank" href="http://www.paidmembershipspro.com/support/initial-plugin-setup/ssl/">SSL</a> or <a title="Paid Memberships Pro - Payment Gateway Settings" target="_blank" href="http://www.paidmembershipspro.com/support/initial-plugin-setup/payment-gateway/">Payment Gateway Settings</a>.', 'pmpro'); ?></p>
|
96 |
+
|
97 |
+
<table class="form-table">
|
98 |
+
<tbody>
|
99 |
+
<tr class="pmpro_settings_divider">
|
100 |
+
<td colspan="2">
|
101 |
+
Choose a Gateway
|
102 |
+
</td>
|
103 |
+
</tr>
|
104 |
+
<tr>
|
105 |
+
<th scope="row" valign="top">
|
106 |
+
<label for="gateway"><?php _e('Payment Gateway', 'pmpro');?>:</label>
|
107 |
+
</th>
|
108 |
+
<td>
|
109 |
+
<select id="gateway" name="gateway" onchange="pmpro_changeGateway(jQuery(this).val());">
|
110 |
+
<?php
|
111 |
+
$pmpro_gateways = pmpro_gateways();
|
112 |
+
foreach($pmpro_gateways as $pmpro_gateway_name => $pmpro_gateway_label)
|
113 |
+
{
|
114 |
+
?>
|
115 |
+
<option value="<?php echo esc_attr($pmpro_gateway_name);?>" <?php selected($gateway, $pmpro_gateway_name);?>><?php echo $pmpro_gateway_label;?></option>
|
116 |
+
<?php
|
117 |
+
}
|
118 |
+
?>
|
119 |
+
</select>
|
120 |
+
</td>
|
121 |
+
</tr>
|
122 |
+
<tr>
|
123 |
+
<th scope="row" valign="top">
|
124 |
+
<label for="gateway_environment"><?php _e('Gateway Environment', 'pmpro');?>:</label>
|
125 |
+
</th>
|
126 |
+
<td>
|
127 |
+
<select name="gateway_environment">
|
128 |
+
<option value="sandbox" <?php selected( $gateway_environment, "sandbox" ); ?>><?php _e('Sandbox/Testing', 'pmpro');?></option>
|
129 |
+
<option value="live" <?php selected( $gateway_environment, "live" ); ?>><?php _e('Live/Production', 'pmpro');?></option>
|
130 |
+
</select>
|
131 |
+
<script>
|
132 |
+
function pmpro_changeGateway(gateway)
|
133 |
+
{
|
134 |
+
//hide all gateway options
|
135 |
+
jQuery('tr.gateway').hide();
|
136 |
+
jQuery('tr.gateway_'+gateway).show();
|
137 |
+
}
|
138 |
+
pmpro_changeGateway(jQuery('#gateway').val());
|
139 |
+
</script>
|
140 |
+
</td>
|
141 |
+
</tr>
|
142 |
+
|
143 |
+
<?php /* Gateway Specific Settings */ ?>
|
144 |
+
<?php do_action('pmpro_payment_option_fields', $payment_option_values, $gateway); ?>
|
145 |
+
|
146 |
+
<tr class="pmpro_settings_divider">
|
147 |
+
<td colspan="2">
|
148 |
+
Currency and Tax Settings
|
149 |
+
</td>
|
150 |
+
</tr>
|
151 |
+
<tr class="gateway gateway_ <?php echo esc_attr(pmpro_getClassesForPaymentSettingsField("currency"));?>" <?php if(!empty($gateway) && $gateway != "paypal" && $gateway != "paypalexpress" && $gateway != "paypalstandard" && $gateway != "braintree" && $gateway != "twocheckout" && $gateway != "cybersource" && $gateway != "payflowpro" && $gateway != "stripe" && $gateway != "authorizenet" && $gateway != "gourl") { ?>style="display: none;"<?php } ?>>
|
152 |
+
<th scope="row" valign="top">
|
153 |
+
<label for="currency"><?php _e('Currency', 'pmpro');?>:</label>
|
154 |
+
</th>
|
155 |
+
<td>
|
156 |
+
<select name="currency">
|
157 |
+
<?php
|
158 |
+
global $pmpro_currencies;
|
159 |
+
foreach($pmpro_currencies as $ccode => $cdescription)
|
160 |
+
{
|
161 |
+
if(is_array($cdescription))
|
162 |
+
$cdescription = $cdescription['name'];
|
163 |
+
?>
|
164 |
+
<option value="<?php echo $ccode?>" <?php if($currency == $ccode) { ?>selected="selected"<?php } ?>><?php echo $cdescription?></option>
|
165 |
+
<?php
|
166 |
+
}
|
167 |
+
?>
|
168 |
+
</select>
|
169 |
+
<small><?php _e( 'Not all currencies will be supported by every gateway. Please check with your gateway.', 'pmpro' ); ?></small>
|
170 |
+
</td>
|
171 |
+
</tr>
|
172 |
+
<tr class="gateway gateway_ <?php echo esc_attr(pmpro_getClassesForPaymentSettingsField("accepted_credit_cards"));?>" <?php if(!empty($gateway) && $gateway != "authorizenet" && $gateway != "paypal" && $gateway != "stripe" && $gateway != "payflowpro" && $gateway != "braintree" && $gateway != "twocheckout" && $gateway != "cybersource") { ?>style="display: none;"<?php } ?>>
|
173 |
+
<th scope="row" valign="top">
|
174 |
+
<label for="creditcards"><?php _e('Accepted Credit Card Types', 'pmpro');?></label>
|
175 |
+
</th>
|
176 |
+
<td>
|
177 |
+
<input type="checkbox" id="creditcards_visa" name="creditcards_visa" value="1" <?php if(in_array("Visa", $pmpro_accepted_credit_cards)) { ?>checked="checked"<?php } ?> /> <label for="creditcards_visa">Visa</label><br />
|
178 |
+
<input type="checkbox" id="creditcards_mastercard" name="creditcards_mastercard" value="1" <?php if(in_array("Mastercard", $pmpro_accepted_credit_cards)) { ?>checked="checked"<?php } ?> /> <label for="creditcards_mastercard">Mastercard</label><br />
|
179 |
+
<input type="checkbox" id="creditcards_amex" name="creditcards_amex" value="1" <?php if(in_array("American Express", $pmpro_accepted_credit_cards)) { ?>checked="checked"<?php } ?> /> <label for="creditcards_amex">American Express</label><br />
|
180 |
+
<input type="checkbox" id="creditcards_discover" name="creditcards_discover" value="1" <?php if(in_array("Discover", $pmpro_accepted_credit_cards)) { ?>checked="checked"<?php } ?> /> <label for="creditcards_discover">Discover</label><br />
|
181 |
+
<input type="checkbox" id="creditcards_dinersclub" name="creditcards_dinersclub" value="1" <?php if(in_array("Diners Club", $pmpro_accepted_credit_cards)) {?>checked="checked"<?php } ?> /> <label for="creditcards_dinersclub">Diner's Club</label><br />
|
182 |
+
<input type="checkbox" id="creditcards_enroute" name="creditcards_enroute" value="1" <?php if(in_array("EnRoute", $pmpro_accepted_credit_cards)) {?>checked="checked"<?php } ?> /> <label for="creditcards_enroute">EnRoute</label><br />
|
183 |
+
<input type="checkbox" id="creditcards_jcb" name="creditcards_jcb" value="1" <?php if(in_array("JCB", $pmpro_accepted_credit_cards)) {?>checked="checked"<?php } ?> /> <label for="creditcards_jcb">JCB</label><br />
|
184 |
+
</td>
|
185 |
+
</tr>
|
186 |
+
<tr class="gateway gateway_ <?php echo esc_attr(pmpro_getClassesForPaymentSettingsField("tax_rate"));?>" <?php if(!empty($gateway) && $gateway != "stripe" && $gateway != "authorizenet" && $gateway != "paypal" && $gateway != "paypalexpress" && $gateway != "check" && $gateway != "paypalstandard" && $gateway != "payflowpro" && $gateway != "braintree" && $gateway != "twocheckout" && $gateway != "cybersource") { ?>style="display: none;"<?php } ?>>
|
187 |
+
<th scope="row" valign="top">
|
188 |
+
<label for="tax"><?php _e('Sales Tax', 'pmpro');?> <small>(<?php _e('optional', 'pmpro');?>)</small></label>
|
189 |
+
</th>
|
190 |
+
<td>
|
191 |
+
<?php _e('Tax State', 'pmpro');?>:
|
192 |
+
<input type="text" id="tax_state" name="tax_state" size="4" value="<?php echo esc_attr($tax_state)?>" /> <small>(<?php _e('abbreviation, e.g. "PA"', 'pmpro');?>)</small>
|
193 |
+
Tax Rate:
|
194 |
+
<input type="text" id="tax_rate" name="tax_rate" size="10" value="<?php echo esc_attr($tax_rate)?>" /> <small>(<?php _e('decimal, e.g. "0.06"', 'pmpro');?>)</small>
|
195 |
+
<p><small><?php _e('US only. If values are given, tax will be applied for any members ordering from the selected state.<br />For non-US or more complex tax rules, use the <a target="_blank" href="http://www.paidmembershipspro.com/2013/10/non-us-taxes-paid-memberships-pro/">pmpro_tax filter</a>.', 'pmpro');?></small></p>
|
196 |
+
</td>
|
197 |
+
</tr>
|
198 |
+
|
199 |
+
<tr class="pmpro_settings_divider">
|
200 |
+
<td colspan="2">
|
201 |
+
SSL Settings
|
202 |
+
</td>
|
203 |
+
</tr>
|
204 |
+
<tr class="gateway gateway_ <?php echo esc_attr(pmpro_getClassesForPaymentSettingsField("use_ssl"));?>">
|
205 |
+
<th scope="row" valign="top">
|
206 |
+
<label for="use_ssl"><?php _e('Force SSL', 'pmpro');?>:</label>
|
207 |
+
</th>
|
208 |
+
<td>
|
209 |
+
<select id="use_ssl" name="use_ssl">
|
210 |
+
<option value="0" <?php if(empty($use_ssl)) { ?>selected="selected"<?php } ?>><?php _e('No', 'pmpro');?></option>
|
211 |
+
<option value="1" <?php if(!empty($use_ssl) && $use_ssl == 1) { ?>selected="selected"<?php } ?>><?php _e('Yes', 'pmpro');?></option>
|
212 |
+
<option value="2" <?php if(!empty($use_ssl) && $use_ssl == 2) { ?>selected="selected"<?php } ?>><?php _e('Yes (with JavaScript redirects)', 'pmpro');?></option>
|
213 |
+
</select>
|
214 |
+
<small>Recommended: Yes. Try the JavaScript redirects setting if you are having issues with infinite redirect loops.</small>
|
215 |
+
</td>
|
216 |
+
</tr>
|
217 |
+
<tr>
|
218 |
+
<th scope="row" valign="top">
|
219 |
+
<label for="sslseal"><?php _e('SSL Seal Code', 'pmpro');?>:</label>
|
220 |
+
</th>
|
221 |
+
<td>
|
222 |
+
<textarea id="sslseal" name="sslseal" rows="3" cols="80"><?php echo stripslashes(esc_textarea($sslseal))?></textarea>
|
223 |
+
<br /><small>Your <strong><a target="_blank" href="http://www.paidmembershipspro.com/documentation/initial-plugin-setup/ssl/">SSL Certificate</a></strong> must be installed by your web host. Your <strong>SSL Seal</strong> will be a short HTML or JavaScript snippet that can be pasted here.</small>
|
224 |
+
</td>
|
225 |
+
</tr>
|
226 |
+
<tr>
|
227 |
+
<th scope="row" valign="top">
|
228 |
+
<label for="nuclear_HTTPS"><?php _e('Extra HTTPS URL Filter', 'pmpro');?>:</label>
|
229 |
+
</th>
|
230 |
+
<td>
|
231 |
+
<input type="checkbox" id="nuclear_HTTPS" name="nuclear_HTTPS" value="1" <?php if(!empty($nuclear_HTTPS)) { ?>checked="checked"<?php } ?> /> <label for="nuclear_HTTPS"><?php _e('Pass all generated HTML through a URL filter to add HTTPS to URLs used on secure pages. Check this if you are using SSL and have warnings on your checkout pages.', 'pmpro');?></label>
|
232 |
+
</td>
|
233 |
+
</tr>
|
234 |
+
|
235 |
+
</tbody>
|
236 |
+
</table>
|
237 |
+
<p class="submit">
|
238 |
+
<input name="savesettings" type="submit" class="button-primary" value="<?php _e('Save Settings', 'pmpro');?>" />
|
239 |
+
</p>
|
240 |
+
</form>
|
241 |
+
|
242 |
+
<?php
|
243 |
+
require_once(dirname(__FILE__) . "/admin_footer.php");
|
244 |
+
?>
|
adminpages/reports.php
CHANGED
@@ -1,62 +1,62 @@
|
|
1 |
-
<?php
|
2 |
-
global $pmpro_reports;
|
3 |
-
|
4 |
-
require_once(dirname(__FILE__) . "/admin_header.php");
|
5 |
-
|
6 |
-
//default view, report widgets
|
7 |
-
if(empty($_REQUEST['report']))
|
8 |
-
{
|
9 |
-
//wrapper
|
10 |
-
?>
|
11 |
-
<div id="dashboard-widgets-wrap">
|
12 |
-
<div id="dashboard-widgets" class="metabox-holder pmpro_reports-holder columns-2">
|
13 |
-
<div id="postbox-container-1" class="postbox-container">
|
14 |
-
<div id="normal-sortables" class="meta-box-sortables ui-sortable">
|
15 |
-
<?php
|
16 |
-
|
17 |
-
//report widgets
|
18 |
-
$count = 0;
|
19 |
-
$nreports = count($pmpro_reports);
|
20 |
-
$split = false;
|
21 |
-
foreach($pmpro_reports as $report => $title)
|
22 |
-
{
|
23 |
-
//make sure title is translated (since these are set before translations happen)
|
24 |
-
$title = __($title, "pmpro");
|
25 |
-
|
26 |
-
//put half of the report widgets in postbox-container-2
|
27 |
-
if(!$split && $count++ > $nreports/2)
|
28 |
-
{
|
29 |
-
$split = true;
|
30 |
-
?>
|
31 |
-
</div></div><div id="postbox-container-2" class="postbox-container"><div id="side-sortables" class="meta-box-sortables ui-sortable">
|
32 |
-
<?php
|
33 |
-
}
|
34 |
-
?>
|
35 |
-
<div id="pmpro_report_<?php echo $report; ?>" class="postbox pmpro_clickable" onclick="location.href='<?php echo admin_url("admin.php?page=pmpro-reports&report=" . $report);?>';">
|
36 |
-
<h3 class="hndle"><span><?php echo $title; ?></span></h3>
|
37 |
-
<div class="inside">
|
38 |
-
<?php call_user_func("pmpro_report_" . $report . "_widget"); ?>
|
39 |
-
<div style="margin-top:10px;border-top: 1px solid #ddd; padding-top: 10px; text-align:center;">
|
40 |
-
<a class="button button-primary" href="<?php echo admin_url("admin.php?page=pmpro-reports&report=" . $report);?>"><?php _e('Details', 'pmpro');?></a>
|
41 |
-
</div>
|
42 |
-
</div>
|
43 |
-
</div>
|
44 |
-
<?php
|
45 |
-
}
|
46 |
-
|
47 |
-
//end wrapper
|
48 |
-
?>
|
49 |
-
</div>
|
50 |
-
</div>
|
51 |
-
</div>
|
52 |
-
<?php
|
53 |
-
}
|
54 |
-
else
|
55 |
-
{
|
56 |
-
//view a single report
|
57 |
-
$report = $_REQUEST['report'];
|
58 |
-
call_user_func("pmpro_report_" . $report . "_page");
|
59 |
-
}
|
60 |
-
|
61 |
-
require_once(dirname(__FILE__) . "/admin_footer.php");
|
62 |
?>
|
1 |
+
<?php
|
2 |
+
global $pmpro_reports;
|
3 |
+
|
4 |
+
require_once(dirname(__FILE__) . "/admin_header.php");
|
5 |
+
|
6 |
+
//default view, report widgets
|
7 |
+
if(empty($_REQUEST['report']))
|
8 |
+
{
|
9 |
+
//wrapper
|
10 |
+
?>
|
11 |
+
<div id="dashboard-widgets-wrap">
|
12 |
+
<div id="dashboard-widgets" class="metabox-holder pmpro_reports-holder columns-2">
|
13 |
+
<div id="postbox-container-1" class="postbox-container">
|
14 |
+
<div id="normal-sortables" class="meta-box-sortables ui-sortable">
|
15 |
+
<?php
|
16 |
+
|
17 |
+
//report widgets
|
18 |
+
$count = 0;
|
19 |
+
$nreports = count($pmpro_reports);
|
20 |
+
$split = false;
|
21 |
+
foreach($pmpro_reports as $report => $title)
|
22 |
+
{
|
23 |
+
//make sure title is translated (since these are set before translations happen)
|
24 |
+
$title = __($title, "pmpro");
|
25 |
+
|
26 |
+
//put half of the report widgets in postbox-container-2
|
27 |
+
if(!$split && $count++ > $nreports/2)
|
28 |
+
{
|
29 |
+
$split = true;
|
30 |
+
?>
|
31 |
+
</div></div><div id="postbox-container-2" class="postbox-container"><div id="side-sortables" class="meta-box-sortables ui-sortable">
|
32 |
+
<?php
|
33 |
+
}
|
34 |
+
?>
|
35 |
+
<div id="pmpro_report_<?php echo $report; ?>" class="postbox pmpro_clickable" onclick="location.href='<?php echo admin_url("admin.php?page=pmpro-reports&report=" . $report);?>';">
|
36 |
+
<h3 class="hndle"><span><?php echo $title; ?></span></h3>
|
37 |
+
<div class="inside">
|
38 |
+
<?php call_user_func("pmpro_report_" . $report . "_widget"); ?>
|
39 |
+
<div style="margin-top:10px;border-top: 1px solid #ddd; padding-top: 10px; text-align:center;">
|
40 |
+
<a class="button button-primary" href="<?php echo admin_url("admin.php?page=pmpro-reports&report=" . $report);?>"><?php _e('Details', 'pmpro');?></a>
|
41 |
+
</div>
|
42 |
+
</div>
|
43 |
+
</div>
|
44 |
+
<?php
|
45 |
+
}
|
46 |
+
|
47 |
+
//end wrapper
|
48 |
+
?>
|
49 |
+
</div>
|
50 |
+
</div>
|
51 |
+
</div>
|
52 |
+
<?php
|
53 |
+
}
|
54 |
+
else
|
55 |
+
{
|
56 |
+
//view a single report
|
57 |
+
$report = $_REQUEST['report'];
|
58 |
+
call_user_func("pmpro_report_" . $report . "_page");
|
59 |
+
}
|
60 |
+
|
61 |
+
require_once(dirname(__FILE__) . "/admin_footer.php");
|
62 |
?>
|
adminpages/reports/login.php
CHANGED
@@ -1,420 +1,420 @@
|
|
1 |
-
<?php
|
2 |
-
/*
|
3 |
-
PMPro Report
|
4 |
-
Title: Logins
|
5 |
-
Slug: login
|
6 |
-
|
7 |
-
For each report, add a line like:
|
8 |
-
global $pmpro_reports;
|
9 |
-
$pmpro_reports['slug'] = 'Title';
|
10 |
-
|
11 |
-
For each report, also write two functions:
|
12 |
-
* pmpro_report_{slug}_widget() to show up on the report homepage.
|
13 |
-
* pmpro_report_{slug}_page() to show up when users click on the report page widget.
|
14 |
-
*/
|
15 |
-
global $pmpro_reports;
|
16 |
-
$pmpro_reports['login'] = __('Visits, Views, and Logins', 'pmpro');
|
17 |
-
|
18 |
-
function pmpro_report_login_widget()
|
19 |
-
{
|
20 |
-
global $wpdb;
|
21 |
-
$now = current_time('timestamp');
|
22 |
-
$visits = get_option("pmpro_visits", array("today"=>0, "thisday"=>date("Y-m-d", $now), "alltime"=>0, "month"=>0, "thismonth"=>date("n", $now)));
|
23 |
-
$views = get_option("pmpro_views", array("today"=>0, "thisday"=>date("Y-m-d", $now), "alltime"=>0, "month"=>0, "thismonth"=>date("n", $now)));
|
24 |
-
$logins = get_option("pmpro_logins", array("today"=>0, "thisday"=>date("Y-m-d", $now), "alltime"=>0, "month"=>0, "thismonth"=>date("n", $now)));
|
25 |
-
?>
|
26 |
-
<div style="width: 33%; float: left;">
|
27 |
-
<p><?php _e('Visits Today', 'pmpro')?>: <?php echo $visits['today'];?></p>
|
28 |
-
<p><?php _e('Visits This Month', 'pmpro')?>: <?php echo $visits['month'];?></p>
|
29 |
-
<p><?php _e('Visits All Time', 'pmpro')?>: <?php echo $visits['alltime'];?></p>
|
30 |
-
</div>
|
31 |
-
<div style="width: 33%; float: left;">
|
32 |
-
<p><?php _e('Views Today', 'pmpro')?>: <?php echo $views['today'];?></p>
|
33 |
-
<p><?php _e('Views This Month', 'pmpro')?>: <?php echo $views['month'];?></p>
|
34 |
-
<p><?php _e('Views All Time', 'pmpro')?>: <?php echo $views['alltime'];?></p>
|
35 |
-
</div>
|
36 |
-
<div style="width: 33%; float: left;">
|
37 |
-
<p><?php _e('Logins Today', 'pmpro')?>: <?php echo $logins['today'];?></p>
|
38 |
-
<p><?php _e('Logins This Month', 'pmpro')?>: <?php echo $logins['month'];?></p>
|
39 |
-
<p><?php _e('Logins All Time', 'pmpro')?>: <?php echo $logins['alltime'];?></p>
|
40 |
-
</div>
|
41 |
-
<div class="clear"></div>
|
42 |
-
<?php
|
43 |
-
}
|
44 |
-
|
45 |
-
function pmpro_report_login_page()
|
46 |
-
{
|
47 |
-
global $wpdb;
|
48 |
-
$now = current_time('timestamp');
|
49 |
-
|
50 |
-
//vars
|
51 |
-
if(!empty($_REQUEST['s']))
|
52 |
-
$s = $_REQUEST['s'];
|
53 |
-
else
|
54 |
-
$s = "";
|
55 |
-
|
56 |
-
if(!empty($_REQUEST['l']))
|
57 |
-
$l = intval($_REQUEST['l']);
|
58 |
-
else
|
59 |
-
$l = "";
|
60 |
-
?>
|
61 |
-
<form id="posts-filter" method="get" action="">
|
62 |
-
<h2>
|
63 |
-
<?php _e('Visits, Views, and Logins Report', 'pmpro');?>
|
64 |
-
</h2>
|
65 |
-
<ul class="subsubsub">
|
66 |
-
<li>
|
67 |
-
<?php _ex('Show', 'Dropdown label, e.g. Show All Users', 'pmpro')?> <select name="l" onchange="jQuery('#posts-filter').submit();">
|
68 |
-
<option value="" <?php if(!$l) { ?>selected="selected"<?php } ?>><?php _e('All Users', 'pmpro')?></option>
|
69 |
-
<option value="all" <?php if($l == "all") { ?>selected="selected"<?php } ?>><?php _e('All Levels', 'pmpro')?></option>
|
70 |
-
<?php
|
71 |
-
$levels = $wpdb->get_results("SELECT id, name FROM $wpdb->pmpro_membership_levels ORDER BY name");
|
72 |
-
foreach($levels as $level)
|
73 |
-
{
|
74 |
-
?>
|
75 |
-
<option value="<?php echo $level->id?>" <?php if($l == $level->id) { ?>selected="selected"<?php } ?>><?php echo $level->name?></option>
|
76 |
-
<?php
|
77 |
-
}
|
78 |
-
?>
|
79 |
-
</select>
|
80 |
-
</li>
|
81 |
-
</ul>
|
82 |
-
<p class="search-box">
|
83 |
-
<label class="hidden" for="post-search-input"><?php _ex('Search', 'Search form label', 'pmpro')?> <?php if(empty($l)) echo "Users"; else echo "Members";?>:</label>
|
84 |
-
<input type="hidden" name="page" value="pmpro-reports" />
|
85 |
-
<input type="hidden" name="report" value="login" />
|
86 |
-
<input id="post-search-input" type="text" value="<?php echo esc_attr($s)?>" name="s"/>
|
87 |
-
<input class="button" type="submit" value="Search Members"/>
|
88 |
-
</p>
|
89 |
-
<?php
|
90 |
-
//some vars for the search
|
91 |
-
if(isset($_REQUEST['pn']))
|
92 |
-
$pn = intval($_REQUEST['pn']);
|
93 |
-
else
|
94 |
-
$pn = 1;
|
95 |
-
|
96 |
-
if(isset($_REQUEST['limit']))
|
97 |
-
$limit = intval($_REQUEST['limit']);
|
98 |
-
else
|
99 |
-
$limit = 15;
|
100 |
-
|
101 |
-
$end = $pn * $limit;
|
102 |
-
$start = $end - $limit;
|
103 |
-
|
104 |
-
if($s)
|
105 |
-
{
|
106 |
-
$sqlQuery = "SELECT SQL_CALC_FOUND_ROWS u.ID, u.user_login, u.user_email, UNIX_TIMESTAMP(u.user_registered) as joindate, mu.membership_id, mu.initial_payment, mu.billing_amount, mu.cycle_period, mu.cycle_number, mu.billing_limit, mu.trial_amount, mu.trial_limit, UNIX_TIMESTAMP(mu.startdate) as startdate, UNIX_TIMESTAMP(mu.enddate) as enddate, m.name as membership FROM $wpdb->users u LEFT JOIN $wpdb->usermeta um ON u.ID = um.user_id LEFT JOIN $wpdb->pmpro_memberships_users mu ON u.ID = mu.user_id AND mu.status = 'active' LEFT JOIN $wpdb->pmpro_membership_levels m ON mu.membership_id = m.id WHERE (u.user_login LIKE '%" . esc_sql($s) . "%' OR u.user_email LIKE '%" . esc_sql($s) . "%' OR um.meta_value LIKE '%" . esc_sql($s) . "%') ";
|
107 |
-
|
108 |
-
if($l == "all")
|
109 |
-
$sqlQuery .= " AND mu.status = 'active' AND mu.membership_id > 0 ";
|
110 |
-
elseif($l)
|
111 |
-
$sqlQuery .= " AND mu.membership_id = '" . $l . "' ";
|
112 |
-
|
113 |
-
$sqlQuery .= "GROUP BY u.ID ORDER BY user_registered DESC LIMIT $start, $limit";
|
114 |
-
}
|
115 |
-
else
|
116 |
-
{
|
117 |
-
$sqlQuery = "SELECT SQL_CALC_FOUND_ROWS u.ID, u.user_login, u.user_email, UNIX_TIMESTAMP(u.user_registered) as joindate, mu.membership_id, mu.initial_payment, mu.billing_amount, mu.cycle_period, mu.cycle_number, mu.billing_limit, mu.trial_amount, mu.trial_limit, UNIX_TIMESTAMP(mu.startdate) as startdate, UNIX_TIMESTAMP(mu.enddate) as enddate, m.name as membership FROM $wpdb->users u LEFT JOIN $wpdb->pmpro_memberships_users mu ON u.ID = mu.user_id AND mu.status = 'active' LEFT JOIN $wpdb->pmpro_membership_levels m ON mu.membership_id = m.id";
|
118 |
-
$sqlQuery .= " WHERE 1=1 ";
|
119 |
-
|
120 |
-
if($l == "all")
|
121 |
-
$sqlQuery .= " AND mu.membership_id > 0 AND mu.status = 'active' ";
|
122 |
-
elseif($l)
|
123 |
-
$sqlQuery .= " AND mu.membership_id = '" . $l . "' ";
|
124 |
-
$sqlQuery .= "GROUP BY u.ID ORDER BY user_registered DESC LIMIT $start, $limit";
|
125 |
-
}
|
126 |
-
|
127 |
-
$sqlQuery = apply_filters("pmpro_members_list_sql", $sqlQuery);
|
128 |
-
|
129 |
-
$theusers = $wpdb->get_results($sqlQuery);
|
130 |
-
$totalrows = $wpdb->get_var("SELECT FOUND_ROWS() as found_rows");
|
131 |
-
|
132 |
-
if($theusers)
|
133 |
-
{
|
134 |
-
?>
|
135 |
-
<p class="clear"><?php echo strval($totalrows)?> <?php if(empty($l)) echo "users"; else echo "members";?> found.
|
136 |
-
<?php
|
137 |
-
}
|
138 |
-
?>
|
139 |
-
<table class="widefat">
|
140 |
-
<thead>
|
141 |
-
<tr class="thead">
|
142 |
-
<th><?php _e('ID', 'pmpro')?></th>
|
143 |
-
<th><?php _e('User', 'pmpro')?></th>
|
144 |
-
<th><?php _e('Name', 'pmpro')?></th>
|
145 |
-
<th><?php _e('Membership', 'pmpro')?></th>
|
146 |
-
<th><?php _e('Joined', 'pmpro')?></th>
|
147 |
-
<th><?php _e('Expires', 'pmpro')?></th>
|
148 |
-
<th><?php _e('Last Visit', 'pmpro')?></th>
|
149 |
-
<th><?php _e('Visits This Month', 'pmpro')?></th>
|
150 |
-
<th><?php _e('Total Visits', 'pmpro')?></th>
|
151 |
-
<th><?php _e('Views This Month', 'pmpro')?></th>
|
152 |
-
<th><?php _e('Total Views', 'pmpro')?></th>
|
153 |
-
<th><?php _e('Last Login', 'pmpro')?></th>
|
154 |
-
<th><?php _e('Logins This Month', 'pmpro')?></th>
|
155 |
-
<th><?php _e('Total Logins', 'pmpro')?></th>
|
156 |
-
</tr>
|
157 |
-
</thead>
|
158 |
-
<tbody id="users" class="list:user user-list">
|
159 |
-
<?php
|
160 |
-
$count = 0;
|
161 |
-
foreach($theusers as $auser)
|
162 |
-
{
|
163 |
-
//get meta
|
164 |
-
$theuser = get_userdata($auser->ID);
|
165 |
-
$visits = get_user_meta($auser->ID, "pmpro_visits", true);
|
166 |
-
$views = get_user_meta($auser->ID, "pmpro_views", true);
|
167 |
-
$logins = get_user_meta($auser->ID, "pmpro_logins", true);
|
168 |
-
if(empty($logins))
|
169 |
-
$logins = array("last"=>"N/A", "month"=>"N/A", "alltime"=>"N/A");
|
170 |
-
?>
|
171 |
-
<tr <?php if($count++ % 2 == 0) { ?>class="alternate"<?php } ?>>
|
172 |
-
<td><?php echo $theuser->ID?></td>
|
173 |
-
<td>
|
174 |
-
<?php echo get_avatar($theuser->ID, 32)?>
|
175 |
-
<strong>
|
176 |
-
<?php
|
177 |
-
$userlink = '<a href="user-edit.php?user_id=' . $theuser->ID . '">' . $theuser->user_login . '</a>';
|
178 |
-
$userlink = apply_filters("pmpro_members_list_user_link", $userlink, $theuser);
|
179 |
-
echo $userlink;
|
180 |
-
?>
|
181 |
-
</strong>
|
182 |
-
</td>
|
183 |
-
<td>
|
184 |
-
<?php echo $theuser->display_name;?>
|
185 |
-
</td>
|
186 |
-
<td><?php echo $auser->membership?></td>
|
187 |
-
<td><?php echo date("m/d/Y", strtotime($theuser->user_registered, current_time("timestamp")))?></td>
|
188 |
-
<td>
|
189 |
-
<?php
|
190 |
-
if($auser->enddate)
|
191 |
-
echo date(get_option('date_format'), $auser->enddate);
|
192 |
-
else
|
193 |
-
echo "Never";
|
194 |
-
?>
|
195 |
-
</td>
|
196 |
-
<td><?php if(!empty($visits['last'])) echo $visits['last'];?></td>
|
197 |
-
<td><?php if(!empty($visits['month']) && pmpro_isDateThisMonth($visits['last'])) echo $visits['month'];?></td>
|
198 |
-
<td><?php if(!empty($visits['alltime'])) echo $visits['alltime'];?></td>
|
199 |
-
<td><?php if(!empty($views['month']) && pmpro_isDateThisMonth($views['last'])) echo $views['month'];?></td>
|
200 |
-
<td><?php if(!empty($views['alltime'])) echo $views['alltime'];?></td>
|
201 |
-
<td><?php if(!empty($logins['last'])) echo $logins['last'];?></td>
|
202 |
-
<td><?php if(!empty($logins['month']) && pmpro_isDateThisMonth($logins['last'])) echo $logins['month'];?></td>
|
203 |
-
<td><?php if(!empty($logins['alltime'])) echo $logins['alltime'];?></td>
|
204 |
-
</tr>
|
205 |
-
<?php
|
206 |
-
}
|
207 |
-
|
208 |
-
if(!$theusers)
|
209 |
-
{
|
210 |
-
?>
|
211 |
-
<tr>
|
212 |
-
<td colspan="9"><p><?php _e('No members found.', 'pmpro')?> <?php if($l) { ?><a href="?page=pmpro-memberslist&s=<?php echo esc_attr($s)?>"><?php _e('Search all levels', 'pmpro')?></a>.<?php } ?></p></td>
|
213 |
-
</tr>
|
214 |
-
<?php
|
215 |
-
}
|
216 |
-
?>
|
217 |
-
</tbody>
|
218 |
-
</table>
|
219 |
-
</form>
|
220 |
-
|
221 |
-
<?php
|
222 |
-
echo pmpro_getPaginationString($pn, $totalrows, $limit, 1, get_admin_url(NULL, "/admin.php?page=pmpro-reports&report=login&s=" . urlencode($s)), "&l=$l&limit=$limit&pn=");
|
223 |
-
?>
|
224 |
-
<?php
|
225 |
-
}
|
226 |
-
|
227 |
-
/*
|
228 |
-
Other code required for your reports. This file is loaded every time WP loads with PMPro enabled.
|
229 |
-
*/
|
230 |
-
|
231 |
-
//track visits
|
232 |
-
function pmpro_report_login_wp_visits()
|
233 |
-
{
|
234 |
-
//don't track admin
|
235 |
-
if(is_admin())
|
236 |
-
return;
|
237 |
-
|
238 |
-
//only track logged in users
|
239 |
-
if(!is_user_logged_in())
|
240 |
-
return;
|
241 |
-
|
242 |
-
//check for cookie
|
243 |
-
if(!empty($_COOKIE['pmpro_visit']))
|
244 |
-
return;
|
245 |
-
|
246 |
-
$now = current_time('timestamp');
|
247 |
-
|
248 |
-
//set cookie, then track
|
249 |
-
setcookie("pmpro_visit", "1", NULL, COOKIEPATH, COOKIE_DOMAIN, false);
|
250 |
-
|
251 |
-
global $current_user;
|
252 |
-
//track for user
|
253 |
-
if(!empty($current_user->ID))
|
254 |
-
{
|
255 |
-
$visits = $current_user->pmpro_visits;
|
256 |
-
if(empty($visits))
|
257 |
-
$visits = array("last"=>"N/A", "thisdate"=>NULL, "month"=>0, "thismonth"=>NULL, "alltime"=>0);
|
258 |
-
|
259 |
-
//track logins for user
|
260 |
-
$visits['last'] = date(get_option("date_format"));
|
261 |
-
$visits['alltime']++;
|
262 |
-
$thismonth = date("n", $now);
|
263 |
-
if($thismonth == $visits['thismonth'])
|
264 |
-
$visits['month']++;
|
265 |
-
else
|
266 |
-
{
|
267 |
-
$visits['month'] = 1;
|
268 |
-
$visits['thismonth'] = $thismonth;
|
269 |
-
}
|
270 |
-
|
271 |
-
//update user data
|
272 |
-
update_user_meta($current_user->ID, "pmpro_visits", $visits);
|
273 |
-
}
|
274 |
-
|
275 |
-
//track for all
|
276 |
-
$visits = get_option("pmpro_visits");
|
277 |
-
if(empty($visits))
|
278 |
-
$visits = array("today"=>0, "thisdate"=>NULL, "month"=>0, "thismonth"=> NULL, "alltime"=>0);
|
279 |
-
|
280 |
-
$visits['alltime']++;
|
281 |
-
$thisdate = date("Y-d-m", $now);
|
282 |
-
if($thisdate == $visits['thisdate'])
|
283 |
-
$visits['today']++;
|
284 |
-
else
|
285 |
-
{
|
286 |
-
$visits['today'] = 1;
|
287 |
-
$visits['thisdate'] = $thisdate;
|
288 |
-
}
|
289 |
-
if($thismonth == $visits['thismonth'])
|
290 |
-
$visits['month']++;
|
291 |
-
else
|
292 |
-
{
|
293 |
-
$visits['month'] = 1;
|
294 |
-
$visits['thismonth'] = $thismonth;
|
295 |
-
}
|
296 |
-
|
297 |
-
update_option("pmpro_visits", $visits);
|
298 |
-
}
|
299 |
-
add_action("wp", "pmpro_report_login_wp_visits");
|
300 |
-
|
301 |
-
//we want to clear the pmpro_visit cookie on login/logout
|
302 |
-
function pmpro_report_login_clear_visit_cookie()
|
303 |
-
{
|
304 |
-
if(isset($_COOKIE['pmpro_visit']))
|
305 |
-
unset($_COOKIE['pmpro_visit']);
|
306 |
-
}
|
307 |
-
add_action("wp_login", "pmpro_report_login_clear_visit_cookie");
|
308 |
-
add_action("wp_logout", "pmpro_report_login_clear_visit_cookie");
|
309 |
-
|
310 |
-
//track views
|
311 |
-
function pmpro_report_login_wp_views()
|
312 |
-
{
|
313 |
-
//don't track admin
|
314 |
-
if(is_admin())
|
315 |
-
return;
|
316 |
-
|
317 |
-
global $current_user;
|
318 |
-
$now = current_time('timestamp');
|
319 |
-
|
320 |
-
//track for user
|
321 |
-
if(!empty($current_user->ID))
|
322 |
-
{
|
323 |
-
$views = $current_user->pmpro_views;
|
324 |
-
if(empty($views))
|
325 |
-
$views = array("last"=>"N/A", "month"=>0, "alltime"=>0);
|
326 |
-
|
327 |
-
//track logins for user
|
328 |
-
$views['last'] = date(get_option("date_format"), $now);
|
329 |
-
$views['alltime']++;
|
330 |
-
$thismonth = date("n", $now);
|
331 |
-
if(isset($views['thismonth']) && $thismonth == $views['thismonth'])
|
332 |
-
$views['month']++;
|
333 |
-
else
|
334 |
-
{
|
335 |
-
$views['month'] = 1;
|
336 |
-
$views['thismonth'] = $thismonth;
|
337 |
-
}
|
338 |
-
|
339 |
-
//update user data
|
340 |
-
update_user_meta($current_user->ID, "pmpro_views", $views);
|
341 |
-
}
|
342 |
-
|
343 |
-
//track for all
|
344 |
-
$views = get_option("pmpro_views");
|
345 |
-
if(empty($views))
|
346 |
-
$views = array("today"=>0, "thisdate"=> NULL, "month"=>0, "thismonth"=> NULL, "alltime"=>0);
|
347 |
-
|
348 |
-
$views['alltime']++;
|
349 |
-
$thisdate = date("Y-d-m", $now);
|
350 |
-
if($thisdate == $views['thisdate'])
|
351 |
-
$views['today']++;
|
352 |
-
else
|
353 |
-
{
|
354 |
-
$views['today'] = 1;
|
355 |
-
$views['thisdate'] = $thisdate;
|
356 |
-
}
|
357 |
-
$thismonth = date("n", $now);
|
358 |
-
if(isset($views['thismonth']) && $thismonth == $views['thismonth'])
|
359 |
-
$views['month']++;
|
360 |
-
else
|
361 |
-
{
|
362 |
-
$views['month'] = 1;
|
363 |
-
$views['thismonth'] = $thismonth;
|
364 |
-
}
|
365 |
-
|
366 |
-
update_option("pmpro_views", $views);
|
367 |
-
}
|
368 |
-
add_action("wp", "pmpro_report_login_wp_views");
|
369 |
-
|
370 |
-
//track logins
|
371 |
-
function pmpro_report_login_wp_login($user_login)
|
372 |
-
{
|
373 |
-
$now = current_time('timestamp');
|
374 |
-
|
375 |
-
//get user data
|
376 |
-
$user = get_user_by("login", $user_login);
|
377 |
-
$logins = $user->pmpro_logins;
|
378 |
-
if(empty($logins))
|
379 |
-
$logins = array("last"=>"N/A", "thisdate"=>NULL, "month"=>0, "thismonth"=> NULL, "alltime"=>0);
|
380 |
-
|
381 |
-
//track logins for user
|
382 |
-
$logins['last'] = date(get_option("date_format"), $now);
|
383 |
-
$logins['alltime']++;
|
384 |
-
$thismonth = date("n", $now);
|
385 |
-
if($thismonth == $logins['thismonth'])
|
386 |
-
$logins['month']++;
|
387 |
-
else
|
388 |
-
{
|
389 |
-
$logins['month'] = 1;
|
390 |
-
$logins['thismonth'] = $thismonth;
|
391 |
-
}
|
392 |
-
|
393 |
-
//update user data
|
394 |
-
update_user_meta($user->ID, "pmpro_logins", $logins);
|
395 |
-
|
396 |
-
//track logins overall
|
397 |
-
$logins = get_option("pmpro_logins");
|
398 |
-
if(empty($logins))
|
399 |
-
$logins = array("today"=>0, "thisdate"=>NULL, "month"=>0, "thismonth"=>NULL, "alltime"=>0);
|
400 |
-
|
401 |
-
$logins['alltime']++;
|
402 |
-
$thisdate = date("Y-d-m", $now);
|
403 |
-
if($thisdate == $logins['thisdate'])
|
404 |
-
$logins['today']++;
|
405 |
-
else
|
406 |
-
{
|
407 |
-
$logins['today'] = 1;
|
408 |
-
$logins['thisdate'] = $thisdate;
|
409 |
-
}
|
410 |
-
if($thismonth == $logins['thismonth'])
|
411 |
-
$logins['month']++;
|
412 |
-
else
|
413 |
-
{
|
414 |
-
$logins['month'] = 1;
|
415 |
-
$logins['thismonth'] = $thismonth;
|
416 |
-
}
|
417 |
-
|
418 |
-
update_option("pmpro_logins", $logins);
|
419 |
-
}
|
420 |
add_action("wp_login", "pmpro_report_login_wp_login");
|
1 |
+
<?php
|
2 |
+
/*
|
3 |
+
PMPro Report
|
4 |
+
Title: Logins
|
5 |
+
Slug: login
|
6 |
+
|
7 |
+
For each report, add a line like:
|
8 |
+
global $pmpro_reports;
|
9 |
+
$pmpro_reports['slug'] = 'Title';
|
10 |
+
|
11 |
+
For each report, also write two functions:
|
12 |
+
* pmpro_report_{slug}_widget() to show up on the report homepage.
|
13 |
+
* pmpro_report_{slug}_page() to show up when users click on the report page widget.
|
14 |
+
*/
|
15 |
+
global $pmpro_reports;
|
16 |
+
$pmpro_reports['login'] = __('Visits, Views, and Logins', 'pmpro');
|
17 |
+
|
18 |
+
function pmpro_report_login_widget()
|
19 |
+
{
|
20 |
+
global $wpdb;
|
21 |
+
$now = current_time('timestamp');
|
22 |
+
$visits = get_option("pmpro_visits", array("today"=>0, "thisday"=>date("Y-m-d", $now), "alltime"=>0, "month"=>0, "thismonth"=>date("n", $now)));
|
23 |
+
$views = get_option("pmpro_views", array("today"=>0, "thisday"=>date("Y-m-d", $now), "alltime"=>0, "month"=>0, "thismonth"=>date("n", $now)));
|
24 |
+
$logins = get_option("pmpro_logins", array("today"=>0, "thisday"=>date("Y-m-d", $now), "alltime"=>0, "month"=>0, "thismonth"=>date("n", $now)));
|
25 |
+
?>
|
26 |
+
<div style="width: 33%; float: left;">
|
27 |
+
<p><?php _e('Visits Today', 'pmpro')?>: <?php echo $visits['today'];?></p>
|
28 |
+
<p><?php _e('Visits This Month', 'pmpro')?>: <?php echo $visits['month'];?></p>
|
29 |
+
<p><?php _e('Visits All Time', 'pmpro')?>: <?php echo $visits['alltime'];?></p>
|
30 |
+
</div>
|
31 |
+
<div style="width: 33%; float: left;">
|
32 |
+
<p><?php _e('Views Today', 'pmpro')?>: <?php echo $views['today'];?></p>
|
33 |
+
<p><?php _e('Views This Month', 'pmpro')?>: <?php echo $views['month'];?></p>
|
34 |
+
<p><?php _e('Views All Time', 'pmpro')?>: <?php echo $views['alltime'];?></p>
|
35 |
+
</div>
|
36 |
+
<div style="width: 33%; float: left;">
|
37 |
+
<p><?php _e('Logins Today', 'pmpro')?>: <?php echo $logins['today'];?></p>
|
38 |
+
<p><?php _e('Logins This Month', 'pmpro')?>: <?php echo $logins['month'];?></p>
|
39 |
+
<p><?php _e('Logins All Time', 'pmpro')?>: <?php echo $logins['alltime'];?></p>
|
40 |
+
</div>
|
41 |
+
<div class="clear"></div>
|
42 |
+
<?php
|
43 |
+
}
|
44 |
+
|
45 |
+
function pmpro_report_login_page()
|
46 |
+
{
|
47 |
+
global $wpdb;
|
48 |
+
$now = current_time('timestamp');
|
49 |
+
|
50 |
+
//vars
|
51 |
+
if(!empty($_REQUEST['s']))
|
52 |
+
$s = $_REQUEST['s'];
|
53 |
+
else
|
54 |
+
$s = "";
|
55 |
+
|
56 |
+
if(!empty($_REQUEST['l']))
|
57 |
+
$l = intval($_REQUEST['l']);
|
58 |
+
else
|
59 |
+
$l = "";
|
60 |
+
?>
|
61 |
+
<form id="posts-filter" method="get" action="">
|
62 |
+
<h2>
|
63 |
+
<?php _e('Visits, Views, and Logins Report', 'pmpro');?>
|
64 |
+
</h2>
|
65 |
+
<ul class="subsubsub">
|
66 |
+
<li>
|
67 |
+
<?php _ex('Show', 'Dropdown label, e.g. Show All Users', 'pmpro')?> <select name="l" onchange="jQuery('#posts-filter').submit();">
|
68 |
+
<option value="" <?php if(!$l) { ?>selected="selected"<?php } ?>><?php _e('All Users', 'pmpro')?></option>
|
69 |
+
<option value="all" <?php if($l == "all") { ?>selected="selected"<?php } ?>><?php _e('All Levels', 'pmpro')?></option>
|
70 |
+
<?php
|
71 |
+
$levels = $wpdb->get_results("SELECT id, name FROM $wpdb->pmpro_membership_levels ORDER BY name");
|
72 |
+
foreach($levels as $level)
|
73 |
+
{
|
74 |
+
?>
|
75 |
+
<option value="<?php echo $level->id?>" <?php if($l == $level->id) { ?>selected="selected"<?php } ?>><?php echo $level->name?></option>
|
76 |
+
<?php
|
77 |
+
}
|
78 |
+
?>
|
79 |
+
</select>
|
80 |
+
</li>
|
81 |
+
</ul>
|
82 |
+
<p class="search-box">
|
83 |
+
<label class="hidden" for="post-search-input"><?php _ex('Search', 'Search form label', 'pmpro')?> <?php if(empty($l)) echo "Users"; else echo "Members";?>:</label>
|
84 |
+
<input type="hidden" name="page" value="pmpro-reports" />
|
85 |
+
<input type="hidden" name="report" value="login" />
|
86 |
+
<input id="post-search-input" type="text" value="<?php echo esc_attr($s)?>" name="s"/>
|
87 |
+
<input class="button" type="submit" value="Search Members"/>
|
88 |
+
</p>
|
89 |
+
<?php
|
90 |
+
//some vars for the search
|
91 |
+
if(isset($_REQUEST['pn']))
|
92 |
+
$pn = intval($_REQUEST['pn']);
|
93 |
+
else
|
94 |
+
$pn = 1;
|
95 |
+
|
96 |
+
if(isset($_REQUEST['limit']))
|
97 |
+
$limit = intval($_REQUEST['limit']);
|
98 |
+
else
|
99 |
+
$limit = 15;
|
100 |
+
|
101 |
+
$end = $pn * $limit;
|
102 |
+
$start = $end - $limit;
|
103 |
+
|
104 |
+
if($s)
|
105 |
+
{
|
106 |
+
$sqlQuery = "SELECT SQL_CALC_FOUND_ROWS u.ID, u.user_login, u.user_email, UNIX_TIMESTAMP(u.user_registered) as joindate, mu.membership_id, mu.initial_payment, mu.billing_amount, mu.cycle_period, mu.cycle_number, mu.billing_limit, mu.trial_amount, mu.trial_limit, UNIX_TIMESTAMP(mu.startdate) as startdate, UNIX_TIMESTAMP(mu.enddate) as enddate, m.name as membership FROM $wpdb->users u LEFT JOIN $wpdb->usermeta um ON u.ID = um.user_id LEFT JOIN $wpdb->pmpro_memberships_users mu ON u.ID = mu.user_id AND mu.status = 'active' LEFT JOIN $wpdb->pmpro_membership_levels m ON mu.membership_id = m.id WHERE (u.user_login LIKE '%" . esc_sql($s) . "%' OR u.user_email LIKE '%" . esc_sql($s) . "%' OR um.meta_value LIKE '%" . esc_sql($s) . "%') ";
|
107 |
+
|
108 |
+
if($l == "all")
|
109 |
+
$sqlQuery .= " AND mu.status = 'active' AND mu.membership_id > 0 ";
|
110 |
+
elseif($l)
|
111 |
+
$sqlQuery .= " AND mu.membership_id = '" . $l . "' ";
|
112 |
+
|
113 |
+
$sqlQuery .= "GROUP BY u.ID ORDER BY user_registered DESC LIMIT $start, $limit";
|
114 |
+
}
|
115 |
+
else
|
116 |
+
{
|
117 |
+
$sqlQuery = "SELECT SQL_CALC_FOUND_ROWS u.ID, u.user_login, u.user_email, UNIX_TIMESTAMP(u.user_registered) as joindate, mu.membership_id, mu.initial_payment, mu.billing_amount, mu.cycle_period, mu.cycle_number, mu.billing_limit, mu.trial_amount, mu.trial_limit, UNIX_TIMESTAMP(mu.startdate) as startdate, UNIX_TIMESTAMP(mu.enddate) as enddate, m.name as membership FROM $wpdb->users u LEFT JOIN $wpdb->pmpro_memberships_users mu ON u.ID = mu.user_id AND mu.status = 'active' LEFT JOIN $wpdb->pmpro_membership_levels m ON mu.membership_id = m.id";
|
118 |
+
$sqlQuery .= " WHERE 1=1 ";
|
119 |
+
|
120 |
+
if($l == "all")
|
121 |
+
$sqlQuery .= " AND mu.membership_id > 0 AND mu.status = 'active' ";
|
122 |
+
elseif($l)
|
123 |
+
$sqlQuery .= " AND mu.membership_id = '" . $l . "' ";
|
124 |
+
$sqlQuery .= "GROUP BY u.ID ORDER BY user_registered DESC LIMIT $start, $limit";
|
125 |
+
}
|
126 |
+
|
127 |
+
$sqlQuery = apply_filters("pmpro_members_list_sql", $sqlQuery);
|
128 |
+
|
129 |
+
$theusers = $wpdb->get_results($sqlQuery);
|
130 |
+
$totalrows = $wpdb->get_var("SELECT FOUND_ROWS() as found_rows");
|
131 |
+
|
132 |
+
if($theusers)
|
133 |
+
{
|
134 |
+
?>
|
135 |
+
<p class="clear"><?php echo strval($totalrows)?> <?php if(empty($l)) echo "users"; else echo "members";?> found.
|
136 |
+
<?php
|
137 |
+
}
|
138 |
+
?>
|
139 |
+
<table class="widefat">
|
140 |
+
<thead>
|
141 |
+
<tr class="thead">
|
142 |
+
<th><?php _e('ID', 'pmpro')?></th>
|
143 |
+
<th><?php _e('User', 'pmpro')?></th>
|
144 |
+
<th><?php _e('Name', 'pmpro')?></th>
|
145 |
+
<th><?php _e('Membership', 'pmpro')?></th>
|
146 |
+
<th><?php _e('Joined', 'pmpro')?></th>
|
147 |
+
<th><?php _e('Expires', 'pmpro')?></th>
|
148 |
+
<th><?php _e('Last Visit', 'pmpro')?></th>
|
149 |
+
<th><?php _e('Visits This Month', 'pmpro')?></th>
|
150 |
+
<th><?php _e('Total Visits', 'pmpro')?></th>
|
151 |
+
<th><?php _e('Views This Month', 'pmpro')?></th>
|
152 |
+
<th><?php _e('Total Views', 'pmpro')?></th>
|
153 |
+
<th><?php _e('Last Login', 'pmpro')?></th>
|
154 |
+
<th><?php _e('Logins This Month', 'pmpro')?></th>
|
155 |
+
<th><?php _e('Total Logins', 'pmpro')?></th>
|
156 |
+
</tr>
|
157 |
+
</thead>
|
158 |
+
<tbody id="users" class="list:user user-list">
|
159 |
+
<?php
|
160 |
+
$count = 0;
|
161 |
+
foreach($theusers as $auser)
|
162 |
+
{
|
163 |
+
//get meta
|
164 |
+
$theuser = get_userdata($auser->ID);
|
165 |
+
$visits = get_user_meta($auser->ID, "pmpro_visits", true);
|
166 |
+
$views = get_user_meta($auser->ID, "pmpro_views", true);
|
167 |
+
$logins = get_user_meta($auser->ID, "pmpro_logins", true);
|
168 |
+
if(empty($logins))
|
169 |
+
$logins = array("last"=>"N/A", "month"=>"N/A", "alltime"=>"N/A");
|
170 |
+
?>
|
171 |
+
<tr <?php if($count++ % 2 == 0) { ?>class="alternate"<?php } ?>>
|
172 |
+
<td><?php echo $theuser->ID?></td>
|
173 |
+
<td>
|
174 |
+
<?php echo get_avatar($theuser->ID, 32)?>
|
175 |
+
<strong>
|
176 |
+
<?php
|
177 |
+
$userlink = '<a href="user-edit.php?user_id=' . $theuser->ID . '">' . $theuser->user_login . '</a>';
|
178 |
+
$userlink = apply_filters("pmpro_members_list_user_link", $userlink, $theuser);
|
179 |
+
echo $userlink;
|
180 |
+
?>
|
181 |
+
</strong>
|
182 |
+
</td>
|
183 |
+
<td>
|
184 |
+
<?php echo $theuser->display_name;?>
|
185 |
+
</td>
|
186 |
+
<td><?php echo $auser->membership?></td>
|
187 |
+
<td><?php echo date("m/d/Y", strtotime($theuser->user_registered, current_time("timestamp")))?></td>
|
188 |
+
<td>
|
189 |
+
<?php
|
190 |
+
if($auser->enddate)
|
191 |
+
echo date(get_option('date_format'), $auser->enddate);
|
192 |
+
else
|
193 |
+
echo "Never";
|
194 |
+
?>
|
195 |
+
</td>
|
196 |
+
<td><?php if(!empty($visits['last'])) echo $visits['last'];?></td>
|
197 |
+
<td><?php if(!empty($visits['month']) && pmpro_isDateThisMonth($visits['last'])) echo $visits['month'];?></td>
|
198 |
+
<td><?php if(!empty($visits['alltime'])) echo $visits['alltime'];?></td>
|
199 |
+
<td><?php if(!empty($views['month']) && pmpro_isDateThisMonth($views['last'])) echo $views['month'];?></td>
|
200 |
+
<td><?php if(!empty($views['alltime'])) echo $views['alltime'];?></td>
|
201 |
+
<td><?php if(!empty($logins['last'])) echo $logins['last'];?></td>
|
202 |
+
<td><?php if(!empty($logins['month']) && pmpro_isDateThisMonth($logins['last'])) echo $logins['month'];?></td>
|
203 |
+
<td><?php if(!empty($logins['alltime'])) echo $logins['alltime'];?></td>
|
204 |
+
</tr>
|
205 |
+
<?php
|
206 |
+
}
|
207 |
+
|
208 |
+
if(!$theusers)
|
209 |
+
{
|
210 |
+
?>
|
211 |
+
<tr>
|
212 |
+
<td colspan="9"><p><?php _e('No members found.', 'pmpro')?> <?php if($l) { ?><a href="?page=pmpro-memberslist&s=<?php echo esc_attr($s)?>"><?php _e('Search all levels', 'pmpro')?></a>.<?php } ?></p></td>
|
213 |
+
</tr>
|
214 |
+
<?php
|
215 |
+
}
|
216 |
+
?>
|
217 |
+
</tbody>
|
218 |
+
</table>
|
219 |
+
</form>
|
220 |
+
|
221 |
+
<?php
|
222 |
+
echo pmpro_getPaginationString($pn, $totalrows, $limit, 1, get_admin_url(NULL, "/admin.php?page=pmpro-reports&report=login&s=" . urlencode($s)), "&l=$l&limit=$limit&pn=");
|
223 |
+
?>
|
224 |
+
<?php
|
225 |
+
}
|
226 |
+
|
227 |
+
/*
|
228 |
+
Other code required for your reports. This file is loaded every time WP loads with PMPro enabled.
|
229 |
+
*/
|
230 |
+
|
231 |
+
//track visits
|
232 |
+
function pmpro_report_login_wp_visits()
|
233 |
+
{
|
234 |
+
//don't track admin
|
235 |
+
if(is_admin())
|
236 |
+
return;
|
237 |
+
|
238 |
+
//only track logged in users
|
239 |
+
if(!is_user_logged_in())
|
240 |
+
return;
|
241 |
+
|
242 |
+
//check for cookie
|
243 |
+
if(!empty($_COOKIE['pmpro_visit']))
|
244 |
+
return;
|
245 |
+
|
246 |
+
$now = current_time('timestamp');
|
247 |
+
|
248 |
+
//set cookie, then track
|
249 |
+
setcookie("pmpro_visit", "1", NULL, COOKIEPATH, COOKIE_DOMAIN, false);
|
250 |
+
|
251 |
+
global $current_user;
|
252 |
+
//track for user
|
253 |
+
if(!empty($current_user->ID))
|
254 |
+
{
|
255 |
+
$visits = $current_user->pmpro_visits;
|
256 |
+
if(empty($visits))
|
257 |
+
$visits = array("last"=>"N/A", "thisdate"=>NULL, "month"=>0, "thismonth"=>NULL, "alltime"=>0);
|
258 |
+
|
259 |
+
//track logins for user
|
260 |
+
$visits['last'] = date(get_option("date_format"));
|
261 |
+
$visits['alltime']++;
|
262 |
+
$thismonth = date("n", $now);
|
263 |
+
if($thismonth == $visits['thismonth'])
|
264 |
+
$visits['month']++;
|
265 |
+
else
|
266 |
+
{
|
267 |
+
$visits['month'] = 1;
|
268 |
+
$visits['thismonth'] = $thismonth;
|
269 |
+
}
|
270 |
+
|
271 |
+
//update user data
|
272 |
+
update_user_meta($current_user->ID, "pmpro_visits", $visits);
|
273 |
+
}
|
274 |
+
|
275 |
+
//track for all
|
276 |
+
$visits = get_option("pmpro_visits");
|
277 |
+
if(empty($visits))
|
278 |
+
$visits = array("today"=>0, "thisdate"=>NULL, "month"=>0, "thismonth"=> NULL, "alltime"=>0);
|
279 |
+
|
280 |
+
$visits['alltime']++;
|
281 |
+
$thisdate = date("Y-d-m", $now);
|
282 |
+
if($thisdate == $visits['thisdate'])
|
283 |
+
$visits['today']++;
|
284 |
+
else
|
285 |
+
{
|
286 |
+
$visits['today'] = 1;
|
287 |
+
$visits['thisdate'] = $thisdate;
|
288 |
+
}
|
289 |
+
if($thismonth == $visits['thismonth'])
|
290 |
+
$visits['month']++;
|
291 |
+
else
|
292 |
+
{
|
293 |
+
$visits['month'] = 1;
|
294 |
+
$visits['thismonth'] = $thismonth;
|
295 |
+
}
|
296 |
+
|
297 |
+
update_option("pmpro_visits", $visits);
|
298 |
+
}
|
299 |
+
add_action("wp", "pmpro_report_login_wp_visits");
|
300 |
+
|
301 |
+
//we want to clear the pmpro_visit cookie on login/logout
|
302 |
+
function pmpro_report_login_clear_visit_cookie()
|
303 |
+
{
|
304 |
+
if(isset($_COOKIE['pmpro_visit']))
|
305 |
+
unset($_COOKIE['pmpro_visit']);
|
306 |
+
}
|
307 |
+
add_action("wp_login", "pmpro_report_login_clear_visit_cookie");
|
308 |
+
add_action("wp_logout", "pmpro_report_login_clear_visit_cookie");
|
309 |
+
|
310 |
+
//track views
|
311 |
+
function pmpro_report_login_wp_views()
|
312 |
+
{
|
313 |
+
//don't track admin
|
314 |
+
if(is_admin())
|
315 |
+
return;
|
316 |
+
|
317 |
+
global $current_user;
|
318 |
+
$now = current_time('timestamp');
|
319 |
+
|
320 |
+
//track for user
|
321 |
+
if(!empty($current_user->ID))
|
322 |
+
{
|
323 |
+
$views = $current_user->pmpro_views;
|
324 |
+
if(empty($views))
|
325 |
+
$views = array("last"=>"N/A", "month"=>0, "alltime"=>0);
|
326 |
+
|
327 |
+
//track logins for user
|
328 |
+
$views['last'] = date(get_option("date_format"), $now);
|
329 |
+
$views['alltime']++;
|
330 |
+
$thismonth = date("n", $now);
|
331 |
+
if(isset($views['thismonth']) && $thismonth == $views['thismonth'])
|
332 |
+
$views['month']++;
|
333 |
+
else
|
334 |
+
{
|
335 |
+
$views['month'] = 1;
|
336 |
+
$views['thismonth'] = $thismonth;
|
337 |
+
}
|
338 |
+
|
339 |
+
//update user data
|
340 |
+
update_user_meta($current_user->ID, "pmpro_views", $views);
|
341 |
+
}
|
342 |
+
|
343 |
+
//track for all
|
344 |
+
$views = get_option("pmpro_views");
|
345 |
+
if(empty($views))
|
346 |
+
$views = array("today"=>0, "thisdate"=> NULL, "month"=>0, "thismonth"=> NULL, "alltime"=>0);
|
347 |
+
|
348 |
+
$views['alltime']++;
|
349 |
+
$thisdate = date("Y-d-m", $now);
|
350 |
+
if($thisdate == $views['thisdate'])
|
351 |
+
$views['today']++;
|
352 |
+
else
|
353 |
+
{
|
354 |
+
$views['today'] = 1;
|
355 |
+
$views['thisdate'] = $thisdate;
|
356 |
+
}
|
357 |
+
$thismonth = date("n", $now);
|
358 |
+
if(isset($views['thismonth']) && $thismonth == $views['thismonth'])
|
359 |
+
$views['month']++;
|
360 |
+
else
|
361 |
+
{
|
362 |
+
$views['month'] = 1;
|
363 |
+
$views['thismonth'] = $thismonth;
|
364 |
+
}
|
365 |
+
|
366 |
+
update_option("pmpro_views", $views);
|
367 |
+
}
|
368 |
+
add_action("wp", "pmpro_report_login_wp_views");
|
369 |
+
|
370 |
+
//track logins
|
371 |
+
function pmpro_report_login_wp_login($user_login)
|
372 |
+
{
|
373 |
+
$now = current_time('timestamp');
|
374 |
+
|
375 |
+
//get user data
|
376 |
+
$user = get_user_by("login", $user_login);
|
377 |
+
$logins = $user->pmpro_logins;
|
378 |
+
if(empty($logins))
|
379 |
+
$logins = array("last"=>"N/A", "thisdate"=>NULL, "month"=>0, "thismonth"=> NULL, "alltime"=>0);
|
380 |
+
|
381 |
+
//track logins for user
|
382 |
+
$logins['last'] = date(get_option("date_format"), $now);
|
383 |
+
$logins['alltime']++;
|
384 |
+
$thismonth = date("n", $now);
|
385 |
+
if($thismonth == $logins['thismonth'])
|
386 |
+
$logins['month']++;
|
387 |
+
else
|
388 |
+
{
|
389 |
+
$logins['month'] = 1;
|
390 |
+
$logins['thismonth'] = $thismonth;
|
391 |
+
}
|
392 |
+
|
393 |
+
//update user data
|
394 |
+
update_user_meta($user->ID, "pmpro_logins", $logins);
|
395 |
+
|
396 |
+
//track logins overall
|
397 |
+
$logins = get_option("pmpro_logins");
|
398 |
+
if(empty($logins))
|
399 |
+
$logins = array("today"=>0, "thisdate"=>NULL, "month"=>0, "thismonth"=>NULL, "alltime"=>0);
|
400 |
+
|
401 |
+
$logins['alltime']++;
|
402 |
+
$thisdate = date("Y-d-m", $now);
|
403 |
+
if($thisdate == $logins['thisdate'])
|
404 |
+
$logins['today']++;
|
405 |
+
else
|
406 |
+
{
|
407 |
+
$logins['today'] = 1;
|
408 |
+
$logins['thisdate'] = $thisdate;
|
409 |
+
}
|
410 |
+
if($thismonth == $logins['thismonth'])
|
411 |
+
$logins['month']++;
|
412 |
+
else
|
413 |
+
{
|
414 |
+
$logins['month'] = 1;
|
415 |
+
$logins['thismonth'] = $thismonth;
|
416 |
+
}
|
417 |
+
|
418 |
+
update_option("pmpro_logins", $logins);
|
419 |
+
}
|
420 |
add_action("wp_login", "pmpro_report_login_wp_login");
|
adminpages/reports/memberships.php
CHANGED
@@ -1,660 +1,660 @@
|
|
1 |
-
<?php
|
2 |
-
/*
|
3 |
-
PMPro Report
|
4 |
-
Title: Membership Stats
|
5 |
-
Slug: memberships
|
6 |
-
|
7 |
-
For each report, add a line like:
|
8 |
-
global $pmpro_reports;
|
9 |
-
$pmpro_reports['slug'] = 'Title';
|
10 |
-
|
11 |
-
For each report, also write two functions:
|
12 |
-
* pmpro_report_{slug}_widget() to show up on the report homepage.
|
13 |
-
* pmpro_report_{slug}_page() to show up when users click on the report page widget.
|
14 |
-
*/
|
15 |
-
|
16 |
-
global $pmpro_reports;
|
17 |
-
|
18 |
-
$pmpro_reports['memberships'] = __('Membership Stats', 'pmpro');
|
19 |
-
|
20 |
-
//queue Google Visualization JS on report page
|
21 |
-
function pmpro_report_memberships_init() {
|
22 |
-
if(is_admin() && isset($_REQUEST['report']) && $_REQUEST['report'] == "memberships" && isset($_REQUEST['page']) && $_REQUEST['page'] == "pmpro-reports")
|
23 |
-
wp_enqueue_script("jsapi", "https://www.google.com/jsapi");
|
24 |
-
}
|
25 |
-
add_action( 'init', 'pmpro_report_memberships_init' );
|
26 |
-
|
27 |
-
|
28 |
-
//widget
|
29 |
-
function pmpro_report_memberships_widget() {
|
30 |
-
global $wpdb, $pmpro_currency_symbol;
|
31 |
-
?>
|
32 |
-
<style type="text/css">
|
33 |
-
#pmpro_report_memberships .section-label {
|
34 |
-
margin: 15px 0;
|
35 |
-
font-size: 18px;
|
36 |
-
text-align: left;
|
37 |
-
display: block;
|
38 |
-
}
|
39 |
-
|
40 |
-
#pmpro_report_memberships .section-label:first-child {
|
41 |
-
margin-top: 0;
|
42 |
-
}
|
43 |
-
|
44 |
-
#pmpro_report_memberships div {text-align: center;}
|
45 |
-
#pmpro_report_memberships em {display: block; font-style: normal; font-size: 2em; margin: 5px; line-height: 26px;}
|
46 |
-
</style>
|
47 |
-
<span id="pmpro_report_memberships">
|
48 |
-
<label class="section-label"><?php _e('Signups', 'pmpro');?>:</label>
|
49 |
-
<div style="width: 25%; float: left;">
|
50 |
-
<label><?php _e('All Time', 'pmpro');?></label>
|
51 |
-
<em><?php echo pmpro_getSignups( 'all time' ); ?></em>
|
52 |
-
</div>
|
53 |
-
<div style="width: 25%; float: left;">
|
54 |
-
<label><?php _e('This Year', 'pmpro');?></label>
|
55 |
-
<em><?php echo pmpro_getSignups( 'this year' ); ?></em>
|
56 |
-
</div>
|
57 |
-
<div style="width: 25%; float: left;">
|
58 |
-
<label><?php _e('This Month', 'pmpro');?></label>
|
59 |
-
<em><?php echo pmpro_getSignups( 'this month' ); ?></em>
|
60 |
-
</div>
|
61 |
-
<div style="width: 25%; float: left;">
|
62 |
-
<label><?php _e('Today', 'pmpro');?></label>
|
63 |
-
<em><?php echo pmpro_getSignups( 'today' ); ?></em>
|
64 |
-
</div>
|
65 |
-
<div class="clear"></div>
|
66 |
-
|
67 |
-
<label class="section-label"><?php _e('Cancellations', 'pmpro');?>:</label>
|
68 |
-
<div style="width: 25%; float: left;">
|
69 |
-
<label><?php _e('All Time', 'pmpro');?></label>
|
70 |
-
<em><?php echo pmpro_getCancellations( 'all time' ); ?></em>
|
71 |
-
</div>
|
72 |
-
<div style="width: 25%; float: left;">
|
73 |
-
<label><?php _e('This Year', 'pmpro');?></label>
|
74 |
-
<em><?php echo pmpro_getCancellations( 'this year' ); ?></em>
|
75 |
-
</div>
|
76 |
-
<div style="width: 25%; float: left;">
|
77 |
-
<label><?php _e('This Month', 'pmpro');?></label>
|
78 |
-
<em><?php echo pmpro_getCancellations( 'this month' ); ?></em>
|
79 |
-
</div>
|
80 |
-
<div style="width: 25%; float: left;">
|
81 |
-
<label><?php _e('Today', 'pmpro');?></label>
|
82 |
-
<em><?php echo pmpro_getCancellations( 'today' ); ?></em>
|
83 |
-
</div>
|
84 |
-
<div class="clear"></div>
|
85 |
-
|
86 |
-
<label class="section-label"><?php _e('Other Stats', 'pmpro');?>:</label>
|
87 |
-
<div style="width: 33%; float: left;">
|
88 |
-
<label><?php _e('Monthly Recurring Revenue (MRR)', 'pmpro');?></label>
|
89 |
-
<em><?php echo pmpro_formatPrice(pmpro_getMRR( 'all time' )); ?></em>
|
90 |
-
</div>
|
91 |
-
<div style="width: 33%; float: left;">
|
92 |
-
<label><?php _e('Cancellation Rate', 'pmpro');?></label>
|
93 |
-
<em><?php echo pmpro_getCancellationRate('all time' ); ?>%</em>
|
94 |
-
</div>
|
95 |
-
<div style="width: 33%; float: left;">
|
96 |
-
<label><?php _e('Lifetime Value (LTV)', 'pmpro');?></label>
|
97 |
-
<em><?php echo pmpro_formatPrice(pmpro_getLTV('all time')); ?></em>
|
98 |
-
</div>
|
99 |
-
<div class="clear"></div>
|
100 |
-
</span>
|
101 |
-
<?php
|
102 |
-
}
|
103 |
-
|
104 |
-
function pmpro_report_memberships_page()
|
105 |
-
{
|
106 |
-
global $wpdb, $pmpro_currency_symbol;
|
107 |
-
|
108 |
-
//get values from form
|
109 |
-
if(isset($_REQUEST['type']))
|
110 |
-
$type = sanitize_text_field($_REQUEST['type']);
|
111 |
-
else
|
112 |
-
$type = "signup_v_cancel";
|
113 |
-
|
114 |
-
if(isset($_REQUEST['period']))
|
115 |
-
$period = sanitize_text_field($_REQUEST['period']);
|
116 |
-
else
|
117 |
-
$period = "monthly";
|
118 |
-
|
119 |
-
if(isset($_REQUEST['month']))
|
120 |
-
$month = intval($_REQUEST['month']);
|
121 |
-
else
|
122 |
-
$month = date("n");
|
123 |
-
|
124 |
-
$thisyear = date("Y");
|
125 |
-
if(isset($_REQUEST['year']))
|
126 |
-
$year = intval($_REQUEST['year']);
|
127 |
-
else
|
128 |
-
$year = date("Y");
|
129 |
-
|
130 |
-
if(isset($_REQUEST['level']))
|
131 |
-
$l = intval($_REQUEST['level']);
|
132 |
-
else
|
133 |
-
$l = "";
|
134 |
-
|
135 |
-
//calculate start date and how to group dates returned from DB
|
136 |
-
if($period == "daily")
|
137 |
-
{
|
138 |
-
$startdate = $year . '-' . substr("0" . $month, strlen($month) - 1, 2) . '-01';
|
139 |
-
$enddate = $year . '-' . substr("0" . $month, strlen($month) - 1, 2) . '-31';
|
140 |
-
$date_function = 'DAY';
|
141 |
-
}
|
142 |
-
elseif($period == "monthly")
|
143 |
-
{
|
144 |
-
$startdate = $year . '-01-01';
|
145 |
-
$enddate = strval(intval($year)+1) . '-01-01';
|
146 |
-
$date_function = 'MONTH';
|
147 |
-
}
|
148 |
-
elseif($period == "annual")
|
149 |
-
{
|
150 |
-
$startdate = '1960-01-01'; //all time
|
151 |
-
$date_function = 'YEAR';
|
152 |
-
}
|
153 |
-
|
154 |
-
//testing or live data
|
155 |
-
$gateway_environment = pmpro_getOption("gateway_environment");
|
156 |
-
|
157 |
-
//get data
|
158 |
-
if ( $type === "signup_v_cancel" ) {
|
159 |
-
$sqlQuery = "SELECT $date_function(startdate) as date, COUNT(DISTINCT user_id) as signups
|
160 |
-
FROM $wpdb->pmpro_memberships_users WHERE startdate >= '" . $startdate . "' ";
|
161 |
-
|
162 |
-
if(!empty($enddate))
|
163 |
-
$sqlQuery .= "AND startdate < '" . $enddate . "' ";
|
164 |
-
}
|
165 |
-
if ( $type === "mrr_ltv" ) {
|
166 |
-
// Get total revenue, number of months in system, and date
|
167 |
-
if ( $period == 'annual' )
|
168 |
-
$sqlQuery = "SELECT SUM(total) as total, COUNT(DISTINCT MONTH(timestamp)) as months, $date_function(timestamp) as date
|
169 |
-
FROM $wpdb->pmpro_membership_orders WHERE status NOT IN('refunded', 'review', 'token')
|
170 |
-
AND timestamp >= '" . $startdate . "' AND gateway_environment = '" . esc_sql($gateway_environment) . "' ";
|
171 |
-
|
172 |
-
if ( $period == 'monthly' )
|
173 |
-
$sqlQuery = "SELECT SUM(total) as total, $date_function(timestamp) as date
|
174 |
-
FROM $wpdb->pmpro_membership_orders WHERE status NOT IN('refunded', 'review', 'token')
|
175 |
-
AND timestamp >= '" . $startdate . "' AND gateway_environment = '" . esc_sql($gateway_environment) . "' ";
|
176 |
-
|
177 |
-
if(!empty($enddate))
|
178 |
-
$sqlQuery .= "AND timestamp < '" . $enddate . "' ";
|
179 |
-
}
|
180 |
-
|
181 |
-
if(!empty($l))
|
182 |
-
$sqlQuery .= "AND membership_id IN(" . $l . ") ";
|
183 |
-
|
184 |
-
$sqlQuery .= " GROUP BY date ORDER BY date ";
|
185 |
-
|
186 |
-
$dates = $wpdb->get_results($sqlQuery);
|
187 |
-
|
188 |
-
//fill in blanks in dates
|
189 |
-
$cols = array();
|
190 |
-
if($period == "daily")
|
191 |
-
{
|
192 |
-
$lastday = date("t", strtotime($startdate, current_time("timestamp")));
|
193 |
-
|
194 |
-
for($i = 1; $i <= $lastday; $i++)
|
195 |
-
{
|
196 |
-
// Signups vs. Cancellations
|
197 |
-
if ( $type === "signup_v_cancel" ) {
|
198 |
-
$cols[$i] = new stdClass();
|
199 |
-
$cols[$i]->signups = 0;
|
200 |
-
foreach($dates as $date)
|
201 |
-
{
|
202 |
-
if( $date->date == $i ) {
|
203 |
-
$cols[$i]->signups = $date->signups;
|
204 |
-
}
|
205 |
-
}
|
206 |
-
}
|
207 |
-
}
|
208 |
-
}
|
209 |
-
elseif($period == "monthly")
|
210 |
-
{
|
211 |
-
for($i = 1; $i < 13; $i++)
|
212 |
-
{
|
213 |
-
// Signups vs. Cancellations
|
214 |
-
if ( $type === "signup_v_cancel" ) {
|
215 |
-
$cols[$i] = new stdClass();
|
216 |
-
$cols[$i]->date = $i;
|
217 |
-
$cols[$i]->signups = 0;
|
218 |
-
foreach($dates as $date)
|
219 |
-
{
|
220 |
-
if( $date->date == $i ) {
|
221 |
-
$cols[$i]->date = $date->date;
|
222 |
-
$cols[$i]->signups = $date->signups;
|
223 |
-
}
|
224 |
-
}
|
225 |
-
}
|
226 |
-
|
227 |
-
// MRR & LTV
|
228 |
-
if ( $type === "mrr_ltv" ) {
|
229 |
-
$cols[$i] = new stdClass();
|
230 |
-
$cols[$i]->date = $i;
|
231 |
-
$cols[$i]->months = 1;
|
232 |
-
foreach($dates as $date)
|
233 |
-
{
|
234 |
-
if( $date->date == $i ) {
|
235 |
-
$cols[$i]->total = $date->total;
|
236 |
-
}
|
237 |
-
}
|
238 |
-
}
|
239 |
-
}
|
240 |
-
}
|
241 |
-
elseif($period == "annual") //annual
|
242 |
-
{
|
243 |
-
}
|
244 |
-
|
245 |
-
$dates = ( ! empty( $cols ) ) ? $cols : $dates;
|
246 |
-
|
247 |
-
// Signups vs. cancellations
|
248 |
-
if ( $type === "signup_v_cancel" )
|
249 |
-
{
|
250 |
-
$sqlQuery = "SELECT $date_function(mu1.modified) as date, COUNT(DISTINCT mu1.user_id) as cancellations
|
251 |
-
FROM $wpdb->pmpro_memberships_users mu1
|
252 |
-
LEFT JOIN $wpdb->pmpro_memberships_users mu2 ON mu1.user_id = mu2.user_id AND
|
253 |
-
mu2.modified > mu1.enddate AND
|
254 |
-
DATE_ADD(mu1.modified, INTERVAL 1 DAY) > mu2.startdate
|
255 |
-
WHERE mu1.status = 'inactive'
|
256 |
-
AND mu2.id IS NULL
|
257 |
-
AND mu1.startdate >= '" . $startdate . "'
|
258 |
-
AND mu1.startdate < '" . $enddate . "' ";
|
259 |
-
|
260 |
-
//restrict by level
|
261 |
-
if(!empty($l))
|
262 |
-
$sqlQuery .= "AND membership_id IN(" . $l . ") ";
|
263 |
-
|
264 |
-
$sqlQuery .= " GROUP BY date ORDER BY date ";
|
265 |
-
|
266 |
-
$cdates = $wpdb->get_results($sqlQuery, OBJECT_K);
|
267 |
-
|
268 |
-
foreach( $dates as &$date )
|
269 |
-
{
|
270 |
-
if(!empty($cdates[$date->date]))
|
271 |
-
$date->cancellations = $cdates[$date->date]->cancellations;
|
272 |
-
else
|
273 |
-
$date->cancellations = 0;
|
274 |
-
}
|
275 |
-
}
|
276 |
-
|
277 |
-
// MRR & LTV
|
278 |
-
if ( $type === "mrr_ltv" && count( $dates ) === 1 ) {
|
279 |
-
$dummy_date = new stdClass();
|
280 |
-
$dummy_date->total = 0;
|
281 |
-
$dummy_date->months = 0;
|
282 |
-
$dummy_date->date = $dates[0]->date - 1;
|
283 |
-
array_unshift( $dates, $dummy_date ); // Add to beginning
|
284 |
-
}
|
285 |
-
?>
|
286 |
-
<form id="posts-filter" method="get" action="">
|
287 |
-
<h2>
|
288 |
-
<?php _e('Membership Stats', 'pmpro');?>
|
289 |
-
</h2>
|
290 |
-
<ul class="subsubsub">
|
291 |
-
<li>
|
292 |
-
<?php _ex('Show', 'Dropdown label, e.g. Show Daily Revenue for January', 'pmpro')?>
|
293 |
-
<select id="period" name="period">
|
294 |
-
<option value="daily" <?php selected($period, "daily");?>><?php _e('Daily', 'pmpro');?></option>
|
295 |
-
<option value="monthly" <?php selected($period, "monthly");?>><?php _e('Monthly', 'pmpro');?></option>
|
296 |
-
<option value="annual" <?php selected($period, "annual");?>><?php _e('Annual', 'pmpro');?></option>
|
297 |
-
</select>
|
298 |
-
<select id="type" name="type">
|
299 |
-
<option value="signup_v_cancel" <?php selected($type, "signup_v_cancel");?>><?php _e('Signups vs. Cancellations', 'pmpro');?></option>
|
300 |
-
<?php /*
|
301 |
-
<option value="mrr_ltv" <?php selected($type, "mrr_ltv");?>><?php _e('MRR & LTV', 'pmpro');?></option>
|
302 |
-
*/ ?>
|
303 |
-
</select>
|
304 |
-
<span id="for"><?php _ex('for', 'Dropdown label, e.g. Show Daily Revenue for January', 'pmpro')?></span>
|
305 |
-
<select id="month" name="month">
|
306 |
-
<?php for($i = 1; $i < 13; $i++) { ?>
|
307 |
-
<option value="<?php echo $i;?>" <?php selected($month, $i);?>><?php echo date("F", mktime(0, 0, 0, $i, 2));?></option>
|
308 |
-
<?php } ?>
|
309 |
-
</select>
|
310 |
-
<select id="year" name="year">
|
311 |
-
<?php for($i = $thisyear; $i > 2007; $i--) { ?>
|
312 |
-
<option value="<?php echo $i;?>" <?php selected($year, $i);?>><?php echo $i;?></option>
|
313 |
-
<?php } ?>
|
314 |
-
</select>
|
315 |
-
<span id="for"><?php _ex('for', 'Dropdown label, e.g. Show Daily Revenue for January', 'pmpro')?></span>
|
316 |
-
<select name="level">
|
317 |
-
<option value="" <?php if(!$l) { ?>selected="selected"<?php } ?>><?php _e('All Levels', 'pmpro');?></option>
|
318 |
-
<?php
|
319 |
-
$levels = $wpdb->get_results("SELECT id, name FROM $wpdb->pmpro_membership_levels ORDER BY name");
|
320 |
-
foreach($levels as $level)
|
321 |
-
{
|
322 |
-
?>
|
323 |
-
<option value="<?php echo $level->id?>" <?php if($l == $level->id) { ?>selected="selected"<?php } ?>><?php echo $level->name?></option>
|
324 |
-
<?php
|
325 |
-
}
|
326 |
-
?>
|
327 |
-
</select>
|
328 |
-
|
329 |
-
<input type="hidden" name="page" value="pmpro-reports" />
|
330 |
-
<input type="hidden" name="report" value="memberships" />
|
331 |
-
<input type="submit" value="<?php _ex('Generate Report', 'Submit button value.', 'pmpro');?>" />
|
332 |
-
</li>
|
333 |
-
</ul>
|
334 |
-
|
335 |
-
<div id="chart_div" style="clear: both; width: 100%; height: 500px;"></div>
|
336 |
-
|
337 |
-
<script>
|
338 |
-
//update month/year when period dropdown is changed
|
339 |
-
jQuery(document).ready(function() {
|
340 |
-
jQuery('#period').change(function() {
|
341 |
-
pmpro_ShowMonthOrYear();
|
342 |
-
});
|
343 |
-
});
|
344 |
-
|
345 |
-
function pmpro_ShowMonthOrYear()
|
346 |
-
{
|
347 |
-
var period = jQuery('#period').val();
|
348 |
-
if(period == 'daily')
|
349 |
-
{
|
350 |
-
jQuery('#for').show();
|
351 |
-
jQuery('#month').show();
|
352 |
-
jQuery('#year').show();
|
353 |
-
}
|
354 |
-
else if(period == 'monthly')
|
355 |
-
{
|
356 |
-
jQuery('#for').show();
|
357 |
-
jQuery('#month').hide();
|
358 |
-
jQuery('#year').show();
|
359 |
-
}
|
360 |
-
else
|
361 |
-
{
|
362 |
-
jQuery('#for').hide();
|
363 |
-
jQuery('#month').hide();
|
364 |
-
jQuery('#year').hide();
|
365 |
-
}
|
366 |
-
}
|
367 |
-
|
368 |
-
pmpro_ShowMonthOrYear();
|
369 |
-
|
370 |
-
//draw the chart
|
371 |
-
google.load("visualization", "1", {packages:["corechart"]});
|
372 |
-
google.setOnLoadCallback(drawChart);
|
373 |
-
function drawChart() {
|
374 |
-
|
375 |
-
var data = google.visualization.arrayToDataTable([
|
376 |
-
<?php if ( $type === "signup_v_cancel" ) : // Signups vs. cancellations ?>
|
377 |
-
['<?php echo $date_function;?>', 'Signups', 'Cancellations'],
|
378 |
-
<?php foreach($dates as $key => $value) { ?>
|
379 |
-
['<?php if($period == "monthly") echo date("M", mktime(0,0,0,$value->date,2)); else if($period == "daily") echo $key; else echo $value->date;?>', <?php echo $value->signups; ?>, <?php echo $value->cancellations; ?>],
|
380 |
-
<?php } ?>
|
381 |
-
<?php endif; ?>
|
382 |
-
|
383 |
-
<?php if ( $type === "mrr_ltv" ) : // Signups vs. cancellations ?>
|
384 |
-
['<?php echo $date_function;?>', 'MRR', 'LTV'],
|
385 |
-
<?php foreach($dates as $key => $value) { ?>
|
386 |
-
['<?php if($period == "monthly") echo date("M", mktime(0,0,0,$value->date,2)); else if($period == "daily") echo $key; else echo $value->date;?>', <?php echo (($mrr = $value->total / $value->months) && $mrr != 0) ? $mrr : 0; ?>, <?php echo pmpro_getLTV($period, NULL, $mrr ); ?>],
|
387 |
-
<?php } ?>
|
388 |
-
<?php endif; ?>
|
389 |
-
]);
|
390 |
-
|
391 |
-
var options = {
|
392 |
-
colors: ['#0099c6', '#dc3912'],
|
393 |
-
hAxis: {title: '<?php echo $date_function;?>', titleTextStyle: {color: 'black'}, maxAlternation: 1},
|
394 |
-
vAxis: {color: 'green', titleTextStyle: {color: '#51a351'}},
|
395 |
-
};
|
396 |
-
|
397 |
-
<?php if ( $type === "signup_v_cancel" ) : // Signups vs. cancellations ?>
|
398 |
-
var chart = new google.visualization.ColumnChart(document.getElementById('chart_div'));
|
399 |
-
<?php elseif ( $type === "mrr_ltv" ) : // MRR & LTV ?>
|
400 |
-
|
401 |
-
<?php
|
402 |
-
//prefix or suffix?
|
403 |
-
if(pmpro_getCurrencyPosition() == "right")
|
404 |
-
$position = "suffix";
|
405 |
-
else
|
406 |
-
$position = "prefix";
|
407 |
-
?>
|
408 |
-
|
409 |
-
var formatter = new google.visualization.NumberFormat({<?php echo $position;?>: '<?php echo html_entity_decode($pmpro_currency_symbol);?>'});
|
410 |
-
formatter.format(data, 2);
|
411 |
-
var formatter = new google.visualization.NumberFormat({<?php echo $position;?>: '<?php echo html_entity_decode($pmpro_currency_symbol);?>'});
|
412 |
-
formatter.format(data, 1);
|
413 |
-
|
414 |
-
var chart = new google.visualization.LineChart(document.getElementById('chart_div'));
|
415 |
-
<?php endif; ?>
|
416 |
-
chart.draw(data, options);
|
417 |
-
}
|
418 |
-
</script>
|
419 |
-
|
420 |
-
</form>
|
421 |
-
<?php
|
422 |
-
}
|
423 |
-
|
424 |
-
|
425 |
-
|
426 |
-
/*
|
427 |
-
Other code required for your reports. This file is loaded every time WP loads with PMPro enabled.
|
428 |
-
*/
|
429 |
-
|
430 |
-
//get signups
|
431 |
-
function pmpro_getSignups($period = false, $levels = 'all')
|
432 |
-
{
|
433 |
-
//check for a transient
|
434 |
-
$cache = get_transient( 'pmpro_report_memberships_signups' );
|
435 |
-
if( ! empty( $cache ) && ! empty( $cache[$period] ) && ! empty( $cache[$period][$levels] ) )
|
436 |
-
return $cache[$period][$levels];
|
437 |
-
|
438 |
-
//a sale is an order with status = success
|
439 |
-
if( $period == 'today' )
|
440 |
-
$startdate = date(' Y-m-d' );
|
441 |
-
elseif( $period == 'this month')
|
442 |
-
$startdate = date( 'Y-m' ) . '-01';
|
443 |
-
elseif( $period == 'this year')
|
444 |
-
$startdate = date( 'Y' ) . '-01-01';
|
445 |
-
else
|
446 |
-
$startdate = '';
|
447 |
-
|
448 |
-
|
449 |
-
//build query
|
450 |
-
global $wpdb;
|
451 |
-
|
452 |
-
$sqlQuery = "SELECT COUNT(DISTINCT user_id) FROM $wpdb->pmpro_memberships_users WHERE startdate >= '" . $startdate . "' ";
|
453 |
-
|
454 |
-
//restrict by level
|
455 |
-
if(!empty($levels) && $levels != 'all')
|
456 |
-
$sqlQuery .= "AND membership_id IN(" . $levels . ") ";
|
457 |
-
|
458 |
-
$signups = $wpdb->get_var($sqlQuery);
|
459 |
-
|
460 |
-
//save in cache
|
461 |
-
if(!empty($cache) && !empty($cache[$period]))
|
462 |
-
$cache[$period][$levels] = $signups;
|
463 |
-
elseif(!empty($cache))
|
464 |
-
$cache[$period] = array($levels => $signups);
|
465 |
-
else
|
466 |
-
$cache = array($period => array($levels => $signups));
|
467 |
-
|
468 |
-
set_transient("pmpro_report_memberships_signups", $cache, 3600*24);
|
469 |
-
|
470 |
-
return $signups;
|
471 |
-
}
|
472 |
-
|
473 |
-
//get cancellations
|
474 |
-
function pmpro_getCancellations($period = false, $levels = 'all')
|
475 |
-
{
|
476 |
-
//check for a transient
|
477 |
-
$cache = get_transient( 'pmpro_report_memberships_cancellations' );
|
478 |
-
if( ! empty( $cache ) && ! empty( $cache[$period] ) && ! empty( $cache[$period][$levels] ) )
|
479 |
-
return $cache[$period][$levels];
|
480 |
-
|
481 |
-
//figure out start date
|
482 |
-
if( $period == 'today' )
|
483 |
-
$startdate = date(' Y-m-d' );
|
484 |
-
elseif( $period == 'this month')
|
485 |
-
$startdate = date( 'Y-m' ) . '-01';
|
486 |
-
elseif( $period == 'this year')
|
487 |
-
$startdate = date( 'Y' ) . '-01-01';
|
488 |
-
else
|
489 |
-
$startdate = '';
|
490 |
-
|
491 |
-
$startdate_plus_one = strtotime( $startdate . + ' + 1 day', current_time("timestamp") );
|
492 |
-
|
493 |
-
/*
|
494 |
-
build query.
|
495 |
-
cancellations are marked in the memberships users table with status = 'inactive'
|
496 |
-
we try to ignore cancellations when the user gets a new level with 24 hours (probably an upgrade or downgrade)
|
497 |
-
*/
|
498 |
-
global $wpdb;
|
499 |
-
|
500 |
-
//$sqlQuery = "SELECT mu1.user_id, mu2.user_id FROM $wpdb->pmpro_memberships_users mu1 LEFT JOIN $wpdb->pmpro_memberships_users mu2 ON mu1.user_id = mu2.user_id AND mu2.status = 'inactive' AND mu2.startdate > mu1.startdate";
|
501 |
-
$sqlQuery = "SELECT COUNT(mu1.id)
|
502 |
-
FROM $wpdb->pmpro_memberships_users mu1
|
503 |
-
LEFT JOIN $wpdb->pmpro_memberships_users mu2 ON mu1.user_id = mu2.user_id AND
|
504 |
-
mu2.modified > mu1.enddate AND
|
505 |
-
DATE_ADD(mu1.modified, INTERVAL 1 DAY) > mu2.startdate
|
506 |
-
WHERE mu1.status = 'inactive'
|
507 |
-
AND mu2.id IS NULL
|
508 |
-
AND mu1.startdate >= '" . $startdate . "' ";
|
509 |
-
|
510 |
-
//restrict by level
|
511 |
-
if(!empty($levels) && $levels != 'all')
|
512 |
-
$sqlQuery .= "AND membership_id IN(" . $levels . ") ";
|
513 |
-
|
514 |
-
$cancellations = $wpdb->get_var($sqlQuery);
|
515 |
-
|
516 |
-
//save in cache
|
517 |
-
if(!empty($cache) && !empty($cache[$period]) && is_array($cache[$period]))
|
518 |
-
$cache[$period][$levels] = $cancellations;
|
519 |
-
elseif(!empty($cache))
|
520 |
-
$cache[$period] = array($levels => $cancellations);
|
521 |
-
else
|
522 |
-
$cache = array($period => array($levels => $cancellations));
|
523 |
-
|
524 |
-
set_transient("pmpro_report_memberships_cancellations", $cache, 3600*24);
|
525 |
-
|
526 |
-
return $cancellations;
|
527 |
-
}
|
528 |
-
|
529 |
-
//get MRR
|
530 |
-
function pmpro_getMRR($period, $levels = 'all')
|
531 |
-
{
|
532 |
-
//check for a transient
|
533 |
-
//$cache = get_transient("pmpro_report_mrr");
|
534 |
-
if(!empty($cache) && !empty($cache[$period]) && !empty($cache[$period][$levels]))
|
535 |
-
return $cache[$period][$levels];
|
536 |
-
|
537 |
-
//a sale is an order with status NOT IN refunded, review, token, error
|
538 |
-
if($period == "this month")
|
539 |
-
$startdate = date("Y-m") . "-01";
|
540 |
-
elseif($period == "this year")
|
541 |
-
$startdate = date("Y") . "-01-01";
|
542 |
-
else
|
543 |
-
$startdate = "";
|
544 |
-
|
545 |
-
$gateway_environment = pmpro_getOption("gateway_environment");
|
546 |
-
|
547 |
-
//build query
|
548 |
-
global $wpdb;
|
549 |
-
// Get total revenue
|
550 |
-
$sqlQuery = "SELECT SUM(total) FROM $wpdb->pmpro_membership_orders WHERE status NOT IN('refunded', 'review', 'token', 'error') AND timestamp >= '" . $startdate . "' AND gateway_environment = '" . esc_sql($gateway_environment) . "' ";
|
551 |
-
|
552 |
-
//restrict by level
|
553 |
-
if(!empty($levels) && $levels != 'all') {
|
554 |
-
$sqlQuery .= "AND membership_id IN(" . $levels . ") ";
|
555 |
-
}
|
556 |
-
|
557 |
-
$revenue = $wpdb->get_var($sqlQuery);
|
558 |
-
|
559 |
-
//when was the first order
|
560 |
-
$first_order_timestamp = $wpdb->get_var("SELECT UNIX_TIMESTAMP(`timestamp`) FROM $wpdb->pmpro_membership_orders WHERE `timestamp` IS NOT NULL AND `timestamp` > '0000-00-00 00:00:00' ORDER BY `timestamp` LIMIT 1");
|
561 |
-
|
562 |
-
//if we don't have a timestamp, we can't do this
|
563 |
-
if(empty($first_order_timestamp))
|
564 |
-
return false;
|
565 |
-
|
566 |
-
//how many months ago was the first order
|
567 |
-
$months = $wpdb->get_var("SELECT PERIOD_DIFF('" . date("Ym") . "', '" . date("Ym", $first_order_timestamp) . "')");
|
568 |
-
|
569 |
-
/* this works in PHP 5.3+ without using MySQL to get the diff
|
570 |
-
$date1 = new DateTime(date("Y-m-d", $first_order_timestamp));
|
571 |
-
$date2 = new DateTime(date("Y-m-d"));
|
572 |
-
$interval = $date1->diff($date2);
|
573 |
-
$years = intval($interval->format('%y'));
|
574 |
-
$months = $years*12 + intval($interval->format('%m'));
|
575 |
-
*/
|
576 |
-
|
577 |
-
if($months > 0)
|
578 |
-
$mrr = $revenue / $months;
|
579 |
-
else
|
580 |
-
$mrr = 0;
|
581 |
-
|
582 |
-
//save in cache
|
583 |
-
if(!empty($cache) && !empty($cache[$period]))
|
584 |
-
$cache[$period][$levels] = $mrr;
|
585 |
-
elseif(!empty($cache))
|
586 |
-
$cache[$period] = array($levels => $mrr);
|
587 |
-
else
|
588 |
-
$cache = array($period => array($levels => $mrr));
|
589 |
-
|
590 |
-
set_transient("pmpro_report_mrr", $cache, 3600*24);
|
591 |
-
|
592 |
-
return $mrr;
|
593 |
-
}
|
594 |
-
|
595 |
-
//get Cancellation Rate
|
596 |
-
function pmpro_getCancellationRate($period, $levels = 'all')
|
597 |
-
{
|
598 |
-
//check for a transient
|
599 |
-
$cache = get_transient("pmpro_report_cancellation_rate");
|
600 |
-
if(!empty($cache) && !empty($cache[$period]) && !empty($cache[$period][$levels]))
|
601 |
-
return $cache[$period][$levels];
|
602 |
-
|
603 |
-
$signups = pmpro_getSignups($period, $levels);
|
604 |
-
$cancellations = pmpro_getCancellations($period, $levels);
|
605 |
-
|
606 |
-
if(empty($signups))
|
607 |
-
return false;
|
608 |
-
|
609 |
-
$rate = number_format(($cancellations / $signups)*100, 2);
|
610 |
-
|
611 |
-
//save in cache
|
612 |
-
if(!empty($cache) && !empty($cache[$period]))
|
613 |
-
$cache[$period][$levels] = $rate;
|
614 |
-
elseif(!empty($cache))
|
615 |
-
$cache[$period] = array($levels => $rate);
|
616 |
-
else
|
617 |
-
$cache = array($period => array($levels => $rate));
|
618 |
-
|
619 |
-
set_transient("pmpro_report_cancellation_rate", $cache, 3600*24);
|
620 |
-
|
621 |
-
return $rate;
|
622 |
-
}
|
623 |
-
|
624 |
-
//get LTV
|
625 |
-
function pmpro_getLTV($period, $levels = 'all', $mrr = NULL, $signups = NULL, $cancellation_rate = NULL)
|
626 |
-
{
|
627 |
-
if(empty($mrr))
|
628 |
-
$mrr = pmpro_getMRR($period, $levels);
|
629 |
-
if(empty($signups))
|
630 |
-
$signups = pmpro_getSignups($period, $levels);
|
631 |
-
if(empty($cancellation_rate))
|
632 |
-
$cancellation_rate = pmpro_getCancellationRate($period, $levels);
|
633 |
-
|
634 |
-
//average monthly spend
|
635 |
-
if(empty($signups))
|
636 |
-
return false;
|
637 |
-
|
638 |
-
if($signups > 0)
|
639 |
-
$ams = $mrr / $signups;
|
640 |
-
else
|
641 |
-
$ams = 0;
|
642 |
-
|
643 |
-
if($cancellation_rate > 0)
|
644 |
-
$ltv = $ams * (1/$cancellation_rate);
|
645 |
-
else
|
646 |
-
$ltv = $ams;
|
647 |
-
|
648 |
-
return $ltv;
|
649 |
-
}
|
650 |
-
|
651 |
-
//delete transients when an order goes through
|
652 |
-
function pmpro_report_memberships_delete_transients()
|
653 |
-
{
|
654 |
-
delete_transient("pmpro_report_mrr");
|
655 |
-
delete_transient("pmpro_report_cancellation_rate");
|
656 |
-
delete_transient("pmpro_report_memberships_cancellations");
|
657 |
-
delete_transient("pmpro_report_memberships_signups");
|
658 |
-
}
|
659 |
-
add_action("pmpro_after_checkout", "pmpro_report_memberships_delete_transients");
|
660 |
-
add_action("pmpro_updated_order", "pmpro_report_memberships_delete_transients");
|
1 |
+
<?php
|
2 |
+
/*
|
3 |
+
PMPro Report
|
4 |
+
Title: Membership Stats
|
5 |
+
Slug: memberships
|
6 |
+
|
7 |
+
For each report, add a line like:
|
8 |
+
global $pmpro_reports;
|
9 |
+
$pmpro_reports['slug'] = 'Title';
|
10 |
+
|
11 |
+
For each report, also write two functions:
|
12 |
+
* pmpro_report_{slug}_widget() to show up on the report homepage.
|
13 |
+
* pmpro_report_{slug}_page() to show up when users click on the report page widget.
|
14 |
+
*/
|
15 |
+
|
16 |
+
global $pmpro_reports;
|
17 |
+
|
18 |
+
$pmpro_reports['memberships'] = __('Membership Stats', 'pmpro');
|
19 |
+
|
20 |
+
//queue Google Visualization JS on report page
|
21 |
+
function pmpro_report_memberships_init() {
|
22 |
+
if(is_admin() && isset($_REQUEST['report']) && $_REQUEST['report'] == "memberships" && isset($_REQUEST['page']) && $_REQUEST['page'] == "pmpro-reports")
|
23 |
+
wp_enqueue_script("jsapi", "https://www.google.com/jsapi");
|
24 |
+
}
|
25 |
+
add_action( 'init', 'pmpro_report_memberships_init' );
|
26 |
+
|
27 |
+
|
28 |
+
//widget
|
29 |
+
function pmpro_report_memberships_widget() {
|
30 |
+
global $wpdb, $pmpro_currency_symbol;
|
31 |
+
?>
|
32 |
+
<style type="text/css">
|
33 |
+
#pmpro_report_memberships .section-label {
|
34 |
+
margin: 15px 0;
|
35 |
+
font-size: 18px;
|
36 |
+
text-align: left;
|
37 |
+
display: block;
|
38 |
+
}
|
39 |
+
|
40 |
+
#pmpro_report_memberships .section-label:first-child {
|
41 |
+
margin-top: 0;
|
42 |
+
}
|
43 |
+
|
44 |
+
#pmpro_report_memberships div {text-align: center;}
|
45 |
+
#pmpro_report_memberships em {display: block; font-style: normal; font-size: 2em; margin: 5px; line-height: 26px;}
|
46 |
+
</style>
|
47 |
+
<span id="pmpro_report_memberships">
|
48 |
+
<label class="section-label"><?php _e('Signups', 'pmpro');?>:</label>
|
49 |
+
<div style="width: 25%; float: left;">
|
50 |
+
<label><?php _e('All Time', 'pmpro');?></label>
|
51 |
+
<em><?php echo pmpro_getSignups( 'all time' ); ?></em>
|
52 |
+
</div>
|
53 |
+
<div style="width: 25%; float: left;">
|
54 |
+
<label><?php _e('This Year', 'pmpro');?></label>
|
55 |
+
<em><?php echo pmpro_getSignups( 'this year' ); ?></em>
|
56 |
+
</div>
|
57 |
+
<div style="width: 25%; float: left;">
|
58 |
+
<label><?php _e('This Month', 'pmpro');?></label>
|
59 |
+
<em><?php echo pmpro_getSignups( 'this month' ); ?></em>
|
60 |
+
</div>
|
61 |
+
<div style="width: 25%; float: left;">
|
62 |
+
<label><?php _e('Today', 'pmpro');?></label>
|
63 |
+
<em><?php echo pmpro_getSignups( 'today' ); ?></em>
|
64 |
+
</div>
|
65 |
+
<div class="clear"></div>
|
66 |
+
|
67 |
+
<label class="section-label"><?php _e('Cancellations', 'pmpro');?>:</label>
|
68 |
+
<div style="width: 25%; float: left;">
|
69 |
+
<label><?php _e('All Time', 'pmpro');?></label>
|
70 |
+
<em><?php echo pmpro_getCancellations( 'all time' ); ?></em>
|
71 |
+
</div>
|
72 |
+
<div style="width: 25%; float: left;">
|
73 |
+
<label><?php _e('This Year', 'pmpro');?></label>
|
74 |
+
<em><?php echo pmpro_getCancellations( 'this year' ); ?></em>
|
75 |
+
</div>
|
76 |
+
<div style="width: 25%; float: left;">
|
77 |
+
<label><?php _e('This Month', 'pmpro');?></label>
|
78 |
+
<em><?php echo pmpro_getCancellations( 'this month' ); ?></em>
|
79 |
+
</div>
|
80 |
+
<div style="width: 25%; float: left;">
|
81 |
+
<label><?php _e('Today', 'pmpro');?></label>
|
82 |
+
<em><?php echo pmpro_getCancellations( 'today' ); ?></em>
|
83 |
+
</div>
|
84 |
+
<div class="clear"></div>
|
85 |
+
|
86 |
+
<label class="section-label"><?php _e('Other Stats', 'pmpro');?>:</label>
|
87 |
+
<div style="width: 33%; float: left;">
|
88 |
+
<label><?php _e('Monthly Recurring Revenue (MRR)', 'pmpro');?></label>
|
89 |
+
<em><?php echo pmpro_formatPrice(pmpro_getMRR( 'all time' )); ?></em>
|
90 |
+
</div>
|
91 |
+
<div style="width: 33%; float: left;">
|
92 |
+
<label><?php _e('Cancellation Rate', 'pmpro');?></label>
|
93 |
+
<em><?php echo pmpro_getCancellationRate('all time' ); ?>%</em>
|
94 |
+
</div>
|
95 |
+
<div style="width: 33%; float: left;">
|
96 |
+
<label><?php _e('Lifetime Value (LTV)', 'pmpro');?></label>
|
97 |
+
<em><?php echo pmpro_formatPrice(pmpro_getLTV('all time')); ?></em>
|
98 |
+
</div>
|
99 |
+
<div class="clear"></div>
|
100 |
+
</span>
|
101 |
+
<?php
|
102 |
+
}
|
103 |
+
|
104 |
+
function pmpro_report_memberships_page()
|
105 |
+
{
|
106 |
+
global $wpdb, $pmpro_currency_symbol;
|
107 |
+
|
108 |
+
//get values from form
|
109 |
+
if(isset($_REQUEST['type']))
|
110 |
+
$type = sanitize_text_field($_REQUEST['type']);
|
111 |
+
else
|
112 |
+
$type = "signup_v_cancel";
|
113 |
+
|
114 |
+
if(isset($_REQUEST['period']))
|
115 |
+
$period = sanitize_text_field($_REQUEST['period']);
|
116 |
+
else
|
117 |
+
$period = "monthly";
|
118 |
+
|
119 |
+
if(isset($_REQUEST['month']))
|
120 |
+
$month = intval($_REQUEST['month']);
|
121 |
+
else
|
122 |
+
$month = date("n");
|
123 |
+
|
124 |
+
$thisyear = date("Y");
|
125 |
+
if(isset($_REQUEST['year']))
|
126 |
+
$year = intval($_REQUEST['year']);
|
127 |
+
else
|
128 |
+
$year = date("Y");
|
129 |
+
|
130 |
+
if(isset($_REQUEST['level']))
|
131 |
+
$l = intval($_REQUEST['level']);
|
132 |
+
else
|
133 |
+
$l = "";
|
134 |
+
|
135 |
+
//calculate start date and how to group dates returned from DB
|
136 |
+
if($period == "daily")
|
137 |
+
{
|
138 |
+
$startdate = $year . '-' . substr("0" . $month, strlen($month) - 1, 2) . '-01';
|
139 |
+
$enddate = $year . '-' . substr("0" . $month, strlen($month) - 1, 2) . '-31';
|
140 |
+
$date_function = 'DAY';
|
141 |
+
}
|
142 |
+
elseif($period == "monthly")
|
143 |
+
{
|
144 |
+
$startdate = $year . '-01-01';
|
145 |
+
$enddate = strval(intval($year)+1) . '-01-01';
|
146 |
+
$date_function = 'MONTH';
|
147 |
+
}
|
148 |
+
elseif($period == "annual")
|
149 |
+
{
|
150 |
+
$startdate = '1960-01-01'; //all time
|
151 |
+
$date_function = 'YEAR';
|
152 |
+
}
|
153 |
+
|
154 |
+
//testing or live data
|
155 |
+
$gateway_environment = pmpro_getOption("gateway_environment");
|
156 |
+
|
157 |
+
//get data
|
158 |
+
if ( $type === "signup_v_cancel" ) {
|
159 |
+
$sqlQuery = "SELECT $date_function(startdate) as date, COUNT(DISTINCT user_id) as signups
|
160 |
+
FROM $wpdb->pmpro_memberships_users WHERE startdate >= '" . $startdate . "' ";
|
161 |
+
|
162 |
+
if(!empty($enddate))
|
163 |
+
$sqlQuery .= "AND startdate < '" . $enddate . "' ";
|
164 |
+
}
|
165 |
+
if ( $type === "mrr_ltv" ) {
|
166 |
+
// Get total revenue, number of months in system, and date
|
167 |
+
if ( $period == 'annual' )
|
168 |
+
$sqlQuery = "SELECT SUM(total) as total, COUNT(DISTINCT MONTH(timestamp)) as months, $date_function(timestamp) as date
|
169 |
+
FROM $wpdb->pmpro_membership_orders WHERE status NOT IN('refunded', 'review', 'token')
|
170 |
+
AND timestamp >= '" . $startdate . "' AND gateway_environment = '" . esc_sql($gateway_environment) . "' ";
|
171 |
+
|
172 |
+
if ( $period == 'monthly' )
|
173 |
+
$sqlQuery = "SELECT SUM(total) as total, $date_function(timestamp) as date
|
174 |
+
FROM $wpdb->pmpro_membership_orders WHERE status NOT IN('refunded', 'review', 'token')
|
175 |
+
AND timestamp >= '" . $startdate . "' AND gateway_environment = '" . esc_sql($gateway_environment) . "' ";
|
176 |
+
|
177 |
+
if(!empty($enddate))
|
178 |
+
$sqlQuery .= "AND timestamp < '" . $enddate . "' ";
|
179 |
+
}
|
180 |
+
|
181 |
+
if(!empty($l))
|
182 |
+
$sqlQuery .= "AND membership_id IN(" . $l . ") ";
|
183 |
+
|
184 |
+
$sqlQuery .= " GROUP BY date ORDER BY date ";
|
185 |
+
|
186 |
+
$dates = $wpdb->get_results($sqlQuery);
|
187 |
+
|
188 |
+
//fill in blanks in dates
|
189 |
+
$cols = array();
|
190 |
+
if($period == "daily")
|
191 |
+
{
|
192 |
+
$lastday = date("t", strtotime($startdate, current_time("timestamp")));
|
193 |
+
|
194 |
+
for($i = 1; $i <= $lastday; $i++)
|
195 |
+
{
|
196 |
+
// Signups vs. Cancellations
|
197 |
+
if ( $type === "signup_v_cancel" ) {
|
198 |
+
$cols[$i] = new stdClass();
|
199 |
+
$cols[$i]->signups = 0;
|
200 |
+
foreach($dates as $date)
|
201 |
+
{
|
202 |
+
if( $date->date == $i ) {
|
203 |
+
$cols[$i]->signups = $date->signups;
|
204 |
+
}
|
205 |
+
}
|
206 |
+
}
|
207 |
+
}
|
208 |
+
}
|
209 |
+
elseif($period == "monthly")
|
210 |
+
{
|
211 |
+
for($i = 1; $i < 13; $i++)
|
212 |
+
{
|
213 |
+
// Signups vs. Cancellations
|
214 |
+
if ( $type === "signup_v_cancel" ) {
|
215 |
+
$cols[$i] = new stdClass();
|
216 |
+
$cols[$i]->date = $i;
|
217 |
+
$cols[$i]->signups = 0;
|
218 |
+
foreach($dates as $date)
|
219 |
+
{
|
220 |
+
if( $date->date == $i ) {
|
221 |
+
$cols[$i]->date = $date->date;
|
222 |
+
$cols[$i]->signups = $date->signups;
|
223 |
+
}
|
224 |
+
}
|
225 |
+
}
|
226 |
+
|
227 |
+
// MRR & LTV
|
228 |
+
if ( $type === "mrr_ltv" ) {
|
229 |
+
$cols[$i] = new stdClass();
|
230 |
+
$cols[$i]->date = $i;
|
231 |
+
$cols[$i]->months = 1;
|
232 |
+
foreach($dates as $date)
|
233 |
+
{
|
234 |
+
if( $date->date == $i ) {
|
235 |
+
$cols[$i]->total = $date->total;
|
236 |
+
}
|
237 |
+
}
|
238 |
+
}
|
239 |
+
}
|
240 |
+
}
|
241 |
+
elseif($period == "annual") //annual
|
242 |
+
{
|
243 |
+
}
|
244 |
+
|
245 |
+
$dates = ( ! empty( $cols ) ) ? $cols : $dates;
|
246 |
+
|
247 |
+
// Signups vs. cancellations
|
248 |
+
if ( $type === "signup_v_cancel" )
|
249 |
+
{
|
250 |
+
$sqlQuery = "SELECT $date_function(mu1.modified) as date, COUNT(DISTINCT mu1.user_id) as cancellations
|
251 |
+
FROM $wpdb->pmpro_memberships_users mu1
|
252 |
+
LEFT JOIN $wpdb->pmpro_memberships_users mu2 ON mu1.user_id = mu2.user_id AND
|
253 |
+
mu2.modified > mu1.enddate AND
|
254 |
+
DATE_ADD(mu1.modified, INTERVAL 1 DAY) > mu2.startdate
|
255 |
+
WHERE mu1.status = 'inactive'
|
256 |
+
AND mu2.id IS NULL
|
257 |
+
AND mu1.startdate >= '" . $startdate . "'
|
258 |
+
AND mu1.startdate < '" . $enddate . "' ";
|
259 |
+
|
260 |
+
//restrict by level
|
261 |
+
if(!empty($l))
|
262 |
+
$sqlQuery .= "AND membership_id IN(" . $l . ") ";
|
263 |
+
|
264 |
+
$sqlQuery .= " GROUP BY date ORDER BY date ";
|
265 |
+
|
266 |
+
$cdates = $wpdb->get_results($sqlQuery, OBJECT_K);
|
267 |
+
|
268 |
+
foreach( $dates as &$date )
|
269 |
+
{
|
270 |
+
if(!empty($cdates[$date->date]))
|
271 |
+
$date->cancellations = $cdates[$date->date]->cancellations;
|
272 |
+
else
|
273 |
+
$date->cancellations = 0;
|
274 |
+
}
|
275 |
+
}
|
276 |
+
|
277 |
+
// MRR & LTV
|
278 |
+
if ( $type === "mrr_ltv" && count( $dates ) === 1 ) {
|
279 |
+
$dummy_date = new stdClass();
|
280 |
+
$dummy_date->total = 0;
|
281 |
+
$dummy_date->months = 0;
|
282 |
+
$dummy_date->date = $dates[0]->date - 1;
|
283 |
+
array_unshift( $dates, $dummy_date ); // Add to beginning
|
284 |
+
}
|
285 |
+
?>
|
286 |
+
<form id="posts-filter" method="get" action="">
|
287 |
+
<h2>
|
288 |
+
<?php _e('Membership Stats', 'pmpro');?>
|
289 |
+
</h2>
|
290 |
+
<ul class="subsubsub">
|
291 |
+
<li>
|
292 |
+
<?php _ex('Show', 'Dropdown label, e.g. Show Daily Revenue for January', 'pmpro')?>
|
293 |
+
<select id="period" name="period">
|
294 |
+
<option value="daily" <?php selected($period, "daily");?>><?php _e('Daily', 'pmpro');?></option>
|
295 |
+
<option value="monthly" <?php selected($period, "monthly");?>><?php _e('Monthly', 'pmpro');?></option>
|
296 |
+
<option value="annual" <?php selected($period, "annual");?>><?php _e('Annual', 'pmpro');?></option>
|
297 |
+
</select>
|
298 |
+
<select id="type" name="type">
|
299 |
+
<option value="signup_v_cancel" <?php selected($type, "signup_v_cancel");?>><?php _e('Signups vs. Cancellations', 'pmpro');?></option>
|
300 |
+
<?php /*
|
301 |
+
<option value="mrr_ltv" <?php selected($type, "mrr_ltv");?>><?php _e('MRR & LTV', 'pmpro');?></option>
|
302 |
+
*/ ?>
|
303 |
+
</select>
|
304 |
+
<span id="for"><?php _ex('for', 'Dropdown label, e.g. Show Daily Revenue for January', 'pmpro')?></span>
|
305 |
+
<select id="month" name="month">
|
306 |
+
<?php for($i = 1; $i < 13; $i++) { ?>
|
307 |
+
<option value="<?php echo $i;?>" <?php selected($month, $i);?>><?php echo date("F", mktime(0, 0, 0, $i, 2));?></option>
|
308 |
+
<?php } ?>
|
309 |
+
</select>
|
310 |
+
<select id="year" name="year">
|
311 |
+
<?php for($i = $thisyear; $i > 2007; $i--) { ?>
|
312 |
+
<option value="<?php echo $i;?>" <?php selected($year, $i);?>><?php echo $i;?></option>
|
313 |
+
<?php } ?>
|
314 |
+
</select>
|
315 |
+
<span id="for"><?php _ex('for', 'Dropdown label, e.g. Show Daily Revenue for January', 'pmpro')?></span>
|
316 |
+
<select name="level">
|
317 |
+
<option value="" <?php if(!$l) { ?>selected="selected"<?php } ?>><?php _e('All Levels', 'pmpro');?></option>
|
318 |
+
<?php
|
319 |
+
$levels = $wpdb->get_results("SELECT id, name FROM $wpdb->pmpro_membership_levels ORDER BY name");
|
320 |
+
foreach($levels as $level)
|
321 |
+
{
|
322 |
+
?>
|
323 |
+
<option value="<?php echo $level->id?>" <?php if($l == $level->id) { ?>selected="selected"<?php } ?>><?php echo $level->name?></option>
|
324 |
+
<?php
|
325 |
+
}
|
326 |
+
?>
|
327 |
+
</select>
|
328 |
+
|
329 |
+
<input type="hidden" name="page" value="pmpro-reports" />
|
330 |
+
<input type="hidden" name="report" value="memberships" />
|
331 |
+
<input type="submit" value="<?php _ex('Generate Report', 'Submit button value.', 'pmpro');?>" />
|
332 |
+
</li>
|
333 |
+
</ul>
|
334 |
+
|
335 |
+
<div id="chart_div" style="clear: both; width: 100%; height: 500px;"></div>
|
336 |
+
|
337 |
+
<script>
|
338 |
+
//update month/year when period dropdown is changed
|
339 |
+
jQuery(document).ready(function() {
|
340 |
+
jQuery('#period').change(function() {
|
341 |
+
pmpro_ShowMonthOrYear();
|
342 |
+
});
|
343 |
+
});
|
344 |
+
|
345 |
+
function pmpro_ShowMonthOrYear()
|
346 |
+
{
|
347 |
+
var period = jQuery('#period').val();
|
348 |
+
if(period == 'daily')
|
349 |
+
{
|
350 |
+
jQuery('#for').show();
|
351 |
+
jQuery('#month').show();
|
352 |
+
jQuery('#year').show();
|
353 |
+
}
|
354 |
+
else if(period == 'monthly')
|
355 |
+
{
|
356 |
+
jQuery('#for').show();
|
357 |
+
jQuery('#month').hide();
|
358 |
+
jQuery('#year').show();
|
359 |
+
}
|
360 |
+
else
|
361 |
+
{
|
362 |
+
jQuery('#for').hide();
|
363 |
+
jQuery('#month').hide();
|
364 |
+
jQuery('#year').hide();
|
365 |
+
}
|
366 |
+
}
|
367 |
+
|
368 |
+
pmpro_ShowMonthOrYear();
|
369 |
+
|
370 |
+
//draw the chart
|
371 |
+
google.load("visualization", "1", {packages:["corechart"]});
|
372 |
+
google.setOnLoadCallback(drawChart);
|
373 |
+
function drawChart() {
|
374 |
+
|
375 |
+
var data = google.visualization.arrayToDataTable([
|
376 |
+
<?php if ( $type === "signup_v_cancel" ) : // Signups vs. cancellations ?>
|
377 |
+
['<?php echo $date_function;?>', 'Signups', 'Cancellations'],
|
378 |
+
<?php foreach($dates as $key => $value) { ?>
|
379 |
+
['<?php if($period == "monthly") echo date("M", mktime(0,0,0,$value->date,2)); else if($period == "daily") echo $key; else echo $value->date;?>', <?php echo $value->signups; ?>, <?php echo $value->cancellations; ?>],
|
380 |
+
<?php } ?>
|
381 |
+
<?php endif; ?>
|
382 |
+
|
383 |
+
<?php if ( $type === "mrr_ltv" ) : // Signups vs. cancellations ?>
|
384 |
+
['<?php echo $date_function;?>', 'MRR', 'LTV'],
|
385 |
+
<?php foreach($dates as $key => $value) { ?>
|
386 |
+
['<?php if($period == "monthly") echo date("M", mktime(0,0,0,$value->date,2)); else if($period == "daily") echo $key; else echo $value->date;?>', <?php echo (($mrr = $value->total / $value->months) && $mrr != 0) ? $mrr : 0; ?>, <?php echo pmpro_getLTV($period, NULL, $mrr ); ?>],
|
387 |
+
<?php } ?>
|
388 |
+
<?php endif; ?>
|
389 |
+
]);
|
390 |
+
|
391 |
+
var options = {
|
392 |
+
colors: ['#0099c6', '#dc3912'],
|
393 |
+
hAxis: {title: '<?php echo $date_function;?>', titleTextStyle: {color: 'black'}, maxAlternation: 1},
|
394 |
+
vAxis: {color: 'green', titleTextStyle: {color: '#51a351'}},
|
395 |
+
};
|
396 |
+
|
397 |
+
<?php if ( $type === "signup_v_cancel" ) : // Signups vs. cancellations ?>
|
398 |
+
var chart = new google.visualization.ColumnChart(document.getElementById('chart_div'));
|
399 |
+
<?php elseif ( $type === "mrr_ltv" ) : // MRR & LTV ?>
|
400 |
+
|
401 |
+
<?php
|
402 |
+
//prefix or suffix?
|
403 |
+
if(pmpro_getCurrencyPosition() == "right")
|
404 |
+
$position = "suffix";
|
405 |
+
else
|
406 |
+
$position = "prefix";
|
407 |
+
?>
|
408 |
+
|
409 |
+
var formatter = new google.visualization.NumberFormat({<?php echo $position;?>: '<?php echo html_entity_decode($pmpro_currency_symbol);?>'});
|
410 |
+
formatter.format(data, 2);
|
411 |
+
var formatter = new google.visualization.NumberFormat({<?php echo $position;?>: '<?php echo html_entity_decode($pmpro_currency_symbol);?>'});
|
412 |
+
formatter.format(data, 1);
|
413 |
+
|
414 |
+
var chart = new google.visualization.LineChart(document.getElementById('chart_div'));
|
415 |
+
<?php endif; ?>
|
416 |
+
chart.draw(data, options);
|
417 |
+
}
|
418 |
+
</script>
|
419 |
+
|
420 |
+
</form>
|
421 |
+
<?php
|
422 |
+
}
|
423 |
+
|
424 |
+
|
425 |
+
|
426 |
+
/*
|
427 |
+
Other code required for your reports. This file is loaded every time WP loads with PMPro enabled.
|
428 |
+
*/
|
429 |
+
|
430 |
+
//get signups
|
431 |
+
function pmpro_getSignups($period = false, $levels = 'all')
|
432 |
+
{
|
433 |
+
//check for a transient
|
434 |
+
$cache = get_transient( 'pmpro_report_memberships_signups' );
|
435 |
+
if( ! empty( $cache ) && ! empty( $cache[$period] ) && ! empty( $cache[$period][$levels] ) )
|
436 |
+
return $cache[$period][$levels];
|
437 |
+
|
438 |
+
//a sale is an order with status = success
|
439 |
+
if( $period == 'today' )
|
440 |
+
$startdate = date(' Y-m-d' );
|
441 |
+
elseif( $period == 'this month')
|
442 |
+
$startdate = date( 'Y-m' ) . '-01';
|
443 |
+
elseif( $period == 'this year')
|
444 |
+
$startdate = date( 'Y' ) . '-01-01';
|
445 |
+
else
|
446 |
+
$startdate = '';
|
447 |
+
|
448 |
+
|
449 |
+
//build query
|
450 |
+
global $wpdb;
|
451 |
+
|
452 |
+
$sqlQuery = "SELECT COUNT(DISTINCT user_id) FROM $wpdb->pmpro_memberships_users WHERE startdate >= '" . $startdate . "' ";
|
453 |
+
|
454 |
+
//restrict by level
|
455 |
+
if(!empty($levels) && $levels != 'all')
|
456 |
+
$sqlQuery .= "AND membership_id IN(" . $levels . ") ";
|
457 |
+
|
458 |
+
$signups = $wpdb->get_var($sqlQuery);
|
459 |
+
|
460 |
+
//save in cache
|
461 |
+
if(!empty($cache) && !empty($cache[$period]))
|
462 |
+
$cache[$period][$levels] = $signups;
|
463 |
+
elseif(!empty($cache))
|
464 |
+
$cache[$period] = array($levels => $signups);
|
465 |
+
else
|
466 |
+
$cache = array($period => array($levels => $signups));
|
467 |
+
|
468 |
+
set_transient("pmpro_report_memberships_signups", $cache, 3600*24);
|
469 |
+
|
470 |
+
return $signups;
|
471 |
+
}
|
472 |
+
|
473 |
+
//get cancellations
|
474 |
+
function pmpro_getCancellations($period = false, $levels = 'all')
|
475 |
+
{
|
476 |
+
//check for a transient
|
477 |
+
$cache = get_transient( 'pmpro_report_memberships_cancellations' );
|
478 |
+
if( ! empty( $cache ) && ! empty( $cache[$period] ) && ! empty( $cache[$period][$levels] ) )
|
479 |
+
return $cache[$period][$levels];
|
480 |
+
|
481 |
+
//figure out start date
|
482 |
+
if( $period == 'today' )
|
483 |
+
$startdate = date(' Y-m-d' );
|
484 |
+
elseif( $period == 'this month')
|
485 |
+
$startdate = date( 'Y-m' ) . '-01';
|
486 |
+
elseif( $period == 'this year')
|
487 |
+
$startdate = date( 'Y' ) . '-01-01';
|
488 |
+
else
|
489 |
+
$startdate = '';
|
490 |
+
|
491 |
+
$startdate_plus_one = strtotime( $startdate . + ' + 1 day', current_time("timestamp") );
|
492 |
+
|
493 |
+
/*
|
494 |
+
build query.
|
495 |
+
cancellations are marked in the memberships users table with status = 'inactive'
|
496 |
+
we try to ignore cancellations when the user gets a new level with 24 hours (probably an upgrade or downgrade)
|
497 |
+
*/
|
498 |
+
global $wpdb;
|
499 |
+
|
500 |
+
//$sqlQuery = "SELECT mu1.user_id, mu2.user_id FROM $wpdb->pmpro_memberships_users mu1 LEFT JOIN $wpdb->pmpro_memberships_users mu2 ON mu1.user_id = mu2.user_id AND mu2.status = 'inactive' AND mu2.startdate > mu1.startdate";
|
501 |
+
$sqlQuery = "SELECT COUNT(mu1.id)
|
502 |
+
FROM $wpdb->pmpro_memberships_users mu1
|
503 |
+
LEFT JOIN $wpdb->pmpro_memberships_users mu2 ON mu1.user_id = mu2.user_id AND
|
504 |
+
mu2.modified > mu1.enddate AND
|
505 |
+
DATE_ADD(mu1.modified, INTERVAL 1 DAY) > mu2.startdate
|
506 |
+
WHERE mu1.status = 'inactive'
|
507 |
+
AND mu2.id IS NULL
|
508 |
+
AND mu1.startdate >= '" . $startdate . "' ";
|
509 |
+
|
510 |
+
//restrict by level
|
511 |
+
if(!empty($levels) && $levels != 'all')
|
512 |
+
$sqlQuery .= "AND membership_id IN(" . $levels . ") ";
|
513 |
+
|
514 |
+
$cancellations = $wpdb->get_var($sqlQuery);
|
515 |
+
|
516 |
+
//save in cache
|
517 |
+
if(!empty($cache) && !empty($cache[$period]) && is_array($cache[$period]))
|
518 |
+
$cache[$period][$levels] = $cancellations;
|
519 |
+
elseif(!empty($cache))
|
520 |
+
$cache[$period] = array($levels => $cancellations);
|
521 |
+
else
|
522 |
+
$cache = array($period => array($levels => $cancellations));
|
523 |
+
|
524 |
+
set_transient("pmpro_report_memberships_cancellations", $cache, 3600*24);
|
525 |
+
|
526 |
+
return $cancellations;
|
527 |
+
}
|
528 |
+
|
529 |
+
//get MRR
|
530 |
+
function pmpro_getMRR($period, $levels = 'all')
|
531 |
+
{
|
532 |
+
//check for a transient
|
533 |
+
//$cache = get_transient("pmpro_report_mrr");
|
534 |
+
if(!empty($cache) && !empty($cache[$period]) && !empty($cache[$period][$levels]))
|
535 |
+
return $cache[$period][$levels];
|
536 |
+
|
537 |
+
//a sale is an order with status NOT IN refunded, review, token, error
|
538 |
+
if($period == "this month")
|
539 |
+
$startdate = date("Y-m") . "-01";
|
540 |
+
elseif($period == "this year")
|
541 |
+
$startdate = date("Y") . "-01-01";
|
542 |
+
else
|
543 |
+
$startdate = "";
|
544 |
+
|
545 |
+
$gateway_environment = pmpro_getOption("gateway_environment");
|
546 |
+
|
547 |
+
//build query
|
548 |
+
global $wpdb;
|
549 |
+
// Get total revenue
|
550 |
+
$sqlQuery = "SELECT SUM(total) FROM $wpdb->pmpro_membership_orders WHERE status NOT IN('refunded', 'review', 'token', 'error') AND timestamp >= '" . $startdate . "' AND gateway_environment = '" . esc_sql($gateway_environment) . "' ";
|
551 |
+
|
552 |
+
//restrict by level
|
553 |
+
if(!empty($levels) && $levels != 'all') {
|
554 |
+
$sqlQuery .= "AND membership_id IN(" . $levels . ") ";
|
555 |
+
}
|
556 |
+
|
557 |
+
$revenue = $wpdb->get_var($sqlQuery);
|
558 |
+
|
559 |
+
//when was the first order
|
560 |
+
$first_order_timestamp = $wpdb->get_var("SELECT UNIX_TIMESTAMP(`timestamp`) FROM $wpdb->pmpro_membership_orders WHERE `timestamp` IS NOT NULL AND `timestamp` > '0000-00-00 00:00:00' ORDER BY `timestamp` LIMIT 1");
|
561 |
+
|
562 |
+
//if we don't have a timestamp, we can't do this
|
563 |
+
if(empty($first_order_timestamp))
|
564 |
+
return false;
|
565 |
+
|
566 |
+
//how many months ago was the first order
|
567 |
+
$months = $wpdb->get_var("SELECT PERIOD_DIFF('" . date("Ym") . "', '" . date("Ym", $first_order_timestamp) . "')");
|
568 |
+
|
569 |
+
/* this works in PHP 5.3+ without using MySQL to get the diff
|
570 |
+
$date1 = new DateTime(date("Y-m-d", $first_order_timestamp));
|
571 |
+
$date2 = new DateTime(date("Y-m-d"));
|
572 |
+
$interval = $date1->diff($date2);
|
573 |
+
$years = intval($interval->format('%y'));
|
574 |
+
$months = $years*12 + intval($interval->format('%m'));
|
575 |
+
*/
|
576 |
+
|
577 |
+
if($months > 0)
|
578 |
+
$mrr = $revenue / $months;
|
579 |
+
else
|
580 |
+
$mrr = 0;
|
581 |
+
|
582 |
+
//save in cache
|
583 |
+
if(!empty($cache) && !empty($cache[$period]))
|
584 |
+
$cache[$period][$levels] = $mrr;
|
585 |
+
elseif(!empty($cache))
|
586 |
+
$cache[$period] = array($levels => $mrr);
|
587 |
+
else
|
588 |
+
$cache = array($period => array($levels => $mrr));
|
589 |
+
|
590 |
+
set_transient("pmpro_report_mrr", $cache, 3600*24);
|
591 |
+
|
592 |
+
return $mrr;
|
593 |
+
}
|
594 |
+
|
595 |
+
//get Cancellation Rate
|
596 |
+
function pmpro_getCancellationRate($period, $levels = 'all')
|
597 |
+
{
|
598 |
+
//check for a transient
|
599 |
+
$cache = get_transient("pmpro_report_cancellation_rate");
|
600 |
+
if(!empty($cache) && !empty($cache[$period]) && !empty($cache[$period][$levels]))
|
601 |
+
return $cache[$period][$levels];
|
602 |
+
|
603 |
+
$signups = pmpro_getSignups($period, $levels);
|
604 |
+
$cancellations = pmpro_getCancellations($period, $levels);
|
605 |
+
|
606 |
+
if(empty($signups))
|
607 |
+
return false;
|
608 |
+
|
609 |
+
$rate = number_format(($cancellations / $signups)*100, 2);
|
610 |
+
|
611 |
+
//save in cache
|
612 |
+
if(!empty($cache) && !empty($cache[$period]))
|
613 |
+
$cache[$period][$levels] = $rate;
|
614 |
+
elseif(!empty($cache))
|
615 |
+
$cache[$period] = array($levels => $rate);
|
616 |
+
else
|
617 |
+
$cache = array($period => array($levels => $rate));
|
618 |
+
|
619 |
+
set_transient("pmpro_report_cancellation_rate", $cache, 3600*24);
|
620 |
+
|
621 |
+
return $rate;
|
622 |
+
}
|
623 |
+
|
624 |
+
//get LTV
|
625 |
+
function pmpro_getLTV($period, $levels = 'all', $mrr = NULL, $signups = NULL, $cancellation_rate = NULL)
|
626 |
+
{
|
627 |
+
if(empty($mrr))
|
628 |
+
$mrr = pmpro_getMRR($period, $levels);
|
629 |
+
if(empty($signups))
|
630 |
+
$signups = pmpro_getSignups($period, $levels);
|
631 |
+
if(empty($cancellation_rate))
|
632 |
+
$cancellation_rate = pmpro_getCancellationRate($period, $levels);
|
633 |
+
|
634 |
+
//average monthly spend
|
635 |
+
if(empty($signups))
|
636 |
+
return false;
|
637 |
+
|
638 |
+
if($signups > 0)
|
639 |
+
$ams = $mrr / $signups;
|
640 |
+
else
|
641 |
+
$ams = 0;
|
642 |
+
|
643 |
+
if($cancellation_rate > 0)
|
644 |
+
$ltv = $ams * (1/$cancellation_rate);
|
645 |
+
else
|
646 |
+
$ltv = $ams;
|
647 |
+
|
648 |
+
return $ltv;
|
649 |
+
}
|
650 |
+
|
651 |
+
//delete transients when an order goes through
|
652 |
+
function pmpro_report_memberships_delete_transients()
|
653 |
+
{
|
654 |
+
delete_transient("pmpro_report_mrr");
|
655 |
+
delete_transient("pmpro_report_cancellation_rate");
|
656 |
+
delete_transient("pmpro_report_memberships_cancellations");
|
657 |
+
delete_transient("pmpro_report_memberships_signups");
|
658 |
+
}
|
659 |
+
add_action("pmpro_after_checkout", "pmpro_report_memberships_delete_transients");
|
660 |
+
add_action("pmpro_updated_order", "pmpro_report_memberships_delete_transients");
|
adminpages/reports/sales.php
CHANGED
@@ -1,406 +1,406 @@
|
|
1 |
-
<?php
|
2 |
-
/*
|
3 |
-
PMPro Report
|
4 |
-
Title: Sales
|
5 |
-
Slug: sales
|
6 |
-
|
7 |
-
For each report, add a line like:
|
8 |
-
global $pmpro_reports;
|
9 |
-
$pmpro_reports['slug'] = 'Title';
|
10 |
-
|
11 |
-
For each report, also write two functions:
|
12 |
-
* pmpro_report_{slug}_widget() to show up on the report homepage.
|
13 |
-
* pmpro_report_{slug}_page() to show up when users click on the report page widget.
|
14 |
-
*/
|
15 |
-
global $pmpro_reports;
|
16 |
-
$gateway_environment = pmpro_getOption("gateway_environment");
|
17 |
-
if($gateway_environment == "sandbox")
|
18 |
-
$pmpro_reports['sales'] = __('Sales and Revenue (Testing/Sandbox)', 'pmpro');
|
19 |
-
else
|
20 |
-
$pmpro_reports['sales'] = __('Sales and Revenue', 'pmpro');
|
21 |
-
|
22 |
-
//queue Google Visualization JS on report page
|
23 |
-
function pmpro_report_sales_init()
|
24 |
-
{
|
25 |
-
if(is_admin() && isset($_REQUEST['report']) && $_REQUEST['report'] == "sales" && isset($_REQUEST['page']) && $_REQUEST['page'] == "pmpro-reports")
|
26 |
-
{
|
27 |
-
wp_enqueue_script("jsapi", "https://www.google.com/jsapi");
|
28 |
-
}
|
29 |
-
}
|
30 |
-
add_action("init", "pmpro_report_sales_init");
|
31 |
-
|
32 |
-
//widget
|
33 |
-
function pmpro_report_sales_widget()
|
34 |
-
{
|
35 |
-
global $wpdb;
|
36 |
-
?>
|
37 |
-
<style>
|
38 |
-
#pmpro_report_sales div {text-align: center;}
|
39 |
-
#pmpro_report_sales em {display: block; font-style: normal; font-size: 2em; margin: 5px;}
|
40 |
-
</style>
|
41 |
-
<span id="#pmpro_report_sales">
|
42 |
-
<div style="width: 25%; float: left;">
|
43 |
-
<em><?php echo pmpro_getSales("all time");?></em>
|
44 |
-
<label>All Time</label>
|
45 |
-
<em><?php echo pmpro_formatPrice(pmpro_getRevenue("all time"));?></em>
|
46 |
-
</div>
|
47 |
-
<div style="width: 25%; float: left;">
|
48 |
-
<em><?php echo pmpro_getSales("this year");?></em>
|
49 |
-
<label>This Year</label>
|
50 |
-
<em><?php echo pmpro_formatPrice(pmpro_getRevenue("this year"));?></em>
|
51 |
-
</div>
|
52 |
-
<div style="width: 25%; float: left;">
|
53 |
-
<em><?php echo pmpro_getSales("this month");?></em>
|
54 |
-
<label>This Month</label>
|
55 |
-
<em><?php echo pmpro_formatPrice(pmpro_getRevenue("this month"));?></em>
|
56 |
-
</div>
|
57 |
-
<div style="width: 25%; float: left;">
|
58 |
-
<em><?php echo pmpro_getSales("today");?></em>
|
59 |
-
<label>Today</label>
|
60 |
-
<em><?php echo pmpro_formatPrice(pmpro_getRevenue("today"));?></em>
|
61 |
-
</div>
|
62 |
-
<div class="clear"></div>
|
63 |
-
</span>
|
64 |
-
<?php
|
65 |
-
}
|
66 |
-
|
67 |
-
function pmpro_report_sales_page()
|
68 |
-
{
|
69 |
-
global $wpdb, $pmpro_currency_symbol, $pmpro_currency, $pmpro_currencies;
|
70 |
-
|
71 |
-
//get values from form
|
72 |
-
if(isset($_REQUEST['type']))
|
73 |
-
$type = sanitize_text_field($_REQUEST['type']);
|
74 |
-
else
|
75 |
-
$type = "revenue";
|
76 |
-
|
77 |
-
if($type == "sales")
|
78 |
-
$type_function = "COUNT";
|
79 |
-
else
|
80 |
-
$type_function = "SUM";
|
81 |
-
|
82 |
-
if(isset($_REQUEST['period']))
|
83 |
-
$period = sanitize_text_field($_REQUEST['period']);
|
84 |
-
else
|
85 |
-
$period = "daily";
|
86 |
-
|
87 |
-
if(isset($_REQUEST['month']))
|
88 |
-
$month = intval($_REQUEST['month']);
|
89 |
-
else
|
90 |
-
$month = date("n");
|
91 |
-
|
92 |
-
$thisyear = date("Y");
|
93 |
-
if(isset($_REQUEST['year']))
|
94 |
-
$year = intval($_REQUEST['year']);
|
95 |
-
else
|
96 |
-
$year = $thisyear;
|
97 |
-
|
98 |
-
if(isset($_REQUEST['level']))
|
99 |
-
$l = intval($_REQUEST['level']);
|
100 |
-
else
|
101 |
-
$l = "";
|
102 |
-
|
103 |
-
//calculate start date and how to group dates returned from DB
|
104 |
-
if($period == "daily")
|
105 |
-
{
|
106 |
-
$startdate = $year . '-' . substr("0" . $month, strlen($month) - 1, 2) . '-01';
|
107 |
-
$enddate = $year . '-' . substr("0" . $month, strlen($month) - 1, 2) . '-31';
|
108 |
-
$date_function = 'DAY';
|
109 |
-
}
|
110 |
-
elseif($period == "monthly")
|
111 |
-
{
|
112 |
-
$startdate = $year . '-01-01';
|
113 |
-
$enddate = strval(intval($year)+1) . '-01-01';
|
114 |
-
$date_function = 'MONTH';
|
115 |
-
}
|
116 |
-
else
|
117 |
-
{
|
118 |
-
$startdate = '1960-01-01'; //all time
|
119 |
-
$date_function = 'YEAR';
|
120 |
-
}
|
121 |
-
|
122 |
-
//testing or live data
|
123 |
-
$gateway_environment = pmpro_getOption("gateway_environment");
|
124 |
-
|
125 |
-
//get data
|
126 |
-
$sqlQuery = "SELECT $date_function(timestamp) as date, $type_function(total) as value FROM $wpdb->pmpro_membership_orders WHERE timestamp >= '" . $startdate . "' AND status NOT IN('refunded', 'review', 'token', 'error') AND gateway_environment = '" . esc_sql($gateway_environment) . "' ";
|
127 |
-
|
128 |
-
if(!empty($enddate))
|
129 |
-
$sqlQuery .= "AND timestamp < '" . $enddate . "' ";
|
130 |
-
|
131 |
-
if(!empty($l))
|
132 |
-
$sqlQuery .= "AND membership_id IN(" . $l . ") ";
|
133 |
-
|
134 |
-
$sqlQuery .= " GROUP BY date ORDER BY date ";
|
135 |
-
|
136 |
-
$dates = $wpdb->get_results($sqlQuery);
|
137 |
-
|
138 |
-
//fill in blanks in dates
|
139 |
-
$cols = array();
|
140 |
-
if($period == "daily")
|
141 |
-
{
|
142 |
-
$lastday = date("t", strtotime($startdate, current_time("timestamp")));
|
143 |
-
|
144 |
-
for($i = 1; $i <= $lastday; $i++)
|
145 |
-
{
|
146 |
-
$cols[$i] = 0;
|
147 |
-
foreach($dates as $date)
|
148 |
-
{
|
149 |
-
if($date->date == $i)
|
150 |
-
$cols[$i] = $date->value;
|
151 |
-
}
|
152 |
-
}
|
153 |
-
}
|
154 |
-
elseif($period == "monthly")
|
155 |
-
{
|
156 |
-
for($i = 1; $i < 13; $i++)
|
157 |
-
{
|
158 |
-
$cols[$i] = 0;
|
159 |
-
foreach($dates as $date)
|
160 |
-
{
|
161 |
-
if($date->date == $i)
|
162 |
-
$cols[$i] = $date->value;
|
163 |
-
}
|
164 |
-
}
|
165 |
-
}
|
166 |
-
else //annual
|
167 |
-
{
|
168 |
-
//get min and max years
|
169 |
-
$min = 9999;
|
170 |
-
$max = 0;
|
171 |
-
foreach($dates as $date)
|
172 |
-
{
|
173 |
-
$min = min($min, $date->date);
|
174 |
-
$max = max($max, $date->date);
|
175 |
-
}
|
176 |
-
|
177 |
-
for($i = $min; $i <= $max; $i++)
|
178 |
-
{
|
179 |
-
foreach($dates as $date)
|
180 |
-
{
|
181 |
-
if($date->date == $i)
|
182 |
-
$cols[$i] = $date->value;
|
183 |
-
}
|
184 |
-
}
|
185 |
-
}
|
186 |
-
?>
|
187 |
-
<form id="posts-filter" method="get" action="">
|
188 |
-
<h2>
|
189 |
-
<?php _e('Sales and Revenue', 'pmpro');?>
|
190 |
-
</h2>
|
191 |
-
|
192 |
-
<div class="tablenav top">
|
193 |
-
<?php _ex('Show', 'Dropdown label, e.g. Show Daily Revenue for January', 'pmpro')?>
|
194 |
-
<select id="period" name="period">
|
195 |
-
<option value="daily" <?php selected($period, "daily");?>><?php _e('Daily', 'pmpro');?></option>
|
196 |
-
<option value="monthly" <?php selected($period, "monthly");?>><?php _e('Monthly', 'pmpro');?></option>
|
197 |
-
<option value="annual" <?php selected($period, "annual");?>><?php _e('Annual', 'pmpro');?></option>
|
198 |
-
</select>
|
199 |
-
<select name="type">
|
200 |
-
<option value="revenue" <?php selected($type, "revenue");?>><?php _e('Revenue', 'pmpro');?></option>
|
201 |
-
<option value="sales" <?php selected($type, "sales");?>><?php _e('Sales', 'pmpro');?></option>
|
202 |
-
</select>
|
203 |
-
<span id="for"><?php _ex('for', 'Dropdown label, e.g. Show Daily Revenue for January', 'pmpro')?></span>
|
204 |
-
<select id="month" name="month">
|
205 |
-
<?php for($i = 1; $i < 13; $i++) { ?>
|
206 |
-
<option value="<?php echo $i;?>" <?php selected($month, $i);?>><?php echo date("F", mktime(0, 0, 0, $i, 2));?></option>
|
207 |
-
<?php } ?>
|
208 |
-
</select>
|
209 |
-
<select id="year" name="year">
|
210 |
-
<?php for($i = $thisyear; $i > 2007; $i--) { ?>
|
211 |
-
<option value="<?php echo $i;?>" <?php selected($year, $i);?>><?php echo $i;?></option>
|
212 |
-
<?php } ?>
|
213 |
-
</select>
|
214 |
-
<span id="for"><?php _ex('for', 'Dropdown label, e.g. Show Daily Revenue for January', 'pmpro')?></span>
|
215 |
-
<select name="level">
|
216 |
-
<option value="" <?php if(!$l) { ?>selected="selected"<?php } ?>><?php _e('All Levels', 'pmpro');?></option>
|
217 |
-
<?php
|
218 |
-
$levels = $wpdb->get_results("SELECT id, name FROM $wpdb->pmpro_membership_levels ORDER BY name");
|
219 |
-
foreach($levels as $level)
|
220 |
-
{
|
221 |
-
?>
|
222 |
-
<option value="<?php echo $level->id?>" <?php if($l == $level->id) { ?>selected="selected"<?php } ?>><?php echo $level->name?></option>
|
223 |
-
<?php
|
224 |
-
}
|
225 |
-
?>
|
226 |
-
</select>
|
227 |
-
|
228 |
-
<input type="hidden" name="page" value="pmpro-reports" />
|
229 |
-
<input type="hidden" name="report" value="sales" />
|
230 |
-
<input type="submit" class="button action" value="<?php _ex('Generate Report', 'Submit button value.', 'pmpro');?>" />
|
231 |
-
</div>
|
232 |
-
|
233 |
-
<div id="chart_div" style="clear: both; width: 100%; height: 500px;"></div>
|
234 |
-
|
235 |
-
<script>
|
236 |
-
//update month/year when period dropdown is changed
|
237 |
-
jQuery(document).ready(function() {
|
238 |
-
jQuery('#period').change(function() {
|
239 |
-
pmpro_ShowMonthOrYear();
|
240 |
-
});
|
241 |
-
});
|
242 |
-
|
243 |
-
function pmpro_ShowMonthOrYear()
|
244 |
-
{
|
245 |
-
var period = jQuery('#period').val();
|
246 |
-
if(period == 'daily')
|
247 |
-
{
|
248 |
-
jQuery('#for').show();
|
249 |
-
jQuery('#month').show();
|
250 |
-
jQuery('#year').show();
|
251 |
-
}
|
252 |
-
else if(period == 'monthly')
|
253 |
-
{
|
254 |
-
jQuery('#for').show();
|
255 |
-
jQuery('#month').hide();
|
256 |
-
jQuery('#year').show();
|
257 |
-
}
|
258 |
-
else
|
259 |
-
{
|
260 |
-
jQuery('#for').hide();
|
261 |
-
jQuery('#month').hide();
|
262 |
-
jQuery('#year').hide();
|
263 |
-
}
|
264 |
-
}
|
265 |
-
|
266 |
-
pmpro_ShowMonthOrYear();
|
267 |
-
|
268 |
-
//draw the chart
|
269 |
-
google.load("visualization", "1", {packages:["corechart"]});
|
270 |
-
google.setOnLoadCallback(drawChart);
|
271 |
-
function drawChart() {
|
272 |
-
|
273 |
-
var data = google.visualization.arrayToDataTable([
|
274 |
-
['<?php echo $date_function;?>', '<?php echo ucwords($type);?>'],
|
275 |
-
<?php foreach($cols as $date => $value) { ?>
|
276 |
-
['<?php if($period == "monthly") echo date("M", mktime(0,0,0,$date,2)); else echo $date;?>', <?php echo $value;?>],
|
277 |
-
<?php } ?>
|
278 |
-
]);
|
279 |
-
|
280 |
-
var options = {
|
281 |
-
colors: ['#51a351', '#387038'],
|
282 |
-
hAxis: {title: '<?php echo $date_function;?>', titleTextStyle: {color: 'black'}, maxAlternation: 1},
|
283 |
-
vAxis: {color: 'green', titleTextStyle: {color: '#51a351'}},
|
284 |
-
};
|
285 |
-
|
286 |
-
<?php
|
287 |
-
if($type != "sales")
|
288 |
-
{
|
289 |
-
if(pmpro_getCurrencyPosition() == "right")
|
290 |
-
$position = "suffix";
|
291 |
-
else
|
292 |
-
$position = "prefix";
|
293 |
-
?>
|
294 |
-
var formatter = new google.visualization.NumberFormat({<?php echo $position;?>: '<?php echo html_entity_decode($pmpro_currency_symbol);?>'});
|
295 |
-
formatter.format(data, 1);
|
296 |
-
<?php
|
297 |
-
}
|
298 |
-
?>
|
299 |
-
|
300 |
-
var chart = new google.visualization.ColumnChart(document.getElementById('chart_div'));
|
301 |
-
chart.draw(data, options);
|
302 |
-
}
|
303 |
-
</script>
|
304 |
-
|
305 |
-
</form>
|
306 |
-
<?php
|
307 |
-
}
|
308 |
-
|
309 |
-
/*
|
310 |
-
Other code required for your reports. This file is loaded every time WP loads with PMPro enabled.
|
311 |
-
*/
|
312 |
-
|
313 |
-
//get sales
|
314 |
-
function pmpro_getSales($period, $levels = NULL)
|
315 |
-
{
|
316 |
-
//check for a transient
|
317 |
-
$cache = get_transient("pmpro_report_sales");
|
318 |
-
if(!empty($cache) && !empty($cache[$period]) && !empty($cache[$period][$levels]))
|
319 |
-
return $cache[$period][$levels];
|
320 |
-
|
321 |
-
//a sale is an order with status NOT IN('refunded', 'review', 'token', 'error')
|
322 |
-
if($period == "today")
|
323 |
-
$startdate = date("Y-m-d");
|
324 |
-
elseif($period == "this month")
|
325 |
-
$startdate = date("Y-m") . "-01";
|
326 |
-
elseif($period == "this year")
|
327 |
-
$startdate = date("Y") . "-01-01";
|
328 |
-
else
|
329 |
-
$startdate = "";
|
330 |
-
|
331 |
-
$gateway_environment = pmpro_getOption("gateway_environment");
|
332 |
-
|
333 |
-
//build query
|
334 |
-
global $wpdb;
|
335 |
-
$sqlQuery = "SELECT COUNT(*) FROM $wpdb->pmpro_membership_orders WHERE status NOT IN('refunded', 'review', 'token', 'error') AND timestamp >= '" . $startdate . "' AND gateway_environment = '" . esc_sql($gateway_environment) . "' ";
|
336 |
-
|
337 |
-
//restrict by level
|
338 |
-
if(!empty($levels))
|
339 |
-
$sqlQuery .= "AND membership_id IN(" . $levels . ") ";
|
340 |
-
|
341 |
-
$sales = $wpdb->get_var($sqlQuery);
|
342 |
-
|
343 |
-
//save in cache
|
344 |
-
if(!empty($cache) && !empty($cache[$period]))
|
345 |
-
$cache[$period][$levels] = $sales;
|
346 |
-
elseif(!empty($cache))
|
347 |
-
$cache[$period] = array($levels => $sales);
|
348 |
-
else
|
349 |
-
$cache = array($period => array($levels => $sales));
|
350 |
-
|
351 |
-
set_transient("pmpro_report_sales", $cache, 3600*24);
|
352 |
-
|
353 |
-
return $sales;
|
354 |
-
}
|
355 |
-
|
356 |
-
//get revenue
|
357 |
-
function pmpro_getRevenue($period, $levels = NULL)
|
358 |
-
{
|
359 |
-
//check for a transient
|
360 |
-
$cache = get_transient("pmpro_report_revenue");
|
361 |
-
if(!empty($cache) && !empty($cache[$period]) && !empty($cache[$period][$levels]))
|
362 |
-
return $cache[$period][$levels];
|
363 |
-
|
364 |
-
//a sale is an order with status NOT IN('refunded', 'review', 'token', 'error')
|
365 |
-
if($period == "today")
|
366 |
-
$startdate = date("Y-m-d");
|
367 |
-
elseif($period == "this month")
|
368 |
-
$startdate = date("Y-m") . "-01";
|
369 |
-
elseif($period == "this year")
|
370 |
-
$startdate = date("Y") . "-01-01";
|
371 |
-
else
|
372 |
-
$startdate = "";
|
373 |
-
|
374 |
-
$gateway_environment = pmpro_getOption("gateway_environment");
|
375 |
-
|
376 |
-
//build query
|
377 |
-
global $wpdb;
|
378 |
-
$sqlQuery = "SELECT SUM(total) FROM $wpdb->pmpro_membership_orders WHERE status NOT IN('refunded', 'review', 'token', 'error') AND timestamp >= '" . $startdate . "' AND gateway_environment = '" . esc_sql($gateway_environment) . "' ";
|
379 |
-
|
380 |
-
//restrict by level
|
381 |
-
if(!empty($levels))
|
382 |
-
$sqlQuery .= "AND membership_id IN(" . $levels . ") ";
|
383 |
-
|
384 |
-
$revenue = $wpdb->get_var($sqlQuery);
|
385 |
-
|
386 |
-
//save in cache
|
387 |
-
if(!empty($cache) && !empty($cache[$period]))
|
388 |
-
$cache[$period][$levels] = $revenue;
|
389 |
-
elseif(!empty($cache))
|
390 |
-
$cache[$period] = array($levels => $revenue);
|
391 |
-
else
|
392 |
-
$cache = array($period => array($levels => $revenue));
|
393 |
-
|
394 |
-
set_transient("pmpro_report_revenue", $cache, 3600*24);
|
395 |
-
|
396 |
-
return $revenue;
|
397 |
-
}
|
398 |
-
|
399 |
-
//delete transients when an order goes through
|
400 |
-
function pmpro_report_sales_delete_transients()
|
401 |
-
{
|
402 |
-
delete_transient("pmpro_report_sales");
|
403 |
-
delete_transient("pmpro_report_revenue");
|
404 |
-
}
|
405 |
-
add_action("pmpro_after_checkout", "pmpro_report_sales_delete_transients");
|
406 |
-
add_action("pmpro_updated_order", "pmpro_report_sales_delete_transients");
|
1 |
+
<?php
|
2 |
+
/*
|
3 |
+
PMPro Report
|
4 |
+
Title: Sales
|
5 |
+
Slug: sales
|
6 |
+
|
7 |
+
For each report, add a line like:
|
8 |
+
global $pmpro_reports;
|
9 |
+
$pmpro_reports['slug'] = 'Title';
|
10 |
+
|
11 |
+
For each report, also write two functions:
|
12 |
+
* pmpro_report_{slug}_widget() to show up on the report homepage.
|
13 |
+
* pmpro_report_{slug}_page() to show up when users click on the report page widget.
|
14 |
+
*/
|
15 |
+
global $pmpro_reports;
|
16 |
+
$gateway_environment = pmpro_getOption("gateway_environment");
|
17 |
+
if($gateway_environment == "sandbox")
|
18 |
+
$pmpro_reports['sales'] = __('Sales and Revenue (Testing/Sandbox)', 'pmpro');
|
19 |
+
else
|
20 |
+
$pmpro_reports['sales'] = __('Sales and Revenue', 'pmpro');
|
21 |
+
|
22 |
+
//queue Google Visualization JS on report page
|
23 |
+
function pmpro_report_sales_init()
|
24 |
+
{
|
25 |
+
if(is_admin() && isset($_REQUEST['report']) && $_REQUEST['report'] == "sales" && isset($_REQUEST['page']) && $_REQUEST['page'] == "pmpro-reports")
|
26 |
+
{
|
27 |
+
wp_enqueue_script("jsapi", "https://www.google.com/jsapi");
|
28 |
+
}
|
29 |
+
}
|
30 |
+
add_action("init", "pmpro_report_sales_init");
|
31 |
+
|
32 |
+
//widget
|
33 |
+
function pmpro_report_sales_widget()
|
34 |
+
{
|
35 |
+
global $wpdb;
|
36 |
+
?>
|
37 |
+
<style>
|
38 |
+
#pmpro_report_sales div {text-align: center;}
|
39 |
+
#pmpro_report_sales em {display: block; font-style: normal; font-size: 2em; margin: 5px;}
|
40 |
+
</style>
|
41 |
+
<span id="#pmpro_report_sales">
|
42 |
+
<div style="width: 25%; float: left;">
|
43 |
+
<em><?php echo pmpro_getSales("all time");?></em>
|
44 |
+
<label>All Time</label>
|
45 |
+
<em><?php echo pmpro_formatPrice(pmpro_getRevenue("all time"));?></em>
|
46 |
+
</div>
|
47 |
+
<div style="width: 25%; float: left;">
|
48 |
+
<em><?php echo pmpro_getSales("this year");?></em>
|
49 |
+
<label>This Year</label>
|
50 |
+
<em><?php echo pmpro_formatPrice(pmpro_getRevenue("this year"));?></em>
|
51 |
+
</div>
|
52 |
+
<div style="width: 25%; float: left;">
|
53 |
+
<em><?php echo pmpro_getSales("this month");?></em>
|
54 |
+
<label>This Month</label>
|
55 |
+
<em><?php echo pmpro_formatPrice(pmpro_getRevenue("this month"));?></em>
|
56 |
+
</div>
|
57 |
+
<div style="width: 25%; float: left;">
|
58 |
+
<em><?php echo pmpro_getSales("today");?></em>
|
59 |
+
<label>Today</label>
|
60 |
+
<em><?php echo pmpro_formatPrice(pmpro_getRevenue("today"));?></em>
|
61 |
+
</div>
|
62 |
+
<div class="clear"></div>
|
63 |
+
</span>
|
64 |
+
<?php
|
65 |
+
}
|
66 |
+
|
67 |
+
function pmpro_report_sales_page()
|
68 |
+
{
|
69 |
+
global $wpdb, $pmpro_currency_symbol, $pmpro_currency, $pmpro_currencies;
|
70 |
+
|
71 |
+
//get values from form
|
72 |
+
if(isset($_REQUEST['type']))
|
73 |
+
$type = sanitize_text_field($_REQUEST['type']);
|
74 |
+
else
|
75 |
+
$type = "revenue";
|
76 |
+
|
77 |
+
if($type == "sales")
|
78 |
+
$type_function = "COUNT";
|
79 |
+
else
|
80 |
+
$type_function = "SUM";
|
81 |
+
|
82 |
+
if(isset($_REQUEST['period']))
|
83 |
+
$period = sanitize_text_field($_REQUEST['period']);
|
84 |
+
else
|
85 |
+
$period = "daily";
|
86 |
+
|
87 |
+
if(isset($_REQUEST['month']))
|
88 |
+
$month = intval($_REQUEST['month']);
|
89 |
+
else
|
90 |
+
$month = date("n");
|
91 |
+
|
92 |
+
$thisyear = date("Y");
|
93 |
+
if(isset($_REQUEST['year']))
|
94 |
+
$year = intval($_REQUEST['year']);
|
95 |
+
else
|
96 |
+
$year = $thisyear;
|
97 |
+
|
98 |
+
if(isset($_REQUEST['level']))
|
99 |
+
$l = intval($_REQUEST['level']);
|
100 |
+
else
|
101 |
+
$l = "";
|
102 |
+
|
103 |
+
//calculate start date and how to group dates returned from DB
|
104 |
+
if($period == "daily")
|
105 |
+
{
|
106 |
+
$startdate = $year . '-' . substr("0" . $month, strlen($month) - 1, 2) . '-01';
|
107 |
+
$enddate = $year . '-' . substr("0" . $month, strlen($month) - 1, 2) . '-31';
|
108 |
+
$date_function = 'DAY';
|
109 |
+
}
|
110 |
+
elseif($period == "monthly")
|
111 |
+
{
|
112 |
+
$startdate = $year . '-01-01';
|
113 |
+
$enddate = strval(intval($year)+1) . '-01-01';
|
114 |
+
$date_function = 'MONTH';
|
115 |
+
}
|
116 |
+
else
|
117 |
+
{
|
118 |
+
$startdate = '1960-01-01'; //all time
|
119 |
+
$date_function = 'YEAR';
|
120 |
+
}
|
121 |
+
|
122 |
+
//testing or live data
|
123 |
+
$gateway_environment = pmpro_getOption("gateway_environment");
|
124 |
+
|
125 |
+
//get data
|
126 |
+
$sqlQuery = "SELECT $date_function(timestamp) as date, $type_function(total) as value FROM $wpdb->pmpro_membership_orders WHERE timestamp >= '" . $startdate . "' AND status NOT IN('refunded', 'review', 'token', 'error') AND gateway_environment = '" . esc_sql($gateway_environment) . "' ";
|
127 |
+
|
128 |
+
if(!empty($enddate))
|
129 |
+
$sqlQuery .= "AND timestamp < '" . $enddate . "' ";
|
130 |
+
|
131 |
+
if(!empty($l))
|
132 |
+
$sqlQuery .= "AND membership_id IN(" . $l . ") ";
|
133 |
+
|
134 |
+
$sqlQuery .= " GROUP BY date ORDER BY date ";
|
135 |
+
|
136 |
+
$dates = $wpdb->get_results($sqlQuery);
|
137 |
+
|
138 |
+
//fill in blanks in dates
|
139 |
+
$cols = array();
|
140 |
+
if($period == "daily")
|
141 |
+
{
|
142 |
+
$lastday = date("t", strtotime($startdate, current_time("timestamp")));
|
143 |
+
|
144 |
+
for($i = 1; $i <= $lastday; $i++)
|
145 |
+
{
|
146 |
+
$cols[$i] = 0;
|
147 |
+
foreach($dates as $date)
|
148 |
+
{
|
149 |
+
if($date->date == $i)
|
150 |
+
$cols[$i] = $date->value;
|
151 |
+
}
|
152 |
+
}
|
153 |
+
}
|
154 |
+
elseif($period == "monthly")
|
155 |
+
{
|
156 |
+
for($i = 1; $i < 13; $i++)
|
157 |
+
{
|
158 |
+
$cols[$i] = 0;
|
159 |
+
foreach($dates as $date)
|
160 |
+
{
|
161 |
+
if($date->date == $i)
|
162 |
+
$cols[$i] = $date->value;
|
163 |
+
}
|
164 |
+
}
|
165 |
+
}
|
166 |
+
else //annual
|
167 |
+
{
|
168 |
+
//get min and max years
|
169 |
+
$min = 9999;
|
170 |
+
$max = 0;
|
171 |
+
foreach($dates as $date)
|
172 |
+
{
|
173 |
+
$min = min($min, $date->date);
|
174 |
+
$max = max($max, $date->date);
|
175 |
+
}
|
176 |
+
|
177 |
+
for($i = $min; $i <= $max; $i++)
|
178 |
+
{
|
179 |
+
foreach($dates as $date)
|
180 |
+
{
|
181 |
+
if($date->date == $i)
|
182 |
+
$cols[$i] = $date->value;
|
183 |
+
}
|
184 |
+
}
|
185 |
+
}
|
186 |
+
?>
|
187 |
+
<form id="posts-filter" method="get" action="">
|
188 |
+
<h2>
|
189 |
+
<?php _e('Sales and Revenue', 'pmpro');?>
|
190 |
+
</h2>
|
191 |
+
|
192 |
+
<div class="tablenav top">
|
193 |
+
<?php _ex('Show', 'Dropdown label, e.g. Show Daily Revenue for January', 'pmpro')?>
|
194 |
+
<select id="period" name="period">
|
195 |
+
<option value="daily" <?php selected($period, "daily");?>><?php _e('Daily', 'pmpro');?></option>
|
196 |
+
<option value="monthly" <?php selected($period, "monthly");?>><?php _e('Monthly', 'pmpro');?></option>
|
197 |
+
<option value="annual" <?php selected($period, "annual");?>><?php _e('Annual', 'pmpro');?></option>
|
198 |
+
</select>
|
199 |
+
<select name="type">
|
200 |
+
<option value="revenue" <?php selected($type, "revenue");?>><?php _e('Revenue', 'pmpro');?></option>
|
201 |
+
<option value="sales" <?php selected($type, "sales");?>><?php _e('Sales', 'pmpro');?></option>
|
202 |
+
</select>
|
203 |
+
<span id="for"><?php _ex('for', 'Dropdown label, e.g. Show Daily Revenue for January', 'pmpro')?></span>
|
204 |
+
<select id="month" name="month">
|
205 |
+
<?php for($i = 1; $i < 13; $i++) { ?>
|
206 |
+
<option value="<?php echo $i;?>" <?php selected($month, $i);?>><?php echo date("F", mktime(0, 0, 0, $i, 2));?></option>
|
207 |
+
<?php } ?>
|
208 |
+
</select>
|
209 |
+
<select id="year" name="year">
|
210 |
+
<?php for($i = $thisyear; $i > 2007; $i--) { ?>
|
211 |
+
<option value="<?php echo $i;?>" <?php selected($year, $i);?>><?php echo $i;?></option>
|
212 |
+
<?php } ?>
|
213 |
+
</select>
|
214 |
+
<span id="for"><?php _ex('for', 'Dropdown label, e.g. Show Daily Revenue for January', 'pmpro')?></span>
|
215 |
+
<select name="level">
|
216 |
+
<option value="" <?php if(!$l) { ?>selected="selected"<?php } ?>><?php _e('All Levels', 'pmpro');?></option>
|
217 |
+
<?php
|
218 |
+
$levels = $wpdb->get_results("SELECT id, name FROM $wpdb->pmpro_membership_levels ORDER BY name");
|
219 |
+
foreach($levels as $level)
|
220 |
+
{
|
221 |
+
?>
|
222 |
+
<option value="<?php echo $level->id?>" <?php if($l == $level->id) { ?>selected="selected"<?php } ?>><?php echo $level->name?></option>
|
223 |
+
<?php
|
224 |
+
}
|
225 |
+
?>
|
226 |
+
</select>
|
227 |
+
|
228 |
+
<input type="hidden" name="page" value="pmpro-reports" />
|
229 |
+
<input type="hidden" name="report" value="sales" />
|
230 |
+
<input type="submit" class="button action" value="<?php _ex('Generate Report', 'Submit button value.', 'pmpro');?>" />
|
231 |
+
</div>
|
232 |
+
|
233 |
+
<div id="chart_div" style="clear: both; width: 100%; height: 500px;"></div>
|
234 |
+
|
235 |
+
<script>
|
236 |
+
//update month/year when period dropdown is changed
|
237 |
+
jQuery(document).ready(function() {
|
238 |
+
jQuery('#period').change(function() {
|
239 |
+
pmpro_ShowMonthOrYear();
|
240 |
+
});
|
241 |
+
});
|
242 |
+
|
243 |
+
function pmpro_ShowMonthOrYear()
|
244 |
+
{
|
245 |
+
var period = jQuery('#period').val();
|
246 |
+
if(period == 'daily')
|
247 |
+
{
|
248 |
+
jQuery('#for').show();
|
249 |
+
jQuery('#month').show();
|
250 |
+
jQuery('#year').show();
|
251 |
+
}
|
252 |
+
else if(period == 'monthly')
|
253 |
+
{
|
254 |
+
jQuery('#for').show();
|
255 |
+
jQuery('#month').hide();
|
256 |
+
jQuery('#year').show();
|
257 |
+
}
|
258 |
+
else
|
259 |
+
{
|
260 |
+
jQuery('#for').hide();
|
261 |
+
jQuery('#month').hide();
|
262 |
+
jQuery('#year').hide();
|
263 |
+
}
|
264 |
+
}
|
265 |
+
|
266 |
+
pmpro_ShowMonthOrYear();
|
267 |
+
|
268 |
+
//draw the chart
|
269 |
+
google.load("visualization", "1", {packages:["corechart"]});
|
270 |
+
google.setOnLoadCallback(drawChart);
|
271 |
+
function drawChart() {
|
272 |
+
|
273 |
+
var data = google.visualization.arrayToDataTable([
|
274 |
+
['<?php echo $date_function;?>', '<?php echo ucwords($type);?>'],
|
275 |
+
<?php foreach($cols as $date => $value) { ?>
|
276 |
+
['<?php if($period == "monthly") echo date("M", mktime(0,0,0,$date,2)); else echo $date;?>', <?php echo $value;?>],
|
277 |
+
<?php } ?>
|
278 |
+
]);
|
279 |
+
|
280 |
+
var options = {
|
281 |
+
colors: ['#51a351', '#387038'],
|
282 |
+
hAxis: {title: '<?php echo $date_function;?>', titleTextStyle: {color: 'black'}, maxAlternation: 1},
|
283 |
+
vAxis: {color: 'green', titleTextStyle: {color: '#51a351'}},
|
284 |
+
};
|
285 |
+
|
286 |
+
<?php
|
287 |
+
if($type != "sales")
|
288 |
+
{
|
289 |
+
if(pmpro_getCurrencyPosition() == "right")
|
290 |
+
$position = "suffix";
|
291 |
+
else
|
292 |
+
$position = "prefix";
|
293 |
+
?>
|
294 |
+
var formatter = new google.visualization.NumberFormat({<?php echo $position;?>: '<?php echo html_entity_decode($pmpro_currency_symbol);?>'});
|
295 |
+
formatter.format(data, 1);
|
296 |
+
<?php
|
297 |
+
}
|
298 |
+
?>
|
299 |
+
|
300 |
+
var chart = new google.visualization.ColumnChart(document.getElementById('chart_div'));
|
301 |
+
chart.draw(data, options);
|
302 |
+
}
|
303 |
+
</script>
|
304 |
+
|
305 |
+
</form>
|
306 |
+
<?php
|
307 |
+
}
|
308 |
+
|
309 |
+
/*
|
310 |
+
Other code required for your reports. This file is loaded every time WP loads with PMPro enabled.
|
311 |
+
*/
|
312 |
+
|
313 |
+
//get sales
|
314 |
+
function pmpro_getSales($period, $levels = NULL)
|
315 |
+
{
|
316 |
+
//check for a transient
|
317 |
+
$cache = get_transient("pmpro_report_sales");
|
318 |
+
if(!empty($cache) && !empty($cache[$period]) && !empty($cache[$period][$levels]))
|
319 |
+
return $cache[$period][$levels];
|
320 |
+
|
321 |
+
//a sale is an order with status NOT IN('refunded', 'review', 'token', 'error')
|
322 |
+
if($period == "today")
|
323 |
+
$startdate = date("Y-m-d");
|
324 |
+
elseif($period == "this month")
|
325 |
+
$startdate = date("Y-m") . "-01";
|
326 |
+
elseif($period == "this year")
|
327 |
+
$startdate = date("Y") . "-01-01";
|
328 |
+
else
|
329 |
+
$startdate = "";
|
330 |
+
|
331 |
+
$gateway_environment = pmpro_getOption("gateway_environment");
|
332 |
+
|
333 |
+
//build query
|
334 |
+
global $wpdb;
|
335 |
+
$sqlQuery = "SELECT COUNT(*) FROM $wpdb->pmpro_membership_orders WHERE status NOT IN('refunded', 'review', 'token', 'error') AND timestamp >= '" . $startdate . "' AND gateway_environment = '" . esc_sql($gateway_environment) . "' ";
|
336 |
+
|
337 |
+
//restrict by level
|
338 |
+
if(!empty($levels))
|
339 |
+
$sqlQuery .= "AND membership_id IN(" . $levels . ") ";
|
340 |
+
|
341 |
+
$sales = $wpdb->get_var($sqlQuery);
|
342 |
+
|
343 |
+
//save in cache
|
344 |
+
if(!empty($cache) && !empty($cache[$period]))
|
345 |
+
$cache[$period][$levels] = $sales;
|
346 |
+
elseif(!empty($cache))
|
347 |
+
$cache[$period] = array($levels => $sales);
|
348 |
+
else
|
349 |
+
$cache = array($period => array($levels => $sales));
|
350 |
+
|
351 |
+
set_transient("pmpro_report_sales", $cache, 3600*24);
|
352 |
+
|
353 |
+
return $sales;
|
354 |
+
}
|
355 |
+
|
356 |
+
//get revenue
|
357 |
+
function pmpro_getRevenue($period, $levels = NULL)
|
358 |
+
{
|
359 |
+
//check for a transient
|
360 |
+
$cache = get_transient("pmpro_report_revenue");
|
361 |
+
if(!empty($cache) && !empty($cache[$period]) && !empty($cache[$period][$levels]))
|
362 |
+
return $cache[$period][$levels];
|
363 |
+
|
364 |
+
//a sale is an order with status NOT IN('refunded', 'review', 'token', 'error')
|
365 |
+
if($period == "today")
|
366 |
+
$startdate = date("Y-m-d");
|
367 |
+
elseif($period == "this month")
|
368 |
+
$startdate = date("Y-m") . "-01";
|
369 |
+
elseif($period == "this year")
|
370 |
+
$startdate = date("Y") . "-01-01";
|
371 |
+
else
|
372 |
+
$startdate = "";
|
373 |
+
|
374 |
+
$gateway_environment = pmpro_getOption("gateway_environment");
|
375 |
+
|
376 |
+
//build query
|
377 |
+
global $wpdb;
|
378 |
+
$sqlQuery = "SELECT SUM(total) FROM $wpdb->pmpro_membership_orders WHERE status NOT IN('refunded', 'review', 'token', 'error') AND timestamp >= '" . $startdate . "' AND gateway_environment = '" . esc_sql($gateway_environment) . "' ";
|
379 |
+
|
380 |
+
//restrict by level
|
381 |
+
if(!empty($levels))
|
382 |
+
$sqlQuery .= "AND membership_id IN(" . $levels . ") ";
|
383 |
+
|
384 |
+
$revenue = $wpdb->get_var($sqlQuery);
|
385 |
+
|
386 |
+
//save in cache
|
387 |
+
if(!empty($cache) && !empty($cache[$period]))
|
388 |
+
$cache[$period][$levels] = $revenue;
|
389 |
+
elseif(!empty($cache))
|
390 |
+
$cache[$period] = array($levels => $revenue);
|
391 |
+
else
|
392 |
+
$cache = array($period => array($levels => $revenue));
|
393 |
+
|
394 |
+
set_transient("pmpro_report_revenue", $cache, 3600*24);
|
395 |
+
|
396 |
+
return $revenue;
|
397 |
+
}
|
398 |
+
|
399 |
+
//delete transients when an order goes through
|
400 |
+
function pmpro_report_sales_delete_transients()
|
401 |
+
{
|
402 |
+
delete_transient("pmpro_report_sales");
|
403 |
+
delete_transient("pmpro_report_revenue");
|
404 |
+
}
|
405 |
+
add_action("pmpro_after_checkout", "pmpro_report_sales_delete_transients");
|
406 |
+
add_action("pmpro_updated_order", "pmpro_report_sales_delete_transients");
|
classes/class.memberorder.php
CHANGED
@@ -246,7 +246,7 @@
|
|
246 |
|
247 |
//filter @since v1.7.14
|
248 |
$this->discount_code = apply_filters("pmpro_order_discount_code", $this->discount_code, $this);
|
249 |
-
|
250 |
return $this->discount_code;
|
251 |
}
|
252 |
|
@@ -295,9 +295,9 @@
|
|
295 |
$discount_code = $this->discount_code->code;
|
296 |
else
|
297 |
$discount_code = $this->discount_code;
|
298 |
-
|
299 |
$sqlQuery = "SELECT l.id, cl.*, l.name, l.description, l.allow_signups FROM $wpdb->pmpro_discount_codes_levels cl LEFT JOIN $wpdb->pmpro_membership_levels l ON cl.level_id = l.id LEFT JOIN $wpdb->pmpro_discount_codes dc ON dc.id = cl.code_id WHERE dc.code = '" . $discount_code . "' AND cl.level_id = '" . $this->membership_id . "' LIMIT 1";
|
300 |
-
|
301 |
$this->membership_level = $wpdb->get_row($sqlQuery);
|
302 |
}
|
303 |
|
246 |
|
247 |
//filter @since v1.7.14
|
248 |
$this->discount_code = apply_filters("pmpro_order_discount_code", $this->discount_code, $this);
|
249 |
+
|
250 |
return $this->discount_code;
|
251 |
}
|
252 |
|
295 |
$discount_code = $this->discount_code->code;
|
296 |
else
|
297 |
$discount_code = $this->discount_code;
|
298 |
+
|
299 |
$sqlQuery = "SELECT l.id, cl.*, l.name, l.description, l.allow_signups FROM $wpdb->pmpro_discount_codes_levels cl LEFT JOIN $wpdb->pmpro_membership_levels l ON cl.level_id = l.id LEFT JOIN $wpdb->pmpro_discount_codes dc ON dc.id = cl.code_id WHERE dc.code = '" . $discount_code . "' AND cl.level_id = '" . $this->membership_id . "' LIMIT 1";
|
300 |
+
|
301 |
$this->membership_level = $wpdb->get_row($sqlQuery);
|
302 |
}
|
303 |
|
classes/class.mimetype.php
CHANGED
@@ -1,239 +1,239 @@
|
|
1 |
-
<?php
|
2 |
-
/**
|
3 |
-
Copyright (C) 2002 Jason Sheets <jsheets@shadonet.com>.
|
4 |
-
All rights reserved.
|
5 |
-
|
6 |
-
THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
|
7 |
-
Redistribution and use in source and binary forms, with or without
|
8 |
-
modification, are permitted provided that the following conditions
|
9 |
-
are met:
|
10 |
-
|
11 |
-
1. Redistributions of source code must retain the above copyright
|
12 |
-
notice, this list of conditions and the following disclaimer.
|
13 |
-
|
14 |
-
2. Redistributions in binary form must reproduce the above copyright
|
15 |
-
notice, this list of conditions and the following disclaimer in the
|
16 |
-
documentation and/or other materials provided with the distribution.
|
17 |
-
|
18 |
-
3. Neither the name of the project nor the names of its contributors
|
19 |
-
may be used to endorse or promote products derived from this software
|
20 |
-
without specific prior written permission.
|
21 |
-
|
22 |
-
THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
|
23 |
-
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
24 |
-
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
25 |
-
ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
|
26 |
-
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
27 |
-
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
28 |
-
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
29 |
-
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
30 |
-
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
31 |
-
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
32 |
-
SUCH DAMAGE.
|
33 |
-
**/
|
34 |
-
|
35 |
-
/**
|
36 |
-
Name: PHP MimeType Class
|
37 |
-
|
38 |
-
Version: 1.0
|
39 |
-
Date Released: 10/20/02
|
40 |
-
|
41 |
-
Description: This class allows a PHP script to determine the mime type
|
42 |
-
a file based on the file extension. This class is handy for PHP versions
|
43 |
-
without the benefit of other tools to determine the mime type. The class
|
44 |
-
defaults to octet-stream so if the file type is not recognized the user
|
45 |
-
is presented with a file download prompt.
|
46 |
-
|
47 |
-
NOTES: The mime types for this version are based on Apache 1.3.27
|
48 |
-
mime types may change or need to be added in the future, the mime types
|
49 |
-
are stored in an array so that an awk or other script can automatically
|
50 |
-
generate the code to make the array.
|
51 |
-
|
52 |
-
Usage:
|
53 |
-
|
54 |
-
First an instance of the mimetype class must be created, then the
|
55 |
-
getType method should be called with the filename. It will return
|
56 |
-
the mime type, an example follows.
|
57 |
-
|
58 |
-
Example:
|
59 |
-
|
60 |
-
$mimetype = new mimetype();
|
61 |
-
print $mimetype->getType('acrobat.pdf');
|
62 |
-
|
63 |
-
Author: Jason Sheets <jsheets@shadonet.com>
|
64 |
-
|
65 |
-
License: This script is distributed under the BSD License, you are free
|
66 |
-
to use, or modify it however you like. If you find this script useful please
|
67 |
-
e-mail me.
|
68 |
-
**/
|
69 |
-
|
70 |
-
class pmpro_mimetype {
|
71 |
-
function getType($filename) {
|
72 |
-
// get base name of the filename provided by user
|
73 |
-
$filename = basename($filename);
|
74 |
-
|
75 |
-
// break file into parts seperated by .
|
76 |
-
$filename = explode('.', $filename);
|
77 |
-
|
78 |
-
// take the last part of the file to get the file extension
|
79 |
-
$filename = $filename[count($filename)-1];
|
80 |
-
|
81 |
-
// find mime type
|
82 |
-
return $this->privFindType($filename);
|
83 |
-
}
|
84 |
-
|
85 |
-
function privFindType($ext) {
|
86 |
-
// create mimetypes array
|
87 |
-
$mimetypes = $this->privBuildMimeArray();
|
88 |
-
|
89 |
-
// return mime type for extension
|
90 |
-
if (isset($mimetypes[$ext])) {
|
91 |
-
return $mimetypes[$ext];
|
92 |
-
// if the extension wasn't found return octet-stream
|
93 |
-
} else {
|
94 |
-
return 'application/octet-stream';
|
95 |
-
}
|
96 |
-
|
97 |
-
}
|
98 |
-
|
99 |
-
function privBuildMimeArray() {
|
100 |
-
return array(
|
101 |
-
"ez" => "application/andrew-inset",
|
102 |
-
"hqx" => "application/mac-binhex40",
|
103 |
-
"cpt" => "application/mac-compactpro",
|
104 |
-
"doc" => "application/msword",
|
105 |
-
"bin" => "application/octet-stream",
|
106 |
-
"dms" => "application/octet-stream",
|
107 |
-
"lha" => "application/octet-stream",
|
108 |
-
"lzh" => "application/octet-stream",
|
109 |
-
"exe" => "application/octet-stream",
|
110 |
-
"class" => "application/octet-stream",
|
111 |
-
"so" => "application/octet-stream",
|
112 |
-
"dll" => "application/octet-stream",
|
113 |
-
"oda" => "application/oda",
|
114 |
-
"pdf" => "application/pdf",
|
115 |
-
"ai" => "application/postscript",
|
116 |
-
"eps" => "application/postscript",
|
117 |
-
"ps" => "application/postscript",
|
118 |
-
"smi" => "application/smil",
|
119 |
-
"smil" => "application/smil",
|
120 |
-
"wbxml" => "application/vnd.wap.wbxml",
|
121 |
-
"wmlc" => "application/vnd.wap.wmlc",
|
122 |
-
"wmlsc" => "application/vnd.wap.wmlscriptc",
|
123 |
-
"bcpio" => "application/x-bcpio",
|
124 |
-
"vcd" => "application/x-cdlink",
|
125 |
-
"pgn" => "application/x-chess-pgn",
|
126 |
-
"cpio" => "application/x-cpio",
|
127 |
-
"csh" => "application/x-csh",
|
128 |
-
"dcr" => "application/x-director",
|
129 |
-
"dir" => "application/x-director",
|
130 |
-
"dxr" => "application/x-director",
|
131 |
-
"dvi" => "application/x-dvi",
|
132 |
-
"spl" => "application/x-futuresplash",
|
133 |
-
"gtar" => "application/x-gtar",
|
134 |
-
"hdf" => "application/x-hdf",
|
135 |
-
"js" => "application/x-javascript",
|
136 |
-
"skp" => "application/x-koan",
|
137 |
-
"skd" => "application/x-koan",
|
138 |
-
"skt" => "application/x-koan",
|
139 |
-
"skm" => "application/x-koan",
|
140 |
-
"latex" => "application/x-latex",
|
141 |
-
"nc" => "application/x-netcdf",
|
142 |
-
"cdf" => "application/x-netcdf",
|
143 |
-
"sh" => "application/x-sh",
|
144 |
-
"shar" => "application/x-shar",
|
145 |
-
"swf" => "application/x-shockwave-flash",
|
146 |
-
"sit" => "application/x-stuffit",
|
147 |
-
"sv4cpio" => "application/x-sv4cpio",
|
148 |
-
"sv4crc" => "application/x-sv4crc",
|
149 |
-
"tar" => "application/x-tar",
|
150 |
-
"tcl" => "application/x-tcl",
|
151 |
-
"tex" => "application/x-tex",
|
152 |
-
"texinfo" => "application/x-texinfo",
|
153 |
-
"texi" => "application/x-texinfo",
|
154 |
-
"t" => "application/x-troff",
|
155 |
-
"tr" => "application/x-troff",
|
156 |
-
"roff" => "application/x-troff",
|
157 |
-
"man" => "application/x-troff-man",
|
158 |
-
"me" => "application/x-troff-me",
|
159 |
-
"ms" => "application/x-troff-ms",
|
160 |
-
"ustar" => "application/x-ustar",
|
161 |
-
"src" => "application/x-wais-source",
|
162 |
-
"xhtml" => "application/xhtml+xml",
|
163 |
-
"xht" => "application/xhtml+xml",
|
164 |
-
"zip" => "application/zip",
|
165 |
-
"au" => "audio/basic",
|
166 |
-
"snd" => "audio/basic",
|
167 |
-
"mid" => "audio/midi",
|
168 |
-
"midi" => "audio/midi",
|
169 |
-
"kar" => "audio/midi",
|
170 |
-
"mpga" => "audio/mpeg",
|
171 |
-
"mp2" => "audio/mpeg",
|
172 |
-
"mp3" => "audio/mpeg",
|
173 |
-
"aif" => "audio/x-aiff",
|
174 |
-
"aiff" => "audio/x-aiff",
|
175 |
-
"aifc" => "audio/x-aiff",
|
176 |
-
"m3u" => "audio/x-mpegurl",
|
177 |
-
"ram" => "audio/x-pn-realaudio",
|
178 |
-
"rm" => "audio/x-pn-realaudio",
|
179 |
-
"rpm" => "audio/x-pn-realaudio-plugin",
|
180 |
-
"ra" => "audio/x-realaudio",
|
181 |
-
"wav" => "audio/x-wav",
|
182 |
-
"pdb" => "chemical/x-pdb",
|
183 |
-
"xyz" => "chemical/x-xyz",
|
184 |
-
"bmp" => "image/bmp",
|
185 |
-
"gif" => "image/gif",
|
186 |
-
"ief" => "image/ief",
|
187 |
-
"jpeg" => "image/jpeg",
|
188 |
-
"jpg" => "image/jpeg",
|
189 |
-
"jpe" => "image/jpeg",
|
190 |
-
"png" => "image/png",
|
191 |
-
"tiff" => "image/tiff",
|
192 |
-
"tif" => "image/tif",
|
193 |
-
"djvu" => "image/vnd.djvu",
|
194 |
-
"djv" => "image/vnd.djvu",
|
195 |
-
"wbmp" => "image/vnd.wap.wbmp",
|
196 |
-
"ras" => "image/x-cmu-raster",
|
197 |
-
"pnm" => "image/x-portable-anymap",
|
198 |
-
"pbm" => "image/x-portable-bitmap",
|
199 |
-
"pgm" => "image/x-portable-graymap",
|
200 |
-
"ppm" => "image/x-portable-pixmap",
|
201 |
-
"rgb" => "image/x-rgb",
|
202 |
-
"xbm" => "image/x-xbitmap",
|
203 |
-
"xpm" => "image/x-xpixmap",
|
204 |
-
"xwd" => "image/x-windowdump",
|
205 |
-
"igs" => "model/iges",
|
206 |
-
"iges" => "model/iges",
|
207 |
-
"msh" => "model/mesh",
|
208 |
-
"mesh" => "model/mesh",
|
209 |
-
"silo" => "model/mesh",
|
210 |
-
"wrl" => "model/vrml",
|
211 |
-
"vrml" => "model/vrml",
|
212 |
-
"css" => "text/css",
|
213 |
-
"html" => "text/html",
|
214 |
-
"htm" => "text/html",
|
215 |
-
"asc" => "text/plain",
|
216 |
-
"txt" => "text/plain",
|
217 |
-
"rtx" => "text/richtext",
|
218 |
-
"rtf" => "text/rtf",
|
219 |
-
"sgml" => "text/sgml",
|
220 |
-
"sgm" => "text/sgml",
|
221 |
-
"tsv" => "text/tab-seperated-values",
|
222 |
-
"wml" => "text/vnd.wap.wml",
|
223 |
-
"wmls" => "text/vnd.wap.wmlscript",
|
224 |
-
"etx" => "text/x-setext",
|
225 |
-
"xml" => "text/xml",
|
226 |
-
"xsl" => "text/xml",
|
227 |
-
"mpeg" => "video/mpeg",
|
228 |
-
"mpg" => "video/mpeg",
|
229 |
-
"mpe" => "video/mpeg",
|
230 |
-
"qt" => "video/quicktime",
|
231 |
-
"mov" => "video/quicktime",
|
232 |
-
"mxu" => "video/vnd.mpegurl",
|
233 |
-
"avi" => "video/x-msvideo",
|
234 |
-
"movie" => "video/x-sgi-movie",
|
235 |
-
"ice" => "x-conference-xcooltalk"
|
236 |
-
);
|
237 |
-
}
|
238 |
-
}
|
239 |
?>
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
Copyright (C) 2002 Jason Sheets <jsheets@shadonet.com>.
|
4 |
+
All rights reserved.
|
5 |
+
|
6 |
+
THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
|
7 |
+
Redistribution and use in source and binary forms, with or without
|
8 |
+
modification, are permitted provided that the following conditions
|
9 |
+
are met:
|
10 |
+
|
11 |
+
1. Redistributions of source code must retain the above copyright
|
12 |
+
notice, this list of conditions and the following disclaimer.
|
13 |
+
|
14 |
+
2. Redistributions in binary form must reproduce the above copyright
|
15 |
+
notice, this list of conditions and the following disclaimer in the
|
16 |
+
documentation and/or other materials provided with the distribution.
|
17 |
+
|
18 |
+
3. Neither the name of the project nor the names of its contributors
|
19 |
+
may be used to endorse or promote products derived from this software
|
20 |
+
without specific prior written permission.
|
21 |
+
|
22 |
+
THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
|
23 |
+
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
24 |
+
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
25 |
+
ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
|
26 |
+
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
27 |
+
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
28 |
+
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
29 |
+
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
30 |
+
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
31 |
+
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
32 |
+
SUCH DAMAGE.
|
33 |
+
**/
|
34 |
+
|
35 |
+
/**
|
36 |
+
Name: PHP MimeType Class
|
37 |
+
|
38 |
+
Version: 1.0
|
39 |
+
Date Released: 10/20/02
|
40 |
+
|
41 |
+
Description: This class allows a PHP script to determine the mime type
|
42 |
+
a file based on the file extension. This class is handy for PHP versions
|
43 |
+
without the benefit of other tools to determine the mime type. The class
|
44 |
+
defaults to octet-stream so if the file type is not recognized the user
|
45 |
+
is presented with a file download prompt.
|
46 |
+
|
47 |
+
NOTES: The mime types for this version are based on Apache 1.3.27
|
48 |
+
mime types may change or need to be added in the future, the mime types
|
49 |
+
are stored in an array so that an awk or other script can automatically
|
50 |
+
generate the code to make the array.
|
51 |
+
|
52 |
+
Usage:
|
53 |
+
|
54 |
+
First an instance of the mimetype class must be created, then the
|
55 |
+
getType method should be called with the filename. It will return
|
56 |
+
the mime type, an example follows.
|
57 |
+
|
58 |
+
Example:
|
59 |
+
|
60 |
+
$mimetype = new mimetype();
|
61 |
+
print $mimetype->getType('acrobat.pdf');
|
62 |
+
|
63 |
+
Author: Jason Sheets <jsheets@shadonet.com>
|
64 |
+
|
65 |
+
License: This script is distributed under the BSD License, you are free
|
66 |
+
to use, or modify it however you like. If you find this script useful please
|
67 |
+
e-mail me.
|
68 |
+
**/
|
69 |
+
|
70 |
+
class pmpro_mimetype {
|
71 |
+
function getType($filename) {
|
72 |
+
// get base name of the filename provided by user
|
73 |
+
$filename = basename($filename);
|
74 |
+
|
75 |
+
// break file into parts seperated by .
|
76 |
+
$filename = explode('.', $filename);
|
77 |
+
|
78 |
+
// take the last part of the file to get the file extension
|
79 |
+
$filename = $filename[count($filename)-1];
|
80 |
+
|
81 |
+
// find mime type
|
82 |
+
return $this->privFindType($filename);
|
83 |
+
}
|
84 |
+
|
85 |
+
function privFindType($ext) {
|
86 |
+
// create mimetypes array
|
87 |
+
$mimetypes = $this->privBuildMimeArray();
|
88 |
+
|
89 |
+
// return mime type for extension
|
90 |
+
if (isset($mimetypes[$ext])) {
|
91 |
+
return $mimetypes[$ext];
|
92 |
+
// if the extension wasn't found return octet-stream
|
93 |
+
} else {
|
94 |
+
return 'application/octet-stream';
|
95 |
+
}
|
96 |
+
|
97 |
+
}
|
98 |
+
|
99 |
+
function privBuildMimeArray() {
|
100 |
+
return array(
|
101 |
+
"ez" => "application/andrew-inset",
|
102 |
+
"hqx" => "application/mac-binhex40",
|
103 |
+
"cpt" => "application/mac-compactpro",
|
104 |
+
"doc" => "application/msword",
|
105 |
+
"bin" => "application/octet-stream",
|
106 |
+
"dms" => "application/octet-stream",
|
107 |
+
"lha" => "application/octet-stream",
|
108 |
+
"lzh" => "application/octet-stream",
|
109 |
+
"exe" => "application/octet-stream",
|
110 |
+
"class" => "application/octet-stream",
|
111 |
+
"so" => "application/octet-stream",
|
112 |
+
"dll" => "application/octet-stream",
|
113 |
+
"oda" => "application/oda",
|
114 |
+
"pdf" => "application/pdf",
|
115 |
+
"ai" => "application/postscript",
|
116 |
+
"eps" => "application/postscript",
|
117 |
+
"ps" => "application/postscript",
|
118 |
+
"smi" => "application/smil",
|
119 |
+
"smil" => "application/smil",
|
120 |
+
"wbxml" => "application/vnd.wap.wbxml",
|
121 |
+
"wmlc" => "application/vnd.wap.wmlc",
|
122 |
+
"wmlsc" => "application/vnd.wap.wmlscriptc",
|
123 |
+
"bcpio" => "application/x-bcpio",
|
124 |
+
"vcd" => "application/x-cdlink",
|
125 |
+
"pgn" => "application/x-chess-pgn",
|
126 |
+
"cpio" => "application/x-cpio",
|
127 |
+
"csh" => "application/x-csh",
|
128 |
+
"dcr" => "application/x-director",
|
129 |
+
"dir" => "application/x-director",
|
130 |
+
"dxr" => "application/x-director",
|
131 |
+
"dvi" => "application/x-dvi",
|
132 |
+
"spl" => "application/x-futuresplash",
|
133 |
+
"gtar" => "application/x-gtar",
|
134 |
+
"hdf" => "application/x-hdf",
|
135 |
+
"js" => "application/x-javascript",
|
136 |
+
"skp" => "application/x-koan",
|
137 |
+
"skd" => "application/x-koan",
|
138 |
+
"skt" => "application/x-koan",
|
139 |
+
"skm" => "application/x-koan",
|
140 |
+
"latex" => "application/x-latex",
|
141 |
+
"nc" => "application/x-netcdf",
|
142 |
+
"cdf" => "application/x-netcdf",
|
143 |
+
"sh" => "application/x-sh",
|
144 |
+
"shar" => "application/x-shar",
|
145 |
+
"swf" => "application/x-shockwave-flash",
|
146 |
+
"sit" => "application/x-stuffit",
|
147 |
+
"sv4cpio" => "application/x-sv4cpio",
|
148 |
+
"sv4crc" => "application/x-sv4crc",
|
149 |
+
"tar" => "application/x-tar",
|
150 |
+
"tcl" => "application/x-tcl",
|
151 |
+
"tex" => "application/x-tex",
|
152 |
+
"texinfo" => "application/x-texinfo",
|
153 |
+
"texi" => "application/x-texinfo",
|
154 |
+
"t" => "application/x-troff",
|
155 |
+
"tr" => "application/x-troff",
|
156 |
+
"roff" => "application/x-troff",
|
157 |
+
"man" => "application/x-troff-man",
|
158 |
+
"me" => "application/x-troff-me",
|
159 |
+
"ms" => "application/x-troff-ms",
|
160 |
+
"ustar" => "application/x-ustar",
|
161 |
+
"src" => "application/x-wais-source",
|
162 |
+
"xhtml" => "application/xhtml+xml",
|
163 |
+
"xht" => "application/xhtml+xml",
|
164 |
+
"zip" => "application/zip",
|
165 |
+
"au" => "audio/basic",
|
166 |
+
"snd" => "audio/basic",
|
167 |
+
"mid" => "audio/midi",
|
168 |
+
"midi" => "audio/midi",
|
169 |
+
"kar" => "audio/midi",
|
170 |
+
"mpga" => "audio/mpeg",
|
171 |
+
"mp2" => "audio/mpeg",
|
172 |
+
"mp3" => "audio/mpeg",
|
173 |
+
"aif" => "audio/x-aiff",
|
174 |
+
"aiff" => "audio/x-aiff",
|
175 |
+
"aifc" => "audio/x-aiff",
|
176 |
+
"m3u" => "audio/x-mpegurl",
|
177 |
+
"ram" => "audio/x-pn-realaudio",
|
178 |
+
"rm" => "audio/x-pn-realaudio",
|
179 |
+
"rpm" => "audio/x-pn-realaudio-plugin",
|
180 |
+
"ra" => "audio/x-realaudio",
|
181 |
+
"wav" => "audio/x-wav",
|
182 |
+
"pdb" => "chemical/x-pdb",
|
183 |
+
"xyz" => "chemical/x-xyz",
|
184 |
+
"bmp" => "image/bmp",
|
185 |
+
"gif" => "image/gif",
|
186 |
+
"ief" => "image/ief",
|
187 |
+
"jpeg" => "image/jpeg",
|
188 |
+
"jpg" => "image/jpeg",
|
189 |
+
"jpe" => "image/jpeg",
|
190 |
+
"png" => "image/png",
|
191 |
+
"tiff" => "image/tiff",
|
192 |
+
"tif" => "image/tif",
|
193 |
+
"djvu" => "image/vnd.djvu",
|
194 |
+
"djv" => "image/vnd.djvu",
|
195 |
+
"wbmp" => "image/vnd.wap.wbmp",
|
196 |
+
"ras" => "image/x-cmu-raster",
|
197 |
+
"pnm" => "image/x-portable-anymap",
|
198 |
+
"pbm" => "image/x-portable-bitmap",
|
199 |
+
"pgm" => "image/x-portable-graymap",
|
200 |
+
"ppm" => "image/x-portable-pixmap",
|
201 |
+
"rgb" => "image/x-rgb",
|
202 |
+
"xbm" => "image/x-xbitmap",
|
203 |
+
"xpm" => "image/x-xpixmap",
|
204 |
+
"xwd" => "image/x-windowdump",
|
205 |
+
"igs" => "model/iges",
|
206 |
+
"iges" => "model/iges",
|
207 |
+
"msh" => "model/mesh",
|
208 |
+
"mesh" => "model/mesh",
|
209 |
+
"silo" => "model/mesh",
|
210 |
+
"wrl" => "model/vrml",
|
211 |
+
"vrml" => "model/vrml",
|
212 |
+
"css" => "text/css",
|
213 |
+
"html" => "text/html",
|
214 |
+
"htm" => "text/html",
|
215 |
+
"asc" => "text/plain",
|
216 |
+
"txt" => "text/plain",
|
217 |
+
"rtx" => "text/richtext",
|
218 |
+
"rtf" => "text/rtf",
|
219 |
+
"sgml" => "text/sgml",
|
220 |
+
"sgm" => "text/sgml",
|
221 |
+
"tsv" => "text/tab-seperated-values",
|
222 |
+
"wml" => "text/vnd.wap.wml",
|
223 |
+
"wmls" => "text/vnd.wap.wmlscript",
|
224 |
+
"etx" => "text/x-setext",
|
225 |
+
"xml" => "text/xml",
|
226 |
+
"xsl" => "text/xml",
|
227 |
+
"mpeg" => "video/mpeg",
|
228 |
+
"mpg" => "video/mpeg",
|
229 |
+
"mpe" => "video/mpeg",
|
230 |
+
"qt" => "video/quicktime",
|
231 |
+
"mov" => "video/quicktime",
|
232 |
+
"mxu" => "video/vnd.mpegurl",
|
233 |
+
"avi" => "video/x-msvideo",
|
234 |
+
"movie" => "video/x-sgi-movie",
|
235 |
+
"ice" => "x-conference-xcooltalk"
|
236 |
+
);
|
237 |
+
}
|
238 |
+
}
|
239 |
?>
|
classes/class.pmproemail.php
CHANGED
@@ -1,815 +1,815 @@
|
|
1 |
-
<?php
|
2 |
-
class PMProEmail
|
3 |
-
{
|
4 |
-
function PMProEmail()
|
5 |
-
{
|
6 |
-
$this->email = $this->from = $this->fromname = $this->subject = $this->template = $this->data = $this->body = NULL;
|
7 |
-
}
|
8 |
-
|
9 |
-
function sendEmail($email = NULL, $from = NULL, $fromname = NULL, $subject = NULL, $template = NULL, $data = NULL)
|
10 |
-
{
|
11 |
-
//if values were passed
|
12 |
-
if($email)
|
13 |
-
$this->email = $email;
|
14 |
-
if($from)
|
15 |
-
$this->from = $from;
|
16 |
-
if($fromname)
|
17 |
-
$this->fromname = $fromname;
|
18 |
-
if($subject)
|
19 |
-
$this->subject = $subject;
|
20 |
-
if($template)
|
21 |
-
$this->template = $template;
|
22 |
-
if($data)
|
23 |
-
$this->data = $data;
|
24 |
-
|
25 |
-
//default values
|
26 |
-
global $current_user;
|
27 |
-
if(!$this->email)
|
28 |
-
$this->email = $current_user->user_email;
|
29 |
-
|
30 |
-
if(!$this->from)
|
31 |
-
$this->from = pmpro_getOption("from_email");
|
32 |
-
|
33 |
-
if(!$this->fromname)
|
34 |
-
$this->fromname = pmpro_getOption("from_name");
|
35 |
-
|
36 |
-
if(!$this->subject)
|
37 |
-
$this->subject = sprintf(__("An Email From %s", "pmpro"), get_option("blogname"));
|
38 |
-
|
39 |
-
//decode the subject line in case there are apostrophes/etc in it
|
40 |
-
$this->subject = html_entity_decode($this->subject, ENT_QUOTES, 'UTF-8');
|
41 |
-
|
42 |
-
if(!$this->template)
|
43 |
-
$this->template = "default";
|
44 |
-
|
45 |
-
$this->headers = array("Content-Type: text/html");
|
46 |
-
|
47 |
-
$this->attachments = NULL;
|
48 |
-
|
49 |
-
//load the template
|
50 |
-
$locale = apply_filters("plugin_locale", get_locale(), "pmpro");
|
51 |
-
if(file_exists(get_stylesheet_directory() . "/paid-memberships-pro/email/" . $this->template . ".html"))
|
52 |
-
$this->body = file_get_contents(get_stylesheet_directory() . "/paid-memberships-pro/email/" . $this->template . ".html"); //email folder in pmpro folder in theme
|
53 |
-
elseif(file_exists(get_stylesheet_directory() . "/membership-email-" . $this->template . ".html"))
|
54 |
-
$this->body = file_get_contents(get_stylesheet_directory() . "/membership-email-" . $this->template . ".html"); //membership- file in pmpro folder in theme
|
55 |
-
elseif(file_exists(TEMPLATEPATH . "/membership-email-" . $this->template . ".html"))
|
56 |
-
$this->body = file_get_contents(TEMPLATEPATH . "/membership-email-" . $this->template . ".html"); //membership- file in theme root
|
57 |
-
elseif(file_exists(WP_LANG_DIR . '/pmpro/email/' . $this->template . ".html"))
|
58 |
-
$this->body = file_get_contents(WP_LANG_DIR . '/pmpro/email/' . $this->template . ".html"); //email folder in WP language folder
|
59 |
-
elseif(file_exists(PMPRO_DIR . "/languages/" . $locale . "/" . $this->template . ".html"))
|
60 |
-
$this->body = file_get_contents(PMPRO_DIR . "/languages/" . $locale . "/" . $this->template . ".html"); //email folder in PMPro language folder
|
61 |
-
elseif(file_exists(PMPRO_DIR . "/email/" . $this->template . ".html"))
|
62 |
-
$this->body = file_get_contents(PMPRO_DIR . "/email/" . $this->template . ".html"); //default template in plugin
|
63 |
-
elseif(!empty($this->data) && !empty($this->data['body']))
|
64 |
-
$this->body = $this->data['body'];
|
65 |
-
|
66 |
-
//header and footer
|
67 |
-
/* This is handled for all emails via the pmpro_send_html function in paid-memberships-pro now
|
68 |
-
if(file_exists(TEMPLATEPATH . "/email_header.html"))
|
69 |
-
{
|
70 |
-
$this->body = file_get_contents(TEMPLATEPATH . "/email_header.html") . "\n" . $this->body;
|
71 |
-
}
|
72 |
-
if(file_exists(TEMPLATEPATH . "/email_footer.html"))
|
73 |
-
{
|
74 |
-
$this->body = $this->body . "\n" . file_get_contents(TEMPLATEPATH . "/email_footer.html");
|
75 |
-
}
|
76 |
-
*/
|
77 |
-
|
78 |
-
//if data is a string, assume we mean to replace !!body!! with it
|
79 |
-
if(is_string($this->data))
|
80 |
-
$this->data = array("body"=>$data);
|
81 |
-
|
82 |
-
//filter for data
|
83 |
-
$this->data = apply_filters("pmpro_email_data", $this->data, $this); //filter
|
84 |
-
|
85 |
-
//swap data into body
|
86 |
-
if(is_array($this->data))
|
87 |
-
{
|
88 |
-
foreach($this->data as $key => $value)
|
89 |
-
{
|
90 |
-
$this->body = str_replace("!!" . $key . "!!", $value, $this->body);
|
91 |
-
}
|
92 |
-
}
|
93 |
-
|
94 |
-
//filters
|
95 |
-
$temail = apply_filters("pmpro_email_filter", $this); //allows filtering entire email at once
|
96 |
-
$this->email = apply_filters("pmpro_email_recipient", $temail->email, $this);
|
97 |
-
$this->from = apply_filters("pmpro_email_sender", $temail->from, $this);
|
98 |
-
$this->fromname = apply_filters("pmpro_email_sender_name", $temail->fromname, $this);
|
99 |
-
$this->subject = apply_filters("pmpro_email_subject", $temail->subject, $this);
|
100 |
-
$this->template = apply_filters("pmpro_email_template", $temail->template, $this);
|
101 |
-
$this->body = apply_filters("pmpro_email_body", $temail->body, $this);
|
102 |
-
$this->headers = apply_filters("pmpro_email_headers", $temail->headers, $this);
|
103 |
-
$this->attachments = apply_filters("pmpro_email_attachments", $temail->attachments, $this);
|
104 |
-
|
105 |
-
if(wp_mail($this->email,$this->subject,$this->body,$this->headers,$this->attachments))
|
106 |
-
{
|
107 |
-
return true;
|
108 |
-
}
|
109 |
-
else
|
110 |
-
{
|
111 |
-
return false;
|
112 |
-
}
|
113 |
-
}
|
114 |
-
|
115 |
-
function sendCancelEmail($user = NULL)
|
116 |
-
{
|
117 |
-
global $current_user;
|
118 |
-
if(!$user)
|
119 |
-
$user = $current_user;
|
120 |
-
|
121 |
-
if(!$user)
|
122 |
-
return false;
|
123 |
-
|
124 |
-
$this->email = $user->user_email;
|
125 |
-
$this->subject = sprintf(__("Your membership at %s has been CANCELLED", "pmpro"), get_option("blogname"));
|
126 |
-
$this->template = "cancel";
|
127 |
-
$this->data = array("name" => $user->display_name, "user_login" => $user->user_login, "sitename" => get_option("blogname"), "siteemail" => pmpro_getOption("from_email"));
|
128 |
-
|
129 |
-
return $this->sendEmail();
|
130 |
-
}
|
131 |
-
|
132 |
-
function sendCancelAdminEmail($user = NULL, $old_level_id)
|
133 |
-
{
|
134 |
-
global $wpdb, $current_user;
|
135 |
-
if(!$user)
|
136 |
-
$user = $current_user;
|
137 |
-
|
138 |
-
if(!$user)
|
139 |
-
return false;
|
140 |
-
|
141 |
-
//check settings
|
142 |
-
$send = pmpro_getOption("email_admin_cancels");
|
143 |
-
if(empty($send))
|
144 |
-
return true; //didn't send, but we also don't want to indicate failure because the settings say to not send
|
145 |
-
|
146 |
-
$this->email = get_bloginfo("admin_email");
|
147 |
-
$this->subject = sprintf(__("Membership for %s at %s has been CANCELLED", "pmpro"), $user->user_login, get_option("blogname"));
|
148 |
-
$this->template = "cancel_admin";
|
149 |
-
$this->data = array("user_login" => $user->user_login, "user_email" => $user->user_email, "display_name" => $user->display_name, "sitename" => get_option("blogname"), "siteemail" => pmpro_getOption("from_email"), "login_link" => wp_login_url());
|
150 |
-
$this->data['membership_id'] = $old_level_id;
|
151 |
-
$this->data['membership_level_name'] = $wpdb->get_var("SELECT name FROM $wpdb->pmpro_membership_levels WHERE id = '" . $old_level_id . "' LIMIT 1");
|
152 |
-
|
153 |
-
//start and end date
|
154 |
-
$startdate = $wpdb->get_var("SELECT UNIX_TIMESTAMP(startdate) as startdate FROM $wpdb->pmpro_memberships_users WHERE user_id = '" . $user->ID . "' AND membership_id = '" . $old_level_id . "' AND status = 'inactive' ORDER BY id DESC");
|
155 |
-
if(!empty($startdate))
|
156 |
-
$this->data['startdate'] = date(get_option('date_format'), $startdate);
|
157 |
-
else
|
158 |
-
$this->data['startdate'] = "";
|
159 |
-
$enddate = $wpdb->get_var("SELECT UNIX_TIMESTAMP(enddate) as enddate FROM $wpdb->pmpro_memberships_users WHERE user_id = '" . $user->ID . "' AND membership_id = '" . $old_level_id . "' AND status = 'inactive' ORDER BY id DESC");
|
160 |
-
if(!empty($enddate))
|
161 |
-
$this->data['enddate'] = date(get_option('date_format'), $enddate);
|
162 |
-
else
|
163 |
-
$this->data['enddate'] = "";
|
164 |
-
|
165 |
-
return $this->sendEmail();
|
166 |
-
}
|
167 |
-
|
168 |
-
function sendCheckoutEmail($user = NULL, $invoice = NULL)
|
169 |
-
{
|
170 |
-
global $wpdb, $current_user;
|
171 |
-
if(!$user)
|
172 |
-
$user = $current_user;
|
173 |
-
|
174 |
-
if(!$user)
|
175 |
-
return false;
|
176 |
-
|
177 |
-
$this->email = $user->user_email;
|
178 |
-
$this->subject = sprintf(__("Your membership confirmation for %s", "pmpro"), get_option("blogname"));
|
179 |
-
|
180 |
-
$this->data = array(
|
181 |
-
"subject" => $this->subject,
|
182 |
-
"name" => $user->display_name,
|
183 |
-
"user_login" => $user->user_login,
|
184 |
-
"sitename" => get_option("blogname"),
|
185 |
-
"siteemail" => pmpro_getOption("from_email"),
|
186 |
-
"membership_id" => $user->membership_level->id,
|
187 |
-
"membership_level_name" => $user->membership_level->name,
|
188 |
-
"membership_cost" => pmpro_getLevelCost($user->membership_level),
|
189 |
-
"login_link" => wp_login_url(pmpro_url("account")),
|
190 |
-
"display_name" => $user->display_name,
|
191 |
-
"user_email" => $user->user_email,0
|
192 |
-
);
|
193 |
-
|
194 |
-
if(!empty($invoice) && !pmpro_isLevelFree($user->membership_level))
|
195 |
-
{
|
196 |
-
if($invoice->gateway == "paypalexpress")
|
197 |
-
$this->template = "checkout_express";
|
198 |
-
elseif($invoice->gateway == "check")
|
199 |
-
{
|
200 |
-
$this->template = "checkout_check";
|
201 |
-
$this->data["instructions"] = wpautop(pmpro_getOption("instructions"));
|
202 |
-
}
|
203 |
-
elseif(pmpro_isLevelTrial($user->membership_level))
|
204 |
-
$this->template = "checkout_trial";
|
205 |
-
else
|
206 |
-
$this->template = "checkout_paid";
|
207 |
-
$this->data["invoice_id"] = $invoice->code;
|
208 |
-
$this->data["invoice_total"] = pmpro_formatPrice($invoice->total);
|
209 |
-
$this->data["invoice_date"] = date(get_option('date_format'), $invoice->timestamp);
|
210 |
-
$this->data["billing_name"] = $invoice->billing->name;
|
211 |
-
$this->data["billing_street"] = $invoice->billing->street;
|
212 |
-
$this->data["billing_city"] = $invoice->billing->city;
|
213 |
-
$this->data["billing_state"] = $invoice->billing->state;
|
214 |
-
$this->data["billing_zip"] = $invoice->billing->zip;
|
215 |
-
$this->data["billing_country"] = $invoice->billing->country;
|
216 |
-
$this->data["billing_phone"] = $invoice->billing->phone;
|
217 |
-
$this->data["cardtype"] = $invoice->cardtype;
|
218 |
-
$this->data["accountnumber"] = hideCardNumber($invoice->accountnumber);
|
219 |
-
$this->data["expirationmonth"] = $invoice->expirationmonth;
|
220 |
-
$this->data["expirationyear"] = $invoice->expirationyear;
|
221 |
-
$this->data["billing_address"] = pmpro_formatAddress($invoice->billing->name,
|
222 |
-
$invoice->billing->street,
|
223 |
-
"", //address 2
|
224 |
-
$invoice->billing->city,
|
225 |
-
$invoice->billing->state,
|
226 |
-
$invoice->billing->zip,
|
227 |
-
$invoice->billing->country,
|
228 |
-
$invoice->billing->phone);
|
229 |
-
|
230 |
-
if($invoice->getDiscountCode())
|
231 |
-
$this->data["discount_code"] = "<p>" . __("Discount Code", "pmpro") . ": " . $invoice->discount_code->code . "</p>\n";
|
232 |
-
else
|
233 |
-
$this->data["discount_code"] = "";
|
234 |
-
}
|
235 |
-
elseif(pmpro_isLevelFree($user->membership_level))
|
236 |
-
{
|
237 |
-
$this->template = "checkout_free";
|
238 |
-
global $discount_code;
|
239 |
-
if(!empty($discount_code))
|
240 |
-
$this->data["discount_code"] = "<p>" . __("Discount Code", "pmpro") . ": " . $discount_code . "</p>\n";
|
241 |
-
else
|
242 |
-
$this->data["discount_code"] = "";
|
243 |
-
}
|
244 |
-
else
|
245 |
-
{
|
246 |
-
$this->template = "checkout_freetrial";
|
247 |
-
global $discount_code;
|
248 |
-
if(!empty($discount_code))
|
249 |
-
$this->data["discount_code"] = "<p>" . __("Discount Code", "pmpro") . ": " . $discount_code . "</p>\n";
|
250 |
-
else
|
251 |
-
$this->data["discount_code"] = "";
|
252 |
-
}
|
253 |
-
|
254 |
-
$enddate = $wpdb->get_var("SELECT UNIX_TIMESTAMP(enddate) FROM $wpdb->pmpro_memberships_users WHERE user_id = '" . $user->ID . "' AND status = 'active' LIMIT 1");
|
255 |
-
if($enddate)
|
256 |
-
$this->data["membership_expiration"] = "<p>" . sprintf(__("This membership will expire on %s.", "pmpro"), date(get_option('date_format'), $enddate)) . "</p>\n";
|
257 |
-
else
|
258 |
-
$this->data["membership_expiration"] = "";
|
259 |
-
|
260 |
-
return $this->sendEmail();
|
261 |
-
}
|
262 |
-
|
263 |
-
function sendCheckoutAdminEmail($user = NULL, $invoice = NULL)
|
264 |
-
{
|
265 |
-
global $wpdb, $current_user;
|
266 |
-
if(!$user)
|
267 |
-
$user = $current_user;
|
268 |
-
|
269 |
-
if(!$user)
|
270 |
-
return false;
|
271 |
-
|
272 |
-
//check settings
|
273 |
-
$send = pmpro_getOption("email_admin_checkout");
|
274 |
-
if(empty($send))
|
275 |
-
return true; //didn't send, but we also don't want to indicate failure because the settings say to not send
|
276 |
-
|
277 |
-
$this->email = get_bloginfo("admin_email");
|
278 |
-
$this->subject = sprintf(__("Member Checkout for %s at %s", "pmpro"), $user->membership_level->name, get_option("blogname"));
|
279 |
-
|
280 |
-
$this->data = array(
|
281 |
-
"subject" => $this->subject,
|
282 |
-
"name" => $user->display_name,
|
283 |
-
"user_login" => $user->user_login,
|
284 |
-
"sitename" => get_option("blogname"),
|
285 |
-
"siteemail" => pmpro_getOption("from_email"),
|
286 |
-
"membership_id" => $user->membership_level->id,
|
287 |
-
"membership_level_name" => $user->membership_level->name,
|
288 |
-
"membership_cost" => pmpro_getLevelCost($user->membership_level),
|
289 |
-
"login_link" => wp_login_url(pmpro_url("account")),
|
290 |
-
"display_name" => $user->display_name,
|
291 |
-
"user_email" => $user->user_email,0
|
292 |
-
);
|
293 |
-
|
294 |
-
if(!empty($invoice) && !pmpro_isLevelFree($user->membership_level))
|
295 |
-
{
|
296 |
-
if($invoice->gateway == "paypalexpress")
|
297 |
-
$this->template = "checkout_express_admin";
|
298 |
-
elseif($invoice->gateway == "check")
|
299 |
-
$this->template = "checkout_check_admin";
|
300 |
-
elseif(pmpro_isLevelTrial($user->membership_level))
|
301 |
-
$this->template = "checkout_trial_admin";
|
302 |
-
else
|
303 |
-
$this->template = "checkout_paid_admin";
|
304 |
-
$this->data["invoice_id"] = $invoice->code;
|
305 |
-
$this->data["invoice_total"] = pmpro_formatPrice($invoice->total);
|
306 |
-
$this->data["invoice_date"] = date(get_option('date_format'), $invoice->timestamp);
|
307 |
-
$this->data["billing_name"] = $invoice->billing->name;
|
308 |
-
$this->data["billing_street"] = $invoice->billing->street;
|
309 |
-
$this->data["billing_city"] = $invoice->billing->city;
|
310 |
-
$this->data["billing_state"] = $invoice->billing->state;
|
311 |
-
$this->data["billing_zip"] = $invoice->billing->zip;
|
312 |
-
$this->data["billing_country"] = $invoice->billing->country;
|
313 |
-
$this->data["billing_phone"] = $invoice->billing->phone;
|
314 |
-
$this->data["cardtype"] = $invoice->cardtype;
|
315 |
-
$this->data["accountnumber"] = hideCardNumber($invoice->accountnumber);
|
316 |
-
$this->data["expirationmonth"] = $invoice->expirationmonth;
|
317 |
-
$this->data["expirationyear"] = $invoice->expirationyear;
|
318 |
-
$this->data["billing_address"] = pmpro_formatAddress($invoice->billing->name,
|
319 |
-
$invoice->billing->street,
|
320 |
-
"", //address 2
|
321 |
-
$invoice->billing->city,
|
322 |
-
$invoice->billing->state,
|
323 |
-
$invoice->billing->zip,
|
324 |
-
$invoice->billing->country,
|
325 |
-
$invoice->billing->phone);
|
326 |
-
|
327 |
-
if($invoice->getDiscountCode())
|
328 |
-
$this->data["discount_code"] = "<p>" . __("Discount Code", "pmpro") . ": " . $invoice->discount_code->code . "</p>\n";
|
329 |
-
else
|
330 |
-
$this->data["discount_code"] = "";
|
331 |
-
}
|
332 |
-
elseif(pmpro_isLevelFree($user->membership_level))
|
333 |
-
{
|
334 |
-
$this->template = "checkout_free_admin";
|
335 |
-
global $discount_code;
|
336 |
-
if(!empty($discount_code))
|
337 |
-
$this->data["discount_code"] = "<p>" . __("Discount Code", "pmpro") . ": " . $discount_code . "</p>\n";
|
338 |
-
else
|
339 |
-
$this->data["discount_code"] = "";
|
340 |
-
}
|
341 |
-
else
|
342 |
-
{
|
343 |
-
$this->template = "checkout_freetrial_admin";
|
344 |
-
$this->data["discount_code"] = "";
|
345 |
-
}
|
346 |
-
|
347 |
-
$enddate = $wpdb->get_var("SELECT UNIX_TIMESTAMP(enddate) FROM $wpdb->pmpro_memberships_users WHERE user_id = '" . $user->ID . "' AND status = 'active' LIMIT 1");
|
348 |
-
if($enddate)
|
349 |
-
$this->data["membership_expiration"] = "<p>" . sprintf(__("This membership will expire on %s.", "pmpro"), date(get_option('date_format'), $enddate)) . "</p>\n";
|
350 |
-
else
|
351 |
-
$this->data["membership_expiration"] = "";
|
352 |
-
|
353 |
-
return $this->sendEmail();
|
354 |
-
}
|
355 |
-
|
356 |
-
function sendBillingEmail($user = NULL, $invoice = NULL)
|
357 |
-
{
|
358 |
-
global $current_user;
|
359 |
-
if(!$user)
|
360 |
-
$user = $current_user;
|
361 |
-
|
362 |
-
if(!$user || !$invoice)
|
363 |
-
return false;
|
364 |
-
|
365 |
-
$this->email = $user->user_email;
|
366 |
-
$this->subject = sprintf(__("Your billing information has been udpated at %s", "pmpro"), get_option("blogname"));
|
367 |
-
$this->template = "billing";
|
368 |
-
|
369 |
-
$this->data = array(
|
370 |
-
"subject" => $this->subject,
|
371 |
-
"name" => $user->display_name,
|
372 |
-
"user_login" => $user->user_login,
|
373 |
-
"sitename" => get_option("blogname"),
|
374 |
-
"siteemail" => pmpro_getOption("from_email"),
|
375 |
-
"membership_id" => $user->membership_level->id,
|
376 |
-
"membership_level_name" => $user->membership_level->name,
|
377 |
-
"display_name" => $user->display_name,
|
378 |
-
"user_email" => $user->user_email,
|
379 |
-
"billing_name" => $invoice->billing->name,
|
380 |
-
"billing_street" => $invoice->billing->street,
|
381 |
-
"billing_city" => $invoice->billing->city,
|
382 |
-
"billing_state" => $invoice->billing->state,
|
383 |
-
"billing_zip" => $invoice->billing->zip,
|
384 |
-
"billing_country" => $invoice->billing->country,
|
385 |
-
"billing_phone" => $invoice->billing->phone,
|
386 |
-
"cardtype" => $invoice->cardtype,
|
387 |
-
"accountnumber" => hideCardNumber($invoice->accountnumber),
|
388 |
-
"expirationmonth" => $invoice->expirationmonth,
|
389 |
-
"expirationyear" => $invoice->expirationyear,
|
390 |
-
"login_link" => wp_login_url(pmpro_url("account"))
|
391 |
-
);
|
392 |
-
$this->data["billing_address"] = pmpro_formatAddress($invoice->billing->name,
|
393 |
-
$invoice->billing->street,
|
394 |
-
"", //address 2
|
395 |
-
$invoice->billing->city,
|
396 |
-
$invoice->billing->state,
|
397 |
-
$invoice->billing->zip,
|
398 |
-
$invoice->billing->country,
|
399 |
-
$invoice->billing->phone);
|
400 |
-
|
401 |
-
return $this->sendEmail();
|
402 |
-
}
|
403 |
-
|
404 |
-
function sendBillingAdminEmail($user = NULL, $invoice = NULL)
|
405 |
-
{
|
406 |
-
global $current_user;
|
407 |
-
if(!$user)
|
408 |
-
$user = $current_user;
|
409 |
-
|
410 |
-
if(!$user || !$invoice)
|
411 |
-
return false;
|
412 |
-
|
413 |
-
//check settings
|
414 |
-
$send = pmpro_getOption("email_admin_billing");
|
415 |
-
if(empty($send))
|
416 |
-
return true; //didn't send, but we also don't want to indicate failure because the settings say to not send
|
417 |
-
|
418 |
-
$this->email = get_bloginfo("admin_email");
|
419 |
-
$this->subject = sprintf(__("Billing information has been udpated for %s at %s", "pmpro"), $user->user_login, get_option("blogname"));
|
420 |
-
$this->template = "billing_admin";
|
421 |
-
|
422 |
-
$this->data = array(
|
423 |
-
"subject" => $this->subject,
|
424 |
-
"name" => $user->display_name,
|
425 |
-
"user_login" => $user->user_login,
|
426 |
-
"sitename" => get_option("blogname"),
|
427 |
-
"siteemail" => pmpro_getOption("from_email"),
|
428 |
-
"membership_id" => $user->membership_level->id,
|
429 |
-
"membership_level_name" => $user->membership_level->name,
|
430 |
-
"display_name" => $user->display_name,
|
431 |
-
"user_email" => $user->user_email,
|
432 |
-
"billing_name" => $invoice->billing->name,
|
433 |
-
"billing_street" => $invoice->billing->street,
|
434 |
-
"billing_city" => $invoice->billing->city,
|
435 |
-
"billing_state" => $invoice->billing->state,
|
436 |
-
"billing_zip" => $invoice->billing->zip,
|
437 |
-
"billing_country" => $invoice->billing->country,
|
438 |
-
"billing_phone" => $invoice->billing->phone,
|
439 |
-
"cardtype" => $invoice->cardtype,
|
440 |
-
"accountnumber" => hideCardNumber($invoice->accountnumber),
|
441 |
-
"expirationmonth" => $invoice->expirationmonth,
|
442 |
-
"expirationyear" => $invoice->expirationyear,
|
443 |
-
"login_link" => wp_login_url()
|
444 |
-
);
|
445 |
-
$this->data["billing_address"] = pmpro_formatAddress($invoice->billing->name,
|
446 |
-
$invoice->billing->street,
|
447 |
-
"", //address 2
|
448 |
-
$invoice->billing->city,
|
449 |
-
$invoice->billing->state,
|
450 |
-
$invoice->billing->zip,
|
451 |
-
$invoice->billing->country,
|
452 |
-
$invoice->billing->phone);
|
453 |
-
|
454 |
-
return $this->sendEmail();
|
455 |
-
}
|
456 |
-
|
457 |
-
function sendBillingFailureEmail($user = NULL, $invoice = NULL)
|
458 |
-
{
|
459 |
-
global $current_user;
|
460 |
-
if(!$user)
|
461 |
-
$user = $current_user;
|
462 |
-
|
463 |
-
if(!$user || !$invoice)
|
464 |
-
return false;
|
465 |
-
|
466 |
-
$this->email = $user->user_email;
|
467 |
-
$this->subject = sprintf(__("Membership Payment Failed at %s", "pmpro"), get_option("blogname"));
|
468 |
-
$this->template = "billing_failure";
|
469 |
-
|
470 |
-
$this->data = array(
|
471 |
-
"subject" => $this->subject,
|
472 |
-
"name" => $user->display_name,
|
473 |
-
"user_login" => $user->user_login,
|
474 |
-
"sitename" => get_option("blogname"),
|
475 |
-
"siteemail" => pmpro_getOption("from_email"),
|
476 |
-
"membership_id" => $user->membership_level->id,
|
477 |
-
"membership_level_name" => $user->membership_level->name,
|
478 |
-
"display_name" => $user->display_name,
|
479 |
-
"user_email" => $user->user_email,
|
480 |
-
"billing_name" => $invoice->billing->name,
|
481 |
-
"billing_street" => $invoice->billing->street,
|
482 |
-
"billing_city" => $invoice->billing->city,
|
483 |
-
"billing_state" => $invoice->billing->state,
|
484 |
-
"billing_zip" => $invoice->billing->zip,
|
485 |
-
"billing_country" => $invoice->billing->country,
|
486 |
-
"billing_phone" => $invoice->billing->phone,
|
487 |
-
"cardtype" => $invoice->cardtype,
|
488 |
-
"accountnumber" => hideCardNumber($invoice->accountnumber),
|
489 |
-
"expirationmonth" => $invoice->expirationmonth,
|
490 |
-
"expirationyear" => $invoice->expirationyear,
|
491 |
-
"login_link" => wp_login_url(pmpro_url("billing"))
|
492 |
-
);
|
493 |
-
$this->data["billing_address"] = pmpro_formatAddress($invoice->billing->name,
|
494 |
-
$invoice->billing->street,
|
495 |
-
"", //address 2
|
496 |
-
$invoice->billing->city,
|
497 |
-
$invoice->billing->state,
|
498 |
-
$invoice->billing->zip,
|
499 |
-
$invoice->billing->country,
|
500 |
-
$invoice->billing->phone);
|
501 |
-
|
502 |
-
return $this->sendEmail();
|
503 |
-
}
|
504 |
-
|
505 |
-
function sendBillingFailureAdminEmail($email, $invoice = NULL)
|
506 |
-
{
|
507 |
-
if(!$invoice)
|
508 |
-
return false;
|
509 |
-
|
510 |
-
$user = get_userdata($invoice->user_id);
|
511 |
-
|
512 |
-
$this->email = $email;
|
513 |
-
$this->subject = sprintf(__("Membership Payment Failed For %s at %s", "pmpro"), $user->display_name, get_option("blogname"));
|
514 |
-
$this->template = "billing_failure_admin";
|
515 |
-
|
516 |
-
$this->data = array(
|
517 |
-
"subject" => $this->subject,
|
518 |
-
"name" => "Admin",
|
519 |
-
"user_login" => $user->user_login,
|
520 |
-
"sitename" => get_option("blogname"),
|
521 |
-
"siteemail" => pmpro_getOption("from_email"),
|
522 |
-
"membership_id" => $user->membership_level->id,
|
523 |
-
"membership_level_name" => $user->membership_level->name,
|
524 |
-
"display_name" => $user->display_name,
|
525 |
-
"user_email" => $user->user_email,
|
526 |
-
"billing_name" => $invoice->billing->name,
|
527 |
-
"billing_street" => $invoice->billing->street,
|
528 |
-
"billing_city" => $invoice->billing->city,
|
529 |
-
"billing_state" => $invoice->billing->state,
|
530 |
-
"billing_zip" => $invoice->billing->zip,
|
531 |
-
"billing_country" => $invoice->billing->country,
|
532 |
-
"billing_phone" => $invoice->billing->phone,
|
533 |
-
"cardtype" => $invoice->cardtype,
|
534 |
-
"accountnumber" => hideCardNumber($invoice->accountnumber),
|
535 |
-
"expirationmonth" => $invoice->expirationmonth,
|
536 |
-
"expirationyear" => $invoice->expirationyear,
|
537 |
-
"login_link" => wp_login_url(pmpro_url("billing"))
|
538 |
-
);
|
539 |
-
$this->data["billing_address"] = pmpro_formatAddress($invoice->billing->name,
|
540 |
-
$invoice->billing->street,
|
541 |
-
"", //address 2
|
542 |
-
$invoice->billing->city,
|
543 |
-
$invoice->billing->state,
|
544 |
-
$invoice->billing->zip,
|
545 |
-
$invoice->billing->country,
|
546 |
-
$invoice->billing->phone);
|
547 |
-
return $this->sendEmail();
|
548 |
-
}
|
549 |
-
|
550 |
-
function sendCreditCardExpiringEmail($user = NULL, $invoice = NULL)
|
551 |
-
{
|
552 |
-
global $current_user;
|
553 |
-
if(!$user)
|
554 |
-
$user = $current_user;
|
555 |
-
|
556 |
-
if(!$user || !$invoice)
|
557 |
-
return false;
|
558 |
-
|
559 |
-
$this->email = $user->user_email;
|
560 |
-
$this->subject = sprintf(__("Credit Card on File Expiring Soon at %s", "pmpro"), get_option("blogname"));
|
561 |
-
$this->template = "credit_card_expiring";
|
562 |
-
|
563 |
-
$this->data = array(
|
564 |
-
"subject" => $this->subject,
|
565 |
-
"name" => $user->display_name,
|
566 |
-
"user_login" => $user->user_login,
|
567 |
-
"sitename" => get_option("blogname"),
|
568 |
-
"siteemail" => pmpro_getOption("from_email"),
|
569 |
-
"membership_id" => $user->membership_level->id,
|
570 |
-
"membership_level_name" => $user->membership_level->name,
|
571 |
-
"display_name" => $user->display_name,
|
572 |
-
"user_email" => $user->user_email,
|
573 |
-
"billing_name" => $invoice->billing->name,
|
574 |
-
"billing_street" => $invoice->billing->street,
|
575 |
-
"billing_city" => $invoice->billing->city,
|
576 |
-
"billing_state" => $invoice->billing->state,
|
577 |
-
"billing_zip" => $invoice->billing->zip,
|
578 |
-
"billing_country" => $invoice->billing->country,
|
579 |
-
"billing_phone" => $invoice->billing->phone,
|
580 |
-
"cardtype" => $invoice->cardtype,
|
581 |
-
"accountnumber" => hideCardNumber($invoice->accountnumber),
|
582 |
-
"expirationmonth" => $invoice->expirationmonth,
|
583 |
-
"expirationyear" => $invoice->expirationyear,
|
584 |
-
"login_link" => wp_login_url(pmpro_url("billing"))
|
585 |
-
);
|
586 |
-
$this->data["billing_address"] = pmpro_formatAddress($invoice->billing->name,
|
587 |
-
$invoice->billing->street,
|
588 |
-
"", //address 2
|
589 |
-
$invoice->billing->city,
|
590 |
-
$invoice->billing->state,
|
591 |
-
$invoice->billing->zip,
|
592 |
-
$invoice->billing->country,
|
593 |
-
$invoice->billing->phone);
|
594 |
-
|
595 |
-
return $this->sendEmail();
|
596 |
-
}
|
597 |
-
|
598 |
-
function sendInvoiceEmail($user = NULL, $invoice = NULL)
|
599 |
-
{
|
600 |
-
global $wpdb, $current_user;
|
601 |
-
if(!$user)
|
602 |
-
$user = $current_user;
|
603 |
-
|
604 |
-
if(!$user || !$invoice)
|
605 |
-
return false;
|
606 |
-
|
607 |
-
$this->email = $user->user_email;
|
608 |
-
$this->subject = sprintf(__("INVOICE for %s membership", "pmpro"), get_option("blogname"));
|
609 |
-
$this->template = "invoice";
|
610 |
-
|
611 |
-
$this->data = array(
|
612 |
-
"subject" => $this->subject,
|
613 |
-
"name" => $user->display_name,
|
614 |
-
"user_login" => $user->user_login,
|
615 |
-
"sitename" => get_option("blogname"),
|
616 |
-
"siteemail" => pmpro_getOption("from_email"),
|
617 |
-
"membership_id" => $user->membership_level->id,
|
618 |
-
"membership_level_name" => $user->membership_level->name,
|
619 |
-
"display_name" => $user->display_name,
|
620 |
-
"user_email" => $user->user_email,
|
621 |
-
"invoice_id" => $invoice->code,
|
622 |
-
"invoice_total" => pmpro_formatPrice($invoice->total),
|
623 |
-
"invoice_date" => date(get_option('date_format'), $invoice->timestamp),
|
624 |
-
"billing_name" => $invoice->billing->name,
|
625 |
-
"billing_street" => $invoice->billing->street,
|
626 |
-
"billing_city" => $invoice->billing->city,
|
627 |
-
"billing_state" => $invoice->billing->state,
|
628 |
-
"billing_zip" => $invoice->billing->zip,
|
629 |
-
"billing_country" => $invoice->billing->country,
|
630 |
-
"billing_phone" => $invoice->billing->phone,
|
631 |
-
"cardtype" => $invoice->cardtype,
|
632 |
-
"accountnumber" => hideCardNumber($invoice->accountnumber),
|
633 |
-
"expirationmonth" => $invoice->expirationmonth,
|
634 |
-
"expirationyear" => $invoice->expirationyear,
|
635 |
-
"login_link" => wp_login_url(pmpro_url("account")),
|
636 |
-
"invoice_link" => wp_login_url(pmpro_url("invoice", "?invoice=" . $invoice->code)
|
637 |
-
));
|
638 |
-
$this->data["billing_address"] = pmpro_formatAddress($invoice->billing->name,
|
639 |
-
$invoice->billing->street,
|
640 |
-
"", //address 2
|
641 |
-
$invoice->billing->city,
|
642 |
-
$invoice->billing->state,
|
643 |
-
$invoice->billing->zip,
|
644 |
-
$invoice->billing->country,
|
645 |
-
$invoice->billing->phone);
|
646 |
-
|
647 |
-
if($invoice->getDiscountCode())
|
648 |
-
$this->data["discount_code"] = "<p>" . __("Discount Code", "pmpro") . ": " . $invoice->discount_code . "</p>\n";
|
649 |
-
else
|
650 |
-
$this->data["discount_code"] = "";
|
651 |
-
|
652 |
-
$enddate = $wpdb->get_var("SELECT UNIX_TIMESTAMP(enddate) FROM $wpdb->pmpro_memberships_users WHERE user_id = '" . $user->ID . "' AND status = 'active' LIMIT 1");
|
653 |
-
if($enddate)
|
654 |
-
$this->data["membership_expiration"] = "<p>" . sprintf(__("This membership will expire on %s.", "pmpro"), date(get_option('date_format'), $enddate)) . "</p>\n";
|
655 |
-
else
|
656 |
-
$this->data["membership_expiration"] = "";
|
657 |
-
|
658 |
-
return $this->sendEmail();
|
659 |
-
}
|
660 |
-
|
661 |
-
function sendTrialEndingEmail($user = NULL)
|
662 |
-
{
|
663 |
-
global $current_user, $wpdb;
|
664 |
-
if(!$user)
|
665 |
-
$user = $current_user;
|
666 |
-
|
667 |
-
if(!$user)
|
668 |
-
return false;
|
669 |
-
|
670 |
-
//make sure we have the current membership level data
|
671 |
-
/*$user->membership_level = $wpdb->get_row("SELECT l.id AS ID, l.name AS name, UNIX_TIMESTAMP(mu.startdate) as startdate, mu.billing_amount, mu.cycle_number, mu.cycle_period, mu.trial_amount, mu.trial_limit
|
672 |
-
FROM {$wpdb->pmpro_membership_levels} AS l
|
673 |
-
JOIN {$wpdb->pmpro_memberships_users} AS mu ON (l.id = mu.membership_id)
|
674 |
-
WHERE mu.user_id = " . $user->ID . "
|
675 |
-
LIMIT 1");*/
|
676 |
-
$user->membership_level = pmpro_getMembershipLevelForUser($user->ID);
|
677 |
-
|
678 |
-
$this->email = $user->user_email;
|
679 |
-
$this->subject = sprintf(__("Your trial at %s is ending soon", "pmpro"), get_option("blogname"));
|
680 |
-
$this->template = "trial_ending";
|
681 |
-
$this->data = array(
|
682 |
-
"subject" => $this->subject,
|
683 |
-
"name" => $user->display_name,
|
684 |
-
"user_login" => $user->user_login,
|
685 |
-
"sitename" => get_option("blogname"),
|
686 |
-
"membership_id" => $user->membership_level->id,
|
687 |
-
"membership_level_name" => $user->membership_level->name,
|
688 |
-
"siteemail" => pmpro_getOption("from_email"),
|
689 |
-
"login_link" => wp_login_url(),
|
690 |
-
"display_name" => $user->display_name,
|
691 |
-
"user_email" => $user->user_email,
|
692 |
-
"billing_amount" => pmpro_formatPrice($user->membership_level->billing_amount),
|
693 |
-
"cycle_number" => $user->membership_level->cycle_number,
|
694 |
-
"cycle_period" => $user->membership_level->cycle_period,
|
695 |
-
"trial_amount" => pmpro_formatPrice($user->membership_level->trial_amount),
|
696 |
-
"trial_limit" => $user->membership_level->trial_limit,
|
697 |
-
"trial_end" => date(get_option('date_format'), strtotime(date("m/d/Y", $user->membership_level->startdate) . " + " . $user->membership_level->trial_limit . " " . $user->membership_level->cycle_period), current_time("timestamp"))
|
698 |
-
);
|
699 |
-
|
700 |
-
return $this->sendEmail();
|
701 |
-
}
|
702 |
-
|
703 |
-
function sendMembershipExpiredEmail($user = NULL)
|
704 |
-
{
|
705 |
-
global $current_user, $wpdb;
|
706 |
-
if(!$user)
|
707 |
-
$user = $current_user;
|
708 |
-
|
709 |
-
if(!$user)
|
710 |
-
return false;
|
711 |
-
|
712 |
-
$this->email = $user->user_email;
|
713 |
-
$this->subject = sprintf(__("Your membership at %s has ended", "pmpro"), get_option("blogname"));
|
714 |
-
$this->template = "membership_expired";
|
715 |
-
$this->data = array("subject" => $this->subject, "name" => $user->display_name, "user_login" => $user->user_login, "sitename" => get_option("blogname"), "siteemail" => pmpro_getOption("from_email"), "login_link" => wp_login_url(), "display_name" => $user->display_name, "user_email" => $user->user_email, "levels_link" => pmpro_url("levels"));
|
716 |
-
|
717 |
-
return $this->sendEmail();
|
718 |
-
}
|
719 |
-
|
720 |
-
function sendMembershipExpiringEmail($user = NULL)
|
721 |
-
{
|
722 |
-
global $current_user, $wpdb;
|
723 |
-
if(!$user)
|
724 |
-
$user = $current_user;
|
725 |
-
|
726 |
-
if(!$user)
|
727 |
-
return false;
|
728 |
-
|
729 |
-
//make sure we have the current membership level data
|
730 |
-
/*$user->membership_level = $wpdb->get_row("SELECT l.id AS ID, l.name AS name, UNIX_TIMESTAMP(mu.enddate) as enddate
|
731 |
-
FROM {$wpdb->pmpro_membership_levels} AS l
|
732 |
-
JOIN {$wpdb->pmpro_memberships_users} AS mu ON (l.id = mu.membership_id)
|
733 |
-
WHERE mu.user_id = " . $user->ID . "
|
734 |
-
LIMIT 1");*/
|
735 |
-
$user->membership_level = pmpro_getMembershipLevelForUser($user->ID);
|
736 |
-
|
737 |
-
$this->email = $user->user_email;
|
738 |
-
$this->subject = sprintf(__("Your membership at %s will end soon", "pmpro"), get_option("blogname"));
|
739 |
-
$this->template = "membership_expiring";
|
740 |
-
$this->data = array("subject" => $this->subject, "name" => $user->display_name, "user_login" => $user->user_login, "sitename" => get_option("blogname"), "membership_id" => $user->membership_level->id, "membership_level_name" => $user->membership_level->name, "siteemail" => pmpro_getOption("from_email"), "login_link" => wp_login_url(), "enddate" => date(get_option('date_format'), $user->membership_level->enddate), "display_name" => $user->display_name, "user_email" => $user->user_email);
|
741 |
-
|
742 |
-
return $this->sendEmail();
|
743 |
-
}
|
744 |
-
|
745 |
-
function sendAdminChangeEmail($user = NULL)
|
746 |
-
{
|
747 |
-
global $current_user, $wpdb;
|
748 |
-
if(!$user)
|
749 |
-
$user = $current_user;
|
750 |
-
|
751 |
-
if(!$user)
|
752 |
-
return false;
|
753 |
-
|
754 |
-
//make sure we have the current membership level data
|
755 |
-
$user->membership_level = pmpro_getMembershipLevelForUser($user->ID);
|
756 |
-
|
757 |
-
$this->email = $user->user_email;
|
758 |
-
$this->subject = sprintf(__("Your membership at %s has been changed", "pmpro"), get_option("blogname"));
|
759 |
-
$this->template = "admin_change";
|
760 |
-
$this->data = array("subject" => $this->subject, "name" => $user->display_name, "user_login" => $user->user_login, "sitename" => get_option("blogname"), "membership_id" => $user->membership_level->id, "membership_level_name" => $user->membership_level->name, "siteemail" => pmpro_getOption("from_email"), "login_link" => wp_login_url());
|
761 |
-
if($user->membership_level->ID)
|
762 |
-
$this->data["membership_change"] = sprintf(__("The new level is %s", "pmpro"), $user->membership_level->name);
|
763 |
-
else
|
764 |
-
$this->data["membership_change"] = __("Your membership has been cancelled", "pmpro");
|
765 |
-
|
766 |
-
if(!empty($user->membership_level->enddate))
|
767 |
-
{
|
768 |
-
$this->data["membership_change"] .= ". " . sprintf(__("This membership will expire on %s", "pmpro"), date(get_option('date_format'), $user->membership_level->enddate));
|
769 |
-
}
|
770 |
-
elseif(!empty($this->expiration_changed))
|
771 |
-
{
|
772 |
-
$this->data["membership_change"] .= ". " . __("This membership does not expire", "pmpro");
|
773 |
-
}
|
774 |
-
|
775 |
-
return $this->sendEmail();
|
776 |
-
}
|
777 |
-
|
778 |
-
function sendAdminChangeAdminEmail($user = NULL)
|
779 |
-
{
|
780 |
-
global $current_user, $wpdb;
|
781 |
-
if(!$user)
|
782 |
-
$user = $current_user;
|
783 |
-
|
784 |
-
if(!$user)
|
785 |
-
return false;
|
786 |
-
|
787 |
-
//check settings
|
788 |
-
$send = pmpro_getOption("email_admin_changes");
|
789 |
-
if(empty($send))
|
790 |
-
return true; //didn't send, but we also don't want to indicate failure because the settings say to not send
|
791 |
-
|
792 |
-
//make sure we have the current membership level data
|
793 |
-
$user->membership_level = pmpro_getMembershipLevelForUser($user->ID);
|
794 |
-
|
795 |
-
$this->email = get_bloginfo("admin_email");
|
796 |
-
$this->subject = sprintf(__("Membership for %s at %s has been changed", "pmpro"), $user->user_login, get_option("blogname"));
|
797 |
-
$this->template = "admin_change_admin";
|
798 |
-
$this->data = array("subject" => $this->subject, "name" => $user->display_name, "user_login" => $user->user_login, "sitename" => get_option("blogname"), "membership_level_name" => $user->membership_level->name, "siteemail" => get_bloginfo("admin_email"), "login_link" => wp_login_url());
|
799 |
-
if($user->membership_level->ID)
|
800 |
-
$this->data["membership_change"] = sprintf(__("The new level is %s", "pmpro"), $user->membership_level->name);
|
801 |
-
else
|
802 |
-
$this->data["membership_change"] = __("Membership has been cancelled", "pmpro");
|
803 |
-
|
804 |
-
if(!empty($user->membership_level->enddate))
|
805 |
-
{
|
806 |
-
$this->data["membership_change"] .= ". " . sprintf(__("This membership will expire on %s", "pmpro"), date(get_option('date_format'), $user->membership_level->enddate));
|
807 |
-
}
|
808 |
-
elseif(!empty($this->expiration_changed))
|
809 |
-
{
|
810 |
-
$this->data["membership_change"] .= ". " . __("This membership does not expire", "pmpro");
|
811 |
-
}
|
812 |
-
|
813 |
-
return $this->sendEmail();
|
814 |
-
}
|
815 |
-
}
|
1 |
+
<?php
|
2 |
+
class PMProEmail
|
3 |
+
{
|
4 |
+
function PMProEmail()
|
5 |
+
{
|
6 |
+
$this->email = $this->from = $this->fromname = $this->subject = $this->template = $this->data = $this->body = NULL;
|
7 |
+
}
|
8 |
+
|
9 |
+
function sendEmail($email = NULL, $from = NULL, $fromname = NULL, $subject = NULL, $template = NULL, $data = NULL)
|
10 |
+
{
|
11 |
+
//if values were passed
|
12 |
+
if($email)
|
13 |
+
$this->email = $email;
|
14 |
+
if($from)
|
15 |
+
$this->from = $from;
|
16 |
+
if($fromname)
|
17 |
+
$this->fromname = $fromname;
|
18 |
+
if($subject)
|
19 |
+
$this->subject = $subject;
|
20 |
+
if($template)
|
21 |
+
$this->template = $template;
|
22 |
+
if($data)
|
23 |
+
$this->data = $data;
|
24 |
+
|
25 |
+
//default values
|
26 |
+
global $current_user;
|
27 |
+
if(!$this->email)
|
28 |
+
$this->email = $current_user->user_email;
|
29 |
+
|
30 |
+
if(!$this->from)
|
31 |
+
$this->from = pmpro_getOption("from_email");
|
32 |
+
|
33 |
+
if(!$this->fromname)
|
34 |
+
$this->fromname = pmpro_getOption("from_name");
|
35 |
+
|
36 |
+
if(!$this->subject)
|
37 |
+
$this->subject = sprintf(__("An Email From %s", "pmpro"), get_option("blogname"));
|
38 |
+
|
39 |
+
//decode the subject line in case there are apostrophes/etc in it
|
40 |
+
$this->subject = html_entity_decode($this->subject, ENT_QUOTES, 'UTF-8');
|
41 |
+
|
42 |
+
if(!$this->template)
|
43 |
+
$this->template = "default";
|
44 |
+
|
45 |
+
$this->headers = array("Content-Type: text/html");
|
46 |
+
|
47 |
+
$this->attachments = NULL;
|
48 |
+
|
49 |
+
//load the template
|
50 |
+
$locale = apply_filters("plugin_locale", get_locale(), "pmpro");
|
51 |
+
if(file_exists(get_stylesheet_directory() . "/paid-memberships-pro/email/" . $this->template . ".html"))
|
52 |
+
$this->body = file_get_contents(get_stylesheet_directory() . "/paid-memberships-pro/email/" . $this->template . ".html"); //email folder in pmpro folder in theme
|
53 |
+
elseif(file_exists(get_stylesheet_directory() . "/membership-email-" . $this->template . ".html"))
|
54 |
+
$this->body = file_get_contents(get_stylesheet_directory() . "/membership-email-" . $this->template . ".html"); //membership- file in pmpro folder in theme
|
55 |
+
elseif(file_exists(TEMPLATEPATH . "/membership-email-" . $this->template . ".html"))
|
56 |
+
$this->body = file_get_contents(TEMPLATEPATH . "/membership-email-" . $this->template . ".html"); //membership- file in theme root
|
57 |
+
elseif(file_exists(WP_LANG_DIR . '/pmpro/email/' . $this->template . ".html"))
|
58 |
+
$this->body = file_get_contents(WP_LANG_DIR . '/pmpro/email/' . $this->template . ".html"); //email folder in WP language folder
|
59 |
+
elseif(file_exists(PMPRO_DIR . "/languages/" . $locale . "/" . $this->template . ".html"))
|
60 |
+
$this->body = file_get_contents(PMPRO_DIR . "/languages/" . $locale . "/" . $this->template . ".html"); //email folder in PMPro language folder
|
61 |
+
elseif(file_exists(PMPRO_DIR . "/email/" . $this->template . ".html"))
|
62 |
+
$this->body = file_get_contents(PMPRO_DIR . "/email/" . $this->template . ".html"); //default template in plugin
|
63 |
+
elseif(!empty($this->data) && !empty($this->data['body']))
|
64 |
+
$this->body = $this->data['body'];
|
65 |
+
|
66 |
+
//header and footer
|
67 |
+
/* This is handled for all emails via the pmpro_send_html function in paid-memberships-pro now
|
68 |
+
if(file_exists(TEMPLATEPATH . "/email_header.html"))
|
69 |
+
{
|
70 |
+
$this->body = file_get_contents(TEMPLATEPATH . "/email_header.html") . "\n" . $this->body;
|
71 |
+
}
|
72 |
+
if(file_exists(TEMPLATEPATH . "/email_footer.html"))
|
73 |
+
{
|
74 |
+
$this->body = $this->body . "\n" . file_get_contents(TEMPLATEPATH . "/email_footer.html");
|
75 |
+
}
|
76 |
+
*/
|
77 |
+
|
78 |
+
//if data is a string, assume we mean to replace !!body!! with it
|
79 |
+
if(is_string($this->data))
|
80 |
+
$this->data = array("body"=>$data);
|
81 |
+
|
82 |
+
//filter for data
|
83 |
+
$this->data = apply_filters("pmpro_email_data", $this->data, $this); //filter
|
84 |
+
|
85 |
+
//swap data into body
|
86 |
+
if(is_array($this->data))
|
87 |
+
{
|
88 |
+
foreach($this->data as $key => $value)
|
89 |
+
{
|
90 |
+
$this->body = str_replace("!!" . $key . "!!", $value, $this->body);
|
91 |
+
}
|
92 |
+
}
|
93 |
+
|
94 |
+
//filters
|
95 |
+
$temail = apply_filters("pmpro_email_filter", $this); //allows filtering entire email at once
|
96 |
+
$this->email = apply_filters("pmpro_email_recipient", $temail->email, $this);
|
97 |
+
$this->from = apply_filters("pmpro_email_sender", $temail->from, $this);
|
98 |
+
$this->fromname = apply_filters("pmpro_email_sender_name", $temail->fromname, $this);
|
99 |
+
$this->subject = apply_filters("pmpro_email_subject", $temail->subject, $this);
|
100 |
+
$this->template = apply_filters("pmpro_email_template", $temail->template, $this);
|
101 |
+
$this->body = apply_filters("pmpro_email_body", $temail->body, $this);
|
102 |
+
$this->headers = apply_filters("pmpro_email_headers", $temail->headers, $this);
|
103 |
+
$this->attachments = apply_filters("pmpro_email_attachments", $temail->attachments, $this);
|
104 |
+
|
105 |
+
if(wp_mail($this->email,$this->subject,$this->body,$this->headers,$this->attachments))
|
106 |
+
{
|
107 |
+
return true;
|
108 |
+
}
|
109 |
+
else
|
110 |
+
{
|
111 |
+
return false;
|
112 |
+
}
|
113 |
+
}
|
114 |
+
|
115 |
+
function sendCancelEmail($user = NULL)
|
116 |
+
{
|
117 |
+
global $current_user;
|
118 |
+
if(!$user)
|
119 |
+
$user = $current_user;
|
120 |
+
|
121 |
+
if(!$user)
|
122 |
+
return false;
|
123 |
+
|
124 |
+
$this->email = $user->user_email;
|
125 |
+
$this->subject = sprintf(__("Your membership at %s has been CANCELLED", "pmpro"), get_option("blogname"));
|
126 |
+
$this->template = "cancel";
|
127 |
+
$this->data = array("name" => $user->display_name, "user_login" => $user->user_login, "sitename" => get_option("blogname"), "siteemail" => pmpro_getOption("from_email"));
|
128 |
+
|
129 |
+
return $this->sendEmail();
|
130 |
+
}
|
131 |
+
|
132 |
+
function sendCancelAdminEmail($user = NULL, $old_level_id)
|
133 |
+
{
|
134 |
+
global $wpdb, $current_user;
|
135 |
+
if(!$user)
|
136 |
+
$user = $current_user;
|
137 |
+
|
138 |
+
if(!$user)
|
139 |
+
return false;
|
140 |
+
|
141 |
+
//check settings
|
142 |
+
$send = pmpro_getOption("email_admin_cancels");
|
143 |
+
if(empty($send))
|
144 |
+
return true; //didn't send, but we also don't want to indicate failure because the settings say to not send
|
145 |
+
|
146 |
+
$this->email = get_bloginfo("admin_email");
|
147 |
+
$this->subject = sprintf(__("Membership for %s at %s has been CANCELLED", "pmpro"), $user->user_login, get_option("blogname"));
|
148 |
+
$this->template = "cancel_admin";
|
149 |
+
$this->data = array("user_login" => $user->user_login, "user_email" => $user->user_email, "display_name" => $user->display_name, "sitename" => get_option("blogname"), "siteemail" => pmpro_getOption("from_email"), "login_link" => wp_login_url());
|
150 |
+
$this->data['membership_id'] = $old_level_id;
|
151 |
+
$this->data['membership_level_name'] = $wpdb->get_var("SELECT name FROM $wpdb->pmpro_membership_levels WHERE id = '" . $old_level_id . "' LIMIT 1");
|
152 |
+
|
153 |
+
//start and end date
|
154 |
+
$startdate = $wpdb->get_var("SELECT UNIX_TIMESTAMP(startdate) as startdate FROM $wpdb->pmpro_memberships_users WHERE user_id = '" . $user->ID . "' AND membership_id = '" . $old_level_id . "' AND status = 'inactive' ORDER BY id DESC");
|
155 |
+
if(!empty($startdate))
|
156 |
+
$this->data['startdate'] = date(get_option('date_format'), $startdate);
|
157 |
+
else
|
158 |
+
$this->data['startdate'] = "";
|
159 |
+
$enddate = $wpdb->get_var("SELECT UNIX_TIMESTAMP(enddate) as enddate FROM $wpdb->pmpro_memberships_users WHERE user_id = '" . $user->ID . "' AND membership_id = '" . $old_level_id . "' AND status = 'inactive' ORDER BY id DESC");
|
160 |
+
if(!empty($enddate))
|
161 |
+
$this->data['enddate'] = date(get_option('date_format'), $enddate);
|
162 |
+
else
|
163 |
+
$this->data['enddate'] = "";
|
164 |
+
|
165 |
+
return $this->sendEmail();
|
166 |
+
}
|
167 |
+
|
168 |
+
function sendCheckoutEmail($user = NULL, $invoice = NULL)
|
169 |
+
{
|
170 |
+
global $wpdb, $current_user;
|
171 |
+
if(!$user)
|
172 |
+
$user = $current_user;
|
173 |
+
|
174 |
+
if(!$user)
|
175 |
+
return false;
|
176 |
+
|
177 |
+
$this->email = $user->user_email;
|
178 |
+
$this->subject = sprintf(__("Your membership confirmation for %s", "pmpro"), get_option("blogname"));
|
179 |
+
|
180 |
+
$this->data = array(
|
181 |
+
"subject" => $this->subject,
|
182 |
+
"name" => $user->display_name,
|
183 |
+
"user_login" => $user->user_login,
|
184 |
+
"sitename" => get_option("blogname"),
|
185 |
+
"siteemail" => pmpro_getOption("from_email"),
|
186 |
+
"membership_id" => $user->membership_level->id,
|
187 |
+
"membership_level_name" => $user->membership_level->name,
|
188 |
+
"membership_cost" => pmpro_getLevelCost($user->membership_level),
|
189 |
+
"login_link" => wp_login_url(pmpro_url("account")),
|
190 |
+
"display_name" => $user->display_name,
|
191 |
+
"user_email" => $user->user_email,0
|
192 |
+
);
|
193 |
+
|
194 |
+
if(!empty($invoice) && !pmpro_isLevelFree($user->membership_level))
|
195 |
+
{
|
196 |
+
if($invoice->gateway == "paypalexpress")
|
197 |
+
$this->template = "checkout_express";
|
198 |
+
elseif($invoice->gateway == "check")
|
199 |
+
{
|
200 |
+
$this->template = "checkout_check";
|
201 |
+
$this->data["instructions"] = wpautop(pmpro_getOption("instructions"));
|
202 |
+
}
|
203 |
+
elseif(pmpro_isLevelTrial($user->membership_level))
|
204 |
+
$this->template = "checkout_trial";
|
205 |
+
else
|
206 |
+
$this->template = "checkout_paid";
|
207 |
+
$this->data["invoice_id"] = $invoice->code;
|
208 |
+
$this->data["invoice_total"] = pmpro_formatPrice($invoice->total);
|
209 |
+
$this->data["invoice_date"] = date(get_option('date_format'), $invoice->timestamp);
|
210 |
+
$this->data["billing_name"] = $invoice->billing->name;
|
211 |
+
$this->data["billing_street"] = $invoice->billing->street;
|
212 |
+
$this->data["billing_city"] = $invoice->billing->city;
|
213 |
+
$this->data["billing_state"] = $invoice->billing->state;
|
214 |
+
$this->data["billing_zip"] = $invoice->billing->zip;
|
215 |
+
$this->data["billing_country"] = $invoice->billing->country;
|
216 |
+
$this->data["billing_phone"] = $invoice->billing->phone;
|
217 |
+
$this->data["cardtype"] = $invoice->cardtype;
|
218 |
+
$this->data["accountnumber"] = hideCardNumber($invoice->accountnumber);
|
219 |
+
$this->data["expirationmonth"] = $invoice->expirationmonth;
|
220 |
+
$this->data["expirationyear"] = $invoice->expirationyear;
|
221 |
+
$this->data["billing_address"] = pmpro_formatAddress($invoice->billing->name,
|
222 |
+
$invoice->billing->street,
|
223 |
+
"", //address 2
|
224 |
+
$invoice->billing->city,
|
225 |
+
$invoice->billing->state,
|
226 |
+
$invoice->billing->zip,
|
227 |
+
$invoice->billing->country,
|
228 |
+
$invoice->billing->phone);
|
229 |
+
|
230 |
+
if($invoice->getDiscountCode())
|
231 |
+
$this->data["discount_code"] = "<p>" . __("Discount Code", "pmpro") . ": " . $invoice->discount_code->code . "</p>\n";
|
232 |
+
else
|
233 |
+
$this->data["discount_code"] = "";
|
234 |
+
}
|
235 |
+
elseif(pmpro_isLevelFree($user->membership_level))
|
236 |
+
{
|
237 |
+
$this->template = "checkout_free";
|
238 |
+
global $discount_code;
|
239 |
+
if(!empty($discount_code))
|
240 |
+
$this->data["discount_code"] = "<p>" . __("Discount Code", "pmpro") . ": " . $discount_code . "</p>\n";
|
241 |
+
else
|
242 |
+
$this->data["discount_code"] = "";
|
243 |
+
}
|
244 |
+
else
|
245 |
+
{
|
246 |
+
$this->template = "checkout_freetrial";
|
247 |
+
global $discount_code;
|
248 |
+
if(!empty($discount_code))
|
249 |
+
$this->data["discount_code"] = "<p>" . __("Discount Code", "pmpro") . ": " . $discount_code . "</p>\n";
|
250 |
+
else
|
251 |
+
$this->data["discount_code"] = "";
|
252 |
+
}
|
253 |
+
|
254 |
+
$enddate = $wpdb->get_var("SELECT UNIX_TIMESTAMP(enddate) FROM $wpdb->pmpro_memberships_users WHERE user_id = '" . $user->ID . "' AND status = 'active' LIMIT 1");
|
255 |
+
if($enddate)
|
256 |
+
$this->data["membership_expiration"] = "<p>" . sprintf(__("This membership will expire on %s.", "pmpro"), date(get_option('date_format'), $enddate)) . "</p>\n";
|
257 |
+
else
|
258 |
+
$this->data["membership_expiration"] = "";
|
259 |
+
|
260 |
+
return $this->sendEmail();
|
261 |
+
}
|
262 |
+
|
263 |
+
function sendCheckoutAdminEmail($user = NULL, $invoice = NULL)
|
264 |
+
{
|
265 |
+
global $wpdb, $current_user;
|
266 |
+
if(!$user)
|
267 |
+
$user = $current_user;
|
268 |
+
|
269 |
+
if(!$user)
|
270 |
+
return false;
|
271 |
+
|
272 |
+
//check settings
|
273 |
+
$send = pmpro_getOption("email_admin_checkout");
|
274 |
+
if(empty($send))
|
275 |
+
return true; //didn't send, but we also don't want to indicate failure because the settings say to not send
|
276 |
+
|
277 |
+
$this->email = get_bloginfo("admin_email");
|
278 |
+
$this->subject = sprintf(__("Member Checkout for %s at %s", "pmpro"), $user->membership_level->name, get_option("blogname"));
|
279 |
+
|
280 |
+
$this->data = array(
|
281 |
+
"subject" => $this->subject,
|
282 |
+
"name" => $user->display_name,
|
283 |
+
"user_login" => $user->user_login,
|
284 |
+
"sitename" => get_option("blogname"),
|
285 |
+
"siteemail" => pmpro_getOption("from_email"),
|
286 |
+
"membership_id" => $user->membership_level->id,
|
287 |
+
"membership_level_name" => $user->membership_level->name,
|
288 |
+
"membership_cost" => pmpro_getLevelCost($user->membership_level),
|
289 |
+
"login_link" => wp_login_url(pmpro_url("account")),
|
290 |
+
"display_name" => $user->display_name,
|
291 |
+
"user_email" => $user->user_email,0
|
292 |
+
);
|
293 |
+
|
294 |
+
if(!empty($invoice) && !pmpro_isLevelFree($user->membership_level))
|
295 |
+
{
|
296 |
+
if($invoice->gateway == "paypalexpress")
|
297 |
+
$this->template = "checkout_express_admin";
|
298 |
+
elseif($invoice->gateway == "check")
|
299 |
+
$this->template = "checkout_check_admin";
|
300 |
+
elseif(pmpro_isLevelTrial($user->membership_level))
|
301 |
+
$this->template = "checkout_trial_admin";
|
302 |
+
else
|
303 |
+
$this->template = "checkout_paid_admin";
|
304 |
+
$this->data["invoice_id"] = $invoice->code;
|
305 |
+
$this->data["invoice_total"] = pmpro_formatPrice($invoice->total);
|
306 |
+
$this->data["invoice_date"] = date(get_option('date_format'), $invoice->timestamp);
|
307 |
+
$this->data["billing_name"] = $invoice->billing->name;
|
308 |
+
$this->data["billing_street"] = $invoice->billing->street;
|
309 |
+
$this->data["billing_city"] = $invoice->billing->city;
|
310 |
+
$this->data["billing_state"] = $invoice->billing->state;
|
311 |
+
$this->data["billing_zip"] = $invoice->billing->zip;
|
312 |
+
$this->data["billing_country"] = $invoice->billing->country;
|
313 |
+
$this->data["billing_phone"] = $invoice->billing->phone;
|
314 |
+
$this->data["cardtype"] = $invoice->cardtype;
|
315 |
+
$this->data["accountnumber"] = hideCardNumber($invoice->accountnumber);
|
316 |
+
$this->data["expirationmonth"] = $invoice->expirationmonth;
|
317 |
+
$this->data["expirationyear"] = $invoice->expirationyear;
|
318 |
+
$this->data["billing_address"] = pmpro_formatAddress($invoice->billing->name,
|
319 |
+
$invoice->billing->street,
|
320 |
+
"", //address 2
|
321 |
+
$invoice->billing->city,
|
322 |
+
$invoice->billing->state,
|
323 |
+
$invoice->billing->zip,
|
324 |
+
$invoice->billing->country,
|
325 |
+
$invoice->billing->phone);
|
326 |
+
|
327 |
+
if($invoice->getDiscountCode())
|
328 |
+
$this->data["discount_code"] = "<p>" . __("Discount Code", "pmpro") . ": " . $invoice->discount_code->code . "</p>\n";
|
329 |
+
else
|
330 |
+
$this->data["discount_code"] = "";
|
331 |
+
}
|
332 |
+
elseif(pmpro_isLevelFree($user->membership_level))
|
333 |
+
{
|
334 |
+
$this->template = "checkout_free_admin";
|
335 |
+
global $discount_code;
|
336 |
+
if(!empty($discount_code))
|
337 |
+
$this->data["discount_code"] = "<p>" . __("Discount Code", "pmpro") . ": " . $discount_code . "</p>\n";
|
338 |
+
else
|
339 |
+
$this->data["discount_code"] = "";
|
340 |
+
}
|
341 |
+
else
|
342 |
+
{
|
343 |
+
$this->template = "checkout_freetrial_admin";
|
344 |
+
$this->data["discount_code"] = "";
|
345 |
+
}
|
346 |
+
|
347 |
+
$enddate = $wpdb->get_var("SELECT UNIX_TIMESTAMP(enddate) FROM $wpdb->pmpro_memberships_users WHERE user_id = '" . $user->ID . "' AND status = 'active' LIMIT 1");
|
348 |
+
if($enddate)
|
349 |
+
$this->data["membership_expiration"] = "<p>" . sprintf(__("This membership will expire on %s.", "pmpro"), date(get_option('date_format'), $enddate)) . "</p>\n";
|
350 |
+
else
|
351 |
+
$this->data["membership_expiration"] = "";
|
352 |
+
|
353 |
+
return $this->sendEmail();
|
354 |
+
}
|
355 |
+
|
356 |
+
function sendBillingEmail($user = NULL, $invoice = NULL)
|
357 |
+
{
|
358 |
+
global $current_user;
|
359 |
+
if(!$user)
|
360 |
+
$user = $current_user;
|
361 |
+
|
362 |
+
if(!$user || !$invoice)
|
363 |
+
return false;
|
364 |
+
|
365 |
+
$this->email = $user->user_email;
|
366 |
+
$this->subject = sprintf(__("Your billing information has been udpated at %s", "pmpro"), get_option("blogname"));
|
367 |
+
$this->template = "billing";
|
368 |
+
|
369 |
+
$this->data = array(
|
370 |
+
"subject" => $this->subject,
|
371 |
+
"name" => $user->display_name,
|
372 |
+
"user_login" => $user->user_login,
|
373 |
+
"sitename" => get_option("blogname"),
|
374 |
+
"siteemail" => pmpro_getOption("from_email"),
|
375 |
+
"membership_id" => $user->membership_level->id,
|
376 |
+
"membership_level_name" => $user->membership_level->name,
|
377 |
+
"display_name" => $user->display_name,
|
378 |
+
"user_email" => $user->user_email,
|
379 |
+
"billing_name" => $invoice->billing->name,
|
380 |
+
"billing_street" => $invoice->billing->street,
|
381 |
+
"billing_city" => $invoice->billing->city,
|
382 |
+
"billing_state" => $invoice->billing->state,
|
383 |
+
"billing_zip" => $invoice->billing->zip,
|
384 |
+
"billing_country" => $invoice->billing->country,
|
385 |
+
"billing_phone" => $invoice->billing->phone,
|
386 |
+
"cardtype" => $invoice->cardtype,
|
387 |
+
"accountnumber" => hideCardNumber($invoice->accountnumber),
|
388 |
+
"expirationmonth" => $invoice->expirationmonth,
|
389 |
+
"expirationyear" => $invoice->expirationyear,
|
390 |
+
"login_link" => wp_login_url(pmpro_url("account"))
|
391 |
+
);
|
392 |
+
$this->data["billing_address"] = pmpro_formatAddress($invoice->billing->name,
|
393 |
+
$invoice->billing->street,
|
394 |
+
"", //address 2
|
395 |
+
$invoice->billing->city,
|
396 |
+
$invoice->billing->state,
|
397 |
+
$invoice->billing->zip,
|
398 |
+
$invoice->billing->country,
|
399 |
+
$invoice->billing->phone);
|
400 |
+
|
401 |
+
return $this->sendEmail();
|
402 |
+
}
|
403 |
+
|
404 |
+
function sendBillingAdminEmail($user = NULL, $invoice = NULL)
|
405 |
+
{
|
406 |
+
global $current_user;
|
407 |
+
if(!$user)
|
408 |
+
$user = $current_user;
|
409 |
+
|
410 |
+
if(!$user || !$invoice)
|
411 |
+
return false;
|
412 |
+
|
413 |
+
//check settings
|
414 |
+
$send = pmpro_getOption("email_admin_billing");
|
415 |
+
if(empty($send))
|
416 |
+
return true; //didn't send, but we also don't want to indicate failure because the settings say to not send
|
417 |
+
|
418 |
+
$this->email = get_bloginfo("admin_email");
|
419 |
+
$this->subject = sprintf(__("Billing information has been udpated for %s at %s", "pmpro"), $user->user_login, get_option("blogname"));
|
420 |
+
$this->template = "billing_admin";
|
421 |
+
|
422 |
+
$this->data = array(
|
423 |
+
"subject" => $this->subject,
|
424 |
+
"name" => $user->display_name,
|
425 |
+
"user_login" => $user->user_login,
|
426 |
+
"sitename" => get_option("blogname"),
|
427 |
+
"siteemail" => pmpro_getOption("from_email"),
|
428 |
+
"membership_id" => $user->membership_level->id,
|
429 |
+
"membership_level_name" => $user->membership_level->name,
|
430 |
+
"display_name" => $user->display_name,
|
431 |
+
"user_email" => $user->user_email,
|
432 |
+
"billing_name" => $invoice->billing->name,
|
433 |
+
"billing_street" => $invoice->billing->street,
|
434 |
+
"billing_city" => $invoice->billing->city,
|
435 |
+
"billing_state" => $invoice->billing->state,
|
436 |
+
"billing_zip" => $invoice->billing->zip,
|
437 |
+
"billing_country" => $invoice->billing->country,
|
438 |
+
"billing_phone" => $invoice->billing->phone,
|
439 |
+
"cardtype" => $invoice->cardtype,
|
440 |
+
"accountnumber" => hideCardNumber($invoice->accountnumber),
|
441 |
+
"expirationmonth" => $invoice->expirationmonth,
|
442 |
+
"expirationyear" => $invoice->expirationyear,
|
443 |
+
"login_link" => wp_login_url()
|
444 |
+
);
|
445 |
+
$this->data["billing_address"] = pmpro_formatAddress($invoice->billing->name,
|
446 |
+
$invoice->billing->street,
|
447 |
+
"", //address 2
|
448 |
+
$invoice->billing->city,
|
449 |
+
$invoice->billing->state,
|
450 |
+
$invoice->billing->zip,
|
451 |
+
$invoice->billing->country,
|
452 |
+
$invoice->billing->phone);
|
453 |
+
|
454 |
+
return $this->sendEmail();
|
455 |
+
}
|
456 |
+
|
457 |
+
function sendBillingFailureEmail($user = NULL, $invoice = NULL)
|
458 |
+
{
|
459 |
+
global $current_user;
|
460 |
+
if(!$user)
|
461 |
+
$user = $current_user;
|
462 |
+
|
463 |
+
if(!$user || !$invoice)
|
464 |
+
return false;
|
465 |
+
|
466 |
+
$this->email = $user->user_email;
|
467 |
+
$this->subject = sprintf(__("Membership Payment Failed at %s", "pmpro"), get_option("blogname"));
|
468 |
+
$this->template = "billing_failure";
|
469 |
+
|
470 |
+
$this->data = array(
|
471 |
+
"subject" => $this->subject,
|
472 |
+
"name" => $user->display_name,
|
473 |
+
"user_login" => $user->user_login,
|
474 |
+
"sitename" => get_option("blogname"),
|
475 |
+
"siteemail" => pmpro_getOption("from_email"),
|
476 |
+
"membership_id" => $user->membership_level->id,
|
477 |
+
"membership_level_name" => $user->membership_level->name,
|
478 |
+
"display_name" => $user->display_name,
|
479 |
+
"user_email" => $user->user_email,
|
480 |
+
"billing_name" => $invoice->billing->name,
|
481 |
+
"billing_street" => $invoice->billing->street,
|
482 |
+
"billing_city" => $invoice->billing->city,
|
483 |
+
"billing_state" => $invoice->billing->state,
|
484 |
+
"billing_zip" => $invoice->billing->zip,
|
485 |
+
"billing_country" => $invoice->billing->country,
|
486 |
+
"billing_phone" => $invoice->billing->phone,
|
487 |
+
"cardtype" => $invoice->cardtype,
|
488 |
+
"accountnumber" => hideCardNumber($invoice->accountnumber),
|
489 |
+
"expirationmonth" => $invoice->expirationmonth,
|
490 |
+
"expirationyear" => $invoice->expirationyear,
|
491 |
+
"login_link" => wp_login_url(pmpro_url("billing"))
|
492 |
+
);
|
493 |
+
$this->data["billing_address"] = pmpro_formatAddress($invoice->billing->name,
|
494 |
+
$invoice->billing->street,
|
495 |
+
"", //address 2
|
496 |
+
$invoice->billing->city,
|
497 |
+
$invoice->billing->state,
|
498 |
+
$invoice->billing->zip,
|
499 |
+
$invoice->billing->country,
|
500 |
+
$invoice->billing->phone);
|
501 |
+
|
502 |
+
return $this->sendEmail();
|
503 |
+
}
|
504 |
+
|
505 |
+
function sendBillingFailureAdminEmail($email, $invoice = NULL)
|
506 |
+
{
|
507 |
+
if(!$invoice)
|
508 |
+
return false;
|
509 |
+
|
510 |
+
$user = get_userdata($invoice->user_id);
|
511 |
+
|
512 |
+
$this->email = $email;
|
513 |
+
$this->subject = sprintf(__("Membership Payment Failed For %s at %s", "pmpro"), $user->display_name, get_option("blogname"));
|
514 |
+
$this->template = "billing_failure_admin";
|
515 |
+
|
516 |
+
$this->data = array(
|
517 |
+
"subject" => $this->subject,
|
518 |
+
"name" => "Admin",
|
519 |
+
"user_login" => $user->user_login,
|
520 |
+
"sitename" => get_option("blogname"),
|
521 |
+
"siteemail" => pmpro_getOption("from_email"),
|
522 |
+
"membership_id" => $user->membership_level->id,
|
523 |
+
"membership_level_name" => $user->membership_level->name,
|
524 |
+
"display_name" => $user->display_name,
|
525 |
+
"user_email" => $user->user_email,
|
526 |
+
"billing_name" => $invoice->billing->name,
|
527 |
+
"billing_street" => $invoice->billing->street,
|
528 |
+
"billing_city" => $invoice->billing->city,
|
529 |
+
"billing_state" => $invoice->billing->state,
|
530 |
+
"billing_zip" => $invoice->billing->zip,
|
531 |
+
"billing_country" => $invoice->billing->country,
|
532 |
+
"billing_phone" => $invoice->billing->phone,
|
533 |
+
"cardtype" => $invoice->cardtype,
|
534 |
+
"accountnumber" => hideCardNumber($invoice->accountnumber),
|
535 |
+
"expirationmonth" => $invoice->expirationmonth,
|
536 |
+
"expirationyear" => $invoice->expirationyear,
|
537 |
+
"login_link" => wp_login_url(pmpro_url("billing"))
|
538 |
+
);
|
539 |
+
$this->data["billing_address"] = pmpro_formatAddress($invoice->billing->name,
|
540 |
+
$invoice->billing->street,
|
541 |
+
"", //address 2
|
542 |
+
$invoice->billing->city,
|
543 |
+
$invoice->billing->state,
|
544 |
+
$invoice->billing->zip,
|
545 |
+
$invoice->billing->country,
|
546 |
+
$invoice->billing->phone);
|
547 |
+
return $this->sendEmail();
|
548 |
+
}
|
549 |
+
|
550 |
+
function sendCreditCardExpiringEmail($user = NULL, $invoice = NULL)
|
551 |
+
{
|
552 |
+
global $current_user;
|
553 |
+
if(!$user)
|
554 |
+
$user = $current_user;
|
555 |
+
|
556 |
+
if(!$user || !$invoice)
|
557 |
+
return false;
|
558 |
+
|
559 |
+
$this->email = $user->user_email;
|
560 |
+
$this->subject = sprintf(__("Credit Card on File Expiring Soon at %s", "pmpro"), get_option("blogname"));
|
561 |
+
$this->template = "credit_card_expiring";
|
562 |
+
|
563 |
+
$this->data = array(
|
564 |
+
"subject" => $this->subject,
|
565 |
+
"name" => $user->display_name,
|
566 |
+
"user_login" => $user->user_login,
|
567 |
+
"sitename" => get_option("blogname"),
|
568 |
+
"siteemail" => pmpro_getOption("from_email"),
|
569 |
+
"membership_id" => $user->membership_level->id,
|
570 |
+
"membership_level_name" => $user->membership_level->name,
|
571 |
+
"display_name" => $user->display_name,
|
572 |
+
"user_email" => $user->user_email,
|
573 |
+
"billing_name" => $invoice->billing->name,
|
574 |
+
"billing_street" => $invoice->billing->street,
|
575 |
+
"billing_city" => $invoice->billing->city,
|
576 |
+
"billing_state" => $invoice->billing->state,
|
577 |
+
"billing_zip" => $invoice->billing->zip,
|
578 |
+
"billing_country" => $invoice->billing->country,
|
579 |
+
"billing_phone" => $invoice->billing->phone,
|
580 |
+
"cardtype" => $invoice->cardtype,
|
581 |
+
"accountnumber" => hideCardNumber($invoice->accountnumber),
|
582 |
+
"expirationmonth" => $invoice->expirationmonth,
|
583 |
+
"expirationyear" => $invoice->expirationyear,
|
584 |
+
"login_link" => wp_login_url(pmpro_url("billing"))
|
585 |
+
);
|
586 |
+
$this->data["billing_address"] = pmpro_formatAddress($invoice->billing->name,
|
587 |
+
$invoice->billing->street,
|
588 |
+
"", //address 2
|
589 |
+
$invoice->billing->city,
|
590 |
+
$invoice->billing->state,
|
591 |
+
$invoice->billing->zip,
|
592 |
+
$invoice->billing->country,
|
593 |
+
$invoice->billing->phone);
|
594 |
+
|
595 |
+
return $this->sendEmail();
|
596 |
+
}
|
597 |
+
|
598 |
+
function sendInvoiceEmail($user = NULL, $invoice = NULL)
|
599 |
+
{
|
600 |
+
global $wpdb, $current_user;
|
601 |
+
if(!$user)
|
602 |
+
$user = $current_user;
|
603 |
+
|
604 |
+
if(!$user || !$invoice)
|
605 |
+
return false;
|
606 |
+
|
607 |
+
$this->email = $user->user_email;
|
608 |
+
$this->subject = sprintf(__("INVOICE for %s membership", "pmpro"), get_option("blogname"));
|
609 |
+
$this->template = "invoice";
|
610 |
+
|
611 |
+
$this->data = array(
|
612 |
+
"subject" => $this->subject,
|
613 |
+
"name" => $user->display_name,
|
614 |
+
"user_login" => $user->user_login,
|
615 |
+
"sitename" => get_option("blogname"),
|
616 |
+
"siteemail" => pmpro_getOption("from_email"),
|
617 |
+
"membership_id" => $user->membership_level->id,
|
618 |
+
"membership_level_name" => $user->membership_level->name,
|
619 |
+
"display_name" => $user->display_name,
|
620 |
+
"user_email" => $user->user_email,
|
621 |
+
"invoice_id" => $invoice->code,
|
622 |
+
"invoice_total" => pmpro_formatPrice($invoice->total),
|
623 |
+
"invoice_date" => date(get_option('date_format'), $invoice->timestamp),
|
624 |
+
"billing_name" => $invoice->billing->name,
|
625 |
+
"billing_street" => $invoice->billing->street,
|
626 |
+
"billing_city" => $invoice->billing->city,
|
627 |
+
"billing_state" => $invoice->billing->state,
|
628 |
+
"billing_zip" => $invoice->billing->zip,
|
629 |
+
"billing_country" => $invoice->billing->country,
|
630 |
+
"billing_phone" => $invoice->billing->phone,
|
631 |
+
"cardtype" => $invoice->cardtype,
|
632 |
+
"accountnumber" => hideCardNumber($invoice->accountnumber),
|
633 |
+
"expirationmonth" => $invoice->expirationmonth,
|
634 |
+
"expirationyear" => $invoice->expirationyear,
|
635 |
+
"login_link" => wp_login_url(pmpro_url("account")),
|
636 |
+
"invoice_link" => wp_login_url(pmpro_url("invoice", "?invoice=" . $invoice->code)
|
637 |
+
));
|
638 |
+
$this->data["billing_address"] = pmpro_formatAddress($invoice->billing->name,
|
639 |
+
$invoice->billing->street,
|
640 |
+
"", //address 2
|
641 |
+
$invoice->billing->city,
|
642 |
+
$invoice->billing->state,
|
643 |
+
$invoice->billing->zip,
|
644 |
+
$invoice->billing->country,
|
645 |
+
$invoice->billing->phone);
|
646 |
+
|
647 |
+
if($invoice->getDiscountCode())
|
648 |
+
$this->data["discount_code"] = "<p>" . __("Discount Code", "pmpro") . ": " . $invoice->discount_code . "</p>\n";
|
649 |
+
else
|
650 |
+
$this->data["discount_code"] = "";
|
651 |
+
|
652 |
+
$enddate = $wpdb->get_var("SELECT UNIX_TIMESTAMP(enddate) FROM $wpdb->pmpro_memberships_users WHERE user_id = '" . $user->ID . "' AND status = 'active' LIMIT 1");
|
653 |
+
if($enddate)
|
654 |
+
$this->data["membership_expiration"] = "<p>" . sprintf(__("This membership will expire on %s.", "pmpro"), date(get_option('date_format'), $enddate)) . "</p>\n";
|
655 |
+
else
|
656 |
+
$this->data["membership_expiration"] = "";
|
657 |
+
|
658 |
+
return $this->sendEmail();
|
659 |
+
}
|
660 |
+
|
661 |
+
function sendTrialEndingEmail($user = NULL)
|
662 |
+
{
|
663 |
+
global $current_user, $wpdb;
|
664 |
+
if(!$user)
|
665 |
+
$user = $current_user;
|
666 |
+
|
667 |
+
if(!$user)
|
668 |
+
return false;
|
669 |
+
|
670 |
+
//make sure we have the current membership level data
|
671 |
+
/*$user->membership_level = $wpdb->get_row("SELECT l.id AS ID, l.name AS name, UNIX_TIMESTAMP(mu.startdate) as startdate, mu.billing_amount, mu.cycle_number, mu.cycle_period, mu.trial_amount, mu.trial_limit
|
672 |
+
FROM {$wpdb->pmpro_membership_levels} AS l
|
673 |
+
JOIN {$wpdb->pmpro_memberships_users} AS mu ON (l.id = mu.membership_id)
|
674 |
+
WHERE mu.user_id = " . $user->ID . "
|
675 |
+
LIMIT 1");*/
|
676 |
+
$user->membership_level = pmpro_getMembershipLevelForUser($user->ID);
|
677 |
+
|
678 |
+
$this->email = $user->user_email;
|
679 |
+
$this->subject = sprintf(__("Your trial at %s is ending soon", "pmpro"), get_option("blogname"));
|
680 |
+
$this->template = "trial_ending";
|
681 |
+
$this->data = array(
|
682 |
+
"subject" => $this->subject,
|
683 |
+
"name" => $user->display_name,
|
684 |
+
"user_login" => $user->user_login,
|
685 |
+
"sitename" => get_option("blogname"),
|
686 |
+
"membership_id" => $user->membership_level->id,
|
687 |
+
"membership_level_name" => $user->membership_level->name,
|
688 |
+
"siteemail" => pmpro_getOption("from_email"),
|
689 |
+
"login_link" => wp_login_url(),
|
690 |
+
"display_name" => $user->display_name,
|
691 |
+
"user_email" => $user->user_email,
|
692 |
+
"billing_amount" => pmpro_formatPrice($user->membership_level->billing_amount),
|
693 |
+
"cycle_number" => $user->membership_level->cycle_number,
|
694 |
+
"cycle_period" => $user->membership_level->cycle_period,
|
695 |
+
"trial_amount" => pmpro_formatPrice($user->membership_level->trial_amount),
|
696 |
+
"trial_limit" => $user->membership_level->trial_limit,
|
697 |
+
"trial_end" => date(get_option('date_format'), strtotime(date("m/d/Y", $user->membership_level->startdate) . " + " . $user->membership_level->trial_limit . " " . $user->membership_level->cycle_period), current_time("timestamp"))
|
698 |
+
);
|
699 |
+
|
700 |
+
return $this->sendEmail();
|
701 |
+
}
|
702 |
+
|
703 |
+
function sendMembershipExpiredEmail($user = NULL)
|
704 |
+
{
|
705 |
+
global $current_user, $wpdb;
|
706 |
+
if(!$user)
|
707 |
+
$user = $current_user;
|
708 |
+
|
709 |
+
if(!$user)
|
710 |
+
return false;
|
711 |
+
|
712 |
+
$this->email = $user->user_email;
|
713 |
+
$this->subject = sprintf(__("Your membership at %s has ended", "pmpro"), get_option("blogname"));
|
714 |
+
$this->template = "membership_expired";
|
715 |
+
$this->data = array("subject" => $this->subject, "name" => $user->display_name, "user_login" => $user->user_login, "sitename" => get_option("blogname"), "siteemail" => pmpro_getOption("from_email"), "login_link" => wp_login_url(), "display_name" => $user->display_name, "user_email" => $user->user_email, "levels_link" => pmpro_url("levels"));
|
716 |
+
|
717 |
+
return $this->sendEmail();
|
718 |
+
}
|
719 |
+
|
720 |
+
function sendMembershipExpiringEmail($user = NULL)
|
721 |
+
{
|
722 |
+
global $current_user, $wpdb;
|
723 |
+
if(!$user)
|
724 |
+
$user = $current_user;
|
725 |
+
|
726 |
+
if(!$user)
|
727 |
+
return false;
|
728 |
+
|
729 |
+
//make sure we have the current membership level data
|
730 |
+
/*$user->membership_level = $wpdb->get_row("SELECT l.id AS ID, l.name AS name, UNIX_TIMESTAMP(mu.enddate) as enddate
|
731 |
+
FROM {$wpdb->pmpro_membership_levels} AS l
|
732 |
+
JOIN {$wpdb->pmpro_memberships_users} AS mu ON (l.id = mu.membership_id)
|
733 |
+
WHERE mu.user_id = " . $user->ID . "
|
734 |
+
LIMIT 1");*/
|
735 |
+
$user->membership_level = pmpro_getMembershipLevelForUser($user->ID);
|
736 |
+
|
737 |
+
$this->email = $user->user_email;
|
738 |
+
$this->subject = sprintf(__("Your membership at %s will end soon", "pmpro"), get_option("blogname"));
|
739 |
+
$this->template = "membership_expiring";
|
740 |
+
$this->data = array("subject" => $this->subject, "name" => $user->display_name, "user_login" => $user->user_login, "sitename" => get_option("blogname"), "membership_id" => $user->membership_level->id, "membership_level_name" => $user->membership_level->name, "siteemail" => pmpro_getOption("from_email"), "login_link" => wp_login_url(), "enddate" => date(get_option('date_format'), $user->membership_level->enddate), "display_name" => $user->display_name, "user_email" => $user->user_email);
|
741 |
+
|
742 |
+
return $this->sendEmail();
|
743 |
+
}
|
744 |
+
|
745 |
+
function sendAdminChangeEmail($user = NULL)
|
746 |
+
{
|
747 |
+
global $current_user, $wpdb;
|
748 |
+
if(!$user)
|
749 |
+
$user = $current_user;
|
750 |
+
|
751 |
+
if(!$user)
|
752 |
+
return false;
|
753 |
+
|
754 |
+
//make sure we have the current membership level data
|
755 |
+
$user->membership_level = pmpro_getMembershipLevelForUser($user->ID);
|
756 |
+
|
757 |
+
$this->email = $user->user_email;
|
758 |
+
$this->subject = sprintf(__("Your membership at %s has been changed", "pmpro"), get_option("blogname"));
|
759 |
+
$this->template = "admin_change";
|
760 |
+
$this->data = array("subject" => $this->subject, "name" => $user->display_name, "user_login" => $user->user_login, "sitename" => get_option("blogname"), "membership_id" => $user->membership_level->id, "membership_level_name" => $user->membership_level->name, "siteemail" => pmpro_getOption("from_email"), "login_link" => wp_login_url());
|
761 |
+
if($user->membership_level->ID)
|
762 |
+
$this->data["membership_change"] = sprintf(__("The new level is %s", "pmpro"), $user->membership_level->name);
|
763 |
+
else
|
764 |
+
$this->data["membership_change"] = __("Your membership has been cancelled", "pmpro");
|
765 |
+
|
766 |
+
if(!empty($user->membership_level->enddate))
|
767 |
+
{
|
768 |
+
$this->data["membership_change"] .= ". " . sprintf(__("This membership will expire on %s", "pmpro"), date(get_option('date_format'), $user->membership_level->enddate));
|
769 |
+
}
|
770 |
+
elseif(!empty($this->expiration_changed))
|
771 |
+
{
|
772 |
+
$this->data["membership_change"] .= ". " . __("This membership does not expire", "pmpro");
|
773 |
+
}
|
774 |
+
|
775 |
+
return $this->sendEmail();
|
776 |
+
}
|
777 |
+
|
778 |
+
function sendAdminChangeAdminEmail($user = NULL)
|
779 |
+
{
|
780 |
+
global $current_user, $wpdb;
|
781 |
+
if(!$user)
|
782 |
+
$user = $current_user;
|
783 |
+
|
784 |
+
if(!$user)
|
785 |
+
return false;
|
786 |
+
|
787 |
+
//check settings
|
788 |
+
$send = pmpro_getOption("email_admin_changes");
|
789 |
+
if(empty($send))
|
790 |
+
return true; //didn't send, but we also don't want to indicate failure because the settings say to not send
|
791 |
+
|
792 |
+
//make sure we have the current membership level data
|
793 |
+
$user->membership_level = pmpro_getMembershipLevelForUser($user->ID);
|
794 |
+
|
795 |
+
$this->email = get_bloginfo("admin_email");
|
796 |
+
$this->subject = sprintf(__("Membership for %s at %s has been changed", "pmpro"), $user->user_login, get_option("blogname"));
|
797 |
+
$this->template = "admin_change_admin";
|
798 |
+
$this->data = array("subject" => $this->subject, "name" => $user->display_name, "user_login" => $user->user_login, "sitename" => get_option("blogname"), "membership_level_name" => $user->membership_level->name, "siteemail" => get_bloginfo("admin_email"), "login_link" => wp_login_url());
|
799 |
+
if($user->membership_level->ID)
|
800 |
+
$this->data["membership_change"] = sprintf(__("The new level is %s", "pmpro"), $user->membership_level->name);
|
801 |
+
else
|
802 |
+
$this->data["membership_change"] = __("Membership has been cancelled", "pmpro");
|
803 |
+
|
804 |
+
if(!empty($user->membership_level->enddate))
|
805 |
+
{
|
806 |
+
$this->data["membership_change"] .= ". " . sprintf(__("This membership will expire on %s", "pmpro"), date(get_option('date_format'), $user->membership_level->enddate));
|
807 |
+
}
|
808 |
+
elseif(!empty($this->expiration_changed))
|
809 |
+
{
|
810 |
+
$this->data["membership_change"] .= ". " . __("This membership does not expire", "pmpro");
|
811 |
+
}
|
812 |
+
|
813 |
+
return $this->sendEmail();
|
814 |
+
}
|
815 |
+
}
|
classes/gateways/class.pmprogateway.php
CHANGED
@@ -1,220 +1,220 @@
|
|
1 |
-
<?php
|
2 |
-
//require_once(dirname(__FILE__) . "/class.pmprogateway.php");
|
3 |
-
class PMProGateway
|
4 |
-
{
|
5 |
-
function PMProGateway($gateway = NULL)
|
6 |
-
{
|
7 |
-
$this->gateway = $gateway;
|
8 |
-
return $this->gateway;
|
9 |
-
}
|
10 |
-
|
11 |
-
function process(&$order)
|
12 |
-
{
|
13 |
-
//check for initial payment
|
14 |
-
if(floatval($order->InitialPayment) == 0)
|
15 |
-
{
|
16 |
-
//auth first, then process
|
17 |
-
if($this->authorize($order))
|
18 |
-
{
|
19 |
-
$this->void($order);
|
20 |
-
if(!pmpro_isLevelTrial($order->membership_level))
|
21 |
-
{
|
22 |
-
//subscription will start today with a 1 period trial
|
23 |
-
$order->ProfileStartDate = date("Y-m-d") . "T0:0:0";
|
24 |
-
$order->TrialBillingPeriod = $order->BillingPeriod;
|
25 |
-
$order->TrialBillingFrequency = $order->BillingFrequency;
|
26 |
-
$order->TrialBillingCycles = 1;
|
27 |
-
$order->TrialAmount = 0;
|
28 |
-
|
29 |
-
//add a billing cycle to make up for the trial, if applicable
|
30 |
-
if(!empty($order->TotalBillingCycles))
|
31 |
-
$order->TotalBillingCycles++;
|
32 |
-
}
|
33 |
-
elseif($order->InitialPayment == 0 && $order->TrialAmount == 0)
|
34 |
-
{
|
35 |
-
//it has a trial, but the amount is the same as the initial payment, so we can squeeze it in there
|
36 |
-
$order->ProfileStartDate = date("Y-m-d") . "T0:0:0";
|
37 |
-
$order->TrialBillingCycles++;
|
38 |
-
|
39 |
-
//add a billing cycle to make up for the trial, if applicable
|
40 |
-
if($order->TotalBillingCycles)
|
41 |
-
$order->TotalBillingCycles++;
|
42 |
-
}
|
43 |
-
else
|
44 |
-
{
|
45 |
-
//add a period to the start date to account for the initial payment
|
46 |
-
$order->ProfileStartDate = date("Y-m-d", strtotime("+ " . $order->BillingFrequency . " " . $order->BillingPeriod, current_time("timestamp"))) . "T0:0:0";
|
47 |
-
}
|
48 |
-
|
49 |
-
$order->ProfileStartDate = apply_filters("pmpro_profile_start_date", $order->ProfileStartDate, $order);
|
50 |
-
return $this->subscribe($order);
|
51 |
-
}
|
52 |
-
else
|
53 |
-
{
|
54 |
-
if(empty($order->error))
|
55 |
-
$order->error = __("Unknown error: Authorization failed.", "pmpro");
|
56 |
-
return false;
|
57 |
-
}
|
58 |
-
}
|
59 |
-
else
|
60 |
-
{
|
61 |
-
//charge first payment
|
62 |
-
if($this->charge($order))
|
63 |
-
{
|
64 |
-
//setup recurring billing
|
65 |
-
if(pmpro_isLevelRecurring($order->membership_level))
|
66 |
-
{
|
67 |
-
if(!pmpro_isLevelTrial($order->membership_level))
|
68 |
-
{
|
69 |
-
//subscription will start today with a 1 period trial
|
70 |
-
$order->ProfileStartDate = date("Y-m-d") . "T0:0:0";
|
71 |
-
$order->TrialBillingPeriod = $order->BillingPeriod;
|
72 |
-
$order->TrialBillingFrequency = $order->BillingFrequency;
|
73 |
-
$order->TrialBillingCycles = 1;
|
74 |
-
$order->TrialAmount = 0;
|
75 |
-
|
76 |
-
//add a billing cycle to make up for the trial, if applicable
|
77 |
-
if(!empty($order->TotalBillingCycles))
|
78 |
-
$order->TotalBillingCycles++;
|
79 |
-
}
|
80 |
-
elseif($order->InitialPayment == 0 && $order->TrialAmount == 0)
|
81 |
-
{
|
82 |
-
//it has a trial, but the amount is the same as the initial payment, so we can squeeze it in there
|
83 |
-
$order->ProfileStartDate = date("Y-m-d") . "T0:0:0";
|
84 |
-
$order->TrialBillingCycles++;
|
85 |
-
|
86 |
-
//add a billing cycle to make up for the trial, if applicable
|
87 |
-
if(!empty($order->TotalBillingCycles))
|
88 |
-
$order->TotalBillingCycles++;
|
89 |
-
}
|
90 |
-
else
|
91 |
-
{
|
92 |
-
//add a period to the start date to account for the initial payment
|
93 |
-
$order->ProfileStartDate = date("Y-m-d", strtotime("+ " . $this->BillingFrequency . " " . $this->BillingPeriod, current_time("timestamp"))) . "T0:0:0";
|
94 |
-
}
|
95 |
-
|
96 |
-
$order->ProfileStartDate = apply_filters("pmpro_profile_start_date", $order->ProfileStartDate, $order);
|
97 |
-
if($this->subscribe($order))
|
98 |
-
{
|
99 |
-
return true;
|
100 |
-
}
|
101 |
-
else
|
102 |
-
{
|
103 |
-
if($this->void($order))
|
104 |
-
{
|
105 |
-
if(!$order->error)
|
106 |
-
$order->error = __("Unknown error: Payment failed.", "pmpro");
|
107 |
-
}
|
108 |
-
else
|
109 |
-
{
|
110 |
-
if(!$order->error)
|
111 |
-
$order->error = __("Unknown error: Payment failed.", "pmpro");
|
112 |
-
|
113 |
-
$order->error .= " " . __("A partial payment was made that we could not void. Please contact the site owner immediately to correct this.", "pmpro");
|
114 |
-
}
|
115 |
-
|
116 |
-
return false;
|
117 |
-
}
|
118 |
-
}
|
119 |
-
else
|
120 |
-
{
|
121 |
-
//only a one time charge
|
122 |
-
$order->status = "success"; //saved on checkout page
|
123 |
-
return true;
|
124 |
-
}
|
125 |
-
}
|
126 |
-
else
|
127 |
-
{
|
128 |
-
if(empty($order->error))
|
129 |
-
$order->error = __("Unknown error: Payment failed.", "pmpro");
|
130 |
-
|
131 |
-
return false;
|
132 |
-
}
|
133 |
-
}
|
134 |
-
}
|
135 |
-
|
136 |
-
function authorize(&$order)
|
137 |
-
{
|
138 |
-
//create a code for the order
|
139 |
-
if(empty($order->code))
|
140 |
-
$order->code = $order->getRandomCode();
|
141 |
-
|
142 |
-
//simulate a successful authorization
|
143 |
-
$order->payment_transaction_id = "TEST" . $order->code;
|
144 |
-
$order->updateStatus("authorized");
|
145 |
-
return true;
|
146 |
-
}
|
147 |
-
|
148 |
-
function void(&$order)
|
149 |
-
{
|
150 |
-
//need a transaction id
|
151 |
-
if(empty($order->payment_transaction_id))
|
152 |
-
return false;
|
153 |
-
|
154 |
-
//simulate a successful void
|
155 |
-
$order->payment_transaction_id = "TEST" . $order->code;
|
156 |
-
$order->updateStatus("voided");
|
157 |
-
return true;
|
158 |
-
}
|
159 |
-
|
160 |
-
function charge(&$order)
|
161 |
-
{
|
162 |
-
//create a code for the order
|
163 |
-
if(empty($order->code))
|
164 |
-
$order->code = $order->getRandomCode();
|
165 |
-
|
166 |
-
//simulate a successful charge
|
167 |
-
$order->payment_transaction_id = "TEST" . $order->code;
|
168 |
-
$order->updateStatus("success");
|
169 |
-
return true;
|
170 |
-
}
|
171 |
-
|
172 |
-
function subscribe(&$order)
|
173 |
-
{
|
174 |
-
//create a code for the order
|
175 |
-
if(empty($order->code))
|
176 |
-
$order->code = $order->getRandomCode();
|
177 |
-
|
178 |
-
//filter order before subscription. use with care.
|
179 |
-
$order = apply_filters("pmpro_subscribe_order", $order, $this);
|
180 |
-
|
181 |
-
//simulate a successful subscription processing
|
182 |
-
$order->status = "success";
|
183 |
-
$order->subscription_transaction_id = "TEST" . $order->code;
|
184 |
-
return true;
|
185 |
-
}
|
186 |
-
|
187 |
-
function update(&$order)
|
188 |
-
{
|
189 |
-
//simulate a successful billing update
|
190 |
-
return true;
|
191 |
-
}
|
192 |
-
|
193 |
-
function cancel(&$order)
|
194 |
-
{
|
195 |
-
//require a subscription id
|
196 |
-
if(empty($order->subscription_transaction_id))
|
197 |
-
return false;
|
198 |
-
|
199 |
-
//simulate a successful cancel
|
200 |
-
$order->updateStatus("cancelled");
|
201 |
-
return true;
|
202 |
-
}
|
203 |
-
|
204 |
-
function getSubscriptionStatus(&$order)
|
205 |
-
{
|
206 |
-
//require a subscription id
|
207 |
-
if(empty($order->subscription_transaction_id))
|
208 |
-
return false;
|
209 |
-
|
210 |
-
//this looks different for each gateway, but generally an array of some sort
|
211 |
-
return array();
|
212 |
-
}
|
213 |
-
|
214 |
-
function getTransactionStatus(&$order)
|
215 |
-
{
|
216 |
-
//this looks different for each gateway, but generally an array of some sort
|
217 |
-
return array();
|
218 |
-
}
|
219 |
-
}
|
220 |
-
?>
|
1 |
+
<?php
|
2 |
+
//require_once(dirname(__FILE__) . "/class.pmprogateway.php");
|
3 |
+
class PMProGateway
|
4 |
+
{
|
5 |
+
function PMProGateway($gateway = NULL)
|
6 |
+
{
|
7 |
+
$this->gateway = $gateway;
|
8 |
+
return $this->gateway;
|
9 |
+
}
|
10 |
+
|
11 |
+
function process(&$order)
|
12 |
+
{
|
13 |
+
//check for initial payment
|
14 |
+
if(floatval($order->InitialPayment) == 0)
|
15 |
+
{
|
16 |
+
//auth first, then process
|
17 |
+
if($this->authorize($order))
|
18 |
+
{
|
19 |
+
$this->void($order);
|
20 |
+
if(!pmpro_isLevelTrial($order->membership_level))
|
21 |
+
{
|
22 |
+
//subscription will start today with a 1 period trial
|
23 |
+
$order->ProfileStartDate = date("Y-m-d") . "T0:0:0";
|
24 |
+
$order->TrialBillingPeriod = $order->BillingPeriod;
|
25 |
+
$order->TrialBillingFrequency = $order->BillingFrequency;
|
26 |
+
$order->TrialBillingCycles = 1;
|
27 |
+
$order->TrialAmount = 0;
|
28 |
+
|
29 |
+
//add a billing cycle to make up for the trial, if applicable
|
30 |
+
if(!empty($order->TotalBillingCycles))
|
31 |
+
$order->TotalBillingCycles++;
|
32 |
+
}
|
33 |
+
elseif($order->InitialPayment == 0 && $order->TrialAmount == 0)
|
34 |
+
{
|
35 |
+
//it has a trial, but the amount is the same as the initial payment, so we can squeeze it in there
|
36 |
+
$order->ProfileStartDate = date("Y-m-d") . "T0:0:0";
|
37 |
+
$order->TrialBillingCycles++;
|
38 |
+
|
39 |
+
//add a billing cycle to make up for the trial, if applicable
|
40 |
+
if($order->TotalBillingCycles)
|
41 |
+
$order->TotalBillingCycles++;
|
42 |
+
}
|
43 |
+
else
|
44 |
+
{
|
45 |
+
//add a period to the start date to account for the initial payment
|
46 |
+
$order->ProfileStartDate = date("Y-m-d", strtotime("+ " . $order->BillingFrequency . " " . $order->BillingPeriod, current_time("timestamp"))) . "T0:0:0";
|
47 |
+
}
|
48 |
+
|
49 |
+
$order->ProfileStartDate = apply_filters("pmpro_profile_start_date", $order->ProfileStartDate, $order);
|
50 |
+
return $this->subscribe($order);
|
51 |
+
}
|
52 |
+
else
|
53 |
+
{
|
54 |
+
if(empty($order->error))
|
55 |
+
$order->error = __("Unknown error: Authorization failed.", "pmpro");
|
56 |
+
return false;
|
57 |
+
}
|
58 |
+
}
|
59 |
+
else
|
60 |
+
{
|
61 |
+
//charge first payment
|
62 |
+
if($this->charge($order))
|
63 |
+
{
|
64 |
+
//setup recurring billing
|
65 |
+
if(pmpro_isLevelRecurring($order->membership_level))
|
66 |
+
{
|
67 |
+
if(!pmpro_isLevelTrial($order->membership_level))
|
68 |
+
{
|
69 |
+
//subscription will start today with a 1 period trial
|
70 |
+
$order->ProfileStartDate = date("Y-m-d") . "T0:0:0";
|
71 |
+
$order->TrialBillingPeriod = $order->BillingPeriod;
|
72 |
+
$order->TrialBillingFrequency = $order->BillingFrequency;
|
73 |
+
$order->TrialBillingCycles = 1;
|
74 |
+
$order->TrialAmount = 0;
|
75 |
+
|
76 |
+
//add a billing cycle to make up for the trial, if applicable
|
77 |
+
if(!empty($order->TotalBillingCycles))
|
78 |
+
$order->TotalBillingCycles++;
|
79 |
+
}
|
80 |
+
elseif($order->InitialPayment == 0 && $order->TrialAmount == 0)
|
81 |
+
{
|
82 |
+
//it has a trial, but the amount is the same as the initial payment, so we can squeeze it in there
|
83 |
+
$order->ProfileStartDate = date("Y-m-d") . "T0:0:0";
|
84 |
+
$order->TrialBillingCycles++;
|
85 |
+
|
86 |
+
//add a billing cycle to make up for the trial, if applicable
|
87 |
+
if(!empty($order->TotalBillingCycles))
|
88 |
+
$order->TotalBillingCycles++;
|
89 |
+
}
|
90 |
+
else
|
91 |
+
{
|
92 |
+
//add a period to the start date to account for the initial payment
|
93 |
+
$order->ProfileStartDate = date("Y-m-d", strtotime("+ " . $this->BillingFrequency . " " . $this->BillingPeriod, current_time("timestamp"))) . "T0:0:0";
|
94 |
+
}
|
95 |
+
|
96 |
+
$order->ProfileStartDate = apply_filters("pmpro_profile_start_date", $order->ProfileStartDate, $order);
|
97 |
+
if($this->subscribe($order))
|
98 |
+
{
|
99 |
+
return true;
|
100 |
+
}
|
101 |
+
else
|
102 |
+
{
|
103 |
+
if($this->void($order))
|
104 |
+
{
|
105 |
+
if(!$order->error)
|
106 |
+
$order->error = __("Unknown error: Payment failed.", "pmpro");
|
107 |
+
}
|
108 |
+
else
|
109 |
+
{
|
110 |
+
if(!$order->error)
|
111 |
+
$order->error = __("Unknown error: Payment failed.", "pmpro");
|
112 |
+
|
113 |
+
$order->error .= " " . __("A partial payment was made that we could not void. Please contact the site owner immediately to correct this.", "pmpro");
|
114 |
+
}
|
115 |
+
|
116 |
+
return false;
|
117 |
+
}
|
118 |
+
}
|
119 |
+
else
|
120 |
+
{
|
121 |
+
//only a one time charge
|
122 |
+
$order->status = "success"; //saved on checkout page
|
123 |
+
return true;
|
124 |
+
}
|
125 |
+
}
|
126 |
+
else
|
127 |
+
{
|
128 |
+
if(empty($order->error))
|
129 |
+
$order->error = __("Unknown error: Payment failed.", "pmpro");
|
130 |
+
|
131 |
+
return false;
|
132 |
+
}
|
133 |
+
}
|
134 |
+
}
|
135 |
+
|
136 |
+
function authorize(&$order)
|
137 |
+
{
|
138 |
+
//create a code for the order
|
139 |
+
if(empty($order->code))
|
140 |
+
$order->code = $order->getRandomCode();
|
141 |
+
|
142 |
+
//simulate a successful authorization
|
143 |
+
$order->payment_transaction_id = "TEST" . $order->code;
|
144 |
+
$order->updateStatus("authorized");
|
145 |
+
return true;
|
146 |
+
}
|
147 |
+
|
148 |
+
function void(&$order)
|
149 |
+
{
|
150 |
+
//need a transaction id
|
151 |
+
if(empty($order->payment_transaction_id))
|
152 |
+
return false;
|
153 |
+
|
154 |
+
//simulate a successful void
|
155 |
+
$order->payment_transaction_id = "TEST" . $order->code;
|
156 |
+
$order->updateStatus("voided");
|
157 |
+
return true;
|
158 |
+
}
|
159 |
+
|
160 |
+
function charge(&$order)
|
161 |
+
{
|
162 |
+
//create a code for the order
|
163 |
+
if(empty($order->code))
|
164 |
+
$order->code = $order->getRandomCode();
|
165 |
+
|
166 |
+
//simulate a successful charge
|
167 |
+
$order->payment_transaction_id = "TEST" . $order->code;
|
168 |
+
$order->updateStatus("success");
|
169 |
+
return true;
|
170 |
+
}
|
171 |
+
|
172 |
+
function subscribe(&$order)
|
173 |
+
{
|
174 |
+
//create a code for the order
|
175 |
+
if(empty($order->code))
|
176 |
+
$order->code = $order->getRandomCode();
|
177 |
+
|
178 |
+
//filter order before subscription. use with care.
|
179 |
+
$order = apply_filters("pmpro_subscribe_order", $order, $this);
|
180 |
+
|
181 |
+
//simulate a successful subscription processing
|
182 |
+
$order->status = "success";
|
183 |
+
$order->subscription_transaction_id = "TEST" . $order->code;
|
184 |
+
return true;
|
185 |
+
}
|
186 |
+
|
187 |
+
function update(&$order)
|
188 |
+
{
|
189 |
+
//simulate a successful billing update
|
190 |
+
return true;
|
191 |
+
}
|
192 |
+
|
193 |
+
function cancel(&$order)
|
194 |
+
{
|
195 |
+
//require a subscription id
|
196 |
+
if(empty($order->subscription_transaction_id))
|
197 |
+
return false;
|
198 |
+
|
199 |
+
//simulate a successful cancel
|
200 |
+
$order->updateStatus("cancelled");
|
201 |
+
return true;
|
202 |
+
}
|
203 |
+
|
204 |
+
function getSubscriptionStatus(&$order)
|
205 |
+
{
|
206 |
+
//require a subscription id
|
207 |
+
if(empty($order->subscription_transaction_id))
|
208 |
+
return false;
|
209 |
+
|
210 |
+
//this looks different for each gateway, but generally an array of some sort
|
211 |
+
return array();
|
212 |
+
}
|
213 |
+
|
214 |
+
function getTransactionStatus(&$order)
|
215 |
+
{
|
216 |
+
//this looks different for each gateway, but generally an array of some sort
|
217 |
+
return array();
|
218 |
+
}
|
219 |
+
}
|
220 |
+
?>
|
classes/gateways/class.pmprogateway_authorizenet.php
CHANGED
@@ -1,53 +1,53 @@
|
|
1 |
<?php
|
2 |
//include pmprogateway
|
3 |
require_once(dirname(__FILE__) . "/class.pmprogateway.php");
|
4 |
-
|
5 |
//load classes init method
|
6 |
add_action('init', array('PMProGateway_authorizenet', 'init'));
|
7 |
-
|
8 |
class PMProGateway_authorizenet extends PMProGateway
|
9 |
{
|
10 |
function PMProGateway_authorizenet($gateway = NULL)
|
11 |
{
|
12 |
$this->gateway = $gateway;
|
13 |
return $this->gateway;
|
14 |
-
}
|
15 |
-
|
16 |
/**
|
17 |
* Run on WP init
|
18 |
-
*
|
19 |
* @since 1.8
|
20 |
*/
|
21 |
static function init()
|
22 |
-
{
|
23 |
//make sure Authorize.net is a gateway option
|
24 |
add_filter('pmpro_gateways', array('PMProGateway_authorizenet', 'pmpro_gateways'));
|
25 |
-
|
26 |
//add fields to payment settings
|
27 |
add_filter('pmpro_payment_options', array('PMProGateway_authorizenet', 'pmpro_payment_options'));
|
28 |
-
add_filter('pmpro_payment_option_fields', array('PMProGateway_authorizenet', 'pmpro_payment_option_fields'), 10, 2);
|
29 |
}
|
30 |
-
|
31 |
/**
|
32 |
* Make sure this gateway is in the gateways list
|
33 |
-
*
|
34 |
* @since 1.8
|
35 |
*/
|
36 |
static function pmpro_gateways($gateways)
|
37 |
{
|
38 |
if(empty($gateways['authorizenet']))
|
39 |
$gateways['authorizenet'] = __('Authorize.net', 'pmpro');
|
40 |
-
|
41 |
return $gateways;
|
42 |
}
|
43 |
-
|
44 |
/**
|
45 |
* Get a list of payment options that the this gateway needs/supports.
|
46 |
-
*
|
47 |
* @since 1.8
|
48 |
*/
|
49 |
static function getGatewayOptions()
|
50 |
-
{
|
51 |
$options = array(
|
52 |
'sslseal',
|
53 |
'nuclear_HTTPS',
|
@@ -60,29 +60,29 @@
|
|
60 |
'tax_rate',
|
61 |
'accepted_credit_cards'
|
62 |
);
|
63 |
-
|
64 |
return $options;
|
65 |
}
|
66 |
-
|
67 |
/**
|
68 |
* Set payment options for payment settings page.
|
69 |
-
*
|
70 |
* @since 1.8
|
71 |
*/
|
72 |
static function pmpro_payment_options($options)
|
73 |
-
{
|
74 |
//get stripe options
|
75 |
$authorizenet_options = PMProGateway_authorizenet::getGatewayOptions();
|
76 |
-
|
77 |
//merge with others.
|
78 |
$options = array_merge($authorizenet_options, $options);
|
79 |
-
|
80 |
return $options;
|
81 |
}
|
82 |
-
|
83 |
/**
|
84 |
* Display fields for this gateway's options.
|
85 |
-
*
|
86 |
* @since 1.8
|
87 |
*/
|
88 |
static function pmpro_payment_option_fields($values, $gateway)
|
@@ -119,10 +119,10 @@
|
|
119 |
</tr>
|
120 |
<?php
|
121 |
}
|
122 |
-
|
123 |
/**
|
124 |
* Process checkout.
|
125 |
-
*
|
126 |
*/
|
127 |
function process(&$order)
|
128 |
{
|
@@ -131,17 +131,17 @@
|
|
131 |
{
|
132 |
//auth first, then process
|
133 |
if($this->authorize($order))
|
134 |
-
{
|
135 |
-
$this->void($order);
|
136 |
if(!pmpro_isLevelTrial($order->membership_level))
|
137 |
{
|
138 |
//subscription will start today with a 1 period trial
|
139 |
$order->ProfileStartDate = date("Y-m-d") . "T0:0:0";
|
140 |
$order->TrialBillingPeriod = $order->BillingPeriod;
|
141 |
-
$order->TrialBillingFrequency = $order->BillingFrequency;
|
142 |
$order->TrialBillingCycles = 1;
|
143 |
$order->TrialAmount = 0;
|
144 |
-
|
145 |
//add a billing cycle to make up for the trial, if applicable
|
146 |
if(!empty($order->TotalBillingCycles))
|
147 |
$order->TotalBillingCycles++;
|
@@ -149,9 +149,9 @@
|
|
149 |
elseif($order->InitialPayment == 0 && $order->TrialAmount == 0)
|
150 |
{
|
151 |
//it has a trial, but the amount is the same as the initial payment, so we can squeeze it in there
|
152 |
-
$order->ProfileStartDate = date("Y-m-d") . "T0:0:0";
|
153 |
$order->TrialBillingCycles++;
|
154 |
-
|
155 |
//add a billing cycle to make up for the trial, if applicable
|
156 |
if(!empty($order->TotalBillingCycles))
|
157 |
$order->TotalBillingCycles++;
|
@@ -161,12 +161,12 @@
|
|
161 |
//add a period to the start date to account for the initial payment
|
162 |
$order->ProfileStartDate = date("Y-m-d", strtotime("+ " . $order->BillingFrequency . " " . $order->BillingPeriod, current_time("timestamp"))) . "T0:0:0";
|
163 |
}
|
164 |
-
|
165 |
$order->ProfileStartDate = apply_filters("pmpro_profile_start_date", $order->ProfileStartDate, $order);
|
166 |
return $this->subscribe($order);
|
167 |
}
|
168 |
else
|
169 |
-
{
|
170 |
if(empty($order->error))
|
171 |
$order->error = __("Unknown error: Authorization failed.", "pmpro");
|
172 |
return false;
|
@@ -176,19 +176,19 @@
|
|
176 |
{
|
177 |
//charge first payment
|
178 |
if($this->charge($order))
|
179 |
-
{
|
180 |
//setup recurring billing
|
181 |
if(pmpro_isLevelRecurring($order->membership_level))
|
182 |
-
{
|
183 |
if(!pmpro_isLevelTrial($order->membership_level))
|
184 |
{
|
185 |
//subscription will start today with a 1 period trial
|
186 |
$order->ProfileStartDate = date("Y-m-d") . "T0:0:0";
|
187 |
$order->TrialBillingPeriod = $order->BillingPeriod;
|
188 |
-
$order->TrialBillingFrequency = $order->BillingFrequency;
|
189 |
$order->TrialBillingCycles = 1;
|
190 |
$order->TrialAmount = 0;
|
191 |
-
|
192 |
//add a billing cycle to make up for the trial, if applicable
|
193 |
if(!empty($order->TotalBillingCycles))
|
194 |
$order->TotalBillingCycles++;
|
@@ -196,9 +196,9 @@
|
|
196 |
elseif($order->InitialPayment == 0 && $order->TrialAmount == 0)
|
197 |
{
|
198 |
//it has a trial, but the amount is the same as the initial payment, so we can squeeze it in there
|
199 |
-
$order->ProfileStartDate = date("Y-m-d") . "T0:0:0";
|
200 |
$order->TrialBillingCycles++;
|
201 |
-
|
202 |
//add a billing cycle to make up for the trial, if applicable
|
203 |
if(!empty($order->TotalBillingCycles))
|
204 |
$order->TotalBillingCycles++;
|
@@ -208,7 +208,7 @@
|
|
208 |
//add a period to the start date to account for the initial payment
|
209 |
$order->ProfileStartDate = date("Y-m-d", strtotime("+ " . $order->BillingFrequency . " " . $order->BillingPeriod, current_time("timestamp"))) . "T0:0:0";
|
210 |
}
|
211 |
-
|
212 |
$order->ProfileStartDate = apply_filters("pmpro_profile_start_date", $order->ProfileStartDate, $order);
|
213 |
if($this->subscribe($order))
|
214 |
{
|
@@ -224,66 +224,66 @@
|
|
224 |
else
|
225 |
{
|
226 |
if(!$order->error)
|
227 |
-
$order->error = __("Unknown error: Payment failed.", "pmpro");
|
228 |
$order->error .= " " . __("A partial payment was made that we could not void. Please contact the site owner immediately to correct this.", "pmpro");
|
229 |
}
|
230 |
-
|
231 |
-
return false;
|
232 |
}
|
233 |
}
|
234 |
else
|
235 |
{
|
236 |
//only a one time charge
|
237 |
-
$order->status = "success"; //saved on checkout page
|
238 |
return true;
|
239 |
}
|
240 |
}
|
241 |
else
|
242 |
-
{
|
243 |
if(empty($order->error))
|
244 |
$order->error = __("Unknown error: Payment failed.", "pmpro");
|
245 |
-
|
246 |
return false;
|
247 |
-
}
|
248 |
-
}
|
249 |
}
|
250 |
-
|
251 |
function authorize(&$order)
|
252 |
{
|
253 |
if(empty($order->code))
|
254 |
$order->code = $order->getRandomCode();
|
255 |
-
|
256 |
if(empty($order->gateway_environment))
|
257 |
$gateway_environment = pmpro_getOption("gateway_environment");
|
258 |
else
|
259 |
$gateway_environment = $order->gateway_environment;
|
260 |
if($gateway_environment == "live")
|
261 |
-
$host = "secure.authorize.net";
|
262 |
else
|
263 |
-
$host = "test.authorize.net";
|
264 |
-
|
265 |
-
$path = "/gateway/transact.dll";
|
266 |
$post_url = "https://" . $host . $path;
|
267 |
|
268 |
$post_url = apply_filters("pmpro_authorizenet_post_url", $post_url, $gateway_environment);
|
269 |
-
|
270 |
//what amount to authorize? just $1 to test
|
271 |
-
$amount = "1.00";
|
272 |
-
|
273 |
-
//combine address
|
274 |
$address = $order->Address1;
|
275 |
if(!empty($order->Address2))
|
276 |
$address .= "\n" . $order->Address2;
|
277 |
-
|
278 |
//customer stuff
|
279 |
$customer_email = $order->Email;
|
280 |
$customer_phone = $order->billing->phone;
|
281 |
-
|
282 |
if(!isset($order->membership_level->name))
|
283 |
$order->membership_level->name = "";
|
284 |
-
|
285 |
$post_values = array(
|
286 |
-
|
287 |
// the API Login ID and Transaction Key must be replaced with valid values
|
288 |
"x_login" => pmpro_getOption("loginname"),
|
289 |
"x_tran_key" => pmpro_getOption("transactionkey"),
|
@@ -298,7 +298,7 @@
|
|
298 |
"x_card_type" => $order->cardtype,
|
299 |
"x_card_num" => $order->accountnumber,
|
300 |
"x_exp_date" => $order->ExpirationDate,
|
301 |
-
|
302 |
"x_amount" => $amount,
|
303 |
"x_description" => $order->membership_level->name . " " . __("Membership", "pmpro"),
|
304 |
|
@@ -315,17 +315,17 @@
|
|
315 |
// Additional fields can be added here as outlined in the AIM integration
|
316 |
// guide at: http://developer.authorize.net
|
317 |
);
|
318 |
-
|
319 |
if(!empty($order->CVV2))
|
320 |
$post_values["x_card_code"] = $order->CVV2;
|
321 |
-
|
322 |
// This section takes the input fields and converts them to the proper format
|
323 |
// for an http post. For example: "x_login=username&x_tran_key=a1B2c3D4"
|
324 |
$post_string = "";
|
325 |
foreach( $post_values as $key => $value )
|
326 |
{ $post_string .= "$key=" . urlencode( str_replace("#", "%23", $value) ) . "&"; }
|
327 |
$post_string = rtrim( $post_string, "& " );
|
328 |
-
|
329 |
//curl
|
330 |
$request = curl_init($post_url); // initiate curl object
|
331 |
curl_setopt($request, CURLOPT_HEADER, 0); // set to 0 to eliminate header info from response
|
@@ -336,15 +336,15 @@
|
|
336 |
// additional options may be required depending upon your server configuration
|
337 |
// you can find documentation on curl options at http://www.php.net/curl_setopt
|
338 |
curl_close ($request); // close curl object
|
339 |
-
|
340 |
// This line takes the response and breaks it into an array using the specified delimiting character
|
341 |
$response_array = explode($post_values["x_delim_char"],$post_response);
|
342 |
-
|
343 |
if($response_array[0] == 1)
|
344 |
{
|
345 |
$order->payment_transaction_id = $response_array[6];
|
346 |
-
$order->updateStatus("authorized");
|
347 |
-
|
348 |
return true;
|
349 |
}
|
350 |
else
|
@@ -354,30 +354,30 @@
|
|
354 |
$order->error = $response_array[3];
|
355 |
$order->shorterror = $response_array[3];
|
356 |
return false;
|
357 |
-
}
|
358 |
}
|
359 |
-
|
360 |
function void(&$order)
|
361 |
{
|
362 |
if(empty($order->payment_transaction_id))
|
363 |
return false;
|
364 |
-
|
365 |
if(empty($order->gateway_environment))
|
366 |
$gateway_environment = pmpro_getOption("gateway_environment");
|
367 |
else
|
368 |
$gateway_environment = $order->gateway_environment;
|
369 |
if($gateway_environment == "live")
|
370 |
-
$host = "secure.authorize.net";
|
371 |
else
|
372 |
-
$host = "test.authorize.net";
|
373 |
-
|
374 |
-
$path = "/gateway/transact.dll";
|
375 |
$post_url = "https://" . $host . $path;
|
376 |
-
|
377 |
$post_url = apply_filters("pmpro_authorizenet_post_url", $post_url, $gateway_environment);
|
378 |
-
|
379 |
$post_values = array(
|
380 |
-
|
381 |
// the API Login ID and Transaction Key must be replaced with valid values
|
382 |
"x_login" => pmpro_getOption("loginname"),
|
383 |
"x_tran_key" => pmpro_getOption("transactionkey"),
|
@@ -392,14 +392,14 @@
|
|
392 |
// Additional fields can be added here as outlined in the AIM integration
|
393 |
// guide at: http://developer.authorize.net
|
394 |
);
|
395 |
-
|
396 |
// This section takes the input fields and converts them to the proper format
|
397 |
// for an http post. For example: "x_login=username&x_tran_key=a1B2c3D4"
|
398 |
$post_string = "";
|
399 |
foreach( $post_values as $key => $value )
|
400 |
{ $post_string .= "$key=" . urlencode( str_replace("#", "%23", $value) ) . "&"; }
|
401 |
$post_string = rtrim( $post_string, "& " );
|
402 |
-
|
403 |
//curl
|
404 |
$request = curl_init($post_url); // initiate curl object
|
405 |
curl_setopt($request, CURLOPT_HEADER, 0); // set to 0 to eliminate header info from response
|
@@ -410,13 +410,13 @@
|
|
410 |
// additional options may be required depending upon your server configuration
|
411 |
// you can find documentation on curl options at http://www.php.net/curl_setopt
|
412 |
curl_close ($request); // close curl object
|
413 |
-
|
414 |
// This line takes the response and breaks it into an array using the specified delimiting character
|
415 |
$response_array = explode($post_values["x_delim_char"],$post_response);
|
416 |
if($response_array[0] == 1)
|
417 |
{
|
418 |
$order->payment_transaction_id = $response_array[4];
|
419 |
-
$order->updateStatus("voided");
|
420 |
return true;
|
421 |
}
|
422 |
else
|
@@ -426,50 +426,50 @@
|
|
426 |
$order->error = $response_array[3];
|
427 |
$order->shorterror = $response_array[3];
|
428 |
return false;
|
429 |
-
}
|
430 |
-
}
|
431 |
-
|
432 |
function charge(&$order)
|
433 |
{
|
434 |
if(empty($order->code))
|
435 |
$order->code = $order->getRandomCode();
|
436 |
-
|
437 |
if(!empty($order->gateway_environment))
|
438 |
$gateway_environment = $order->gateway_environment;
|
439 |
if(empty($gateway_environment))
|
440 |
$gateway_environment = pmpro_getOption("gateway_environment");
|
441 |
if($gateway_environment == "live")
|
442 |
-
$host = "secure.authorize.net";
|
443 |
else
|
444 |
-
$host = "test.authorize.net";
|
445 |
-
|
446 |
-
$path = "/gateway/transact.dll";
|
447 |
$post_url = "https://" . $host . $path;
|
448 |
|
449 |
$post_url = apply_filters("pmpro_authorizenet_post_url", $post_url, $gateway_environment);
|
450 |
-
|
451 |
-
//what amount to charge?
|
452 |
$amount = $order->InitialPayment;
|
453 |
-
|
454 |
//tax
|
455 |
$order->subtotal = $amount;
|
456 |
$tax = $order->getTax(true);
|
457 |
$amount = round((float)$order->subtotal + (float)$tax, 2);
|
458 |
-
|
459 |
-
//combine address
|
460 |
$address = $order->Address1;
|
461 |
if(!empty($order->Address2))
|
462 |
$address .= "\n" . $order->Address2;
|
463 |
-
|
464 |
//customer stuff
|
465 |
$customer_email = $order->Email;
|
466 |
$customer_phone = $order->billing->phone;
|
467 |
-
|
468 |
if(!isset($order->membership_level->name))
|
469 |
$order->membership_level->name = "";
|
470 |
-
|
471 |
$post_values = array(
|
472 |
-
|
473 |
// the API Login ID and Transaction Key must be replaced with valid values
|
474 |
"x_login" => pmpro_getOption("loginname"),
|
475 |
"x_tran_key" => pmpro_getOption("transactionkey"),
|
@@ -483,8 +483,8 @@
|
|
483 |
"x_method" => "CC",
|
484 |
"x_card_type" => $order->cardtype,
|
485 |
"x_card_num" => $order->accountnumber,
|
486 |
-
"x_exp_date" => $order->ExpirationDate,
|
487 |
-
|
488 |
"x_amount" => $amount,
|
489 |
"x_tax" => $tax,
|
490 |
"x_description" => $order->membership_level->name . " Membership",
|
@@ -499,21 +499,21 @@
|
|
499 |
"x_invoice_num" => $order->code,
|
500 |
"x_phone" => $customer_phone,
|
501 |
"x_email" => $order->Email
|
502 |
-
|
503 |
// Additional fields can be added here as outlined in the AIM integration
|
504 |
// guide at: http://developer.authorize.net
|
505 |
-
);
|
506 |
-
|
507 |
if(!empty($order->CVV2))
|
508 |
$post_values["x_card_code"] = $order->CVV2;
|
509 |
-
|
510 |
// This section takes the input fields and converts them to the proper format
|
511 |
// for an http post. For example: "x_login=username&x_tran_key=a1B2c3D4"
|
512 |
$post_string = "";
|
513 |
foreach( $post_values as $key => $value )
|
514 |
{ $post_string .= "$key=" . urlencode( str_replace("#", "%23", $value) ) . "&"; }
|
515 |
$post_string = rtrim( $post_string, "& " );
|
516 |
-
|
517 |
//curl
|
518 |
$request = curl_init($post_url); // initiate curl object
|
519 |
curl_setopt($request, CURLOPT_HEADER, 0); // set to 0 to eliminate header info from response
|
@@ -524,13 +524,13 @@
|
|
524 |
// additional options may be required depending upon your server configuration
|
525 |
// you can find documentation on curl options at http://www.php.net/curl_setopt
|
526 |
curl_close ($request); // close curl object
|
527 |
-
|
528 |
// This line takes the response and breaks it into an array using the specified delimiting character
|
529 |
$response_array = explode($post_values["x_delim_char"],$post_response);
|
530 |
if($response_array[0] == 1)
|
531 |
{
|
532 |
$order->payment_transaction_id = $response_array[6];
|
533 |
-
$order->updateStatus("success");
|
534 |
return true;
|
535 |
}
|
536 |
else
|
@@ -540,38 +540,38 @@
|
|
540 |
$order->error = $response_array[3];
|
541 |
$order->shorterror = $response_array[3];
|
542 |
return false;
|
543 |
-
}
|
544 |
}
|
545 |
-
|
546 |
function subscribe(&$order)
|
547 |
{
|
548 |
//define variables to send
|
549 |
|
550 |
if(empty($order->code))
|
551 |
$order->code = $order->getRandomCode();
|
552 |
-
|
553 |
//filter order before subscription. use with care.
|
554 |
$order = apply_filters("pmpro_subscribe_order", $order, $this);
|
555 |
-
|
556 |
if(!empty($order->gateway_environment))
|
557 |
$gateway_environment = $order->gateway_environment;
|
558 |
if(empty($gateway_environment))
|
559 |
$gateway_environment = pmpro_getOption("gateway_environment");
|
560 |
if($gateway_environment == "live")
|
561 |
-
$host = "api.authorize.net";
|
562 |
else
|
563 |
-
$host = "apitest.authorize.net";
|
564 |
-
|
565 |
$path = "/xml/v1/request.api";
|
566 |
-
|
567 |
$loginname = pmpro_getOption("loginname");
|
568 |
$transactionkey = pmpro_getOption("transactionkey");
|
569 |
-
|
570 |
$amount = $order->PaymentAmount;
|
571 |
$refId = $order->code;
|
572 |
$name = $order->membership_name;
|
573 |
$length = (int)$order->BillingFrequency;
|
574 |
-
|
575 |
if($order->BillingPeriod == "Month")
|
576 |
$unit = "months";
|
577 |
elseif($order->BillingPeriod == "Day")
|
@@ -588,13 +588,13 @@
|
|
588 |
}
|
589 |
else
|
590 |
return false; //authorize.net only supports months and days
|
591 |
-
|
592 |
$startDate = substr($order->ProfileStartDate, 0, 10);
|
593 |
if(!empty($order->TotalBillingCycles))
|
594 |
$totalOccurrences = (int)$order->TotalBillingCycles;
|
595 |
if(empty($totalOccurrences))
|
596 |
-
$totalOccurrences = 9999;
|
597 |
-
if(isset($order->TrialBillingCycles))
|
598 |
$trialOccurrences = (int)$order->TrialBillingCycles;
|
599 |
else
|
600 |
$trialOccurrences = 0;
|
@@ -602,26 +602,26 @@
|
|
602 |
$trialAmount = $order->TrialAmount;
|
603 |
else
|
604 |
$trialAmount = NULL;
|
605 |
-
|
606 |
//taxes
|
607 |
$amount_tax = $order->getTaxForPrice($amount);
|
608 |
$trial_tax = $order->getTaxForPrice($trialAmount);
|
609 |
-
|
610 |
$amount = round((float)$amount + (float)$amount_tax, 2);
|
611 |
$trialAmount = round((float)$trialAmount + (float)$trial_tax, 2);
|
612 |
-
|
613 |
//authorize.net doesn't support different periods between trial and actual
|
614 |
-
|
615 |
if(!empty($order->TrialBillingPeriod) && $order->TrialBillingPeriod != $order->BillingPeriod)
|
616 |
{
|
617 |
echo "F";
|
618 |
return false;
|
619 |
}
|
620 |
-
|
621 |
-
$cardNumber = $order->accountnumber;
|
622 |
-
$expirationDate = $order->ExpirationDate_YdashM;
|
623 |
$cardCode = $order->CVV2;
|
624 |
-
|
625 |
$firstName = $order->FirstName;
|
626 |
$lastName = $order->LastName;
|
627 |
|
@@ -632,20 +632,20 @@
|
|
632 |
$city = $order->billing->city;
|
633 |
$state = $order->billing->state;
|
634 |
$zip = $order->billing->zip;
|
635 |
-
$country = $order->billing->country;
|
636 |
-
|
637 |
//customer stuff
|
638 |
$customer_email = $order->Email;
|
639 |
if(strpos($order->billing->phone, "+") === false)
|
640 |
$customer_phone = $order->billing->phone;
|
641 |
else
|
642 |
$customer_phone = "";
|
643 |
-
|
644 |
//make sure the phone is in an okay format
|
645 |
$customer_phone = preg_replace("/[^0-9]/", "", $customer_phone);
|
646 |
if(strlen($customer_phone) > 10)
|
647 |
$customer_phone = "";
|
648 |
-
|
649 |
//build xml to post
|
650 |
$this->content =
|
651 |
"<?xml version=\"1.0\" encoding=\"utf-8\"?>" .
|
@@ -665,9 +665,9 @@
|
|
665 |
"<startDate>" . $startDate . "</startDate>".
|
666 |
"<totalOccurrences>". $totalOccurrences . "</totalOccurrences>";
|
667 |
if(!empty($trialOccurrences))
|
668 |
-
$this->content .=
|
669 |
"<trialOccurrences>". $trialOccurrences . "</trialOccurrences>";
|
670 |
-
$this->content .=
|
671 |
"</paymentSchedule>".
|
672 |
"<amount>". $amount ."</amount>";
|
673 |
if(!empty($trialOccurrences))
|
@@ -680,7 +680,7 @@
|
|
680 |
"<expirationDate>" . $expirationDate . "</expirationDate>";
|
681 |
if(!empty($cardCode))
|
682 |
$this->content .= "<cardCode>" . $cardCode . "</cardCode>";
|
683 |
-
$this->content .=
|
684 |
"</creditCard>".
|
685 |
"</payment>".
|
686 |
"<order><invoiceNumber>" . substr($order->code, 0, 20) . "</invoiceNumber></order>".
|
@@ -695,24 +695,24 @@
|
|
695 |
"<city><![CDATA[" . substr($city, 0, 40) . "]]></city>".
|
696 |
"<state>". substr($state, 0, 2) . "</state>".
|
697 |
"<zip>" . substr($zip, 0, 20) . "</zip>".
|
698 |
-
"<country>". substr($country, 0, 60) . "</country>".
|
699 |
"</billTo>".
|
700 |
"</subscription>".
|
701 |
"</ARBCreateSubscriptionRequest>";
|
702 |
-
|
703 |
//send the xml via curl
|
704 |
$this->response = $this->send_request_via_curl($host,$path,$this->content);
|
705 |
//if curl is unavilable you can try using fsockopen
|
706 |
/*
|
707 |
$response = send_request_via_fsockopen($host,$path,$content);
|
708 |
*/
|
709 |
-
|
710 |
-
if(!empty($this->response)) {
|
711 |
list ($refId, $resultCode, $code, $text, $subscriptionId) = $this->parse_return($this->response);
|
712 |
if($resultCode == "Ok")
|
713 |
{
|
714 |
-
$order->status = "success"; //saved on checkout page
|
715 |
-
$order->subscription_transaction_id = $subscriptionId;
|
716 |
return true;
|
717 |
}
|
718 |
else
|
@@ -720,41 +720,41 @@
|
|
720 |
$order->status = "error";
|
721 |
$order->errorcode = $code;
|
722 |
$order->error = $text;
|
723 |
-
$order->shorterror = $text;
|
724 |
return false;
|
725 |
}
|
726 |
-
} else {
|
727 |
$order->status = "error";
|
728 |
$order->error = "Could not connect to Authorize.net";
|
729 |
$order->shorterror = "Could not connect to Authorize.net";
|
730 |
-
return false;
|
731 |
}
|
732 |
-
}
|
733 |
-
|
734 |
function update(&$order)
|
735 |
{
|
736 |
-
//define variables to send
|
737 |
$gateway_environment = $order->gateway_environment;
|
738 |
if(empty($gateway_environment))
|
739 |
$gateway_environment = pmpro_getOption("gateway_environment");
|
740 |
if($gateway_environment == "live")
|
741 |
-
$host = "api.authorize.net";
|
742 |
else
|
743 |
-
$host = "apitest.authorize.net";
|
744 |
-
|
745 |
$path = "/xml/v1/request.api";
|
746 |
-
|
747 |
$loginname = pmpro_getOption("loginname");
|
748 |
$transactionkey = pmpro_getOption("transactionkey");
|
749 |
-
|
750 |
//$amount = $order->PaymentAmount;
|
751 |
$refId = $order->code;
|
752 |
-
$subscriptionId = $order->subscription_transaction_id;
|
753 |
-
|
754 |
-
$cardNumber = $order->accountnumber;
|
755 |
-
$expirationDate = $order->ExpirationDate_YdashM;
|
756 |
$cardCode = $order->CVV2;
|
757 |
-
|
758 |
$firstName = $order->FirstName;
|
759 |
$lastName = $order->LastName;
|
760 |
|
@@ -765,14 +765,14 @@
|
|
765 |
$city = $order->billing->city;
|
766 |
$state = $order->billing->state;
|
767 |
$zip = $order->billing->zip;
|
768 |
-
$country = $order->billing->country;
|
769 |
-
|
770 |
//customer stuff
|
771 |
$customer_email = $order->Email;
|
772 |
if(strpos($order->billing->phone, "+") === false)
|
773 |
$customer_phone = $order->billing->phone;
|
774 |
-
|
775 |
-
|
776 |
//build xml to post
|
777 |
$this->content =
|
778 |
"<?xml version=\"1.0\" encoding=\"utf-8\"?>" .
|
@@ -783,14 +783,14 @@
|
|
783 |
"</merchantAuthentication>".
|
784 |
"<refId>" . substr($refId, 0, 20) . "</refId>".
|
785 |
"<subscriptionId>" . $subscriptionId . "</subscriptionId>".
|
786 |
-
"<subscription>".
|
787 |
"<payment>".
|
788 |
"<creditCard>".
|
789 |
"<cardNumber>" . $cardNumber . "</cardNumber>".
|
790 |
"<expirationDate>" . $expirationDate . "</expirationDate>";
|
791 |
if(!empty($cardCode))
|
792 |
$this->content .= "<cardCode>" . $cardCode . "</cardCode>";
|
793 |
-
$this->content .=
|
794 |
"</creditCard>".
|
795 |
"</payment>".
|
796 |
"<customer>".
|
@@ -804,24 +804,24 @@
|
|
804 |
"<city><![CDATA[" . substr($city, 0, 40) . "]]></city>".
|
805 |
"<state><![CDATA[". substr($state, 0, 2) . "]]></state>".
|
806 |
"<zip>" . substr($zip, 0, 20) . "</zip>".
|
807 |
-
"<country>". substr($country, 0, 60) . "</country>".
|
808 |
"</billTo>".
|
809 |
"</subscription>".
|
810 |
"</ARBUpdateSubscriptionRequest>";
|
811 |
-
|
812 |
//send the xml via curl
|
813 |
$this->response = $this->send_request_via_curl($host,$path,$this->content);
|
814 |
//if curl is unavilable you can try using fsockopen
|
815 |
/*
|
816 |
$response = send_request_via_fsockopen($host,$path,$order->content);
|
817 |
*/
|
818 |
-
|
819 |
-
|
820 |
-
if(!empty($this->response)) {
|
821 |
-
list ($resultCode, $code, $text, $subscriptionId) = $this->parse_return($this->response);
|
822 |
-
|
823 |
if($resultCode == "Ok" || $code == "Ok")
|
824 |
-
{
|
825 |
return true;
|
826 |
}
|
827 |
else
|
@@ -832,39 +832,39 @@
|
|
832 |
$order->shorterror = $text;
|
833 |
return false;
|
834 |
}
|
835 |
-
} else {
|
836 |
$order->status = "error";
|
837 |
$order->error = "Could not connect to Authorize.net";
|
838 |
$order->shorterror = "Could not connect to Authorize.net";
|
839 |
-
return false;
|
840 |
}
|
841 |
}
|
842 |
-
|
843 |
function cancel(&$order)
|
844 |
{
|
845 |
-
//define variables to send
|
846 |
if(!empty($order->subscription_transaction_id))
|
847 |
$subscriptionId = $order->subscription_transaction_id;
|
848 |
else
|
849 |
$subscriptionId = "";
|
850 |
$loginname = pmpro_getOption("loginname");
|
851 |
$transactionkey = pmpro_getOption("transactionkey");
|
852 |
-
|
853 |
if(!empty($order->gateway_environment))
|
854 |
$gateway_environment = $order->gateway_environment;
|
855 |
else
|
856 |
-
$gateway_environment = pmpro_getOption("gateway_environment");
|
857 |
-
|
858 |
if($gateway_environment == "live")
|
859 |
-
$host = "api.authorize.net";
|
860 |
else
|
861 |
-
$host = "apitest.authorize.net";
|
862 |
-
|
863 |
$path = "/xml/v1/request.api";
|
864 |
-
|
865 |
if(!$subscriptionId || !$loginname || !$transactionkey)
|
866 |
return false;
|
867 |
-
|
868 |
//build xml to post
|
869 |
$content =
|
870 |
"<?xml version=\"1.0\" encoding=\"utf-8\"?>".
|
@@ -875,22 +875,22 @@
|
|
875 |
"</merchantAuthentication>" .
|
876 |
"<subscriptionId>" . $subscriptionId . "</subscriptionId>".
|
877 |
"</ARBCancelSubscriptionRequest>";
|
878 |
-
|
879 |
//send the xml via curl
|
880 |
$response = $this->send_request_via_curl($host,$path,$content);
|
881 |
//if curl is unavilable you can try using fsockopen
|
882 |
/*
|
883 |
$response = send_request_via_fsockopen($host,$path,$content);
|
884 |
*/
|
885 |
-
|
886 |
//if the connection and send worked $response holds the return from Authorize.net
|
887 |
if ($response)
|
888 |
-
{
|
889 |
-
list ($resultCode, $code, $text, $subscriptionId) = $this->parse_return($response);
|
890 |
-
|
891 |
if($resultCode == "Ok" || $code == "Ok")
|
892 |
{
|
893 |
-
$order->updateStatus("cancelled");
|
894 |
return true;
|
895 |
}
|
896 |
else
|
@@ -901,41 +901,41 @@
|
|
901 |
$order->shorterror = $text;
|
902 |
return false;
|
903 |
}
|
904 |
-
}
|
905 |
-
else
|
906 |
-
{
|
907 |
$order->status = "error";
|
908 |
$order->error = __("Could not connect to Authorize.net", "pmpro");
|
909 |
$order->shorterror = __("Could not connect to Authorize.net", "pmpro");
|
910 |
-
return false;
|
911 |
}
|
912 |
-
}
|
913 |
-
|
914 |
function getSubscriptionStatus(&$order)
|
915 |
-
{
|
916 |
-
//define variables to send
|
917 |
if(!empty($order->subscription_transaction_id))
|
918 |
$subscriptionId = $order->subscription_transaction_id;
|
919 |
else
|
920 |
$subscriptionId = "";
|
921 |
$loginname = pmpro_getOption("loginname");
|
922 |
$transactionkey = pmpro_getOption("transactionkey");
|
923 |
-
|
924 |
if(!empty($order->gateway_environment))
|
925 |
$gateway_environment = $order->gateway_environment;
|
926 |
else
|
927 |
-
$gateway_environment = pmpro_getOption("gateway_environment");
|
928 |
-
|
929 |
if($gateway_environment == "live")
|
930 |
-
$host = "api.authorize.net";
|
931 |
else
|
932 |
-
$host = "apitest.authorize.net";
|
933 |
-
|
934 |
$path = "/xml/v1/request.api";
|
935 |
-
|
936 |
if(!$subscriptionId || !$loginname || !$transactionkey)
|
937 |
return false;
|
938 |
-
|
939 |
//build xml to post
|
940 |
$content =
|
941 |
"<?xml version=\"1.0\" encoding=\"utf-8\"?>".
|
@@ -946,43 +946,43 @@
|
|
946 |
"</merchantAuthentication>" .
|
947 |
"<subscriptionId>" . $subscriptionId . "</subscriptionId>".
|
948 |
"</ARBGetSubscriptionStatusRequest>";
|
949 |
-
|
950 |
//send the xml via curl
|
951 |
$response = $this->send_request_via_curl($host,$path,$content);
|
952 |
-
|
953 |
//if curl is unavilable you can try using fsockopen
|
954 |
/*
|
955 |
$response = send_request_via_fsockopen($host,$path,$content);
|
956 |
*/
|
957 |
-
|
958 |
//if the connection and send worked $response holds the return from Authorize.net
|
959 |
if($response)
|
960 |
-
{
|
961 |
-
list ($resultCode, $code, $text, $subscriptionId) = $this->parse_return($response);
|
962 |
-
|
963 |
$status = $this->substring_between($response,'<status>','</status>');
|
964 |
-
|
965 |
if($resultCode == "Ok" || $code == "Ok")
|
966 |
{
|
967 |
return $status;
|
968 |
}
|
969 |
else
|
970 |
-
{
|
971 |
$order->status = "error";
|
972 |
$order->errorcode = $resultCode;
|
973 |
$order->error = $message;
|
974 |
$order->shorterror = $text;
|
975 |
}
|
976 |
-
}
|
977 |
-
else
|
978 |
-
{
|
979 |
$order->status = "error";
|
980 |
$order->errorcode = $resultCode;
|
981 |
$order->error = $message;
|
982 |
$order->shorterror = $text;
|
983 |
}
|
984 |
-
}
|
985 |
-
|
986 |
//Authorize.net Function
|
987 |
//function to send xml request via fsockopen
|
988 |
function send_request_via_fsockopen($host,$path,$content)
|
@@ -1048,13 +1048,13 @@
|
|
1048 |
|
1049 |
//Authorize.net Function
|
1050 |
//helper function for parsing response
|
1051 |
-
function substring_between($haystack,$start,$end)
|
1052 |
{
|
1053 |
-
if (strpos($haystack,$start) === false || strpos($haystack,$end) === false)
|
1054 |
{
|
1055 |
return false;
|
1056 |
-
}
|
1057 |
-
else
|
1058 |
{
|
1059 |
$start_position = strpos($haystack,$start)+strlen($start);
|
1060 |
$end_position = strpos($haystack,$end);
|
1 |
<?php
|
2 |
//include pmprogateway
|
3 |
require_once(dirname(__FILE__) . "/class.pmprogateway.php");
|
4 |
+
|
5 |
//load classes init method
|
6 |
add_action('init', array('PMProGateway_authorizenet', 'init'));
|
7 |
+
|
8 |
class PMProGateway_authorizenet extends PMProGateway
|
9 |
{
|
10 |
function PMProGateway_authorizenet($gateway = NULL)
|
11 |
{
|
12 |
$this->gateway = $gateway;
|
13 |
return $this->gateway;
|
14 |
+
}
|
15 |
+
|
16 |
/**
|
17 |
* Run on WP init
|
18 |
+
*
|
19 |
* @since 1.8
|
20 |
*/
|
21 |
static function init()
|
22 |
+
{
|
23 |
//make sure Authorize.net is a gateway option
|
24 |
add_filter('pmpro_gateways', array('PMProGateway_authorizenet', 'pmpro_gateways'));
|
25 |
+
|
26 |
//add fields to payment settings
|
27 |
add_filter('pmpro_payment_options', array('PMProGateway_authorizenet', 'pmpro_payment_options'));
|
28 |
+
add_filter('pmpro_payment_option_fields', array('PMProGateway_authorizenet', 'pmpro_payment_option_fields'), 10, 2);
|
29 |
}
|
30 |
+
|
31 |
/**
|
32 |
* Make sure this gateway is in the gateways list
|
33 |
+
*
|
34 |
* @since 1.8
|
35 |
*/
|
36 |
static function pmpro_gateways($gateways)
|
37 |
{
|
38 |
if(empty($gateways['authorizenet']))
|
39 |
$gateways['authorizenet'] = __('Authorize.net', 'pmpro');
|
40 |
+
|
41 |
return $gateways;
|
42 |
}
|
43 |
+
|
44 |
/**
|
45 |
* Get a list of payment options that the this gateway needs/supports.
|
46 |
+
*
|
47 |
* @since 1.8
|
48 |
*/
|
49 |
static function getGatewayOptions()
|
50 |
+
{
|
51 |
$options = array(
|
52 |
'sslseal',
|
53 |
'nuclear_HTTPS',
|
60 |
'tax_rate',
|
61 |
'accepted_credit_cards'
|
62 |
);
|
63 |
+
|
64 |
return $options;
|
65 |
}
|
66 |
+
|
67 |
/**
|
68 |
* Set payment options for payment settings page.
|
69 |
+
*
|
70 |
* @since 1.8
|
71 |
*/
|
72 |
static function pmpro_payment_options($options)
|
73 |
+
{
|
74 |
//get stripe options
|
75 |
$authorizenet_options = PMProGateway_authorizenet::getGatewayOptions();
|
76 |
+
|
77 |
//merge with others.
|
78 |
$options = array_merge($authorizenet_options, $options);
|
79 |
+
|
80 |
return $options;
|
81 |
}
|
82 |
+
|
83 |
/**
|
84 |
* Display fields for this gateway's options.
|
85 |
+
*
|
86 |
* @since 1.8
|
87 |
*/
|
88 |
static function pmpro_payment_option_fields($values, $gateway)
|
119 |
</tr>
|
120 |
<?php
|
121 |
}
|
122 |
+
|
123 |
/**
|
124 |
* Process checkout.
|
125 |
+
*
|
126 |
*/
|
127 |
function process(&$order)
|
128 |
{
|
131 |
{
|
132 |
//auth first, then process
|
133 |
if($this->authorize($order))
|
134 |
+
{
|
135 |
+
$this->void($order);
|
136 |
if(!pmpro_isLevelTrial($order->membership_level))
|
137 |
{
|
138 |
//subscription will start today with a 1 period trial
|
139 |
$order->ProfileStartDate = date("Y-m-d") . "T0:0:0";
|
140 |
$order->TrialBillingPeriod = $order->BillingPeriod;
|
141 |
+
$order->TrialBillingFrequency = $order->BillingFrequency;
|
142 |
$order->TrialBillingCycles = 1;
|
143 |
$order->TrialAmount = 0;
|
144 |
+
|
145 |
//add a billing cycle to make up for the trial, if applicable
|
146 |
if(!empty($order->TotalBillingCycles))
|
147 |
$order->TotalBillingCycles++;
|
149 |
elseif($order->InitialPayment == 0 && $order->TrialAmount == 0)
|
150 |
{
|
151 |
//it has a trial, but the amount is the same as the initial payment, so we can squeeze it in there
|
152 |
+
$order->ProfileStartDate = date("Y-m-d") . "T0:0:0";
|
153 |
$order->TrialBillingCycles++;
|
154 |
+
|
155 |
//add a billing cycle to make up for the trial, if applicable
|
156 |
if(!empty($order->TotalBillingCycles))
|
157 |
$order->TotalBillingCycles++;
|
161 |
//add a period to the start date to account for the initial payment
|
162 |
$order->ProfileStartDate = date("Y-m-d", strtotime("+ " . $order->BillingFrequency . " " . $order->BillingPeriod, current_time("timestamp"))) . "T0:0:0";
|
163 |
}
|
164 |
+
|
165 |
$order->ProfileStartDate = apply_filters("pmpro_profile_start_date", $order->ProfileStartDate, $order);
|
166 |
return $this->subscribe($order);
|
167 |
}
|
168 |
else
|
169 |
+
{
|
170 |
if(empty($order->error))
|
171 |
$order->error = __("Unknown error: Authorization failed.", "pmpro");
|
172 |
return false;
|
176 |
{
|
177 |
//charge first payment
|
178 |
if($this->charge($order))
|
179 |
+
{
|
180 |
//setup recurring billing
|
181 |
if(pmpro_isLevelRecurring($order->membership_level))
|
182 |
+
{
|
183 |
if(!pmpro_isLevelTrial($order->membership_level))
|
184 |
{
|
185 |
//subscription will start today with a 1 period trial
|
186 |
$order->ProfileStartDate = date("Y-m-d") . "T0:0:0";
|
187 |
$order->TrialBillingPeriod = $order->BillingPeriod;
|
188 |
+
$order->TrialBillingFrequency = $order->BillingFrequency;
|
189 |
$order->TrialBillingCycles = 1;
|
190 |
$order->TrialAmount = 0;
|
191 |
+
|
192 |
//add a billing cycle to make up for the trial, if applicable
|
193 |
if(!empty($order->TotalBillingCycles))
|
194 |
$order->TotalBillingCycles++;
|
196 |
elseif($order->InitialPayment == 0 && $order->TrialAmount == 0)
|
197 |
{
|
198 |
//it has a trial, but the amount is the same as the initial payment, so we can squeeze it in there
|
199 |
+
$order->ProfileStartDate = date("Y-m-d") . "T0:0:0";
|
200 |
$order->TrialBillingCycles++;
|
201 |
+
|
202 |
//add a billing cycle to make up for the trial, if applicable
|
203 |
if(!empty($order->TotalBillingCycles))
|
204 |
$order->TotalBillingCycles++;
|
208 |
//add a period to the start date to account for the initial payment
|
209 |
$order->ProfileStartDate = date("Y-m-d", strtotime("+ " . $order->BillingFrequency . " " . $order->BillingPeriod, current_time("timestamp"))) . "T0:0:0";
|
210 |
}
|
211 |
+
|
212 |
$order->ProfileStartDate = apply_filters("pmpro_profile_start_date", $order->ProfileStartDate, $order);
|
213 |
if($this->subscribe($order))
|
214 |
{
|
224 |
else
|
225 |
{
|
226 |
if(!$order->error)
|
227 |
+
$order->error = __("Unknown error: Payment failed.", "pmpro");
|
228 |
$order->error .= " " . __("A partial payment was made that we could not void. Please contact the site owner immediately to correct this.", "pmpro");
|
229 |
}
|
230 |
+
|
231 |
+
return false;
|
232 |
}
|
233 |
}
|
234 |
else
|
235 |
{
|
236 |
//only a one time charge
|
237 |
+
$order->status = "success"; //saved on checkout page
|
238 |
return true;
|
239 |
}
|
240 |
}
|
241 |
else
|
242 |
+
{
|
243 |
if(empty($order->error))
|
244 |
$order->error = __("Unknown error: Payment failed.", "pmpro");
|
245 |
+
|
246 |
return false;
|
247 |
+
}
|
248 |
+
}
|
249 |
}
|
250 |
+
|
251 |
function authorize(&$order)
|
252 |
{
|
253 |
if(empty($order->code))
|
254 |
$order->code = $order->getRandomCode();
|
255 |
+
|
256 |
if(empty($order->gateway_environment))
|
257 |
$gateway_environment = pmpro_getOption("gateway_environment");
|
258 |
else
|
259 |
$gateway_environment = $order->gateway_environment;
|
260 |
if($gateway_environment == "live")
|
261 |
+
$host = "secure.authorize.net";
|
262 |
else
|
263 |
+
$host = "test.authorize.net";
|
264 |
+
|
265 |
+
$path = "/gateway/transact.dll";
|
266 |
$post_url = "https://" . $host . $path;
|
267 |
|
268 |
$post_url = apply_filters("pmpro_authorizenet_post_url", $post_url, $gateway_environment);
|
269 |
+
|
270 |
//what amount to authorize? just $1 to test
|
271 |
+
$amount = "1.00";
|
272 |
+
|
273 |
+
//combine address
|
274 |
$address = $order->Address1;
|
275 |
if(!empty($order->Address2))
|
276 |
$address .= "\n" . $order->Address2;
|
277 |
+
|
278 |
//customer stuff
|
279 |
$customer_email = $order->Email;
|
280 |
$customer_phone = $order->billing->phone;
|
281 |
+
|
282 |
if(!isset($order->membership_level->name))
|
283 |
$order->membership_level->name = "";
|
284 |
+
|
285 |
$post_values = array(
|
286 |
+
|
287 |
// the API Login ID and Transaction Key must be replaced with valid values
|
288 |
"x_login" => pmpro_getOption("loginname"),
|
289 |
"x_tran_key" => pmpro_getOption("transactionkey"),
|
298 |
"x_card_type" => $order->cardtype,
|
299 |
"x_card_num" => $order->accountnumber,
|
300 |
"x_exp_date" => $order->ExpirationDate,
|
301 |
+
|
302 |
"x_amount" => $amount,
|
303 |
"x_description" => $order->membership_level->name . " " . __("Membership", "pmpro"),
|
304 |
|
315 |
// Additional fields can be added here as outlined in the AIM integration
|
316 |
// guide at: http://developer.authorize.net
|
317 |
);
|
318 |
+
|
319 |
if(!empty($order->CVV2))
|
320 |
$post_values["x_card_code"] = $order->CVV2;
|
321 |
+
|
322 |
// This section takes the input fields and converts them to the proper format
|
323 |
// for an http post. For example: "x_login=username&x_tran_key=a1B2c3D4"
|
324 |
$post_string = "";
|
325 |
foreach( $post_values as $key => $value )
|
326 |
{ $post_string .= "$key=" . urlencode( str_replace("#", "%23", $value) ) . "&"; }
|
327 |
$post_string = rtrim( $post_string, "& " );
|
328 |
+
|
329 |
//curl
|
330 |
$request = curl_init($post_url); // initiate curl object
|
331 |
curl_setopt($request, CURLOPT_HEADER, 0); // set to 0 to eliminate header info from response
|
336 |
// additional options may be required depending upon your server configuration
|
337 |
// you can find documentation on curl options at http://www.php.net/curl_setopt
|
338 |
curl_close ($request); // close curl object
|
339 |
+
|
340 |
// This line takes the response and breaks it into an array using the specified delimiting character
|
341 |
$response_array = explode($post_values["x_delim_char"],$post_response);
|
342 |
+
|
343 |
if($response_array[0] == 1)
|
344 |
{
|
345 |
$order->payment_transaction_id = $response_array[6];
|
346 |
+
$order->updateStatus("authorized");
|
347 |
+
|
348 |
return true;
|
349 |
}
|
350 |
else
|
354 |
$order->error = $response_array[3];
|
355 |
$order->shorterror = $response_array[3];
|
356 |
return false;
|
357 |
+
}
|
358 |
}
|
359 |
+
|
360 |
function void(&$order)
|
361 |
{
|
362 |
if(empty($order->payment_transaction_id))
|
363 |
return false;
|
364 |
+
|
365 |
if(empty($order->gateway_environment))
|
366 |
$gateway_environment = pmpro_getOption("gateway_environment");
|
367 |
else
|
368 |
$gateway_environment = $order->gateway_environment;
|
369 |
if($gateway_environment == "live")
|
370 |
+
$host = "secure.authorize.net";
|
371 |
else
|
372 |
+
$host = "test.authorize.net";
|
373 |
+
|
374 |
+
$path = "/gateway/transact.dll";
|
375 |
$post_url = "https://" . $host . $path;
|
376 |
+
|
377 |
$post_url = apply_filters("pmpro_authorizenet_post_url", $post_url, $gateway_environment);
|
378 |
+
|
379 |
$post_values = array(
|
380 |
+
|
381 |
// the API Login ID and Transaction Key must be replaced with valid values
|
382 |
"x_login" => pmpro_getOption("loginname"),
|
383 |
"x_tran_key" => pmpro_getOption("transactionkey"),
|
392 |
// Additional fields can be added here as outlined in the AIM integration
|
393 |
// guide at: http://developer.authorize.net
|
394 |
);
|
395 |
+
|
396 |
// This section takes the input fields and converts them to the proper format
|
397 |
// for an http post. For example: "x_login=username&x_tran_key=a1B2c3D4"
|
398 |
$post_string = "";
|
399 |
foreach( $post_values as $key => $value )
|
400 |
{ $post_string .= "$key=" . urlencode( str_replace("#", "%23", $value) ) . "&"; }
|
401 |
$post_string = rtrim( $post_string, "& " );
|
402 |
+
|
403 |
//curl
|
404 |
$request = curl_init($post_url); // initiate curl object
|
405 |
curl_setopt($request, CURLOPT_HEADER, 0); // set to 0 to eliminate header info from response
|
410 |
// additional options may be required depending upon your server configuration
|
411 |
// you can find documentation on curl options at http://www.php.net/curl_setopt
|
412 |
curl_close ($request); // close curl object
|
413 |
+
|
414 |
// This line takes the response and breaks it into an array using the specified delimiting character
|
415 |
$response_array = explode($post_values["x_delim_char"],$post_response);
|
416 |
if($response_array[0] == 1)
|
417 |
{
|
418 |
$order->payment_transaction_id = $response_array[4];
|
419 |
+
$order->updateStatus("voided");
|
420 |
return true;
|
421 |
}
|
422 |
else
|
426 |
$order->error = $response_array[3];
|
427 |
$order->shorterror = $response_array[3];
|
428 |
return false;
|
429 |
+
}
|
430 |
+
}
|
431 |
+
|
432 |
function charge(&$order)
|
433 |
{
|
434 |
if(empty($order->code))
|
435 |
$order->code = $order->getRandomCode();
|
436 |
+
|
437 |
if(!empty($order->gateway_environment))
|
438 |
$gateway_environment = $order->gateway_environment;
|
439 |
if(empty($gateway_environment))
|
440 |
$gateway_environment = pmpro_getOption("gateway_environment");
|
441 |
if($gateway_environment == "live")
|
442 |
+
$host = "secure.authorize.net";
|
443 |
else
|
444 |
+
$host = "test.authorize.net";
|
445 |
+
|
446 |
+
$path = "/gateway/transact.dll";
|
447 |
$post_url = "https://" . $host . $path;
|
448 |
|
449 |
$post_url = apply_filters("pmpro_authorizenet_post_url", $post_url, $gateway_environment);
|
450 |
+
|
451 |
+
//what amount to charge?
|
452 |
$amount = $order->InitialPayment;
|
453 |
+
|
454 |
//tax
|
455 |
$order->subtotal = $amount;
|
456 |
$tax = $order->getTax(true);
|
457 |
$amount = round((float)$order->subtotal + (float)$tax, 2);
|
458 |
+
|
459 |
+
//combine address
|
460 |
$address = $order->Address1;
|
461 |
if(!empty($order->Address2))
|
462 |
$address .= "\n" . $order->Address2;
|
463 |
+
|
464 |
//customer stuff
|
465 |
$customer_email = $order->Email;
|
466 |
$customer_phone = $order->billing->phone;
|
467 |
+
|
468 |
if(!isset($order->membership_level->name))
|
469 |
$order->membership_level->name = "";
|
470 |
+
|
471 |
$post_values = array(
|
472 |
+
|
473 |
// the API Login ID and Transaction Key must be replaced with valid values
|
474 |
"x_login" => pmpro_getOption("loginname"),
|
475 |
"x_tran_key" => pmpro_getOption("transactionkey"),
|
483 |
"x_method" => "CC",
|
484 |
"x_card_type" => $order->cardtype,
|
485 |
"x_card_num" => $order->accountnumber,
|
486 |
+
"x_exp_date" => $order->ExpirationDate,
|
487 |
+
|
488 |
"x_amount" => $amount,
|
489 |
"x_tax" => $tax,
|
490 |
"x_description" => $order->membership_level->name . " Membership",
|
499 |
"x_invoice_num" => $order->code,
|
500 |
"x_phone" => $customer_phone,
|
501 |
"x_email" => $order->Email
|
502 |
+
|
503 |
// Additional fields can be added here as outlined in the AIM integration
|
504 |
// guide at: http://developer.authorize.net
|
505 |
+
);
|
506 |
+
|
507 |
if(!empty($order->CVV2))
|
508 |
$post_values["x_card_code"] = $order->CVV2;
|
509 |
+
|
510 |
// This section takes the input fields and converts them to the proper format
|
511 |
// for an http post. For example: "x_login=username&x_tran_key=a1B2c3D4"
|
512 |
$post_string = "";
|
513 |
foreach( $post_values as $key => $value )
|
514 |
{ $post_string .= "$key=" . urlencode( str_replace("#", "%23", $value) ) . "&"; }
|
515 |
$post_string = rtrim( $post_string, "& " );
|
516 |
+
|
517 |
//curl
|
518 |
$request = curl_init($post_url); // initiate curl object
|
519 |
curl_setopt($request, CURLOPT_HEADER, 0); // set to 0 to eliminate header info from response
|
524 |
// additional options may be required depending upon your server configuration
|
525 |
// you can find documentation on curl options at http://www.php.net/curl_setopt
|
526 |
curl_close ($request); // close curl object
|
527 |
+
|
528 |
// This line takes the response and breaks it into an array using the specified delimiting character
|
529 |
$response_array = explode($post_values["x_delim_char"],$post_response);
|
530 |
if($response_array[0] == 1)
|
531 |
{
|
532 |
$order->payment_transaction_id = $response_array[6];
|
533 |
+
$order->updateStatus("success");
|
534 |
return true;
|
535 |
}
|
536 |
else
|
540 |
$order->error = $response_array[3];
|
541 |
$order->shorterror = $response_array[3];
|
542 |
return false;
|
543 |
+
}
|
544 |
}
|
545 |
+
|
546 |
function subscribe(&$order)
|
547 |
{
|
548 |
//define variables to send
|
549 |
|
550 |
if(empty($order->code))
|
551 |
$order->code = $order->getRandomCode();
|
552 |
+
|
553 |
//filter order before subscription. use with care.
|
554 |
$order = apply_filters("pmpro_subscribe_order", $order, $this);
|
555 |
+
|
556 |
if(!empty($order->gateway_environment))
|
557 |
$gateway_environment = $order->gateway_environment;
|
558 |
if(empty($gateway_environment))
|
559 |
$gateway_environment = pmpro_getOption("gateway_environment");
|
560 |
if($gateway_environment == "live")
|
561 |
+
$host = "api.authorize.net";
|
562 |
else
|
563 |
+
$host = "apitest.authorize.net";
|
564 |
+
|
565 |
$path = "/xml/v1/request.api";
|
566 |
+
|
567 |
$loginname = pmpro_getOption("loginname");
|
568 |
$transactionkey = pmpro_getOption("transactionkey");
|
569 |
+
|
570 |
$amount = $order->PaymentAmount;
|
571 |
$refId = $order->code;
|
572 |
$name = $order->membership_name;
|
573 |
$length = (int)$order->BillingFrequency;
|
574 |
+
|
575 |
if($order->BillingPeriod == "Month")
|
576 |
$unit = "months";
|
577 |
elseif($order->BillingPeriod == "Day")
|
588 |
}
|
589 |
else
|
590 |
return false; //authorize.net only supports months and days
|
591 |
+
|
592 |
$startDate = substr($order->ProfileStartDate, 0, 10);
|
593 |
if(!empty($order->TotalBillingCycles))
|
594 |
$totalOccurrences = (int)$order->TotalBillingCycles;
|
595 |
if(empty($totalOccurrences))
|
596 |
+
$totalOccurrences = 9999;
|
597 |
+
if(isset($order->TrialBillingCycles))
|
598 |
$trialOccurrences = (int)$order->TrialBillingCycles;
|
599 |
else
|
600 |
$trialOccurrences = 0;
|
602 |
$trialAmount = $order->TrialAmount;
|
603 |
else
|
604 |
$trialAmount = NULL;
|
605 |
+
|
606 |
//taxes
|
607 |
$amount_tax = $order->getTaxForPrice($amount);
|
608 |
$trial_tax = $order->getTaxForPrice($trialAmount);
|
609 |
+
|
610 |
$amount = round((float)$amount + (float)$amount_tax, 2);
|
611 |
$trialAmount = round((float)$trialAmount + (float)$trial_tax, 2);
|
612 |
+
|
613 |
//authorize.net doesn't support different periods between trial and actual
|
614 |
+
|
615 |
if(!empty($order->TrialBillingPeriod) && $order->TrialBillingPeriod != $order->BillingPeriod)
|
616 |
{
|
617 |
echo "F";
|
618 |
return false;
|
619 |
}
|
620 |
+
|
621 |
+
$cardNumber = $order->accountnumber;
|
622 |
+
$expirationDate = $order->ExpirationDate_YdashM;
|
623 |
$cardCode = $order->CVV2;
|
624 |
+
|
625 |
$firstName = $order->FirstName;
|
626 |
$lastName = $order->LastName;
|
627 |
|
632 |
$city = $order->billing->city;
|
633 |
$state = $order->billing->state;
|
634 |
$zip = $order->billing->zip;
|
635 |
+
$country = $order->billing->country;
|
636 |
+
|
637 |
//customer stuff
|
638 |
$customer_email = $order->Email;
|
639 |
if(strpos($order->billing->phone, "+") === false)
|
640 |
$customer_phone = $order->billing->phone;
|
641 |
else
|
642 |
$customer_phone = "";
|
643 |
+
|
644 |
//make sure the phone is in an okay format
|
645 |
$customer_phone = preg_replace("/[^0-9]/", "", $customer_phone);
|
646 |
if(strlen($customer_phone) > 10)
|
647 |
$customer_phone = "";
|
648 |
+
|
649 |
//build xml to post
|
650 |
$this->content =
|
651 |
"<?xml version=\"1.0\" encoding=\"utf-8\"?>" .
|
665 |
"<startDate>" . $startDate . "</startDate>".
|
666 |
"<totalOccurrences>". $totalOccurrences . "</totalOccurrences>";
|
667 |
if(!empty($trialOccurrences))
|
668 |
+
$this->content .=
|
669 |
"<trialOccurrences>". $trialOccurrences . "</trialOccurrences>";
|
670 |
+
$this->content .=
|
671 |
"</paymentSchedule>".
|
672 |
"<amount>". $amount ."</amount>";
|
673 |
if(!empty($trialOccurrences))
|
680 |
"<expirationDate>" . $expirationDate . "</expirationDate>";
|
681 |
if(!empty($cardCode))
|
682 |
$this->content .= "<cardCode>" . $cardCode . "</cardCode>";
|
683 |
+
$this->content .=
|
684 |
"</creditCard>".
|
685 |
"</payment>".
|
686 |
"<order><invoiceNumber>" . substr($order->code, 0, 20) . "</invoiceNumber></order>".
|
695 |
"<city><![CDATA[" . substr($city, 0, 40) . "]]></city>".
|
696 |
"<state>". substr($state, 0, 2) . "</state>".
|
697 |
"<zip>" . substr($zip, 0, 20) . "</zip>".
|
698 |
+
"<country>". substr($country, 0, 60) . "</country>".
|
699 |
"</billTo>".
|
700 |
"</subscription>".
|
701 |
"</ARBCreateSubscriptionRequest>";
|
702 |
+
|
703 |
//send the xml via curl
|
704 |
$this->response = $this->send_request_via_curl($host,$path,$this->content);
|
705 |
//if curl is unavilable you can try using fsockopen
|
706 |
/*
|
707 |
$response = send_request_via_fsockopen($host,$path,$content);
|
708 |
*/
|
709 |
+
|
710 |
+
if(!empty($this->response)) {
|
711 |
list ($refId, $resultCode, $code, $text, $subscriptionId) = $this->parse_return($this->response);
|
712 |
if($resultCode == "Ok")
|
713 |
{
|
714 |
+
$order->status = "success"; //saved on checkout page
|
715 |
+
$order->subscription_transaction_id = $subscriptionId;
|
716 |
return true;
|
717 |
}
|
718 |
else
|
720 |
$order->status = "error";
|
721 |
$order->errorcode = $code;
|
722 |
$order->error = $text;
|
723 |
+
$order->shorterror = $text;
|
724 |
return false;
|
725 |
}
|
726 |
+
} else {
|
727 |
$order->status = "error";
|
728 |
$order->error = "Could not connect to Authorize.net";
|
729 |
$order->shorterror = "Could not connect to Authorize.net";
|
730 |
+
return false;
|
731 |
}
|
732 |
+
}
|
733 |
+
|
734 |
function update(&$order)
|
735 |
{
|
736 |
+
//define variables to send
|
737 |
$gateway_environment = $order->gateway_environment;
|
738 |
if(empty($gateway_environment))
|
739 |
$gateway_environment = pmpro_getOption("gateway_environment");
|
740 |
if($gateway_environment == "live")
|
741 |
+
$host = "api.authorize.net";
|
742 |
else
|
743 |
+
$host = "apitest.authorize.net";
|
744 |
+
|
745 |
$path = "/xml/v1/request.api";
|
746 |
+
|
747 |
$loginname = pmpro_getOption("loginname");
|
748 |
$transactionkey = pmpro_getOption("transactionkey");
|
749 |
+
|
750 |
//$amount = $order->PaymentAmount;
|
751 |
$refId = $order->code;
|
752 |
+
$subscriptionId = $order->subscription_transaction_id;
|
753 |
+
|
754 |
+
$cardNumber = $order->accountnumber;
|
755 |
+
$expirationDate = $order->ExpirationDate_YdashM;
|
756 |
$cardCode = $order->CVV2;
|
757 |
+
|
758 |
$firstName = $order->FirstName;
|
759 |
$lastName = $order->LastName;
|
760 |
|
765 |
$city = $order->billing->city;
|
766 |
$state = $order->billing->state;
|
767 |
$zip = $order->billing->zip;
|
768 |
+
$country = $order->billing->country;
|
769 |
+
|
770 |
//customer stuff
|
771 |
$customer_email = $order->Email;
|
772 |
if(strpos($order->billing->phone, "+") === false)
|
773 |
$customer_phone = $order->billing->phone;
|
774 |
+
|
775 |
+
|
776 |
//build xml to post
|
777 |
$this->content =
|
778 |
"<?xml version=\"1.0\" encoding=\"utf-8\"?>" .
|
783 |
"</merchantAuthentication>".
|
784 |
"<refId>" . substr($refId, 0, 20) . "</refId>".
|
785 |
"<subscriptionId>" . $subscriptionId . "</subscriptionId>".
|
786 |
+
"<subscription>".
|
787 |
"<payment>".
|
788 |
"<creditCard>".
|
789 |
"<cardNumber>" . $cardNumber . "</cardNumber>".
|
790 |
"<expirationDate>" . $expirationDate . "</expirationDate>";
|
791 |
if(!empty($cardCode))
|
792 |
$this->content .= "<cardCode>" . $cardCode . "</cardCode>";
|
793 |
+
$this->content .=
|
794 |
"</creditCard>".
|
795 |
"</payment>".
|
796 |
"<customer>".
|
804 |
"<city><![CDATA[" . substr($city, 0, 40) . "]]></city>".
|
805 |
"<state><![CDATA[". substr($state, 0, 2) . "]]></state>".
|
806 |
"<zip>" . substr($zip, 0, 20) . "</zip>".
|
807 |
+
"<country>". substr($country, 0, 60) . "</country>".
|
808 |
"</billTo>".
|
809 |
"</subscription>".
|
810 |
"</ARBUpdateSubscriptionRequest>";
|
811 |
+
|
812 |
//send the xml via curl
|
813 |
$this->response = $this->send_request_via_curl($host,$path,$this->content);
|
814 |
//if curl is unavilable you can try using fsockopen
|
815 |
/*
|
816 |
$response = send_request_via_fsockopen($host,$path,$order->content);
|
817 |
*/
|
818 |
+
|
819 |
+
|
820 |
+
if(!empty($this->response)) {
|
821 |
+
list ($resultCode, $code, $text, $subscriptionId) = $this->parse_return($this->response);
|
822 |
+
|
823 |
if($resultCode == "Ok" || $code == "Ok")
|
824 |
+
{
|
825 |
return true;
|
826 |
}
|
827 |
else
|
832 |
$order->shorterror = $text;
|
833 |
return false;
|
834 |
}
|
835 |
+
} else {
|
836 |
$order->status = "error";
|
837 |
$order->error = "Could not connect to Authorize.net";
|
838 |
$order->shorterror = "Could not connect to Authorize.net";
|
839 |
+
return false;
|
840 |
}
|
841 |
}
|
842 |
+
|
843 |
function cancel(&$order)
|
844 |
{
|
845 |
+
//define variables to send
|
846 |
if(!empty($order->subscription_transaction_id))
|
847 |
$subscriptionId = $order->subscription_transaction_id;
|
848 |
else
|
849 |
$subscriptionId = "";
|
850 |
$loginname = pmpro_getOption("loginname");
|
851 |
$transactionkey = pmpro_getOption("transactionkey");
|
852 |
+
|
853 |
if(!empty($order->gateway_environment))
|
854 |
$gateway_environment = $order->gateway_environment;
|
855 |
else
|
856 |
+
$gateway_environment = pmpro_getOption("gateway_environment");
|
857 |
+
|
858 |
if($gateway_environment == "live")
|
859 |
+
$host = "api.authorize.net";
|
860 |
else
|
861 |
+
$host = "apitest.authorize.net";
|
862 |
+
|
863 |
$path = "/xml/v1/request.api";
|
864 |
+
|
865 |
if(!$subscriptionId || !$loginname || !$transactionkey)
|
866 |
return false;
|
867 |
+
|
868 |
//build xml to post
|
869 |
$content =
|
870 |
"<?xml version=\"1.0\" encoding=\"utf-8\"?>".
|
875 |
"</merchantAuthentication>" .
|
876 |
"<subscriptionId>" . $subscriptionId . "</subscriptionId>".
|
877 |
"</ARBCancelSubscriptionRequest>";
|
878 |
+
|
879 |
//send the xml via curl
|
880 |
$response = $this->send_request_via_curl($host,$path,$content);
|
881 |
//if curl is unavilable you can try using fsockopen
|
882 |
/*
|
883 |
$response = send_request_via_fsockopen($host,$path,$content);
|
884 |
*/
|
885 |
+
|
886 |
//if the connection and send worked $response holds the return from Authorize.net
|
887 |
if ($response)
|
888 |
+
{
|
889 |
+
list ($resultCode, $code, $text, $subscriptionId) = $this->parse_return($response);
|
890 |
+
|
891 |
if($resultCode == "Ok" || $code == "Ok")
|
892 |
{
|
893 |
+
$order->updateStatus("cancelled");
|
894 |
return true;
|
895 |
}
|
896 |
else
|
901 |
$order->shorterror = $text;
|
902 |
return false;
|
903 |
}
|
904 |
+
}
|
905 |
+
else
|
906 |
+
{
|
907 |
$order->status = "error";
|
908 |
$order->error = __("Could not connect to Authorize.net", "pmpro");
|
909 |
$order->shorterror = __("Could not connect to Authorize.net", "pmpro");
|
910 |
+
return false;
|
911 |
}
|
912 |
+
}
|
913 |
+
|
914 |
function getSubscriptionStatus(&$order)
|
915 |
+
{
|
916 |
+
//define variables to send
|
917 |
if(!empty($order->subscription_transaction_id))
|
918 |
$subscriptionId = $order->subscription_transaction_id;
|
919 |
else
|
920 |
$subscriptionId = "";
|
921 |
$loginname = pmpro_getOption("loginname");
|
922 |
$transactionkey = pmpro_getOption("transactionkey");
|
923 |
+
|
924 |
if(!empty($order->gateway_environment))
|
925 |
$gateway_environment = $order->gateway_environment;
|
926 |
else
|
927 |
+
$gateway_environment = pmpro_getOption("gateway_environment");
|
928 |
+
|
929 |
if($gateway_environment == "live")
|
930 |
+
$host = "api.authorize.net";
|
931 |
else
|
932 |
+
$host = "apitest.authorize.net";
|
933 |
+
|
934 |
$path = "/xml/v1/request.api";
|
935 |
+
|
936 |
if(!$subscriptionId || !$loginname || !$transactionkey)
|
937 |
return false;
|
938 |
+
|
939 |
//build xml to post
|
940 |
$content =
|
941 |
"<?xml version=\"1.0\" encoding=\"utf-8\"?>".
|
946 |
"</merchantAuthentication>" .
|
947 |
"<subscriptionId>" . $subscriptionId . "</subscriptionId>".
|
948 |
"</ARBGetSubscriptionStatusRequest>";
|
949 |
+
|
950 |
//send the xml via curl
|
951 |
$response = $this->send_request_via_curl($host,$path,$content);
|
952 |
+
|
953 |
//if curl is unavilable you can try using fsockopen
|
954 |
/*
|
955 |
$response = send_request_via_fsockopen($host,$path,$content);
|
956 |
*/
|
957 |
+
|
958 |
//if the connection and send worked $response holds the return from Authorize.net
|
959 |
if($response)
|
960 |
+
{
|
961 |
+
list ($resultCode, $code, $text, $subscriptionId) = $this->parse_return($response);
|
962 |
+
|
963 |
$status = $this->substring_between($response,'<status>','</status>');
|
964 |
+
|
965 |
if($resultCode == "Ok" || $code == "Ok")
|
966 |
{
|
967 |
return $status;
|
968 |
}
|
969 |
else
|
970 |
+
{
|
971 |
$order->status = "error";
|
972 |
$order->errorcode = $resultCode;
|
973 |
$order->error = $message;
|
974 |
$order->shorterror = $text;
|
975 |
}
|
976 |
+
}
|
977 |
+
else
|
978 |
+
{
|
979 |
$order->status = "error";
|
980 |
$order->errorcode = $resultCode;
|
981 |
$order->error = $message;
|
982 |
$order->shorterror = $text;
|
983 |
}
|
984 |
+
}
|
985 |
+
|
986 |
//Authorize.net Function
|
987 |
//function to send xml request via fsockopen
|
988 |
function send_request_via_fsockopen($host,$path,$content)
|
1048 |
|
1049 |
//Authorize.net Function
|
1050 |
//helper function for parsing response
|
1051 |
+
function substring_between($haystack,$start,$end)
|
1052 |
{
|
1053 |
+
if (strpos($haystack,$start) === false || strpos($haystack,$end) === false)
|
1054 |
{
|
1055 |
return false;
|
1056 |
+
}
|
1057 |
+
else
|
1058 |
{
|
1059 |
$start_position = strpos($haystack,$start)+strlen($start);
|
1060 |
$end_position = strpos($haystack,$end);
|
classes/gateways/class.pmprogateway_braintree.php
CHANGED
@@ -1,824 +1,824 @@
|
|
1 |
-
<?php
|
2 |
-
//include pmprogateway
|
3 |
-
require_once(dirname(__FILE__) . "/class.pmprogateway.php");
|
4 |
-
|
5 |
-
//load classes init method
|
6 |
-
add_action('init', array('PMProGateway_braintree', 'init'));
|
7 |
-
|
8 |
-
class PMProGateway_braintree extends PMProGateway
|
9 |
-
{
|
10 |
-
function PMProGateway_braintree($gateway = NULL)
|
11 |
-
{
|
12 |
-
$this->gateway = $gateway;
|
13 |
-
$this->gateway_environment = pmpro_getOption("gateway_environment");
|
14 |
-
|
15 |
-
$this->loadBraintreeLibrary();
|
16 |
-
|
17 |
-
//convert to braintree nomenclature
|
18 |
-
$environment = $this->gateway_environment;
|
19 |
-
if($environment == "live")
|
20 |
-
$environment = "production";
|
21 |
-
|
22 |
-
Braintree_Configuration::environment($environment);
|
23 |
-
Braintree_Configuration::merchantId(pmpro_getOption("braintree_merchantid"));
|
24 |
-
Braintree_Configuration::publicKey(pmpro_getOption("braintree_publickey"));
|
25 |
-
Braintree_Configuration::privateKey(pmpro_getOption("braintree_privatekey"));
|
26 |
-
|
27 |
-
return $this->gateway;
|
28 |
-
}
|
29 |
-
|
30 |
-
/**
|
31 |
-
* Load the Braintree API library.
|
32 |
-
*
|
33 |
-
* @since 1.8.1
|
34 |
-
* Moved into a method in version 1.8.1 so we only load it when needed.
|
35 |
-
*/
|
36 |
-
function loadBraintreeLibrary()
|
37 |
-
{
|
38 |
-
//load Braintree library if it hasn't been loaded already (usually by another plugin using Braintree)
|
39 |
-
if(!class_exists("Braintree"))
|
40 |
-
require_once(dirname(__FILE__) . "/../../includes/lib/Braintree/Braintree.php");
|
41 |
-
}
|
42 |
-
|
43 |
-
/**
|
44 |
-
* Run on WP init
|
45 |
-
*
|
46 |
-
* @since 1.8
|
47 |
-
*/
|
48 |
-
static function init()
|
49 |
-
{
|
50 |
-
//make sure Braintree Payments is a gateway option
|
51 |
-
add_filter('pmpro_gateways', array('PMProGateway_braintree', 'pmpro_gateways'));
|
52 |
-
|
53 |
-
//add fields to payment settings
|
54 |
-
add_filter('pmpro_payment_options', array('PMProGateway_braintree', 'pmpro_payment_options'));
|
55 |
-
add_filter('pmpro_payment_option_fields', array('PMProGateway_braintree', 'pmpro_payment_option_fields'), 10, 2);
|
56 |
-
|
57 |
-
//code to add at checkout if Braintree is the current gateway
|
58 |
-
$gateway = pmpro_getGateway();
|
59 |
-
if($gateway == "braintree")
|
60 |
-
{
|
61 |
-
add_action('pmpro_checkout_before_submit_button', array('PMProGateway_braintree', 'pmpro_checkout_before_submit_button'));
|
62 |
-
add_filter('pmpro_checkout_order', array('PMProGateway_braintree', 'pmpro_checkout_order'));
|
63 |
-
add_filter('pmpro_required_billing_fields', array('PMProGateway_braintree', 'pmpro_required_billing_fields'));
|
64 |
-
add_filter('pmpro_include_payment_information_fields', array('PMProGateway_braintree', 'pmpro_include_payment_information_fields'));
|
65 |
-
}
|
66 |
-
}
|
67 |
-
|
68 |
-
/**
|
69 |
-
* Make sure this gateway is in the gateways list
|
70 |
-
*
|
71 |
-
* @since 1.8
|
72 |
-
*/
|
73 |
-
static function pmpro_gateways($gateways)
|
74 |
-
{
|
75 |
-
if(empty($gateways['braintree']))
|
76 |
-
$gateways['braintree'] = __('Braintree Payments', 'pmpro');
|
77 |
-
|
78 |
-
return $gateways;
|
79 |
-
}
|
80 |
-
|
81 |
-
/**
|
82 |
-
* Get a list of payment options that the this gateway needs/supports.
|
83 |
-
*
|
84 |
-
* @since 1.8
|
85 |
-
*/
|
86 |
-
static function getGatewayOptions()
|
87 |
-
{
|
88 |
-
$options = array(
|
89 |
-
'sslseal',
|
90 |
-
'nuclear_HTTPS',
|
91 |
-
'gateway_environment',
|
92 |
-
'braintree_merchantid',
|
93 |
-
'braintree_publickey',
|
94 |
-
'braintree_privatekey',
|
95 |
-
'braintree_encryptionkey',
|
96 |
-
'currency',
|
97 |
-
'use_ssl',
|
98 |
-
'tax_state',
|
99 |
-
'tax_rate',
|
100 |
-
'accepted_credit_cards'
|
101 |
-
);
|
102 |
-
|
103 |
-
return $options;
|
104 |
-
}
|
105 |
-
|
106 |
-
/**
|
107 |
-
* Set payment options for payment settings page.
|
108 |
-
*
|
109 |
-
* @since 1.8
|
110 |
-
*/
|
111 |
-
static function pmpro_payment_options($options)
|
112 |
-
{
|
113 |
-
//get stripe options
|
114 |
-
$braintree_options = PMProGateway_braintree::getGatewayOptions();
|
115 |
-
|
116 |
-
//merge with others.
|
117 |
-
$options = array_merge($braintree_options, $options);
|
118 |
-
|
119 |
-
return $options;
|
120 |
-
}
|
121 |
-
|
122 |
-
/**
|
123 |
-
* Display fields for this gateway's options.
|
124 |
-
*
|
125 |
-
* @since 1.8
|
126 |
-
*/
|
127 |
-
static function pmpro_payment_option_fields($values, $gateway)
|
128 |
-
{
|
129 |
-
?>
|
130 |
-
<tr class="pmpro_settings_divider gateway gateway_braintree" <?php if($gateway != "braintree") { ?>style="display: none;"<?php } ?>>
|
131 |
-
<td colspan="2">
|
132 |
-
<?php _e('Braintree Settings', 'pmpro'); ?>
|
133 |
-
</td>
|
134 |
-
</tr>
|
135 |
-
<tr class="gateway gateway_braintree" <?php if($gateway != "braintree") { ?>style="display: none;"<?php } ?>>
|
136 |
-
<th scope="row" valign="top">
|
137 |
-
<label for="braintree_merchantid"><?php _e('Merchant ID', 'pmpro');?>:</label>
|
138 |
-
</th>
|
139 |
-
<td>
|
140 |
-
<input type="text" id="braintree_merchantid" name="braintree_merchantid" size="60" value="<?php echo esc_attr($values['braintree_merchantid'])?>" />
|
141 |
-
</td>
|
142 |
-
</tr>
|
143 |
-
<tr class="gateway gateway_braintree" <?php if($gateway != "braintree") { ?>style="display: none;"<?php } ?>>
|
144 |
-
<th scope="row" valign="top">
|
145 |
-
<label for="braintree_publickey"><?php _e('Public Key', 'pmpro');?>:</label>
|
146 |
-
</th>
|
147 |
-
<td>
|
148 |
-
<input type="text" id="braintree_publickey" name="braintree_publickey" size="60" value="<?php echo esc_attr($values['braintree_publickey'])?>" />
|
149 |
-
</td>
|
150 |
-
</tr>
|
151 |
-
<tr class="gateway gateway_braintree" <?php if($gateway != "braintree") { ?>style="display: none;"<?php } ?>>
|
152 |
-
<th scope="row" valign="top">
|
153 |
-
<label for="braintree_privatekey"><?php _e('Private Key', 'pmpro');?>:</label>
|
154 |
-
</th>
|
155 |
-
<td>
|
156 |
-
<input type="text" id="braintree_privatekey" name="braintree_privatekey" size="60" value="<?php echo esc_attr($values['braintree_privatekey'])?>" />
|
157 |
-
</td>
|
158 |
-
</tr>
|
159 |
-
<tr class="gateway gateway_braintree" <?php if($gateway != "braintree") { ?>style="display: none;"<?php } ?>>
|
160 |
-
<th scope="row" valign="top">
|
161 |
-
<label for="braintree_encryptionkey"><?php _e('Client-Side Encryption Key', 'pmpro');?>:</label>
|
162 |
-
</th>
|
163 |
-
<td>
|
164 |
-
<textarea id="braintree_encryptionkey" name="braintree_encryptionkey" rows="3" cols="80"><?php echo esc_textarea($values['braintree_encryptionkey'])?></textarea>
|
165 |
-
</td>
|
166 |
-
</tr>
|
167 |
-
<tr class="gateway gateway_braintree" <?php if($gateway != "braintree") { ?>style="display: none;"<?php } ?>>
|
168 |
-
<th scope="row" valign="top">
|
169 |
-
<label><?php _e('Web Hook URL', 'pmpro');?>:</label>
|
170 |
-
</th>
|
171 |
-
<td>
|
172 |
-
<p>
|
173 |
-
<?php _e('To fully integrate with Braintree, be sure to set your Web Hook URL to', 'pmpro');?>
|
174 |
-
<pre><?php
|
175 |
-
//echo admin_url("admin-ajax.php") . "?action=braintree_webhook";
|
176 |
-
echo PMPRO_URL . "/services/braintree-webhook.php";
|
177 |
-
?></pre>
|
178 |
-
</p>
|
179 |
-
</td>
|
180 |
-
</tr>
|
181 |
-
<?php
|
182 |
-
}
|
183 |
-
|
184 |
-
/**
|
185 |
-
* Filtering orders at checkout.
|
186 |
-
*
|
187 |
-
* @since 1.8
|
188 |
-
*/
|
189 |
-
static function pmpro_checkout_order($morder)
|
190 |
-
{
|
191 |
-
//load up values
|
192 |
-
if(isset($_REQUEST['number']))
|
193 |
-
$braintree_number = $_REQUEST['number'];
|
194 |
-
else
|
195 |
-
$braintree_number = "";
|
196 |
-
|
197 |
-
if(isset($_REQUEST['expiration_date']))
|
198 |
-
$braintree_expiration_date = $_REQUEST['expiration_date'];
|
199 |
-
else
|
200 |
-
$braintree_expiration_date = "";
|
201 |
-
|
202 |
-
if(isset($_REQUEST['cvv']))
|
203 |
-
$braintree_cvv = $_REQUEST['cvv'];
|
204 |
-
else
|
205 |
-
$braintree_cvv = "";
|
206 |
-
|
207 |
-
$morder->braintree = new stdClass();
|
208 |
-
$morder->braintree->number = $braintree_number;
|
209 |
-
$morder->braintree->expiration_date = $braintree_expiration_date;
|
210 |
-
$morder->braintree->cvv = $braintree_cvv;
|
211 |
-
|
212 |
-
return $morder;
|
213 |
-
}
|
214 |
-
|
215 |
-
/**
|
216 |
-
* Don't require the CVV, but look for cvv (lowercase) that braintree sends
|
217 |
-
*
|
218 |
-
*/
|
219 |
-
static function pmpro_required_billing_fields($fields)
|
220 |
-
{
|
221 |
-
unset($fields['CVV']);
|
222 |
-
$fields['cvv'] = true;
|
223 |
-
return $fields;
|
224 |
-
}
|
225 |
-
|
226 |
-
/**
|
227 |
-
* Add some hidden fields and JavaScript to checkout.
|
228 |
-
*
|
229 |
-
*/
|
230 |
-
static function pmpro_checkout_before_submit_button()
|
231 |
-
{
|
232 |
-
?>
|
233 |
-
<input type='hidden' data-encrypted-name='expiration_date' id='credit_card_exp' />
|
234 |
-
<input type='hidden' name='AccountNumber' id='BraintreeAccountNumber' />
|
235 |
-
<script type="text/javascript" src="https://js.braintreegateway.com/v1/braintree.js"></script>
|
236 |
-
<script type="text/javascript">
|
237 |
-
//setup braintree encryption
|
238 |
-
var braintree = Braintree.create('<?php echo pmpro_getOption("braintree_encryptionkey"); ?>');
|
239 |
-
braintree.onSubmitEncryptForm('pmpro_form');
|
240 |
-
|
241 |
-
//pass expiration dates in original format
|
242 |
-
function pmpro_updateBraintreeCardExp()
|
243 |
-
{
|
244 |
-
jQuery('#credit_card_exp').val(jQuery('#ExpirationMonth').val() + "/" + jQuery('#ExpirationYear').val());
|
245 |
-
}
|
246 |
-
jQuery('#ExpirationMonth, #ExpirationYear').change(function() {
|
247 |
-
pmpro_updateBraintreeCardExp();
|
248 |
-
});
|
249 |
-
pmpro_updateBraintreeCardExp();
|
250 |
-
|
251 |
-
//pass last 4 of credit card
|
252 |
-
function pmpro_updateBraintreeAccountNumber()
|
253 |
-
{
|
254 |
-
jQuery('#BraintreeAccountNumber').val('XXXXXXXXXXXXX' + jQuery('#AccountNumber').val().substr(jQuery('#AccountNumber').val().length - 4));
|
255 |
-
}
|
256 |
-
jQuery('#AccountNumber').change(function() {
|
257 |
-
pmpro_updateBraintreeAccountNumber();
|
258 |
-
});
|
259 |
-
pmpro_updateBraintreeAccountNumber();
|
260 |
-
</script>
|
261 |
-
<?php
|
262 |
-
}
|
263 |
-
|
264 |
-
/**
|
265 |
-
* Use our own payment fields at checkout. (Remove the name attributes and set some data-encrypted-name attributes.)
|
266 |
-
* @since 1.8
|
267 |
-
*/
|
268 |
-
static function pmpro_include_payment_information_fields($include)
|
269 |
-
{
|
270 |
-
//global vars
|
271 |
-
global $pmpro_requirebilling, $pmpro_show_discount_code, $discount_code, $CardType, $AccountNumber, $ExpirationMonth, $ExpirationYear;
|
272 |
-
|
273 |
-
//get accepted credit cards
|
274 |
-
$pmpro_accepted_credit_cards = pmpro_getOption("accepted_credit_cards");
|
275 |
-
$pmpro_accepted_credit_cards = explode(",", $pmpro_accepted_credit_cards);
|
276 |
-
$pmpro_accepted_credit_cards_string = pmpro_implodeToEnglish($pmpro_accepted_credit_cards);
|
277 |
-
|
278 |
-
//include ours
|
279 |
-
?>
|
280 |
-
<table id="pmpro_payment_information_fields" class="pmpro_checkout top1em" width="100%" cellpadding="0" cellspacing="0" border="0" <?php if(!$pmpro_requirebilling || apply_filters("pmpro_hide_payment_information_fields", false) ) { ?>style="display: none;"<?php } ?>>
|
281 |
-
<thead>
|
282 |
-
<tr>
|
283 |
-
<th><span class="pmpro_thead-msg"><?php printf(__('We Accept %s', 'pmpro'), $pmpro_accepted_credit_cards_string);?></span><?php _e('Payment Information', 'pmpro');?></th>
|
284 |
-
</tr>
|
285 |
-
</thead>
|
286 |
-
<tbody>
|
287 |
-
<tr valign="top">
|
288 |
-
<td>
|
289 |
-
<?php
|
290 |
-
$sslseal = pmpro_getOption("sslseal");
|
291 |
-
if($sslseal)
|
292 |
-
{
|
293 |
-
?>
|
294 |
-
<div class="pmpro_sslseal"><?php echo stripslashes($sslseal)?></div>
|
295 |
-
<?php
|
296 |
-
}
|
297 |
-
?>
|
298 |
-
<?php
|
299 |
-
$pmpro_include_cardtype_field = apply_filters('pmpro_include_cardtype_field', true);
|
300 |
-
if($pmpro_include_cardtype_field)
|
301 |
-
{
|
302 |
-
?>
|
303 |
-
<div class="pmpro_payment-card-type">
|
304 |
-
<label for="CardType"><?php _e('Card Type', 'pmpro');?></label>
|
305 |
-
<select id="CardType" name="CardType" class=" <?php echo pmpro_getClassForField("CardType");?>">
|
306 |
-
<?php foreach($pmpro_accepted_credit_cards as $cc) { ?>
|
307 |
-
<option value="<?php echo $cc?>" <?php if($CardType == $cc) { ?>selected="selected"<?php } ?>><?php echo $cc?></option>
|
308 |
-
<?php } ?>
|
309 |
-
</select>
|
310 |
-
</div>
|
311 |
-
<?php
|
312 |
-
}
|
313 |
-
?>
|
314 |
-
|
315 |
-
<div class="pmpro_payment-account-number">
|
316 |
-
<label for="AccountNumber"><?php _e('Card Number', 'pmpro');?></label>
|
317 |
-
<input id="AccountNumber" name="AccountNumber" class="input <?php echo pmpro_getClassForField("AccountNumber");?>" type="text" size="25" value="<?php echo esc_attr($AccountNumber)?>" data-encrypted-name="number" autocomplete="off" />
|
318 |
-
</div>
|
319 |
-
|
320 |
-
<div class="pmpro_payment-expiration">
|
321 |
-
<label for="ExpirationMonth"><?php _e('Expiration Date', 'pmpro');?></label>
|
322 |
-
<select id="ExpirationMonth" name="ExpirationMonth" class=" <?php echo pmpro_getClassForField("ExpirationMonth");?>">
|
323 |
-
<option value="01" <?php if($ExpirationMonth == "01") { ?>selected="selected"<?php } ?>>01</option>
|
324 |
-
<option value="02" <?php if($ExpirationMonth == "02") { ?>selected="selected"<?php } ?>>02</option>
|
325 |
-
<option value="03" <?php if($ExpirationMonth == "03") { ?>selected="selected"<?php } ?>>03</option>
|
326 |
-
<option value="04" <?php if($ExpirationMonth == "04") { ?>selected="selected"<?php } ?>>04</option>
|
327 |
-
<option value="05" <?php if($ExpirationMonth == "05") { ?>selected="selected"<?php } ?>>05</option>
|
328 |
-
<option value="06" <?php if($ExpirationMonth == "06") { ?>selected="selected"<?php } ?>>06</option>
|
329 |
-
<option value="07" <?php if($ExpirationMonth == "07") { ?>selected="selected"<?php } ?>>07</option>
|
330 |
-
<option value="08" <?php if($ExpirationMonth == "08") { ?>selected="selected"<?php } ?>>08</option>
|
331 |
-
<option value="09" <?php if($ExpirationMonth == "09") { ?>selected="selected"<?php } ?>>09</option>
|
332 |
-
<option value="10" <?php if($ExpirationMonth == "10") { ?>selected="selected"<?php } ?>>10</option>
|
333 |
-
<option value="11" <?php if($ExpirationMonth == "11") { ?>selected="selected"<?php } ?>>11</option>
|
334 |
-
<option value="12" <?php if($ExpirationMonth == "12") { ?>selected="selected"<?php } ?>>12</option>
|
335 |
-
</select>/<select id="ExpirationYear" name="ExpirationYear" class=" <?php echo pmpro_getClassForField("ExpirationYear");?>">
|
336 |
-
<?php
|
337 |
-
for($i = date("Y"); $i < date("Y") + 10; $i++)
|
338 |
-
{
|
339 |
-
?>
|
340 |
-
<option value="<?php echo $i?>" <?php if($ExpirationYear == $i) { ?>selected="selected"<?php } ?>><?php echo $i?></option>
|
341 |
-
<?php
|
342 |
-
}
|
343 |
-
?>
|
344 |
-
</select>
|
345 |
-
</div>
|
346 |
-
|
347 |
-
<?php
|
348 |
-
$pmpro_show_cvv = apply_filters("pmpro_show_cvv", true);
|
349 |
-
if($pmpro_show_cvv)
|
350 |
-
{
|
351 |
-
?>
|
352 |
-
<div class="pmpro_payment-cvv">
|
353 |
-
<label for="CVV"><?php _ex('CVV', 'Credit card security code, CVV/CCV/CVV2', 'pmpro');?></label>
|
354 |
-
<input class="input" id="CVV" name="cvv" type="text" size="4" value="<?php if(!empty($_REQUEST['CVV'])) { echo esc_attr($_REQUEST['CVV']); }?>" class=" <?php echo pmpro_getClassForField("CVV");?>" data-encrypted-name="cvv" /> <small>(<a href="javascript:void(0);" onclick="javascript:window.open('<?php echo pmpro_https_filter(PMPRO_URL)?>/pages/popup-cvv.html','cvv','toolbar=no, location=no, directories=no, status=no, menubar=no, scrollbars=yes, resizable=yes, width=600, height=475');"><?php _ex("what's this?", 'link to CVV help', 'pmpro');?></a>)</small>
|
355 |
-
</div>
|
356 |
-
<?php
|
357 |
-
}
|
358 |
-
?>
|
359 |
-
|
360 |
-
<?php if($pmpro_show_discount_code) { ?>
|
361 |
-
<div class="pmpro_payment-discount-code">
|
362 |
-
<label for="discount_code"><?php _e('Discount Code', 'pmpro');?></label>
|
363 |
-
<input class="input <?php echo pmpro_getClassForField("discount_code");?>" id="discount_code" name="discount_code" type="text" size="20" value="<?php echo esc_attr($discount_code)?>" />
|
364 |
-
<input type="button" id="discount_code_button" name="discount_code_button" value="<?php _e('Apply', 'pmpro');?>" />
|
365 |
-
<p id="discount_code_message" class="pmpro_message" style="display: none;"></p>
|
366 |
-
</div>
|
367 |
-
<?php } ?>
|
368 |
-
|
369 |
-
</td>
|
370 |
-
</tr>
|
371 |
-
</tbody>
|
372 |
-
</table>
|
373 |
-
<?php
|
374 |
-
|
375 |
-
//don't include the default
|
376 |
-
return false;
|
377 |
-
}
|
378 |
-
|
379 |
-
/**
|
380 |
-
* Process checkout.
|
381 |
-
*
|
382 |
-
*/
|
383 |
-
function process(&$order)
|
384 |
-
{
|
385 |
-
//check for initial payment
|
386 |
-
if(floatval($order->InitialPayment) == 0)
|
387 |
-
{
|
388 |
-
//just subscribe
|
389 |
-
return $this->subscribe($order);
|
390 |
-
}
|
391 |
-
else
|
392 |
-
{
|
393 |
-
//charge then subscribe
|
394 |
-
if($this->charge($order))
|
395 |
-
{
|
396 |
-
if(pmpro_isLevelRecurring($order->membership_level))
|
397 |
-
{
|
398 |
-
if($this->subscribe($order))
|
399 |
-
{
|
400 |
-
//yay!
|
401 |
-
return true;
|
402 |
-
}
|
403 |
-
else
|
404 |
-
{
|
405 |
-
//try to refund initial charge
|
406 |
-
return false;
|
407 |
-
}
|
408 |
-
}
|
409 |
-
else
|
410 |
-
{
|
411 |
-
//only a one time charge
|
412 |
-
$order->status = "success"; //saved on checkout page
|
413 |
-
return true;
|
414 |
-
}
|
415 |
-
}
|
416 |
-
else
|
417 |
-
{
|
418 |
-
if(empty($order->error))
|
419 |
-
$order->error = __("Unknown error: Initial payment failed.", "pmpro");
|
420 |
-
return false;
|
421 |
-
}
|
422 |
-
}
|
423 |
-
}
|
424 |
-
|
425 |
-
function charge(&$order)
|
426 |
-
{
|
427 |
-
//create a code for the order
|
428 |
-
if(empty($order->code))
|
429 |
-
$order->code = $order->getRandomCode();
|
430 |
-
|
431 |
-
//what amount to charge?
|
432 |
-
$amount = $order->InitialPayment;
|
433 |
-
|
434 |
-
//tax
|
435 |
-
$order->subtotal = $amount;
|
436 |
-
$tax = $order->getTax(true);
|
437 |
-
$amount = round((float)$order->subtotal + (float)$tax, 2);
|
438 |
-
|
439 |
-
//create a customer
|
440 |
-
$this->getCustomer($order);
|
441 |
-
if(empty($this->customer))
|
442 |
-
{
|
443 |
-
//failed to create customer
|
444 |
-
return false;
|
445 |
-
}
|
446 |
-
|
447 |
-
//charge
|
448 |
-
try
|
449 |
-
{
|
450 |
-
$response = Braintree_Transaction::sale(array(
|
451 |
-
'amount' => $amount,
|
452 |
-
'customerId' => $this->customer->id
|
453 |
-
));
|
454 |
-
}
|
455 |
-
catch (Exception $e)
|
456 |
-
{
|
457 |
-
//$order->status = "error";
|
458 |
-
$order->errorcode = true;
|
459 |
-
$order->error = "Error: " . $e->getMessage();
|
460 |
-
$order->shorterror = $order->error;
|
461 |
-
return false;
|
462 |
-
}
|
463 |
-
|
464 |
-
if($response->success)
|
465 |
-
{
|
466 |
-
//successful charge
|
467 |
-
$transaction_id = $response->transaction->id;
|
468 |
-
$response = Braintree_Transaction::submitForSettlement($transaction_id);
|
469 |
-
if($response->success)
|
470 |
-
{
|
471 |
-
$order->payment_transaction_id = $transaction_id;
|
472 |
-
$order->updateStatus("success");
|
473 |
-
return true;
|
474 |
-
}
|
475 |
-
else
|
476 |
-
{
|
477 |
-
$order->errorcode = true;
|
478 |
-
$order->error = __("Error during settlement:", "pmpro") . " " . $response->message;
|
479 |
-
$order->shorterror = $response->message;
|
480 |
-
return false;
|
481 |
-
}
|
482 |
-
}
|
483 |
-
else
|
484 |
-
{
|
485 |
-
//$order->status = "error";
|
486 |
-
$order->errorcode = true;
|
487 |
-
$order->error = __("Error during charge:", "pmpro") . " " . $response->message;
|
488 |
-
$order->shorterror = $response->message;
|
489 |
-
return false;
|
490 |
-
}
|
491 |
-
}
|
492 |
-
|
493 |
-
/*
|
494 |
-
This function will return a Braintree customer object.
|
495 |
-
If $this->customer is set, it returns it.
|
496 |
-
It first checks if the order has a subscription_transaction_id. If so, that's the customer id.
|
497 |
-
If not, it checks for a user_id on the order and searches for a customer id in the user meta.
|
498 |
-
If a customer id is found, it checks for a customer through the Braintree API.
|
499 |
-
If a customer is found and there is an AccountNumber on the order passed, it will update the customer.
|
500 |
-
If no customer is found and there is an AccountNumber on the order passed, it will create a customer.
|
501 |
-
*/
|
502 |
-
function getCustomer(&$order, $force = false)
|
503 |
-
{
|
504 |
-
global $current_user;
|
505 |
-
|
506 |
-
//already have it?
|
507 |
-
if(!empty($this->customer) && !$force)
|
508 |
-
return $this->customer;
|
509 |
-
|
510 |
-
//try based on user id
|
511 |
-
if(!empty($order->user_id))
|
512 |
-
$user_id = $order->user_id;
|
513 |
-
|
514 |
-
//if no id passed, check the current user
|
515 |
-
if(empty($user_id) && !empty($current_user->ID))
|
516 |
-
$user_id = $current_user->ID;
|
517 |
-
|
518 |
-
//check for a braintree customer id
|
519 |
-
if(!empty($user_id))
|
520 |
-
{
|
521 |
-
$customer_id = get_user_meta($user_id, "pmpro_braintree_customerid", true);
|
522 |
-
}
|
523 |
-
|
524 |
-
//check for an existing stripe customer
|
525 |
-
if(!empty($customer_id))
|
526 |
-
{
|
527 |
-
try
|
528 |
-
{
|
529 |
-
$this->customer = Braintree_Customer::find($customer_id);
|
530 |
-
|
531 |
-
//update the customer address, description and card
|
532 |
-
if(!empty($order->accountnumber))
|
533 |
-
{
|
534 |
-
//put data in array for Braintree API calls
|
535 |
-
$update_array = array(
|
536 |
-
'firstName' => $order->FirstName,
|
537 |
-
'lastName' => $order->LastName,
|
538 |
-
'creditCard' => array(
|
539 |
-
'number' => $order->braintree->number,
|
540 |
-
'expirationDate' => $order->braintree->expiration_date,
|
541 |
-
'cardholderName' => trim($order->FirstName . " " . $order->LastName),
|
542 |
-
'options' => array(
|
543 |
-
'updateExistingToken' => $this->customer->creditCards[0]->token
|
544 |
-
)
|
545 |
-
)
|
546 |
-
);
|
547 |
-
|
548 |
-
//address too?
|
549 |
-
if(!empty($order->billing))
|
550 |
-
//make sure Address2 is set
|
551 |
-
if(!isset($order->Address2))
|
552 |
-
$order->Address2 = '';
|
553 |
-
|
554 |
-
//add billing address to array
|
555 |
-
$update_array['creditCard']['billingAddress'] = array(
|
556 |
-
'firstName' => $order->FirstName,
|
557 |
-
'lastName' => $order->LastName,
|
558 |
-
'streetAddress' => $order->Address1,
|
559 |
-
'extendedAddress' => $order->Address2,
|
560 |
-
'locality' => $order->billing->city,
|
561 |
-
'region' => $order->billing->state,
|
562 |
-
'postalCode' => $order->billing->zip,
|
563 |
-
'countryCodeAlpha2' => $order->billing->country,
|
564 |
-
'options' => array(
|
565 |
-
'updateExisting' => true
|
566 |
-
)
|
567 |
-
);
|
568 |
-
|
569 |
-
//update
|
570 |
-
$response = Braintree_Customer::update($customer_id, $update_array);
|
571 |
-
|
572 |
-
if($response->success)
|
573 |
-
{
|
574 |
-
$this->customer = $response->customer;
|
575 |
-
return $this->customer;
|
576 |
-
}
|
577 |
-
else
|
578 |
-
{
|
579 |
-
$order->error = __("Failed to update customer.", "pmpro") . " " . $response->message;
|
580 |
-
$order->shorterror = $order->error;
|
581 |
-
return false;
|
582 |
-
}
|
583 |
-
}
|
584 |
-
|
585 |
-
return $this->customer;
|
586 |
-
}
|
587 |
-
catch (Exception $e)
|
588 |
-
{
|
589 |
-
//assume no customer found
|
590 |
-
}
|
591 |
-
}
|
592 |
-
|
593 |
-
//no customer id, create one
|
594 |
-
if(!empty($order->accountnumber))
|
595 |
-
{
|
596 |
-
try
|
597 |
-
{
|
598 |
-
$result = Braintree_Customer::create(array(
|
599 |
-
'firstName' => $order->FirstName,
|
600 |
-
'lastName' => $order->LastName,
|
601 |
-
'email' => $order->Email,
|
602 |
-
'phone' => $order->billing->phone,
|
603 |
-
'creditCard' => array(
|
604 |
-
'number' => $order->braintree->number,
|
605 |
-
'expirationDate' => $order->braintree->expiration_date,
|
606 |
-
'cvv' => $order->braintree->cvv,
|
607 |
-
'cardholderName' => trim($order->FirstName . " " . $order->LastName),
|
608 |
-
'billingAddress' => array(
|
609 |
-
'firstName' => $order->FirstName,
|
610 |
-
'lastName' => $order->LastName,
|
611 |
-
'streetAddress' => $order->Address1,
|
612 |
-
'extendedAddress' => $order->Address2,
|
613 |
-
'locality' => $order->billing->city,
|
614 |
-
'region' => $order->billing->state,
|
615 |
-
'postalCode' => $order->billing->zip,
|
616 |
-
'countryCodeAlpha2' => $order->billing->country
|
617 |
-
)
|
618 |
-
)
|
619 |
-
));
|
620 |
-
|
621 |
-
if($result->success)
|
622 |
-
{
|
623 |
-
$this->customer = $result->customer;
|
624 |
-
}
|
625 |
-
else
|
626 |
-
{
|
627 |
-
$order->error = __("Failed to create customer.", "pmpro") . " " . $result->message;
|
628 |
-
$order->shorterror = $order->error;
|
629 |
-
return false;
|
630 |
-
}
|
631 |
-
}
|
632 |
-
catch (Exception $e)
|
633 |
-
{
|
634 |
-
$order->error = __("Error creating customer record with Braintree:", "pmpro") . " " . $e->getMessage();
|
635 |
-
$order->shorterror = $order->error;
|
636 |
-
return false;
|
637 |
-
}
|
638 |
-
|
639 |
-
//if we have no user id, we need to set the customer id after the user is created
|
640 |
-
if(empty($user_id))
|
641 |
-
{
|
642 |
-
global $pmpro_braintree_customerid;
|
643 |
-
$pmpro_braintree_customerid = $this->customer->id;
|
644 |
-
add_action('user_register', array('PMProGateway_braintree','user_register'));
|
645 |
-
}
|
646 |
-
else
|
647 |
-
update_user_meta($user_id, "pmpro_braintree_customerid", $this->customer->id);
|
648 |
-
|
649 |
-
return $this->customer;
|
650 |
-
}
|
651 |
-
|
652 |
-
return false;
|
653 |
-
}
|
654 |
-
|
655 |
-
function subscribe(&$order)
|
656 |
-
{
|
657 |
-
//create a code for the order
|
658 |
-
if(empty($order->code))
|
659 |
-
$order->code = $order->getRandomCode();
|
660 |
-
|
661 |
-
//setup customer
|
662 |
-
$this->getCustomer($order);
|
663 |
-
if(empty($this->customer))
|
664 |
-
return false; //error retrieving customer
|
665 |
-
|
666 |
-
//figure out the amounts
|
667 |
-
$amount = $order->PaymentAmount;
|
668 |
-
$amount_tax = $order->getTaxForPrice($amount);
|
669 |
-
$amount = round((float)$amount + (float)$amount_tax, 2);
|
670 |
-
|
671 |
-
/*
|
672 |
-
There are two parts to the trial. Part 1 is simply the delay until the first payment
|
673 |
-
since we are doing the first payment as a separate transaction.
|
674 |
-
The second part is the actual "trial" set by the admin.
|
675 |
-
|
676 |
-
Stripe only supports Year or Month for billing periods, but we account for Days and Weeks just in case.
|
677 |
-
*/
|
678 |
-
//figure out the trial length (first payment handled by initial charge)
|
679 |
-
if($order->BillingPeriod == "Year")
|
680 |
-
$trial_period_days = $order->BillingFrequency * 365; //annual
|
681 |
-
elseif($order->BillingPeriod == "Day")
|
682 |
-
$trial_period_days = $order->BillingFrequency * 1; //daily
|
683 |
-
elseif($order->BillingPeriod == "Week")
|
684 |
-
$trial_period_days = $order->BillingFrequency * 7; //weekly
|
685 |
-
else
|
686 |
-
$trial_period_days = $order->BillingFrequency * 30; //assume monthly
|
687 |
-
|
688 |
-
//convert to a profile start date
|
689 |
-
$order->ProfileStartDate = date("Y-m-d", strtotime("+ " . $trial_period_days . " Day", current_time("timestamp"))) . "T0:0:0";
|
690 |
-
|
691 |
-
//filter the start date
|
692 |
-
$order->ProfileStartDate = apply_filters("pmpro_profile_start_date", $order->ProfileStartDate, $order);
|
693 |
-
|
694 |
-
//convert back to days
|
695 |
-
$trial_period_days = ceil(abs(strtotime(date("Y-m-d")) - strtotime($order->ProfileStartDate, current_time("timestamp"))) / 86400);
|
696 |
-
|
697 |
-
//now add the actual trial set by the site
|
698 |
-
if(!empty($order->TrialBillingCycles))
|
699 |
-
{
|
700 |
-
$trialOccurrences = (int)$order->TrialBillingCycles;
|
701 |
-
if($order->BillingPeriod == "Year")
|
702 |
-
$trial_period_days = $trial_period_days + (365 * $order->BillingFrequency * $trialOccurrences); //annual
|
703 |
-
elseif($order->BillingPeriod == "Day")
|
704 |
-
$trial_period_days = $trial_period_days + (1 * $order->BillingFrequency * $trialOccurrences); //daily
|
705 |
-
elseif($order->BillingPeriod == "Week")
|
706 |
-
$trial_period_days = $trial_period_days + (7 * $order->BillingFrequency * $trialOccurrences); //weekly
|
707 |
-
else
|
708 |
-
$trial_period_days = $trial_period_days + (30 * $order->BillingFrequency * $trialOccurrences); //assume monthly
|
709 |
-
}
|
710 |
-
|
711 |
-
//subscribe to the plan
|
712 |
-
try
|
713 |
-
{
|
714 |
-
$details = array(
|
715 |
-
'paymentMethodToken' => $this->customer->creditCards[0]->token,
|
716 |
-
'planId' => 'pmpro_' . $order->membership_id,
|
717 |
-
'price' => $amount
|
718 |
-
);
|
719 |
-
|
720 |
-
if(!empty($trial_period_days))
|
721 |
-
{
|
722 |
-
$details['trialPeriod'] = true;
|
723 |
-
$details['trialDuration'] = $trial_period_days;
|
724 |
-
$details['trialDurationUnit'] = "day";
|
725 |
-
}
|
726 |
-
|
727 |
-
if(!empty($order->TotalBillingCycles))
|
728 |
-
$details['numberOfBillingCycles'] = $order->TotalBillingCycles;
|
729 |
-
|
730 |
-
$result = Braintree_Subscription::create($details);
|
731 |
-
}
|
732 |
-
catch (Exception $e)
|
733 |
-
{
|
734 |
-
$order->error = __("Error subscribing customer to plan with Braintree:", "pmpro") . " " . $e->getMessage();
|
735 |
-
//return error
|
736 |
-
$order->shorterror = $order->error;
|
737 |
-
return false;
|
738 |
-
}
|
739 |
-
|
740 |
-
if($result->success)
|
741 |
-
{
|
742 |
-
//if we got this far, we're all good
|
743 |
-
$order->status = "success";
|
744 |
-
$order->subscription_transaction_id = $result->subscription->id;
|
745 |
-
return true;
|
746 |
-
}
|
747 |
-
else
|
748 |
-
{
|
749 |
-
$order->error = __("Failed to subscribe with Braintree:", "pmpro") . " " . $result->message;
|
750 |
-
$order->shorterror = $result->message;
|
751 |
-
return false;
|
752 |
-
}
|
753 |
-
}
|
754 |
-
|
755 |
-
function update(&$order)
|
756 |
-
{
|
757 |
-
//we just have to run getCustomer which will look for the customer and update it with the new token
|
758 |
-
$this->getCustomer($order, true);
|
759 |
-
|
760 |
-
if(!empty($this->customer) && empty($order->error))
|
761 |
-
{
|
762 |
-
return true;
|
763 |
-
}
|
764 |
-
else
|
765 |
-
{
|
766 |
-
return false; //couldn't find the customer
|
767 |
-
}
|
768 |
-
}
|
769 |
-
|
770 |
-
function cancel(&$order)
|
771 |
-
{
|
772 |
-
//require a subscription id
|
773 |
-
if(empty($order->subscription_transaction_id))
|
774 |
-
return false;
|
775 |
-
|
776 |
-
//find the customer
|
777 |
-
if(!empty($order->subscription_transaction_id))
|
778 |
-
{
|
779 |
-
//cancel
|
780 |
-
try
|
781 |
-
{
|
782 |
-
$result = Braintree_Subscription::cancel($order->subscription_transaction_id);
|
783 |
-
}
|
784 |
-
catch(Exception $e)
|
785 |
-
{
|
786 |
-
$order->updateStatus("cancelled"); //assume it's been cancelled already
|
787 |
-
$order->error = __("Could not find the subscription.", "pmpro") . " " . $e->getMessage();
|
788 |
-
$order->shorterror = $order->error;
|
789 |
-
return false; //no subscription found
|
790 |
-
}
|
791 |
-
|
792 |
-
if($result->success)
|
793 |
-
{
|
794 |
-
$order->updateStatus("cancelled");
|
795 |
-
return true;
|
796 |
-
}
|
797 |
-
else
|
798 |
-
{
|
799 |
-
$order->updateStatus("cancelled"); //assume it's been cancelled already
|
800 |
-
$order->error = __("Could not find the subscription.", "pmpro") . " " . $result->message;
|
801 |
-
$order->shorterror = $order->error;
|
802 |
-
return false; //no subscription found
|
803 |
-
}
|
804 |
-
}
|
805 |
-
else
|
806 |
-
{
|
807 |
-
$order->error = __("Could not find the subscription.", "pmpro");
|
808 |
-
$order->shorterror = $order->error;
|
809 |
-
return false; //no customer found
|
810 |
-
}
|
811 |
-
}
|
812 |
-
|
813 |
-
/*
|
814 |
-
Save Braintree customer id after the user is registered.
|
815 |
-
*/
|
816 |
-
static function user_register($user_id)
|
817 |
-
{
|
818 |
-
global $pmpro_braintree_customerid;
|
819 |
-
if(!empty($pmpro_braintree_customerid))
|
820 |
-
{
|
821 |
-
update_user_meta($user_id, 'pmpro_braintree_customerid', $pmpro_braintree_customerid);
|
822 |
-
}
|
823 |
-
}
|
824 |
-
}
|
1 |
+
<?php
|
2 |
+
//include pmprogateway
|
3 |
+
require_once(dirname(__FILE__) . "/class.pmprogateway.php");
|
4 |
+
|
5 |
+
//load classes init method
|
6 |
+
add_action('init', array('PMProGateway_braintree', 'init'));
|
7 |
+
|
8 |
+
class PMProGateway_braintree extends PMProGateway
|
9 |
+
{
|
10 |
+
function PMProGateway_braintree($gateway = NULL)
|
11 |
+
{
|
12 |
+
$this->gateway = $gateway;
|
13 |
+
$this->gateway_environment = pmpro_getOption("gateway_environment");
|
14 |
+
|
15 |
+
$this->loadBraintreeLibrary();
|
16 |
+
|
17 |
+
//convert to braintree nomenclature
|
18 |
+
$environment = $this->gateway_environment;
|
19 |
+
if($environment == "live")
|
20 |
+
$environment = "production";
|
21 |
+
|
22 |
+
Braintree_Configuration::environment($environment);
|
23 |
+
Braintree_Configuration::merchantId(pmpro_getOption("braintree_merchantid"));
|
24 |
+
Braintree_Configuration::publicKey(pmpro_getOption("braintree_publickey"));
|
25 |
+
Braintree_Configuration::privateKey(pmpro_getOption("braintree_privatekey"));
|
26 |
+
|
27 |
+
return $this->gateway;
|
28 |
+
}
|
29 |
+
|
30 |
+
/**
|
31 |
+
* Load the Braintree API library.
|
32 |
+
*
|
33 |
+
* @since 1.8.1
|
34 |
+
* Moved into a method in version 1.8.1 so we only load it when needed.
|
35 |
+
*/
|
36 |
+
function loadBraintreeLibrary()
|
37 |
+
{
|
38 |
+
//load Braintree library if it hasn't been loaded already (usually by another plugin using Braintree)
|
39 |
+
if(!class_exists("Braintree"))
|
40 |
+
require_once(dirname(__FILE__) . "/../../includes/lib/Braintree/Braintree.php");
|
41 |
+
}
|
42 |
+
|
43 |
+
/**
|
44 |
+
* Run on WP init
|
45 |
+
*
|
46 |
+
* @since 1.8
|
47 |
+
*/
|
48 |
+
static function init()
|
49 |
+
{
|
50 |
+
//make sure Braintree Payments is a gateway option
|
51 |
+
add_filter('pmpro_gateways', array('PMProGateway_braintree', 'pmpro_gateways'));
|
52 |
+
|
53 |
+
//add fields to payment settings
|
54 |
+
add_filter('pmpro_payment_options', array('PMProGateway_braintree', 'pmpro_payment_options'));
|
55 |
+
add_filter('pmpro_payment_option_fields', array('PMProGateway_braintree', 'pmpro_payment_option_fields'), 10, 2);
|
56 |
+
|
57 |
+
//code to add at checkout if Braintree is the current gateway
|
58 |
+
$gateway = pmpro_getGateway();
|
59 |
+
if($gateway == "braintree")
|
60 |
+
{
|
61 |
+
add_action('pmpro_checkout_before_submit_button', array('PMProGateway_braintree', 'pmpro_checkout_before_submit_button'));
|
62 |
+
add_filter('pmpro_checkout_order', array('PMProGateway_braintree', 'pmpro_checkout_order'));
|
63 |
+
add_filter('pmpro_required_billing_fields', array('PMProGateway_braintree', 'pmpro_required_billing_fields'));
|
64 |
+
add_filter('pmpro_include_payment_information_fields', array('PMProGateway_braintree', 'pmpro_include_payment_information_fields'));
|
65 |
+
}
|
66 |
+
}
|
67 |
+
|
68 |
+
/**
|
69 |
+
* Make sure this gateway is in the gateways list
|
70 |
+
*
|
71 |
+
* @since 1.8
|
72 |
+
*/
|
73 |
+
static function pmpro_gateways($gateways)
|
74 |
+
{
|
75 |
+
if(empty($gateways['braintree']))
|
76 |
+
$gateways['braintree'] = __('Braintree Payments', 'pmpro');
|
77 |
+
|
78 |
+
return $gateways;
|
79 |
+
}
|
80 |
+
|
81 |
+
/**
|
82 |
+
* Get a list of payment options that the this gateway needs/supports.
|
83 |
+
*
|
84 |
+
* @since 1.8
|
85 |
+
*/
|
86 |
+
static function getGatewayOptions()
|
87 |
+
{
|
88 |
+
$options = array(
|
89 |
+
'sslseal',
|
90 |
+
'nuclear_HTTPS',
|
91 |
+
'gateway_environment',
|
92 |
+
'braintree_merchantid',
|
93 |
+
'braintree_publickey',
|
94 |
+
'braintree_privatekey',
|
95 |
+
'braintree_encryptionkey',
|
96 |
+
'currency',
|
97 |
+
'use_ssl',
|
98 |
+
'tax_state',
|
99 |
+
'tax_rate',
|
100 |
+
'accepted_credit_cards'
|
101 |
+
);
|
102 |
+
|
103 |
+
return $options;
|
104 |
+
}
|
105 |
+
|
106 |
+
/**
|
107 |
+
* Set payment options for payment settings page.
|
108 |
+
*
|
109 |
+
* @since 1.8
|
110 |
+
*/
|
111 |
+
static function pmpro_payment_options($options)
|
112 |
+
{
|
113 |
+
//get stripe options
|
114 |
+
$braintree_options = PMProGateway_braintree::getGatewayOptions();
|
115 |
+
|
116 |
+
//merge with others.
|
117 |
+
$options = array_merge($braintree_options, $options);
|
118 |
+
|
119 |
+
return $options;
|
120 |
+
}
|
121 |
+
|
122 |
+
/**
|
123 |
+
* Display fields for this gateway's options.
|
124 |
+
*
|
125 |
+
* @since 1.8
|
126 |
+
*/
|
127 |
+
static function pmpro_payment_option_fields($values, $gateway)
|
128 |
+
{
|
129 |
+
?>
|
130 |
+
<tr class="pmpro_settings_divider gateway gateway_braintree" <?php if($gateway != "braintree") { ?>style="display: none;"<?php } ?>>
|
131 |
+
<td colspan="2">
|
132 |
+
<?php _e('Braintree Settings', 'pmpro'); ?>
|
133 |
+
</td>
|
134 |
+
</tr>
|
135 |
+
<tr class="gateway gateway_braintree" <?php if($gateway != "braintree") { ?>style="display: none;"<?php } ?>>
|
136 |
+
<th scope="row" valign="top">
|
137 |
+
<label for="braintree_merchantid"><?php _e('Merchant ID', 'pmpro');?>:</label>
|
138 |
+
</th>
|
139 |
+
<td>
|
140 |
+
<input type="text" id="braintree_merchantid" name="braintree_merchantid" size="60" value="<?php echo esc_attr($values['braintree_merchantid'])?>" />
|
141 |
+
</td>
|
142 |
+
</tr>
|
143 |
+
<tr class="gateway gateway_braintree" <?php if($gateway != "braintree") { ?>style="display: none;"<?php } ?>>
|
144 |
+
<th scope="row" valign="top">
|
145 |
+
<label for="braintree_publickey"><?php _e('Public Key', 'pmpro');?>:</label>
|
146 |
+
</th>
|
147 |
+
<td>
|
148 |
+
<input type="text" id="braintree_publickey" name="braintree_publickey" size="60" value="<?php echo esc_attr($values['braintree_publickey'])?>" />
|
149 |
+
</td>
|
150 |
+
</tr>
|
151 |
+
<tr class="gateway gateway_braintree" <?php if($gateway != "braintree") { ?>style="display: none;"<?php } ?>>
|
152 |
+
<th scope="row" valign="top">
|
153 |
+
<label for="braintree_privatekey"><?php _e('Private Key', 'pmpro');?>:</label>
|
154 |
+
</th>
|
155 |
+
<td>
|
156 |
+
<input type="text" id="braintree_privatekey" name="braintree_privatekey" size="60" value="<?php echo esc_attr($values['braintree_privatekey'])?>" />
|
157 |
+
</td>
|
158 |
+
</tr>
|
159 |
+
<tr class="gateway gateway_braintree" <?php if($gateway != "braintree") { ?>style="display: none;"<?php } ?>>
|
160 |
+
<th scope="row" valign="top">
|
161 |
+
<label for="braintree_encryptionkey"><?php _e('Client-Side Encryption Key', 'pmpro');?>:</label>
|
162 |
+
</th>
|
163 |
+
<td>
|
164 |
+
<textarea id="braintree_encryptionkey" name="braintree_encryptionkey" rows="3" cols="80"><?php echo esc_textarea($values['braintree_encryptionkey'])?></textarea>
|
165 |
+
</td>
|
166 |
+
</tr>
|
167 |
+
<tr class="gateway gateway_braintree" <?php if($gateway != "braintree") { ?>style="display: none;"<?php } ?>>
|
168 |
+
<th scope="row" valign="top">
|
169 |
+
<label><?php _e('Web Hook URL', 'pmpro');?>:</label>
|
170 |
+
</th>
|
171 |
+
<td>
|
172 |
+
<p>
|
173 |
+
<?php _e('To fully integrate with Braintree, be sure to set your Web Hook URL to', 'pmpro');?>
|
174 |
+
<pre><?php
|
175 |
+
//echo admin_url("admin-ajax.php") . "?action=braintree_webhook";
|
176 |
+
echo PMPRO_URL . "/services/braintree-webhook.php";
|
177 |
+
?></pre>
|
178 |
+
</p>
|
179 |
+
</td>
|
180 |
+
</tr>
|
181 |
+
<?php
|
182 |
+
}
|
183 |
+
|
184 |
+
/**
|
185 |
+
* Filtering orders at checkout.
|
186 |
+
*
|
187 |
+
* @since 1.8
|
188 |
+
*/
|
189 |
+
static function pmpro_checkout_order($morder)
|
190 |
+
{
|
191 |
+
//load up values
|
192 |
+
if(isset($_REQUEST['number']))
|
193 |
+
$braintree_number = $_REQUEST['number'];
|
194 |
+
else
|
195 |
+
$braintree_number = "";
|
196 |
+
|
197 |
+
if(isset($_REQUEST['expiration_date']))
|
198 |
+
$braintree_expiration_date = $_REQUEST['expiration_date'];
|
199 |
+
else
|
200 |
+
$braintree_expiration_date = "";
|
201 |
+
|
202 |
+
if(isset($_REQUEST['cvv']))
|
203 |
+
$braintree_cvv = $_REQUEST['cvv'];
|
204 |
+
else
|
205 |
+
$braintree_cvv = "";
|
206 |
+
|
207 |
+
$morder->braintree = new stdClass();
|
208 |
+
$morder->braintree->number = $braintree_number;
|
209 |
+
$morder->braintree->expiration_date = $braintree_expiration_date;
|
210 |
+
$morder->braintree->cvv = $braintree_cvv;
|
211 |
+
|
212 |
+
return $morder;
|
213 |
+
}
|
214 |
+
|
215 |
+
/**
|
216 |
+
* Don't require the CVV, but look for cvv (lowercase) that braintree sends
|
217 |
+
*
|
218 |
+
*/
|
219 |
+
static function pmpro_required_billing_fields($fields)
|
220 |
+
{
|
221 |
+
unset($fields['CVV']);
|
222 |
+
$fields['cvv'] = true;
|
223 |
+
return $fields;
|
224 |
+
}
|
225 |
+
|
226 |
+
/**
|
227 |
+
* Add some hidden fields and JavaScript to checkout.
|
228 |
+
*
|
229 |
+
*/
|
230 |
+
static function pmpro_checkout_before_submit_button()
|
231 |
+
{
|
232 |
+
?>
|
233 |
+
<input type='hidden' data-encrypted-name='expiration_date' id='credit_card_exp' />
|
234 |
+
<input type='hidden' name='AccountNumber' id='BraintreeAccountNumber' />
|
235 |
+
<script type="text/javascript" src="https://js.braintreegateway.com/v1/braintree.js"></script>
|
236 |
+
<script type="text/javascript">
|
237 |
+
//setup braintree encryption
|
238 |
+
var braintree = Braintree.create('<?php echo pmpro_getOption("braintree_encryptionkey"); ?>');
|
239 |
+
braintree.onSubmitEncryptForm('pmpro_form');
|
240 |
+
|
241 |
+
//pass expiration dates in original format
|
242 |
+
function pmpro_updateBraintreeCardExp()
|
243 |
+
{
|
244 |
+
jQuery('#credit_card_exp').val(jQuery('#ExpirationMonth').val() + "/" + jQuery('#ExpirationYear').val());
|
245 |
+
}
|
246 |
+
jQuery('#ExpirationMonth, #ExpirationYear').change(function() {
|
247 |
+
pmpro_updateBraintreeCardExp();
|
248 |
+
});
|
249 |
+
pmpro_updateBraintreeCardExp();
|
250 |
+
|
251 |
+
//pass last 4 of credit card
|
252 |
+
function pmpro_updateBraintreeAccountNumber()
|
253 |
+
{
|
254 |
+
jQuery('#BraintreeAccountNumber').val('XXXXXXXXXXXXX' + jQuery('#AccountNumber').val().substr(jQuery('#AccountNumber').val().length - 4));
|
255 |
+
}
|
256 |
+
jQuery('#AccountNumber').change(function() {
|
257 |
+
pmpro_updateBraintreeAccountNumber();
|
258 |
+
});
|
259 |
+
pmpro_updateBraintreeAccountNumber();
|
260 |
+
</script>
|
261 |
+
<?php
|
262 |
+
}
|
263 |
+
|
264 |
+
/**
|
265 |
+
* Use our own payment fields at checkout. (Remove the name attributes and set some data-encrypted-name attributes.)
|
266 |
+
* @since 1.8
|
267 |
+
*/
|
268 |
+
static function pmpro_include_payment_information_fields($include)
|
269 |
+
{
|
270 |
+
//global vars
|
271 |
+
global $pmpro_requirebilling, $pmpro_show_discount_code, $discount_code, $CardType, $AccountNumber, $ExpirationMonth, $ExpirationYear;
|
272 |
+
|
273 |
+
//get accepted credit cards
|
274 |
+
$pmpro_accepted_credit_cards = pmpro_getOption("accepted_credit_cards");
|
275 |
+
$pmpro_accepted_credit_cards = explode(",", $pmpro_accepted_credit_cards);
|
276 |
+
$pmpro_accepted_credit_cards_string = pmpro_implodeToEnglish($pmpro_accepted_credit_cards);
|
277 |
+
|
278 |
+
//include ours
|
279 |
+
?>
|
280 |
+
<table id="pmpro_payment_information_fields" class="pmpro_checkout top1em" width="100%" cellpadding="0" cellspacing="0" border="0" <?php if(!$pmpro_requirebilling || apply_filters("pmpro_hide_payment_information_fields", false) ) { ?>style="display: none;"<?php } ?>>
|
281 |
+
<thead>
|
282 |
+
<tr>
|
283 |
+
<th><span class="pmpro_thead-msg"><?php printf(__('We Accept %s', 'pmpro'), $pmpro_accepted_credit_cards_string);?></span><?php _e('Payment Information', 'pmpro');?></th>
|
284 |
+
</tr>
|
285 |
+
</thead>
|
286 |
+
<tbody>
|
287 |
+
<tr valign="top">
|
288 |
+
<td>
|
289 |
+
<?php
|
290 |
+
$sslseal = pmpro_getOption("sslseal");
|
291 |
+
if($sslseal)
|
292 |
+
{
|
293 |
+
?>
|
294 |
+
<div class="pmpro_sslseal"><?php echo stripslashes($sslseal)?></div>
|
295 |
+
<?php
|
296 |
+
}
|
297 |
+
?>
|
298 |
+
<?php
|
299 |
+
$pmpro_include_cardtype_field = apply_filters('pmpro_include_cardtype_field', true);
|
300 |
+
if($pmpro_include_cardtype_field)
|
301 |
+
{
|
302 |
+
?>
|
303 |
+
<div class="pmpro_payment-card-type">
|
304 |
+
<label for="CardType"><?php _e('Card Type', 'pmpro');?></label>
|
305 |
+
<select id="CardType" name="CardType" class=" <?php echo pmpro_getClassForField("CardType");?>">
|
306 |
+
<?php foreach($pmpro_accepted_credit_cards as $cc) { ?>
|
307 |
+
<option value="<?php echo $cc?>" <?php if($CardType == $cc) { ?>selected="selected"<?php } ?>><?php echo $cc?></option>
|
308 |
+
<?php } ?>
|
309 |
+
</select>
|
310 |
+
</div>
|
311 |
+
<?php
|
312 |
+
}
|
313 |
+
?>
|
314 |
+
|
315 |
+
<div class="pmpro_payment-account-number">
|
316 |
+
<label for="AccountNumber"><?php _e('Card Number', 'pmpro');?></label>
|
317 |
+
<input id="AccountNumber" name="AccountNumber" class="input <?php echo pmpro_getClassForField("AccountNumber");?>" type="text" size="25" value="<?php echo esc_attr($AccountNumber)?>" data-encrypted-name="number" autocomplete="off" />
|
318 |
+
</div>
|
319 |
+
|
320 |
+
<div class="pmpro_payment-expiration">
|
321 |
+
<label for="ExpirationMonth"><?php _e('Expiration Date', 'pmpro');?></label>
|
322 |
+
<select id="ExpirationMonth" name="ExpirationMonth" class=" <?php echo pmpro_getClassForField("ExpirationMonth");?>">
|
323 |
+
<option value="01" <?php if($ExpirationMonth == "01") { ?>selected="selected"<?php } ?>>01</option>
|
324 |
+
<option value="02" <?php if($ExpirationMonth == "02") { ?>selected="selected"<?php } ?>>02</option>
|
325 |
+
<option value="03" <?php if($ExpirationMonth == "03") { ?>selected="selected"<?php } ?>>03</option>
|
326 |
+
<option value="04" <?php if($ExpirationMonth == "04") { ?>selected="selected"<?php } ?>>04</option>
|
327 |
+
<option value="05" <?php if($ExpirationMonth == "05") { ?>selected="selected"<?php } ?>>05</option>
|
328 |
+
<option value="06" <?php if($ExpirationMonth == "06") { ?>selected="selected"<?php } ?>>06</option>
|
329 |
+
<option value="07" <?php if($ExpirationMonth == "07") { ?>selected="selected"<?php } ?>>07</option>
|
330 |
+
<option value="08" <?php if($ExpirationMonth == "08") { ?>selected="selected"<?php } ?>>08</option>
|
331 |
+
<option value="09" <?php if($ExpirationMonth == "09") { ?>selected="selected"<?php } ?>>09</option>
|
332 |
+
<option value="10" <?php if($ExpirationMonth == "10") { ?>selected="selected"<?php } ?>>10</option>
|
333 |
+
<option value="11" <?php if($ExpirationMonth == "11") { ?>selected="selected"<?php } ?>>11</option>
|
334 |
+
<option value="12" <?php if($ExpirationMonth == "12") { ?>selected="selected"<?php } ?>>12</option>
|
335 |
+
</select>/<select id="ExpirationYear" name="ExpirationYear" class=" <?php echo pmpro_getClassForField("ExpirationYear");?>">
|
336 |
+
<?php
|
337 |
+
for($i = date("Y"); $i < date("Y") + 10; $i++)
|
338 |
+
{
|
339 |
+
?>
|
340 |
+
<option value="<?php echo $i?>" <?php if($ExpirationYear == $i) { ?>selected="selected"<?php } ?>><?php echo $i?></option>
|
341 |
+
<?php
|
342 |
+
}
|
343 |
+
?>
|
344 |
+
</select>
|
345 |
+
</div>
|
346 |
+
|
347 |
+
<?php
|
348 |
+
$pmpro_show_cvv = apply_filters("pmpro_show_cvv", true);
|
349 |
+
if($pmpro_show_cvv)
|
350 |
+
{
|
351 |
+
?>
|
352 |
+
<div class="pmpro_payment-cvv">
|
353 |
+
<label for="CVV"><?php _ex('CVV', 'Credit card security code, CVV/CCV/CVV2', 'pmpro');?></label>
|
354 |
+
<input class="input" id="CVV" name="cvv" type="text" size="4" value="<?php if(!empty($_REQUEST['CVV'])) { echo esc_attr($_REQUEST['CVV']); }?>" class=" <?php echo pmpro_getClassForField("CVV");?>" data-encrypted-name="cvv" /> <small>(<a href="javascript:void(0);" onclick="javascript:window.open('<?php echo pmpro_https_filter(PMPRO_URL)?>/pages/popup-cvv.html','cvv','toolbar=no, location=no, directories=no, status=no, menubar=no, scrollbars=yes, resizable=yes, width=600, height=475');"><?php _ex("what's this?", 'link to CVV help', 'pmpro');?></a>)</small>
|
355 |
+
</div>
|
356 |
+
<?php
|
357 |
+
}
|
358 |
+
?>
|
359 |
+
|
360 |
+
<?php if($pmpro_show_discount_code) { ?>
|
361 |
+
<div class="pmpro_payment-discount-code">
|
362 |
+
<label for="discount_code"><?php _e('Discount Code', 'pmpro');?></label>
|
363 |
+
<input class="input <?php echo pmpro_getClassForField("discount_code");?>" id="discount_code" name="discount_code" type="text" size="20" value="<?php echo esc_attr($discount_code)?>" />
|
364 |
+
<input type="button" id="discount_code_button" name="discount_code_button" value="<?php _e('Apply', 'pmpro');?>" />
|
365 |
+
<p id="discount_code_message" class="pmpro_message" style="display: none;"></p>
|
366 |
+
</div>
|
367 |
+
<?php } ?>
|
368 |
+
|
369 |
+
</td>
|
370 |
+
</tr>
|
371 |
+
</tbody>
|
372 |
+
</table>
|
373 |
+
<?php
|
374 |
+
|
375 |
+
//don't include the default
|
376 |
+
return false;
|
377 |
+
}
|
378 |
+
|
379 |
+
/**
|
380 |
+
* Process checkout.
|
381 |
+
*
|
382 |
+
*/
|
383 |
+
function process(&$order)
|
384 |
+
{
|
385 |
+
//check for initial payment
|
386 |
+
if(floatval($order->InitialPayment) == 0)
|
387 |
+
{
|
388 |
+
//just subscribe
|
389 |
+
return $this->subscribe($order);
|
390 |
+
}
|
391 |
+
else
|
392 |
+
{
|
393 |
+
//charge then subscribe
|
394 |
+
if($this->charge($order))
|
395 |
+
{
|
396 |
+
if(pmpro_isLevelRecurring($order->membership_level))
|
397 |
+
{
|
398 |
+
if($this->subscribe($order))
|
399 |
+
{
|
400 |
+
//yay!
|
401 |
+
return true;
|
402 |
+
}
|
403 |
+
else
|
404 |
+
{
|
405 |
+
//try to refund initial charge
|
406 |
+
return false;
|
407 |
+
}
|
408 |
+
}
|
409 |
+
else
|
410 |
+
{
|
411 |
+
//only a one time charge
|
412 |
+
$order->status = "success"; //saved on checkout page
|
413 |
+
return true;
|
414 |
+
}
|
415 |
+
}
|
416 |
+
else
|
417 |
+
{
|
418 |
+
if(empty($order->error))
|
419 |
+
$order->error = __("Unknown error: Initial payment failed.", "pmpro");
|
420 |
+
return false;
|
421 |
+
}
|
422 |
+
}
|
423 |
+
}
|
424 |
+
|
425 |
+
function charge(&$order)
|
426 |
+
{
|
427 |
+
//create a code for the order
|
428 |
+
if(empty($order->code))
|
429 |
+
$order->code = $order->getRandomCode();
|
430 |
+
|
431 |
+
//what amount to charge?
|
432 |
+
$amount = $order->InitialPayment;
|
433 |
+
|
434 |
+
//tax
|
435 |
+
$order->subtotal = $amount;
|
436 |
+
$tax = $order->getTax(true);
|
437 |
+
$amount = round((float)$order->subtotal + (float)$tax, 2);
|
438 |
+
|
439 |
+
//create a customer
|
440 |
+
$this->getCustomer($order);
|
441 |
+
if(empty($this->customer) || !empty($order->error))
|
442 |
+
{
|
443 |
+
//failed to create customer
|
444 |
+
return false;
|
445 |
+
}
|
446 |
+
|
447 |
+
//charge
|
448 |
+
try
|
449 |
+
{
|
450 |
+
$response = Braintree_Transaction::sale(array(
|
451 |
+
'amount' => $amount,
|
452 |
+
'customerId' => $this->customer->id
|
453 |
+
));
|
454 |
+
}
|
455 |
+
catch (Exception $e)
|
456 |
+
{
|
457 |
+
//$order->status = "error";
|
458 |
+
$order->errorcode = true;
|
459 |
+
$order->error = "Error: " . $e->getMessage();
|
460 |
+
$order->shorterror = $order->error;
|
461 |
+
return false;
|
462 |
+
}
|
463 |
+
|
464 |
+
if($response->success)
|
465 |
+
{
|
466 |
+
//successful charge
|
467 |
+
$transaction_id = $response->transaction->id;
|
468 |
+
$response = Braintree_Transaction::submitForSettlement($transaction_id);
|
469 |
+
if($response->success)
|
470 |
+
{
|
471 |
+
$order->payment_transaction_id = $transaction_id;
|
472 |
+
$order->updateStatus("success");
|
473 |
+
return true;
|
474 |
+
}
|
475 |
+
else
|
476 |
+
{
|
477 |
+
$order->errorcode = true;
|
478 |
+
$order->error = __("Error during settlement:", "pmpro") . " " . $response->message;
|
479 |
+
$order->shorterror = $response->message;
|
480 |
+
return false;
|
481 |
+
}
|
482 |
+
}
|
483 |
+
else
|
484 |
+
{
|
485 |
+
//$order->status = "error";
|
486 |
+
$order->errorcode = true;
|
487 |
+
$order->error = __("Error during charge:", "pmpro") . " " . $response->message;
|
488 |
+
$order->shorterror = $response->message;
|
489 |
+
return false;
|
490 |
+
}
|
491 |
+
}
|
492 |
+
|
493 |
+
/*
|
494 |
+
This function will return a Braintree customer object.
|
495 |
+
If $this->customer is set, it returns it.
|
496 |
+
It first checks if the order has a subscription_transaction_id. If so, that's the customer id.
|
497 |
+
If not, it checks for a user_id on the order and searches for a customer id in the user meta.
|
498 |
+
If a customer id is found, it checks for a customer through the Braintree API.
|
499 |
+
If a customer is found and there is an AccountNumber on the order passed, it will update the customer.
|
500 |
+
If no customer is found and there is an AccountNumber on the order passed, it will create a customer.
|
501 |
+
*/
|
502 |
+
function getCustomer(&$order, $force = false)
|
503 |
+
{
|
504 |
+
global $current_user;
|
505 |
+
|
506 |
+
//already have it?
|
507 |
+
if(!empty($this->customer) && !$force)
|
508 |
+
return $this->customer;
|
509 |
+
|
510 |
+
//try based on user id
|
511 |
+
if(!empty($order->user_id))
|
512 |
+
$user_id = $order->user_id;
|
513 |
+
|
514 |
+
//if no id passed, check the current user
|
515 |
+
if(empty($user_id) && !empty($current_user->ID))
|
516 |
+
$user_id = $current_user->ID;
|
517 |
+
|
518 |
+
//check for a braintree customer id
|
519 |
+
if(!empty($user_id))
|
520 |
+
{
|
521 |
+
$customer_id = get_user_meta($user_id, "pmpro_braintree_customerid", true);
|
522 |
+
}
|
523 |
+
|
524 |
+
//check for an existing stripe customer
|
525 |
+
if(!empty($customer_id))
|
526 |
+
{
|
527 |
+
try
|
528 |
+
{
|
529 |
+
$this->customer = Braintree_Customer::find($customer_id);
|
530 |
+
|
531 |
+
//update the customer address, description and card
|
532 |
+
if(!empty($order->accountnumber))
|
533 |
+
{
|
534 |
+
//put data in array for Braintree API calls
|
535 |
+
$update_array = array(
|
536 |
+
'firstName' => $order->FirstName,
|
537 |
+
'lastName' => $order->LastName,
|
538 |
+
'creditCard' => array(
|
539 |
+
'number' => $order->braintree->number,
|
540 |
+
'expirationDate' => $order->braintree->expiration_date,
|
541 |
+
'cardholderName' => trim($order->FirstName . " " . $order->LastName),
|
542 |
+
'options' => array(
|
543 |
+
'updateExistingToken' => $this->customer->creditCards[0]->token
|
544 |
+
)
|
545 |
+
)
|
546 |
+
);
|
547 |
+
|
548 |
+
//address too?
|
549 |
+
if(!empty($order->billing))
|
550 |
+
//make sure Address2 is set
|
551 |
+
if(!isset($order->Address2))
|
552 |
+
$order->Address2 = '';
|
553 |
+
|
554 |
+
//add billing address to array
|
555 |
+
$update_array['creditCard']['billingAddress'] = array(
|
556 |
+
'firstName' => $order->FirstName,
|
557 |
+
'lastName' => $order->LastName,
|
558 |
+
'streetAddress' => $order->Address1,
|
559 |
+
'extendedAddress' => $order->Address2,
|
560 |
+
'locality' => $order->billing->city,
|
561 |
+
'region' => $order->billing->state,
|
562 |
+
'postalCode' => $order->billing->zip,
|
563 |
+
'countryCodeAlpha2' => $order->billing->country,
|
564 |
+
'options' => array(
|
565 |
+
'updateExisting' => true
|
566 |
+
)
|
567 |
+
);
|
568 |
+
|
569 |
+
//update
|
570 |
+
$response = Braintree_Customer::update($customer_id, $update_array);
|
571 |
+
|
572 |
+
if($response->success)
|
573 |
+
{
|
574 |
+
$this->customer = $response->customer;
|
575 |
+
return $this->customer;
|
576 |
+
}
|
577 |
+
else
|
578 |
+
{
|
579 |
+
$order->error = __("Failed to update customer.", "pmpro") . " " . $response->message;
|
580 |
+
$order->shorterror = $order->error;
|
581 |
+
return false;
|
582 |
+
}
|
583 |
+
}
|
584 |
+
|
585 |
+
return $this->customer;
|
586 |
+
}
|
587 |
+
catch (Exception $e)
|
588 |
+
{
|
589 |
+
//assume no customer found
|
590 |
+
}
|
591 |
+
}
|
592 |
+
|
593 |
+
//no customer id, create one
|
594 |
+
if(!empty($order->accountnumber))
|
595 |
+
{
|
596 |
+
try
|
597 |
+
{
|
598 |
+
$result = Braintree_Customer::create(array(
|
599 |
+
'firstName' => $order->FirstName,
|
600 |
+
'lastName' => $order->LastName,
|
601 |
+
'email' => $order->Email,
|
602 |
+
'phone' => $order->billing->phone,
|
603 |
+
'creditCard' => array(
|
604 |
+
'number' => $order->braintree->number,
|
605 |
+
'expirationDate' => $order->braintree->expiration_date,
|
606 |
+
'cvv' => $order->braintree->cvv,
|
607 |
+
'cardholderName' => trim($order->FirstName . " " . $order->LastName),
|
608 |
+
'billingAddress' => array(
|
609 |
+
'firstName' => $order->FirstName,
|
610 |
+
'lastName' => $order->LastName,
|
611 |
+
'streetAddress' => $order->Address1,
|
612 |
+
'extendedAddress' => $order->Address2,
|
613 |
+
'locality' => $order->billing->city,
|
614 |
+
'region' => $order->billing->state,
|
615 |
+
'postalCode' => $order->billing->zip,
|
616 |
+
'countryCodeAlpha2' => $order->billing->country
|
617 |
+
)
|
618 |
+
)
|
619 |
+
));
|
620 |
+
|
621 |
+
if($result->success)
|
622 |
+
{
|
623 |
+
$this->customer = $result->customer;
|
624 |
+
}
|
625 |
+
else
|
626 |
+
{
|
627 |
+
$order->error = __("Failed to create customer.", "pmpro") . " " . $result->message;
|
628 |
+
$order->shorterror = $order->error;
|
629 |
+
return false;
|
630 |
+
}
|
631 |
+
}
|
632 |
+
catch (Exception $e)
|
633 |
+
{
|
634 |
+
$order->error = __("Error creating customer record with Braintree:", "pmpro") . " " . $e->getMessage();
|
635 |
+
$order->shorterror = $order->error;
|
636 |
+
return false;
|
637 |
+
}
|
638 |
+
|
639 |
+
//if we have no user id, we need to set the customer id after the user is created
|
640 |
+
if(empty($user_id))
|
641 |
+
{
|
642 |
+
global $pmpro_braintree_customerid;
|
643 |
+
$pmpro_braintree_customerid = $this->customer->id;
|
644 |
+
add_action('user_register', array('PMProGateway_braintree','user_register'));
|
645 |
+
}
|
646 |
+
else
|
647 |
+
update_user_meta($user_id, "pmpro_braintree_customerid", $this->customer->id);
|
648 |
+
|
649 |
+
return $this->customer;
|
650 |
+
}
|
651 |
+
|
652 |
+
return false;
|
653 |
+
}
|
654 |
+
|
655 |
+
function subscribe(&$order)
|
656 |
+
{
|
657 |
+
//create a code for the order
|
658 |
+
if(empty($order->code))
|
659 |
+
$order->code = $order->getRandomCode();
|
660 |
+
|
661 |
+
//setup customer
|
662 |
+
$this->getCustomer($order);
|
663 |
+
if(empty($this->customer) || !empty($order->error))
|
664 |
+
return false; //error retrieving customer
|
665 |
+
|
666 |
+
//figure out the amounts
|
667 |
+
$amount = $order->PaymentAmount;
|
668 |
+
$amount_tax = $order->getTaxForPrice($amount);
|
669 |
+
$amount = round((float)$amount + (float)$amount_tax, 2);
|
670 |
+
|
671 |
+
/*
|
672 |
+
There are two parts to the trial. Part 1 is simply the delay until the first payment
|
673 |
+
since we are doing the first payment as a separate transaction.
|
674 |
+
The second part is the actual "trial" set by the admin.
|
675 |
+
|
676 |
+
Stripe only supports Year or Month for billing periods, but we account for Days and Weeks just in case.
|
677 |
+
*/
|
678 |
+
//figure out the trial length (first payment handled by initial charge)
|
679 |
+
if($order->BillingPeriod == "Year")
|
680 |
+
$trial_period_days = $order->BillingFrequency * 365; //annual
|
681 |
+
elseif($order->BillingPeriod == "Day")
|
682 |
+
$trial_period_days = $order->BillingFrequency * 1; //daily
|
683 |
+
elseif($order->BillingPeriod == "Week")
|
684 |
+
$trial_period_days = $order->BillingFrequency * 7; //weekly
|
685 |
+
else
|
686 |
+
$trial_period_days = $order->BillingFrequency * 30; //assume monthly
|
687 |
+
|
688 |
+
//convert to a profile start date
|
689 |
+
$order->ProfileStartDate = date("Y-m-d", strtotime("+ " . $trial_period_days . " Day", current_time("timestamp"))) . "T0:0:0";
|
690 |
+
|
691 |
+
//filter the start date
|
692 |
+
$order->ProfileStartDate = apply_filters("pmpro_profile_start_date", $order->ProfileStartDate, $order);
|
693 |
+
|
694 |
+
//convert back to days
|
695 |
+
$trial_period_days = ceil(abs(strtotime(date("Y-m-d")) - strtotime($order->ProfileStartDate, current_time("timestamp"))) / 86400);
|
696 |
+
|
697 |
+
//now add the actual trial set by the site
|
698 |
+
if(!empty($order->TrialBillingCycles))
|
699 |
+
{
|
700 |
+
$trialOccurrences = (int)$order->TrialBillingCycles;
|
701 |
+
if($order->BillingPeriod == "Year")
|
702 |
+
$trial_period_days = $trial_period_days + (365 * $order->BillingFrequency * $trialOccurrences); //annual
|
703 |
+
elseif($order->BillingPeriod == "Day")
|
704 |
+
$trial_period_days = $trial_period_days + (1 * $order->BillingFrequency * $trialOccurrences); //daily
|
705 |
+
elseif($order->BillingPeriod == "Week")
|
706 |
+
$trial_period_days = $trial_period_days + (7 * $order->BillingFrequency * $trialOccurrences); //weekly
|
707 |
+
else
|
708 |
+
$trial_period_days = $trial_period_days + (30 * $order->BillingFrequency * $trialOccurrences); //assume monthly
|
709 |
+
}
|
710 |
+
|
711 |
+
//subscribe to the plan
|
712 |
+
try
|
713 |
+
{
|
714 |
+
$details = array(
|
715 |
+
'paymentMethodToken' => $this->customer->creditCards[0]->token,
|
716 |
+
'planId' => 'pmpro_' . $order->membership_id,
|
717 |
+
'price' => $amount
|
718 |
+
);
|
719 |
+
|
720 |
+
if(!empty($trial_period_days))
|
721 |
+
{
|
722 |
+
$details['trialPeriod'] = true;
|
723 |
+
$details['trialDuration'] = $trial_period_days;
|
724 |
+
$details['trialDurationUnit'] = "day";
|
725 |
+
}
|
726 |
+
|
727 |
+
if(!empty($order->TotalBillingCycles))
|
728 |
+
$details['numberOfBillingCycles'] = $order->TotalBillingCycles;
|
729 |
+
|
730 |
+
$result = Braintree_Subscription::create($details);
|
731 |
+
}
|
732 |
+
catch (Exception $e)
|
733 |
+
{
|
734 |
+
$order->error = __("Error subscribing customer to plan with Braintree:", "pmpro") . " " . $e->getMessage();
|
735 |
+
//return error
|
736 |
+
$order->shorterror = $order->error;
|
737 |
+
return false;
|
738 |
+
}
|
739 |
+
|
740 |
+
if($result->success)
|
741 |
+
{
|
742 |
+
//if we got this far, we're all good
|
743 |
+
$order->status = "success";
|
744 |
+
$order->subscription_transaction_id = $result->subscription->id;
|
745 |
+
return true;
|
746 |
+
}
|
747 |
+
else
|
748 |
+
{
|
749 |
+
$order->error = __("Failed to subscribe with Braintree:", "pmpro") . " " . $result->message;
|
750 |
+
$order->shorterror = $result->message;
|
751 |
+
return false;
|
752 |
+
}
|
753 |
+
}
|
754 |
+
|
755 |
+
function update(&$order)
|
756 |
+
{
|
757 |
+
//we just have to run getCustomer which will look for the customer and update it with the new token
|
758 |
+
$this->getCustomer($order, true);
|
759 |
+
|
760 |
+
if(!empty($this->customer) && empty($order->error))
|
761 |
+
{
|
762 |
+
return true;
|
763 |
+
}
|
764 |
+
else
|
765 |
+
{
|
766 |
+
return false; //couldn't find the customer
|
767 |
+
}
|
768 |
+
}
|
769 |
+
|
770 |
+
function cancel(&$order)
|
771 |
+
{
|
772 |
+
//require a subscription id
|
773 |
+
if(empty($order->subscription_transaction_id))
|
774 |
+
return false;
|
775 |
+
|
776 |
+
//find the customer
|
777 |
+
if(!empty($order->subscription_transaction_id))
|
778 |
+
{
|
779 |
+
//cancel
|
780 |
+
try
|
781 |
+
{
|
782 |
+
$result = Braintree_Subscription::cancel($order->subscription_transaction_id);
|
783 |
+
}
|
784 |
+
catch(Exception $e)
|
785 |
+
{
|
786 |
+
$order->updateStatus("cancelled"); //assume it's been cancelled already
|
787 |
+
$order->error = __("Could not find the subscription.", "pmpro") . " " . $e->getMessage();
|
788 |
+
$order->shorterror = $order->error;
|
789 |
+
return false; //no subscription found
|
790 |
+
}
|
791 |
+
|
792 |
+
if($result->success)
|
793 |
+
{
|
794 |
+
$order->updateStatus("cancelled");
|
795 |
+
return true;
|
796 |
+
}
|
797 |
+
else
|
798 |
+
{
|
799 |
+
$order->updateStatus("cancelled"); //assume it's been cancelled already
|
800 |
+
$order->error = __("Could not find the subscription.", "pmpro") . " " . $result->message;
|
801 |
+
$order->shorterror = $order->error;
|
802 |
+
return false; //no subscription found
|
803 |
+
}
|
804 |
+
}
|
805 |
+
else
|
806 |
+
{
|
807 |
+
$order->error = __("Could not find the subscription.", "pmpro");
|
808 |
+
$order->shorterror = $order->error;
|
809 |
+
return false; //no customer found
|
810 |
+
}
|
811 |
+
}
|
812 |
+
|
813 |
+
/*
|
814 |
+
Save Braintree customer id after the user is registered.
|
815 |
+
*/
|
816 |
+
static function user_register($user_id)
|
817 |
+
{
|
818 |
+
global $pmpro_braintree_customerid;
|
819 |
+
if(!empty($pmpro_braintree_customerid))
|
820 |
+
{
|
821 |
+
update_user_meta($user_id, 'pmpro_braintree_customerid', $pmpro_braintree_customerid);
|
822 |
+
}
|
823 |
+
}
|
824 |
+
}
|
classes/gateways/class.pmprogateway_check.php
CHANGED
@@ -1,341 +1,341 @@
|
|
1 |
-
<?php
|
2 |
-
//include pmprogateway
|
3 |
-
require_once(dirname(__FILE__) . "/class.pmprogateway.php");
|
4 |
-
|
5 |
-
//load classes init method
|
6 |
-
add_action('init', array('PMProGateway_check', 'init'));
|
7 |
-
|
8 |
-
class PMProGateway_check extends PMProGateway
|
9 |
-
{
|
10 |
-
function PMProGateway_check($gateway = NULL)
|
11 |
-
{
|
12 |
-
$this->gateway = $gateway;
|
13 |
-
return $this->gateway;
|
14 |
-
}
|
15 |
-
|
16 |
-
/**
|
17 |
-
* Run on WP init
|
18 |
-
*
|
19 |
-
* @since 1.8
|
20 |
-
*/
|
21 |
-
static function init()
|
22 |
-
{
|
23 |
-
//make sure Pay by Check is a gateway option
|
24 |
-
add_filter('pmpro_gateways', array('PMProGateway_check', 'pmpro_gateways'));
|
25 |
-
|
26 |
-
//add fields to payment settings
|
27 |
-
add_filter('pmpro_payment_options', array('PMProGateway_check', 'pmpro_payment_options'));
|
28 |
-
add_filter('pmpro_payment_option_fields', array('PMProGateway_check', 'pmpro_payment_option_fields'), 10, 2);
|
29 |
-
|
30 |
-
//code to add at checkout
|
31 |
-
$gateway = pmpro_getGateway();
|
32 |
-
if($gateway == "check")
|
33 |
-
{
|
34 |
-
add_filter('pmpro_include_billing_address_fields', '__return_false');
|
35 |
-
add_filter('pmpro_include_payment_information_fields', '__return_false');
|
36 |
-
add_filter('pmpro_required_billing_fields', array('PMProGateway_check', 'pmpro_required_billing_fields'));
|
37 |
-
}
|
38 |
-
}
|
39 |
-
|
40 |
-
/**
|
41 |
-
* Make sure Check is in the gateways list
|
42 |
-
*
|
43 |
-
* @since 1.8
|
44 |
-
*/
|
45 |
-
static function pmpro_gateways($gateways)
|
46 |
-
{
|
47 |
-
if(empty($gateways['check']))
|
48 |
-
$gateways['check'] = __('Pay by Check', 'pmpro');
|
49 |
-
|
50 |
-
return $gateways;
|
51 |
-
}
|
52 |
-
|
53 |
-
/**
|
54 |
-
* Get a list of payment options that the Check gateway needs/supports.
|
55 |
-
*
|
56 |
-
* @since 1.8
|
57 |
-
*/
|
58 |
-
static function getGatewayOptions()
|
59 |
-
{
|
60 |
-
$options = array(
|
61 |
-
'sslseal',
|
62 |
-
'nuclear_HTTPS',
|
63 |
-
'gateway_environment',
|
64 |
-
'instructions',
|
65 |
-
'currency',
|
66 |
-
'use_ssl',
|
67 |
-
'tax_state',
|
68 |
-
'tax_rate'
|
69 |
-
);
|
70 |
-
|
71 |
-
return $options;
|
72 |
-
}
|
73 |
-
|
74 |
-
/**
|
75 |
-
* Set payment options for payment settings page.
|
76 |
-
*
|
77 |
-
* @since 1.8
|
78 |
-
*/
|
79 |
-
static function pmpro_payment_options($options)
|
80 |
-
{
|
81 |
-
//get stripe options
|
82 |
-
$check_options = PMProGateway_check::getGatewayOptions();
|
83 |
-
|
84 |
-
//merge with others.
|
85 |
-
$options = array_merge($check_options, $options);
|
86 |
-
|
87 |
-
return $options;
|
88 |
-
}
|
89 |
-
|
90 |
-
/**
|
91 |
-
* Display fields for Check options.
|
92 |
-
*
|
93 |
-
* @since 1.8
|
94 |
-
*/
|
95 |
-
static function pmpro_payment_option_fields($values, $gateway)
|
96 |
-
{
|
97 |
-
?>
|
98 |
-
<tr class="pmpro_settings_divider gateway gateway_check" <?php if($gateway != "check") { ?>style="display: none;"<?php } ?>>
|
99 |
-
<td colspan="2">
|
100 |
-
<?php _e('Pay by Check Settings', 'pmpro'); ?>
|
101 |
-
</td>
|
102 |
-
</tr>
|
103 |
-
<tr class="gateway gateway_check" <?php if($gateway != "check") { ?>style="display: none;"<?php } ?>>
|
104 |
-
<th scope="row" valign="top">
|
105 |
-
<label for="instructions"><?php _e('Instructions', 'pmpro');?></label>
|
106 |
-
</th>
|
107 |
-
<td>
|
108 |
-
<textarea id="instructions" name="instructions" rows="3" cols="80"><?php echo esc_textarea($values['instructions'])?></textarea>
|
109 |
-
<p><small><?php _e('Who to write the check out to. Where to mail it. Shown on checkout, confirmation, and invoice pages.', 'pmpro');?></small></p>
|
110 |
-
</td>
|
111 |
-
</tr>
|
112 |
-
<?php
|
113 |
-
}
|
114 |
-
|
115 |
-
/**
|
116 |
-
* Remove required billing fields
|
117 |
-
*
|
118 |
-
* @since 1.8
|
119 |
-
*/
|
120 |
-
static function pmpro_required_billing_fields($fields)
|
121 |
-
{
|
122 |
-
unset($fields['bfirstname']);
|
123 |
-
unset($fields['blastname']);
|
124 |
-
unset($fields['baddress1']);
|
125 |
-
unset($fields['bcity']);
|
126 |
-
unset($fields['bstate']);
|
127 |
-
unset($fields['bzipcode']);
|
128 |
-
unset($fields['bphone']);
|
129 |
-
unset($fields['bemail']);
|
130 |
-
unset($fields['bcountry']);
|
131 |
-
unset($fields['CardType']);
|
132 |
-
unset($fields['AccountNumber']);
|
133 |
-
unset($fields['ExpirationMonth']);
|
134 |
-
unset($fields['ExpirationYear']);
|
135 |
-
unset($fields['CVV']);
|
136 |
-
|
137 |
-
return $fields;
|
138 |
-
}
|
139 |
-
|
140 |
-
/**
|
141 |
-
* Process checkout.
|
142 |
-
*
|
143 |
-
*/
|
144 |
-
function process(&$order)
|
145 |
-
{
|
146 |
-
//clean up a couple values
|
147 |
-
$order->payment_type = "Check";
|
148 |
-
$order->CardType = "";
|
149 |
-
$order->cardtype = "";
|
150 |
-
|
151 |
-
//check for initial payment
|
152 |
-
if(floatval($order->InitialPayment) == 0)
|
153 |
-
{
|
154 |
-
//auth first, then process
|
155 |
-
if($this->authorize($order))
|
156 |
-
{
|
157 |
-
$this->void($order);
|
158 |
-
if(!pmpro_isLevelTrial($order->membership_level))
|
159 |
-
{
|
160 |
-
//subscription will start today with a 1 period trial
|
161 |
-
$order->ProfileStartDate = date("Y-m-d") . "T0:0:0";
|
162 |
-
$order->TrialBillingPeriod = $order->BillingPeriod;
|
163 |
-
$order->TrialBillingFrequency = $order->BillingFrequency;
|
164 |
-
$order->TrialBillingCycles = 1;
|
165 |
-
$order->TrialAmount = 0;
|
166 |
-
|
167 |
-
//add a billing cycle to make up for the trial, if applicable
|
168 |
-
if(!empty($order->TotalBillingCycles))
|
169 |
-
$order->TotalBillingCycles++;
|
170 |
-
}
|
171 |
-
elseif($order->InitialPayment == 0 && $order->TrialAmount == 0)
|
172 |
-
{
|
173 |
-
//it has a trial, but the amount is the same as the initial payment, so we can squeeze it in there
|
174 |
-
$order->ProfileStartDate = date("Y-m-d") . "T0:0:0";
|
175 |
-
$order->TrialBillingCycles++;
|
176 |
-
|
177 |
-
//add a billing cycle to make up for the trial, if applicable
|
178 |
-
if($order->TotalBillingCycles)
|
179 |
-
$order->TotalBillingCycles++;
|
180 |
-
}
|
181 |
-
else
|
182 |
-
{
|
183 |
-
//add a period to the start date to account for the initial payment
|
184 |
-
$order->ProfileStartDate = date("Y-m-d", strtotime("+ " . $order->BillingFrequency . " " . $order->BillingPeriod, current_time("timestamp"))) . "T0:0:0";
|
185 |
-
}
|
186 |
-
|
187 |
-
$order->ProfileStartDate = apply_filters("pmpro_profile_start_date", $order->ProfileStartDate, $order);
|
188 |
-
return $this->subscribe($order);
|
189 |
-
}
|
190 |
-
else
|
191 |
-
{
|
192 |
-
if(empty($order->error))
|
193 |
-
$order->error = __("Unknown error: Authorization failed.", "pmpro");
|
194 |
-
return false;
|
195 |
-
}
|
196 |
-
}
|
197 |
-
else
|
198 |
-
{
|
199 |
-
//charge first payment
|
200 |
-
if($this->charge($order))
|
201 |
-
{
|
202 |
-
//setup recurring billing
|
203 |
-
if(pmpro_isLevelRecurring($order->membership_level))
|
204 |
-
{
|
205 |
-
if(!pmpro_isLevelTrial($order->membership_level))
|
206 |
-
{
|
207 |
-
//subscription will start today with a 1 period trial
|
208 |
-
$order->ProfileStartDate = date("Y-m-d") . "T0:0:0";
|
209 |
-
$order->TrialBillingPeriod = $order->BillingPeriod;
|
210 |
-
$order->TrialBillingFrequency = $order->BillingFrequency;
|
211 |
-
$order->TrialBillingCycles = 1;
|
212 |
-
$order->TrialAmount = 0;
|
213 |
-
|
214 |
-
//add a billing cycle to make up for the trial, if applicable
|
215 |
-
if(!empty($order->TotalBillingCycles))
|
216 |
-
$order->TotalBillingCycles++;
|
217 |
-
}
|
218 |
-
elseif($order->InitialPayment == 0 && $order->TrialAmount == 0)
|
219 |
-
{
|
220 |
-
//it has a trial, but the amount is the same as the initial payment, so we can squeeze it in there
|
221 |
-
$order->ProfileStartDate = date("Y-m-d") . "T0:0:0";
|
222 |
-
$order->TrialBillingCycles++;
|
223 |
-
|
224 |
-
//add a billing cycle to make up for the trial, if applicable
|
225 |
-
if(!empty($order->TotalBillingCycles))
|
226 |
-
$order->TotalBillingCycles++;
|
227 |
-
}
|
228 |
-
else
|
229 |
-
{
|
230 |
-
//add a period to the start date to account for the initial payment
|
231 |
-
$order->ProfileStartDate = date("Y-m-d", strtotime("+ " . $this->BillingFrequency . " " . $this->BillingPeriod, current_time("timestamp"))) . "T0:0:0";
|
232 |
-
}
|
233 |
-
|
234 |
-
$order->ProfileStartDate = apply_filters("pmpro_profile_start_date", $order->ProfileStartDate, $order);
|
235 |
-
if($this->subscribe($order))
|
236 |
-
{
|
237 |
-
return true;
|
238 |
-
}
|
239 |
-
else
|
240 |
-
{
|
241 |
-
if($this->void($order))
|
242 |
-
{
|
243 |
-
if(!$order->error)
|
244 |
-
$order->error = __("Unknown error: Payment failed.", "pmpro");
|
245 |
-
}
|
246 |
-
else
|
247 |
-
{
|
248 |
-
if(!$order->error)
|
249 |
-
$order->error = __("Unknown error: Payment failed.", "pmpro");
|
250 |
-
|
251 |
-
$order->error .= " " . __("A partial payment was made that we could not void. Please contact the site owner immediately to correct this.", "pmpro");
|
252 |
-
}
|
253 |
-
|
254 |
-
return false;
|
255 |
-
}
|
256 |
-
}
|
257 |
-
else
|
258 |
-
{
|
259 |
-
//only a one time charge
|
260 |
-
$order->status = apply_filters("pmpro_check_status_after_checkout", "success"); //saved on checkout page
|
261 |
-
return true;
|
262 |
-
}
|
263 |
-
}
|
264 |
-
else
|
265 |
-
{
|
266 |
-
if(empty($order->error))
|
267 |
-
$order->error = __("Unknown error: Payment failed.", "pmpro");
|
268 |
-
|
269 |
-
return false;
|
270 |
-
}
|
271 |
-
}
|
272 |
-
}
|
273 |
-
|
274 |
-
function authorize(&$order)
|
275 |
-
{
|
276 |
-
//create a code for the order
|
277 |
-
if(empty($order->code))
|
278 |
-
$order->code = $order->getRandomCode();
|
279 |
-
|
280 |
-
//simulate a successful authorization
|
281 |
-
$order->payment_transaction_id = "CHECK" . $order->code;
|
282 |
-
$order->updateStatus("authorized");
|
283 |
-
return true;
|
284 |
-
}
|
285 |
-
|
286 |
-
function void(&$order)
|
287 |
-
{
|
288 |
-
//need a transaction id
|
289 |
-
if(empty($order->payment_transaction_id))
|
290 |
-
return false;
|
291 |
-
|
292 |
-
//simulate a successful void
|
293 |
-
$order->payment_transaction_id = "CHECK" . $order->code;
|
294 |
-
$order->updateStatus("voided");
|
295 |
-
return true;
|
296 |
-
}
|
297 |
-
|
298 |
-
function charge(&$order)
|
299 |
-
{
|
300 |
-
//create a code for the order
|
301 |
-
if(empty($order->code))
|
302 |
-
$order->code = $order->getRandomCode();
|
303 |
-
|
304 |
-
//simulate a successful charge
|
305 |
-
$order->payment_transaction_id = "CHECK" . $order->code;
|
306 |
-
$order->updateStatus("success");
|
307 |
-
return true;
|
308 |
-
}
|
309 |
-
|
310 |
-
function subscribe(&$order)
|
311 |
-
{
|
312 |
-
//create a code for the order
|
313 |
-
if(empty($order->code))
|
314 |
-
$order->code = $order->getRandomCode();
|
315 |
-
|
316 |
-
//filter order before subscription. use with care.
|
317 |
-
$order = apply_filters("pmpro_subscribe_order", $order, $this);
|
318 |
-
|
319 |
-
//simulate a successful subscription processing
|
320 |
-
$order->status = "success";
|
321 |
-
$order->subscription_transaction_id = "CHECK" . $order->code;
|
322 |
-
return true;
|
323 |
-
}
|
324 |
-
|
325 |
-
function update(&$order)
|
326 |
-
{
|
327 |
-
//simulate a successful billing update
|
328 |
-
return true;
|
329 |
-
}
|
330 |
-
|
331 |
-
function cancel(&$order)
|
332 |
-
{
|
333 |
-
//require a subscription id
|
334 |
-
if(empty($order->subscription_transaction_id))
|
335 |
-
return false;
|
336 |
-
|
337 |
-
//simulate a successful cancel
|
338 |
-
$order->updateStatus("cancelled");
|
339 |
-
return true;
|
340 |
-
}
|
341 |
}
|
1 |
+
<?php
|
2 |
+
//include pmprogateway
|
3 |
+
require_once(dirname(__FILE__) . "/class.pmprogateway.php");
|
4 |
+
|
5 |
+
//load classes init method
|
6 |
+
add_action('init', array('PMProGateway_check', 'init'));
|
7 |
+
|
8 |
+
class PMProGateway_check extends PMProGateway
|
9 |
+
{
|
10 |
+
function PMProGateway_check($gateway = NULL)
|
11 |
+
{
|
12 |
+
$this->gateway = $gateway;
|
13 |
+
return $this->gateway;
|
14 |
+
}
|
15 |
+
|
16 |
+
/**
|
17 |
+
* Run on WP init
|
18 |
+
*
|
19 |
+
* @since 1.8
|
20 |
+
*/
|
21 |
+
static function init()
|
22 |
+
{
|
23 |
+
//make sure Pay by Check is a gateway option
|
24 |
+
add_filter('pmpro_gateways', array('PMProGateway_check', 'pmpro_gateways'));
|
25 |
+
|
26 |
+
//add fields to payment settings
|
27 |
+
add_filter('pmpro_payment_options', array('PMProGateway_check', 'pmpro_payment_options'));
|
28 |
+
add_filter('pmpro_payment_option_fields', array('PMProGateway_check', 'pmpro_payment_option_fields'), 10, 2);
|
29 |
+
|
30 |
+
//code to add at checkout
|
31 |
+
$gateway = pmpro_getGateway();
|
32 |
+
if($gateway == "check")
|
33 |
+
{
|
34 |
+
add_filter('pmpro_include_billing_address_fields', '__return_false');
|
35 |
+
add_filter('pmpro_include_payment_information_fields', '__return_false');
|
36 |
+
add_filter('pmpro_required_billing_fields', array('PMProGateway_check', 'pmpro_required_billing_fields'));
|
37 |
+
}
|
38 |
+
}
|
39 |
+
|
40 |
+
/**
|
41 |
+
* Make sure Check is in the gateways list
|
42 |
+
*
|
43 |
+
* @since 1.8
|
44 |
+
*/
|
45 |
+
static function pmpro_gateways($gateways)
|
46 |
+
{
|
47 |
+
if(empty($gateways['check']))
|
48 |
+
$gateways['check'] = __('Pay by Check', 'pmpro');
|
49 |
+
|
50 |
+
return $gateways;
|
51 |
+
}
|
52 |
+
|
53 |
+
/**
|
54 |
+
* Get a list of payment options that the Check gateway needs/supports.
|
55 |
+
*
|
56 |
+
* @since 1.8
|
57 |
+
*/
|
58 |
+
static function getGatewayOptions()
|
59 |
+
{
|
60 |
+
$options = array(
|
61 |
+
'sslseal',
|
62 |
+
'nuclear_HTTPS',
|
63 |
+
'gateway_environment',
|
64 |
+
'instructions',
|
65 |
+
'currency',
|
66 |
+
'use_ssl',
|
67 |
+
'tax_state',
|
68 |
+
'tax_rate'
|
69 |
+
);
|
70 |
+
|
71 |
+
return $options;
|
72 |
+
}
|
73 |
+
|
74 |
+
/**
|
75 |
+
* Set payment options for payment settings page.
|
76 |
+
*
|
77 |
+
* @since 1.8
|
78 |
+
*/
|
79 |
+
static function pmpro_payment_options($options)
|
80 |
+
{
|
81 |
+
//get stripe options
|
82 |
+
$check_options = PMProGateway_check::getGatewayOptions();
|
83 |
+
|
84 |
+
//merge with others.
|
85 |
+
$options = array_merge($check_options, $options);
|
86 |
+
|
87 |
+
return $options;
|
88 |
+
}
|
89 |
+
|
90 |
+
/**
|
91 |
+
* Display fields for Check options.
|
92 |
+
*
|
93 |
+
* @since 1.8
|
94 |
+
*/
|
95 |
+
static function pmpro_payment_option_fields($values, $gateway)
|
96 |
+
{
|
97 |
+
?>
|
98 |
+
<tr class="pmpro_settings_divider gateway gateway_check" <?php if($gateway != "check") { ?>style="display: none;"<?php } ?>>
|
99 |
+
<td colspan="2">
|
100 |
+
<?php _e('Pay by Check Settings', 'pmpro'); ?>
|
101 |
+
</td>
|
102 |
+
</tr>
|
103 |
+
<tr class="gateway gateway_check" <?php if($gateway != "check") { ?>style="display: none;"<?php } ?>>
|
104 |
+
<th scope="row" valign="top">
|
105 |
+
<label for="instructions"><?php _e('Instructions', 'pmpro');?></label>
|
106 |
+
</th>
|
107 |
+
<td>
|
108 |
+
<textarea id="instructions" name="instructions" rows="3" cols="80"><?php echo esc_textarea($values['instructions'])?></textarea>
|
109 |
+
<p><small><?php _e('Who to write the check out to. Where to mail it. Shown on checkout, confirmation, and invoice pages.', 'pmpro');?></small></p>
|
110 |
+
</td>
|
111 |
+
</tr>
|
112 |
+
<?php
|
113 |
+
}
|
114 |
+
|
115 |
+
/**
|
116 |
+
* Remove required billing fields
|
117 |
+
*
|
118 |
+
* @since 1.8
|
119 |
+
*/
|
120 |
+
static function pmpro_required_billing_fields($fields)
|
121 |
+
{
|
122 |
+
unset($fields['bfirstname']);
|
123 |
+
unset($fields['blastname']);
|
124 |
+
unset($fields['baddress1']);
|
125 |
+
unset($fields['bcity']);
|
126 |
+
unset($fields['bstate']);
|
127 |
+
unset($fields['bzipcode']);
|
128 |
+
unset($fields['bphone']);
|
129 |
+
unset($fields['bemail']);
|
130 |
+
unset($fields['bcountry']);
|
131 |
+
unset($fields['CardType']);
|
132 |
+
unset($fields['AccountNumber']);
|
133 |
+
unset($fields['ExpirationMonth']);
|
134 |
+
unset($fields['ExpirationYear']);
|
135 |
+
unset($fields['CVV']);
|
136 |
+
|
137 |
+
return $fields;
|
138 |
+
}
|
139 |
+
|
140 |
+
/**
|
141 |
+
* Process checkout.
|
142 |
+
*
|
143 |
+
*/
|
144 |
+
function process(&$order)
|
145 |
+
{
|
146 |
+
//clean up a couple values
|
147 |
+
$order->payment_type = "Check";
|
148 |
+
$order->CardType = "";
|
149 |
+
$order->cardtype = "";
|
150 |
+
|
151 |
+
//check for initial payment
|
152 |
+
if(floatval($order->InitialPayment) == 0)
|
153 |
+
{
|
154 |
+
//auth first, then process
|
155 |
+
if($this->authorize($order))
|
156 |
+
{
|
157 |
+
$this->void($order);
|
158 |
+
if(!pmpro_isLevelTrial($order->membership_level))
|
159 |
+
{
|
160 |
+
//subscription will start today with a 1 period trial
|
161 |
+
$order->ProfileStartDate = date("Y-m-d") . "T0:0:0";
|
162 |
+
$order->TrialBillingPeriod = $order->BillingPeriod;
|
163 |
+
$order->TrialBillingFrequency = $order->BillingFrequency;
|
164 |
+
$order->TrialBillingCycles = 1;
|
165 |
+
$order->TrialAmount = 0;
|
166 |
+
|
167 |
+
//add a billing cycle to make up for the trial, if applicable
|
168 |
+
if(!empty($order->TotalBillingCycles))
|
169 |
+
$order->TotalBillingCycles++;
|
170 |
+
}
|
171 |
+
elseif($order->InitialPayment == 0 && $order->TrialAmount == 0)
|
172 |
+
{
|
173 |
+
//it has a trial, but the amount is the same as the initial payment, so we can squeeze it in there
|
174 |
+
$order->ProfileStartDate = date("Y-m-d") . "T0:0:0";
|
175 |
+
$order->TrialBillingCycles++;
|
176 |
+
|
177 |
+
//add a billing cycle to make up for the trial, if applicable
|
178 |
+
if($order->TotalBillingCycles)
|
179 |
+
$order->TotalBillingCycles++;
|
180 |
+
}
|
181 |
+
else
|
182 |
+
{
|
183 |
+
//add a period to the start date to account for the initial payment
|
184 |
+
$order->ProfileStartDate = date("Y-m-d", strtotime("+ " . $order->BillingFrequency . " " . $order->BillingPeriod, current_time("timestamp"))) . "T0:0:0";
|
185 |
+
}
|
186 |
+
|
187 |
+
$order->ProfileStartDate = apply_filters("pmpro_profile_start_date", $order->ProfileStartDate, $order);
|
188 |
+
return $this->subscribe($order);
|
189 |
+
}
|
190 |
+
else
|
191 |
+
{
|
192 |
+
if(empty($order->error))
|
193 |
+
$order->error = __("Unknown error: Authorization failed.", "pmpro");
|
194 |
+
return false;
|
195 |
+
}
|
196 |
+
}
|
197 |
+
else
|
198 |
+
{
|
199 |
+
//charge first payment
|
200 |
+
if($this->charge($order))
|
201 |
+
{
|
202 |
+
//setup recurring billing
|
203 |
+
if(pmpro_isLevelRecurring($order->membership_level))
|
204 |
+
{
|
205 |
+
if(!pmpro_isLevelTrial($order->membership_level))
|
206 |
+
{
|
207 |
+
//subscription will start today with a 1 period trial
|
208 |
+
$order->ProfileStartDate = date("Y-m-d") . "T0:0:0";
|
209 |
+
$order->TrialBillingPeriod = $order->BillingPeriod;
|
210 |
+
$order->TrialBillingFrequency = $order->BillingFrequency;
|
211 |
+
$order->TrialBillingCycles = 1;
|
212 |
+
$order->TrialAmount = 0;
|
213 |
+
|
214 |
+
//add a billing cycle to make up for the trial, if applicable
|
215 |
+
if(!empty($order->TotalBillingCycles))
|
216 |
+
$order->TotalBillingCycles++;
|
217 |
+
}
|
218 |
+
elseif($order->InitialPayment == 0 && $order->TrialAmount == 0)
|
219 |
+
{
|
220 |
+
//it has a trial, but the amount is the same as the initial payment, so we can squeeze it in there
|
221 |
+
$order->ProfileStartDate = date("Y-m-d") . "T0:0:0";
|
222 |
+
$order->TrialBillingCycles++;
|
223 |
+
|
224 |
+
//add a billing cycle to make up for the trial, if applicable
|
225 |
+
if(!empty($order->TotalBillingCycles))
|
226 |
+
$order->TotalBillingCycles++;
|
227 |
+
}
|
228 |
+
else
|
229 |
+
{
|
230 |
+
//add a period to the start date to account for the initial payment
|
231 |
+
$order->ProfileStartDate = date("Y-m-d", strtotime("+ " . $this->BillingFrequency . " " . $this->BillingPeriod, current_time("timestamp"))) . "T0:0:0";
|
232 |
+
}
|
233 |
+
|
234 |
+
$order->ProfileStartDate = apply_filters("pmpro_profile_start_date", $order->ProfileStartDate, $order);
|
235 |
+
if($this->subscribe($order))
|
236 |
+
{
|
237 |
+
return true;
|
238 |
+
}
|
239 |
+
else
|
240 |
+
{
|
241 |
+
if($this->void($order))
|
242 |
+
{
|
243 |
+
if(!$order->error)
|
244 |
+
$order->error = __("Unknown error: Payment failed.", "pmpro");
|
245 |
+
}
|
246 |
+
else
|
247 |
+
{
|
248 |
+
if(!$order->error)
|
249 |
+
$order->error = __("Unknown error: Payment failed.", "pmpro");
|
250 |
+
|
251 |
+
$order->error .= " " . __("A partial payment was made that we could not void. Please contact the site owner immediately to correct this.", "pmpro");
|
252 |
+
}
|
253 |
+
|
254 |
+
return false;
|
255 |
+
}
|
256 |
+
}
|
257 |
+
else
|
258 |
+
{
|
259 |
+
//only a one time charge
|
260 |
+
$order->status = apply_filters("pmpro_check_status_after_checkout", "success"); //saved on checkout page
|
261 |
+
return true;
|
262 |
+
}
|
263 |
+
}
|
264 |
+
else
|
265 |
+
{
|
266 |
+
if(empty($order->error))
|
267 |
+
$order->error = __("Unknown error: Payment failed.", "pmpro");
|
268 |
+
|
269 |
+
return false;
|
270 |
+
}
|
271 |
+
}
|
272 |
+
}
|
273 |
+
|
274 |
+
function authorize(&$order)
|
275 |
+
{
|
276 |
+
//create a code for the order
|
277 |
+
if(empty($order->code))
|
278 |
+
$order->code = $order->getRandomCode();
|
279 |
+
|
280 |
+
//simulate a successful authorization
|
281 |
+
$order->payment_transaction_id = "CHECK" . $order->code;
|
282 |
+
$order->updateStatus("authorized");
|
283 |
+
return true;
|
284 |
+
}
|
285 |
+
|
286 |
+
function void(&$order)
|
287 |
+
{
|
288 |
+
//need a transaction id
|
289 |
+
if(empty($order->payment_transaction_id))
|
290 |
+
return false;
|
291 |
+
|
292 |
+
//simulate a successful void
|
293 |
+
$order->payment_transaction_id = "CHECK" . $order->code;
|
294 |
+
$order->updateStatus("voided");
|
295 |
+
return true;
|
296 |
+
}
|
297 |
+
|
298 |
+
function charge(&$order)
|
299 |
+
{
|
300 |
+
//create a code for the order
|
301 |
+
if(empty($order->code))
|
302 |
+
$order->code = $order->getRandomCode();
|
303 |
+
|
304 |
+
//simulate a successful charge
|
305 |
+
$order->payment_transaction_id = "CHECK" . $order->code;
|
306 |
+
$order->updateStatus("success");
|
307 |
+
return true;
|
308 |
+
}
|
309 |
+
|
310 |
+
function subscribe(&$order)
|
311 |
+
{
|
312 |
+
//create a code for the order
|
313 |
+
if(empty($order->code))
|
314 |
+
$order->code = $order->getRandomCode();
|
315 |
+
|
316 |
+
//filter order before subscription. use with care.
|
317 |
+
$order = apply_filters("pmpro_subscribe_order", $order, $this);
|
318 |
+
|
319 |
+
//simulate a successful subscription processing
|
320 |
+
$order->status = "success";
|
321 |
+
$order->subscription_transaction_id = "CHECK" . $order->code;
|
322 |
+
return true;
|
323 |
+
}
|
324 |
+
|
325 |
+
function update(&$order)
|
326 |
+
{
|
327 |
+
//simulate a successful billing update
|
328 |
+
return true;
|
329 |
+
}
|
330 |
+
|
331 |
+
function cancel(&$order)
|
332 |
+
{
|
333 |
+
//require a subscription id
|
334 |
+
if(empty($order->subscription_transaction_id))
|
335 |
+
return false;
|
336 |
+
|
337 |
+
//simulate a successful cancel
|
338 |
+
$order->updateStatus("cancelled");
|
339 |
+
return true;
|
340 |
+
}
|
341 |
}
|
classes/gateways/class.pmprogateway_cybersource.php
CHANGED
@@ -1,884 +1,884 @@
|
|
1 |
-
<?php
|
2 |
-
//include pmprogateway
|
3 |
-
require_once(dirname(__FILE__) . "/class.pmprogateway.php");
|
4 |
-
|
5 |
-
//load classes init method
|
6 |
-
add_action('init', array('PMProGateway_cybersource', 'init'));
|
7 |
-
|
8 |
-
class PMProGateway_cybersource extends PMProGateway
|
9 |
-
{
|
10 |
-
function PMProGateway_cybersource($gateway = NULL)
|
11 |
-
{
|
12 |
-
if(!class_exists("CyberSourceSoapClient"))
|
13 |
-
require_once(dirname(__FILE__) . "/../../includes/lib/CyberSource/cyber_source_soap_client.php");
|
14 |
-
|
15 |
-
$this->gateway = $gateway;
|
16 |
-
return $this->gateway;
|
17 |
-
}
|
18 |
-
|
19 |
-
/**
|
20 |
-
* Run on WP init
|
21 |
-
*
|
22 |
-
* @since 1.8
|
23 |
-
*/
|
24 |
-
static function init()
|
25 |
-
{
|
26 |
-
//make sure CyberSource is a gateway option
|
27 |
-
add_filter('pmpro_gateways', array('PMProGateway_cybersource', 'pmpro_gateways'));
|
28 |
-
|
29 |
-
//add fields to payment settings
|
30 |
-
add_filter('pmpro_payment_options', array('PMProGateway_cybersource', 'pmpro_payment_options'));
|
31 |
-
add_filter('pmpro_payment_option_fields', array('PMProGateway_cybersource', 'pmpro_payment_option_fields'), 10, 2);
|
32 |
-
}
|
33 |
-
|
34 |
-
/**
|
35 |
-
* Make sure this gateway is in the gateways list
|
36 |
-
*
|
37 |
-
* @since 1.8
|
38 |
-
*/
|
39 |
-
static function pmpro_gateways($gateways)
|
40 |
-
{
|
41 |
-
if(empty($gateways['cybersource']))
|
42 |
-
$gateways['cybersource'] = __('CyberSource', 'pmpro');
|
43 |
-
|
44 |
-
return $gateways;
|
45 |
-
}
|
46 |
-
|
47 |
-
/**
|
48 |
-
* Get a list of payment options that the this gateway needs/supports.
|
49 |
-
*
|
50 |
-
* @since 1.8
|
51 |
-
*/
|
52 |
-
static function getGatewayOptions()
|
53 |
-
{
|
54 |
-
$options = array(
|
55 |
-
'sslseal',
|
56 |
-
'nuclear_HTTPS',
|
57 |
-
'gateway_environment',
|
58 |
-
'cybersource_merchantid',
|
59 |
-
'cybersource_securitykey',
|
60 |
-
'currency',
|
61 |
-
'use_ssl',
|
62 |
-
'tax_state',
|
63 |
-
'tax_rate',
|
64 |
-
'accepted_credit_cards'
|
65 |
-
);
|
66 |
-
|
67 |
-
return $options;
|
68 |
-
}
|
69 |
-
|
70 |
-
/**
|
71 |
-
* Set payment options for payment settings page.
|
72 |
-
*
|
73 |
-
* @since 1.8
|
74 |
-
*/
|
75 |
-
static function pmpro_payment_options($options)
|
76 |
-
{
|
77 |
-
//get stripe options
|
78 |
-
$cybersource_options = PMProGateway_cybersource::getGatewayOptions();
|
79 |
-
|
80 |
-
//merge with others.
|
81 |
-
$options = array_merge($cybersource_options, $options);
|
82 |
-
|
83 |
-
return $options;
|
84 |
-
}
|
85 |
-
|
86 |
-
/**
|
87 |
-
* Display fields for this gateway's options.
|
88 |
-
*
|
89 |
-
* @since 1.8
|
90 |
-
*/
|
91 |
-
static function pmpro_payment_option_fields($values, $gateway)
|
92 |
-
{
|
93 |
-
?>
|
94 |
-
<tr class="pmpro_settings_divider gateway gateway_cybersource" <?php if($gateway != "cybersource") { ?>style="display: none;"<?php } ?>>
|
95 |
-
<td colspan="2">
|
96 |
-
<?php _e('CyberSource Settings', 'pmpro'); ?>
|
97 |
-
</td>
|
98 |
-
</tr>
|
99 |
-
<tr class="gateway gateway_cybersource" <?php if($gateway != "cybersource") { ?>style="display: none;"<?php } ?>>
|
100 |
-
<td colspan="2">
|
101 |
-
<strong><?php _e('Note', 'pmpro');?>:</strong> <?php _e('This gateway option is in beta. Some functionality may not be available. Please contact Paid Memberships Pro with any issues you run into. <strong>Please be sure to upgrade Paid Memberships Pro to the latest versions when available.</strong>', 'pmpro');?>
|
102 |
-
</td>
|
103 |
-
</tr>
|
104 |
-
<tr class="gateway gateway_cybersource" <?php if($gateway != "cybersource") { ?>style="display: none;"<?php } ?>>
|
105 |
-
<th scope="row" valign="top">
|
106 |
-
<label for="cybersource_merchantid"><?php _e('Merchant ID', 'pmpro');?>:</label>
|
107 |
-
</th>
|
108 |
-
<td>
|
109 |
-
<input type="text" id="cybersource_merchantid" name="cybersource_merchantid" size="60" value="<?php echo esc_attr($values['cybersource_merchantid'])?>" />
|
110 |
-
</td>
|
111 |
-
</tr>
|
112 |
-
<tr class="gateway gateway_cybersource" <?php if($gateway != "cybersource") { ?>style="display: none;"<?php } ?>>
|
113 |
-
<th scope="row" valign="top">
|
114 |
-
<label for="cybersource_securitykey"><?php _e('Transaction Security Key', 'pmpro');?>:</label>
|
115 |
-
</th>
|
116 |
-
<td>
|
117 |
-
<textarea id="cybersource_securitykey" name="cybersource_securitykey" rows="3" cols="80"><?php echo esc_textarea($values['cybersource_securitykey']);?></textarea>
|
118 |
-
</td>
|
119 |
-
</tr>
|
120 |
-
<?php
|
121 |
-
}
|
122 |
-
|
123 |
-
/**
|
124 |
-
* Process checkout.
|
125 |
-
*
|
126 |
-
*/
|
127 |
-
function process(&$order)
|
128 |
-
{
|
129 |
-
//check for initial payment
|
130 |
-
if(floatval($order->InitialPayment) == 0)
|
131 |
-
{
|
132 |
-
//auth first, then process
|
133 |
-
if($this->authorize($order))
|
134 |
-
{
|
135 |
-
$this->void($order);
|
136 |
-
if(!pmpro_isLevelTrial($order->membership_level))
|
137 |
-
{
|
138 |
-
//subscription will start today with a 1 period trial
|
139 |
-
$order->ProfileStartDate = date("Y-m-d") . "T0:0:0";
|
140 |
-
$order->TrialBillingPeriod = $order->BillingPeriod;
|
141 |
-
$order->TrialBillingFrequency = $order->BillingFrequency;
|
142 |
-
$order->TrialBillingCycles = 1;
|
143 |
-
$order->TrialAmount = 0;
|
144 |
-
|
145 |
-
//add a billing cycle to make up for the trial, if applicable
|
146 |
-
if(!empty($order->TotalBillingCycles))
|
147 |
-
$order->TotalBillingCycles++;
|
148 |
-
}
|
149 |
-
elseif($order->InitialPayment == 0 && $order->TrialAmount == 0)
|
150 |
-
{
|
151 |
-
//it has a trial, but the amount is the same as the initial payment, so we can squeeze it in there
|
152 |
-
$order->ProfileStartDate = date("Y-m-d") . "T0:0:0";
|
153 |
-
$order->TrialBillingCycles++;
|
154 |
-
|
155 |
-
//add a billing cycle to make up for the trial, if applicable
|
156 |
-
if($order->TotalBillingCycles)
|
157 |
-
$order->TotalBillingCycles++;
|
158 |
-
}
|
159 |
-
else
|
160 |
-
{
|
161 |
-
//add a period to the start date to account for the initial payment
|
162 |
-
$order->ProfileStartDate = date("Y-m-d", strtotime("+ " . $order->BillingFrequency . " " . $order->BillingPeriod, current_time("timestamp"))) . "T0:0:0";
|
163 |
-
}
|
164 |
-
|
165 |
-
$order->ProfileStartDate = apply_filters("pmpro_profile_start_date", $order->ProfileStartDate, $order);
|
166 |
-
return $this->subscribe($order);
|
167 |
-
}
|
168 |
-
else
|
169 |
-
{
|
170 |
-
if(empty($order->error))
|
171 |
-
$order->error = __("Unknown error: Authorization failed.", "pmpro");
|
172 |
-
return false;
|
173 |
-
}
|
174 |
-
}
|
175 |
-
else
|
176 |
-
{
|
177 |
-
//charge first payment
|
178 |
-
if($this->charge($order))
|
179 |
-
{
|
180 |
-
//setup recurring billing
|
181 |
-
if(pmpro_isLevelRecurring($order->membership_level))
|
182 |
-
{
|
183 |
-
if(!pmpro_isLevelTrial($order->membership_level))
|
184 |
-
{
|
185 |
-
//subscription will start today with a 1 period trial
|
186 |
-
$order->ProfileStartDate = date("Y-m-d") . "T0:0:0";
|
187 |
-
$order->TrialBillingPeriod = $order->BillingPeriod;
|
188 |
-
$order->TrialBillingFrequency = $order->BillingFrequency;
|
189 |
-
$order->TrialBillingCycles = 1;
|
190 |
-
$order->TrialAmount = 0;
|
191 |
-
|
192 |
-
//add a billing cycle to make up for the trial, if applicable
|
193 |
-
if(!empty($order->TotalBillingCycles))
|
194 |
-
$order->TotalBillingCycles++;
|
195 |
-
}
|
196 |
-
elseif($order->InitialPayment == 0 && $order->TrialAmount == 0)
|
197 |
-
{
|
198 |
-
//it has a trial, but the amount is the same as the initial payment, so we can squeeze it in there
|
199 |
-
$order->ProfileStartDate = date("Y-m-d") . "T0:0:0";
|
200 |
-
$order->TrialBillingCycles++;
|
201 |
-
|
202 |
-
//add a billing cycle to make up for the trial, if applicable
|
203 |
-
if(!empty($order->TotalBillingCycles))
|
204 |
-
$order->TotalBillingCycles++;
|
205 |
-
}
|
206 |
-
else
|
207 |
-
{
|
208 |
-
//add a period to the start date to account for the initial payment
|
209 |
-
$order->ProfileStartDate = date("Y-m-d", strtotime("+ " . $this->BillingFrequency . " " . $this->BillingPeriod, current_time("timestamp"))) . "T0:0:0";
|
210 |
-
}
|
211 |
-
|
212 |
-
$order->ProfileStartDate = apply_filters("pmpro_profile_start_date", $order->ProfileStartDate, $order);
|
213 |
-
if($this->subscribe($order))
|
214 |
-
{
|
215 |
-
return true;
|
216 |
-
}
|
217 |
-
else
|
218 |
-
{
|
219 |
-
if($this->void($order))
|
220 |
-
{
|
221 |
-
if(!$order->error)
|
222 |
-
$order->error = __("Unknown error: Payment failed.", "pmpro");
|
223 |
-
}
|
224 |
-
else
|
225 |
-
{
|
226 |
-
if(!$order->error)
|
227 |
-
$order->error = __("Unknown error: Payment failed.", "pmpro");
|
228 |
-
|
229 |
-
$order->error .= " " . __("A partial payment was made that we could not void. Please contact the site owner immediately to correct this.", "pmpro");
|
230 |
-
}
|
231 |
-
|
232 |
-
return false;
|
233 |
-
}
|
234 |
-
}
|
235 |
-
else
|
236 |
-
{
|
237 |
-
//only a one time charge
|
238 |
-
$order->status = "success"; //saved on checkout page
|
239 |
-
return true;
|
240 |
-
}
|
241 |
-
}
|
242 |
-
else
|
243 |
-
{
|
244 |
-
if(empty($order->error))
|
245 |
-
$order->error = __("Unknown error: Payment failed.", "pmpro");
|
246 |
-
|
247 |
-
return false;
|
248 |
-
}
|
249 |
-
}
|
250 |
-
}
|
251 |
-
|
252 |
-
function getCardType($name)
|
253 |
-
{
|
254 |
-
$card_types = array(
|
255 |
-
'Visa' => '001',
|
256 |
-
'MasterCard' => '002',
|
257 |
-
'Master Card' => '002',
|
258 |
-
'AMEX' => '003',
|
259 |
-
'American Express' => '003',
|
260 |
-
'Discover' => '004',
|
261 |
-
'Diners Club' => '005',
|
262 |
-
'Carte Blanche' => '006',
|
263 |
-
'JCB' => '007'
|
264 |
-
);
|
265 |
-
|
266 |
-
if(isset($card_types[$name]))
|
267 |
-
return $card_types[$name];
|
268 |
-
else
|
269 |
-
return false;
|
270 |
-
}
|
271 |
-
|
272 |
-
function getWSDL($order)
|
273 |
-
{
|
274 |
-
//which gateway environment?
|
275 |
-
if(empty($order->gateway_environment))
|
276 |
-
$gateway_environment = pmpro_getOption("gateway_environment");
|
277 |
-
else
|
278 |
-
$gateway_environment = $order->gateway_environment;
|
279 |
-
|
280 |
-
//which host?
|
281 |
-
if($gateway_environment == "live")
|
282 |
-
$host = "ics2ws.ic3.com";
|
283 |
-
else
|
284 |
-
$host = "ics2wstest.ic3.com";
|
285 |
-
|
286 |
-
//path
|
287 |
-
$path = "/commerce/1.x/transactionProcessor/CyberSourceTransaction_1.90.wsdl";
|
288 |
-
|
289 |
-
//build url
|
290 |
-
$wsdl_url = "https://" . $host . $path;
|
291 |
-
|
292 |
-
//filter
|
293 |
-
$wsdl_url = apply_filters("pmpro_cybersource_wsdl_url", $wsdl_url, $gateway_environment);
|
294 |
-
|
295 |
-
return $wsdl_url;
|
296 |
-
}
|
297 |
-
|
298 |
-
function authorize(&$order)
|
299 |
-
{
|
300 |
-
global $pmpro_currency;
|
301 |
-
|
302 |
-
if(empty($order->code))
|
303 |
-
$order->code = $order->getRandomCode();
|
304 |
-
|
305 |
-
$wsdl_url = $this->getWSDL($order);
|
306 |
-
|
307 |
-
//what amount to authorize? just $1 to test
|
308 |
-
$amount = "1.00";
|
309 |
-
|
310 |
-
//combine address
|
311 |
-
$address = $order->Address1;
|
312 |
-
if(!empty($order->Address2))
|
313 |
-
$address .= "\n" . $order->Address2;
|
314 |
-
|
315 |
-
//customer stuff
|
316 |
-
$customer_email = $order->Email;
|
317 |
-
$customer_phone = $order->billing->phone;
|
318 |
-
|
319 |
-
if(!isset($order->membership_level->name))
|
320 |
-
$order->membership_level->name = "";
|
321 |
-
|
322 |
-
//to store our request
|
323 |
-
$request = new stdClass();
|
324 |
-
|
325 |
-
//which service?
|
326 |
-
$ccAuthService = new stdClass();
|
327 |
-
$ccAuthService->run = "true";
|
328 |
-
$request->ccAuthService = $ccAuthService;
|
329 |
-
|
330 |
-
//merchant id and order code
|
331 |
-
$request->merchantID = pmpro_getOption("cybersource_merchantid");
|
332 |
-
$request->merchantReferenceCode = $order->code;
|
333 |
-
|
334 |
-
//bill to
|
335 |
-
$billTo = new stdClass();
|
336 |
-
$billTo->firstName = $order->FirstName;
|
337 |
-
$billTo->lastName = $order->LastName;
|
338 |
-
$billTo->street1 = $address;
|
339 |
-
$billTo->city = $order->billing->city;
|
340 |
-
$billTo->state = $order->billing->state;
|
341 |
-
$billTo->postalCode = $order->billing->zip;
|
342 |
-
$billTo->country = $order->billing->country;
|
343 |
-
$billTo->email = $order->Email;
|
344 |
-
$billTo->ipAddress = $_SERVER['REMOTE_ADDR'];
|
345 |
-
$request->billTo = $billTo;
|
346 |
-
|
347 |
-
//card
|
348 |
-
$card = new stdClass();
|
349 |
-
$card->cardType = $this->getCardType($order->cardtype);
|
350 |
-
$card->accountNumber = $order->accountnumber;
|
351 |
-
$card->expirationMonth = $order->expirationmonth;
|
352 |
-
$card->expirationYear = $order->expirationyear;
|
353 |
-
$card->cvNumber = $order->CVV2;
|
354 |
-
$request->card = $card;
|
355 |
-
|
356 |
-
//currency
|
357 |
-
$purchaseTotals = new stdClass();
|
358 |
-
$purchaseTotals->currency = $pmpro_currency;
|
359 |
-
$request->purchaseTotals = $purchaseTotals;
|
360 |
-
|
361 |
-
//item/price
|
362 |
-
$item0 = new stdClass();
|
363 |
-
$item0->unitPrice = $amount;
|
364 |
-
$item0->quantity = "1";
|
365 |
-
$item0->productName = $order->membership_level->name . " Membership";
|
366 |
-
$item0->productSKU = $order->membership_level->id;
|
367 |
-
$item0->id = $order->membership_id;
|
368 |
-
$request->item = array($item0);
|
369 |
-
|
370 |
-
$soapClient = new CyberSourceSoapClient($wsdl_url, array("merchantID"=>pmpro_getOption("cybersource_merchantid"), "transactionKey"=>pmpro_getOption("cybersource_securitykey")));
|
371 |
-
$reply = $soapClient->runTransaction($request);
|
372 |
-
|
373 |
-
if($reply->reasonCode == "100")
|
374 |
-
{
|
375 |
-
//success
|
376 |
-
$order->payment_transaction_id = $reply->requestID;
|
377 |
-
$order->updateStatus("authorized");
|
378 |
-
return true;
|
379 |
-
}
|
380 |
-
else
|
381 |
-
{
|
382 |
-
//error
|
383 |
-
$order->errorcode = $reply->reasonCode;
|
384 |
-
$order->error = $this->getErrorFromCode($reply->reasonCode);
|
385 |
-
$order->shorterror = $this->getErrorFromCode($reply->reasonCode);
|
386 |
-
return false;
|
387 |
-
}
|
388 |
-
}
|
389 |
-
|
390 |
-
function void(&$order)
|
391 |
-
{
|
392 |
-
//need a transaction id
|
393 |
-
if(empty($order->payment_transaction_id))
|
394 |
-
return false;
|
395 |
-
|
396 |
-
//get wsdl
|
397 |
-
$wsdl_url = $this->getWSDL($order);
|
398 |
-
|
399 |
-
//to store our request
|
400 |
-
$request = new stdClass();
|
401 |
-
|
402 |
-
//which service?
|
403 |
-
$voidService = new stdClass();
|
404 |
-
$voidService->run = "true";
|
405 |
-
$voidService->voidRequestID = $order->payment_transaction_id;
|
406 |
-
$request->voidService = $voidService;
|
407 |
-
|
408 |
-
//merchant id and order code
|
409 |
-
$request->merchantID = pmpro_getOption("cybersource_merchantid");
|
410 |
-
$request->merchantReferenceCode = $order->code;
|
411 |
-
|
412 |
-
$soapClient = new CyberSourceSoapClient($wsdl_url, array("merchantID"=>pmpro_getOption("cybersource_merchantid"), "transactionKey"=>pmpro_getOption("cybersource_securitykey")));
|
413 |
-
$reply = $soapClient->runTransaction($request);
|
414 |
-
|
415 |
-
if($reply->reasonCode == "100")
|
416 |
-
{
|
417 |
-
//success
|
418 |
-
$order->payment_transaction_id = $reply->requestID;
|
419 |
-
$order->updateStatus("voided");
|
420 |
-
return true;
|
421 |
-
}
|
422 |
-
else
|
423 |
-
{
|
424 |
-
//error
|
425 |
-
$order->errorcode = $reply->reasonCode;
|
426 |
-
$order->error = $this->getErrorFromCode($reply->reasonCode);
|
427 |
-
$order->shorterror = $this->getErrorFromCode($reply->reasonCode);
|
428 |
-
return false;
|
429 |
-
}
|
430 |
-
}
|
431 |
-
|
432 |
-
function charge(&$order)
|
433 |
-
{
|
434 |
-
global $pmpro_currency;
|
435 |
-
|
436 |
-
//get a code
|
437 |
-
if(empty($order->code))
|
438 |
-
$order->code = $order->getRandomCode();
|
439 |
-
|
440 |
-
//get wsdl
|
441 |
-
$wsdl_url = $this->getWSDL($order);
|
442 |
-
|
443 |
-
//what amount to charge?
|
444 |
-
$amount = $order->InitialPayment;
|
445 |
-
|
446 |
-
//tax
|
447 |
-
$order->subtotal = $amount;
|
448 |
-
$tax = $order->getTax(true);
|
449 |
-
$amount = round((float)$order->subtotal + (float)$tax, 2);
|
450 |
-
|
451 |
-
//combine address
|
452 |
-
$address = $order->Address1;
|
453 |
-
if(!empty($order->Address2))
|
454 |
-
$address .= "\n" . $order->Address2;
|
455 |
-
|
456 |
-
//customer stuff
|
457 |
-
$customer_email = $order->Email;
|
458 |
-
$customer_phone = $order->billing->phone;
|
459 |
-
|
460 |
-
if(!isset($order->membership_level->name))
|
461 |
-
$order->membership_level->name = "";
|
462 |
-
|
463 |
-
//to store our request
|
464 |
-
$request = new stdClass();
|
465 |
-
|
466 |
-
//authorize and capture
|
467 |
-
$ccAuthService = new stdClass();
|
468 |
-
$ccAuthService->run = "true";
|
469 |
-
$request->ccAuthService = $ccAuthService;
|
470 |
-
|
471 |
-
$ccCaptureService = new stdClass();
|
472 |
-
$ccCaptureService->run = "true";
|
473 |
-
$request->ccCaptureService = $ccCaptureService;
|
474 |
-
|
475 |
-
//merchant id and order code
|
476 |
-
$request->merchantID = pmpro_getOption("cybersource_merchantid");
|
477 |
-
$request->merchantReferenceCode = $order->code;
|
478 |
-
|
479 |
-
//bill to
|
480 |
-
$billTo = new stdClass();
|
481 |
-
$billTo->firstName = $order->FirstName;
|
482 |
-
$billTo->lastName = $order->LastName;
|
483 |
-
$billTo->street1 = $address;
|
484 |
-
$billTo->city = $order->billing->city;
|
485 |
-
$billTo->state = $order->billing->state;
|
486 |
-
$billTo->postalCode = $order->billing->zip;
|
487 |
-
$billTo->country = $order->billing->country;
|
488 |
-
$billTo->email = $order->Email;
|
489 |
-
$billTo->ipAddress = $_SERVER['REMOTE_ADDR'];
|
490 |
-
$request->billTo = $billTo;
|
491 |
-
|
492 |
-
//card
|
493 |
-
$card = new stdClass();
|
494 |
-
$card->cardType = $this->getCardType($order->cardtype);
|
495 |
-
$card->accountNumber = $order->accountnumber;
|
496 |
-
$card->expirationMonth = $order->expirationmonth;
|
497 |
-
$card->expirationYear = $order->expirationyear;
|
498 |
-
$card->cvNumber = $order->CVV2;
|
499 |
-
$request->card = $card;
|
500 |
-
|
501 |
-
//currency
|
502 |
-
$purchaseTotals = new stdClass();
|
503 |
-
$purchaseTotals->currency = $pmpro_currency;
|
504 |
-
$request->purchaseTotals = $purchaseTotals;
|
505 |
-
|
506 |
-
//item/price
|
507 |
-
$item0 = new stdClass();
|
508 |
-
$item0->unitPrice = $amount;
|
509 |
-
$item0->quantity = "1";
|
510 |
-
$item0->productName = $order->membership_level->name . " Membership";
|
511 |
-
$item0->productSKU = $order->membership_level->id;
|
512 |
-
$item0->id = $order->membership_id;
|
513 |
-
$request->item = array($item0);
|
514 |
-
|
515 |
-
$soapClient = new CyberSourceSoapClient($wsdl_url, array("merchantID"=>pmpro_getOption("cybersource_merchantid"), "transactionKey"=>pmpro_getOption("cybersource_securitykey")));
|
516 |
-
$reply = $soapClient->runTransaction($request);
|
517 |
-
|
518 |
-
if($reply->reasonCode == "100")
|
519 |
-
{
|
520 |
-
//success
|
521 |
-
$order->payment_transaction_id = $reply->requestID;
|
522 |
-
$order->updateStatus("success");
|
523 |
-
return true;
|
524 |
-
}
|
525 |
-
else
|
526 |
-
{
|
527 |
-
//error
|
528 |
-
$order->errorcode = $reply->reasonCode;
|
529 |
-
$order->error = $this->getErrorFromCode($reply->reasonCode);
|
530 |
-
$order->shorterror = $this->getErrorFromCode($reply->reasonCode);
|
531 |
-
return false;
|
532 |
-
}
|
533 |
-
}
|
534 |
-
|
535 |
-
function subscribe(&$order)
|
536 |
-
{
|
537 |
-
global $currency;
|
538 |
-
|
539 |
-
//create a code for the order
|
540 |
-
if(empty($order->code))
|
541 |
-
$order->code = $order->getRandomCode();
|
542 |
-
|
543 |
-
//filter order before subscription. use with care.
|
544 |
-
$order = apply_filters("pmpro_subscribe_order", $order, $this);
|
545 |
-
|
546 |
-
//get wsdl
|
547 |
-
$wsdl_url = $this->getWSDL($order);
|
548 |
-
|
549 |
-
//to store our request
|
550 |
-
$request = new stdClass();
|
551 |
-
|
552 |
-
//set service type
|
553 |
-
$paySubscriptionCreateService = new stdClass();
|
554 |
-
$paySubscriptionCreateService->run = 'true';
|
555 |
-
$paySubscriptionCreateService->disableAutoAuth = 'true'; //we do our own auth check
|
556 |
-
$request->paySubscriptionCreateService = $paySubscriptionCreateService;
|
557 |
-
|
558 |
-
//merchant id and order code
|
559 |
-
$request->merchantID = pmpro_getOption("cybersource_merchantid");
|
560 |
-
$request->merchantReferenceCode = $order->code;
|
561 |
-
|
562 |
-
/*
|
563 |
-
setup billing amount/etc
|
564 |
-
*/
|
565 |
-
//figure out the amounts
|
566 |
-
$amount = $order->PaymentAmount;
|
567 |
-
$amount_tax = $order->getTaxForPrice($amount);
|
568 |
-
$amount = round((float)$amount + (float)$amount_tax, 2);
|
569 |
-
|
570 |
-
/*
|
571 |
-
There are two parts to the trial. Part 1 is simply the delay until the first payment
|
572 |
-
since we are doing the first payment as a separate transaction.
|
573 |
-
The second part is the actual "trial" set by the admin.
|
574 |
-
*/
|
575 |
-
//figure out the trial length (first payment handled by initial charge)
|
576 |
-
if($order->BillingPeriod == "Year")
|
577 |
-
$trial_period_days = $order->BillingFrequency * 365; //annual
|
578 |
-
elseif($order->BillingPeriod == "Day")
|
579 |
-
$trial_period_days = $order->BillingFrequency * 1; //daily
|
580 |
-
elseif($order->BillingPeriod == "Week")
|
581 |
-
$trial_period_days = $order->BillingFrequency * 7; //weekly
|
582 |
-
else
|
583 |
-
$trial_period_days = $order->BillingFrequency * 30; //assume monthly
|
584 |
-
|
585 |
-
//convert to a profile start date
|
586 |
-
$order->ProfileStartDate = date("Y-m-d", strtotime("+ " . $trial_period_days . " Day", current_time("timestamp"))) . "T0:0:0";
|
587 |
-
|
588 |
-
//filter the start date
|
589 |
-
$order->ProfileStartDate = apply_filters("pmpro_profile_start_date", $order->ProfileStartDate, $order);
|
590 |
-
|
591 |
-
//convert back to days
|
592 |
-
$trial_period_days = ceil(abs(strtotime(date("Y-m-d"), current_time('timestamp')) - strtotime($order->ProfileStartDate, current_time("timestamp"))) / 86400);
|
593 |
-
|
594 |
-
//now add the actual trial set by the site
|
595 |
-
if(!empty($order->TrialBillingCycles))
|
596 |
-
{
|
597 |
-
$trialOccurrences = (int)$order->TrialBillingCycles;
|
598 |
-
if($order->BillingPeriod == "Year")
|
599 |
-
$trial_period_days = $trial_period_days + (365 * $order->BillingFrequency * $trialOccurrences); //annual
|
600 |
-
elseif($order->BillingPeriod == "Day")
|
601 |
-
$trial_period_days = $trial_period_days + (1 * $order->BillingFrequency * $trialOccurrences); //daily
|
602 |
-
elseif($order->BillingPeriod == "Week")
|
603 |
-
$trial_period_days = $trial_period_days + (7 * $order->BillingFrequency * $trialOccurrences); //weekly
|
604 |
-
else
|
605 |
-
$trial_period_days = $trial_period_days + (30 * $order->BillingFrequency * $trialOccurrences); //assume monthly
|
606 |
-
}
|
607 |
-
|
608 |
-
//convert back into a date
|
609 |
-
$profile_start_date = date("Ymd", strtotime("+ " . $trial_period_days . " Days"));
|
610 |
-
|
611 |
-
//figure out the frequency
|
612 |
-
if($order->BillingPeriod == "Year")
|
613 |
-
{
|
614 |
-
$frequency = "annually"; //ignoring BillingFrequency set on level.
|
615 |
-
}
|
616 |
-
elseif($order->BillingPeriod == "Month")
|
617 |
-
{
|
618 |
-
if($order->BillingFrequency == 6)
|
619 |
-
$frequency = "semi annually";
|
620 |
-
elseif($order->BillingFrequency == 3)
|
621 |
-
$frequency = "quarterly";
|
622 |
-
else
|
623 |
-
$frequency = "monthly";
|
624 |
-
}
|
625 |
-
elseif($order->BillingPeriod == "Week")
|
626 |
-
{
|
627 |
-
if($order->BillingFrequency == 4)
|
628 |
-
$frequency = "quad-weekly";
|
629 |
-
elseif($order->BillingFrequency == 2)
|
630 |
-
$frequency = "bi-weekly";
|
631 |
-
else
|
632 |
-
$frequency = "weekly";
|
633 |
-
}
|
634 |
-
elseif($order->BillingPeriod == "Day")
|
635 |
-
{
|
636 |
-
if($order->BillingFrequency == 365)
|
637 |
-
$frequency = "annually";
|
638 |
-
elseif($order->BillingFrequency == 182)
|
639 |
-
$frequency = "semi annually";
|
640 |
-
elseif($order->BillingFrequency == 183)
|
641 |
-
$frequency = "semi annually";
|
642 |
-
elseif($order->BillingFrequency == 90)
|
643 |
-
$frequency = "quaterly";
|
644 |
-
elseif($order->BillingFrequency == 30)
|
645 |
-
$frequency = "monthly";
|
646 |
-
elseif($order->BillingFrequency == 15)
|
647 |
-
$frequency = "semi-monthly";
|
648 |
-
elseif($order->BillingFrequency == 28)
|
649 |
-
$frequency = "quad-weekly";
|
650 |
-
elseif($order->BillingFrequency == 14)
|
651 |
-
$frequency = "bi-weekly";
|
652 |
-
elseif($order->BillingFrequency == 7)
|
653 |
-
$frequency = "weekly";
|
654 |
-
}
|
655 |
-
|
656 |
-
//set subscription info for API
|
657 |
-
$subscription = new stdClass();
|
658 |
-
$subscription->title = $order->membership_level->name;
|
659 |
-
$subscription->paymentMethod = "credit card";
|
660 |
-
$request->subscription = $subscription;
|
661 |
-
|
662 |
-
//recurring info
|
663 |
-
$recurringSubscriptionInfo = new stdClass();
|
664 |
-
$recurringSubscriptionInfo->amount = number_format($amount, 2);
|
665 |
-
$recurringSubscriptionInfo->startDate = $profile_start_date;
|
666 |
-
$recurringSubscriptionInfo->frequency = $frequency;
|
667 |
-
if(!empty($order->TotalBillingCycles))
|
668 |
-
$recurringSubscriptionInfo->numberOfPayments = $order->TotalBillingCycles;
|
669 |
-
$request->recurringSubscriptionInfo = $recurringSubscriptionInfo;
|
670 |
-
|
671 |
-
//combine address
|
672 |
-
$address = $order->Address1;
|
673 |
-
if(!empty($order->Address2))
|
674 |
-
$address .= "\n" . $order->Address2;
|
675 |
-
|
676 |
-
//bill to
|
677 |
-
$billTo = new stdClass();
|
678 |
-
$billTo->firstName = $order->FirstName;
|
679 |
-
$billTo->lastName = $order->LastName;
|
680 |
-
$billTo->street1 = $address;
|
681 |
-
$billTo->city = $order->billing->city;
|
682 |
-
$billTo->state = $order->billing->state;
|
683 |
-
$billTo->postalCode = $order->billing->zip;
|
684 |
-
$billTo->country = $order->billing->country;
|
685 |
-
$billTo->email = $order->Email;
|
686 |
-
$billTo->ipAddress = $_SERVER['REMOTE_ADDR'];
|
687 |
-
$request->billTo = $billTo;
|
688 |
-
|
689 |
-
//card
|
690 |
-
$card = new stdClass();
|
691 |
-
$card->cardType = $this->getCardType($order->cardtype);
|
692 |
-
$card->accountNumber = $order->accountnumber;
|
693 |
-
$card->expirationMonth = $order->expirationmonth;
|
694 |
-
$card->expirationYear = $order->expirationyear;
|
695 |
-
$card->cvNumber = $order->CVV2;
|
696 |
-
$request->card = $card;
|
697 |
-
|
698 |
-
//currency
|
699 |
-
$purchaseTotals = new stdClass();
|
700 |
-
$purchaseTotals->currency = $pmpro_currency;
|
701 |
-
$request->purchaseTotals = $purchaseTotals;
|
702 |
-
|
703 |
-
$soapClient = new CyberSourceSoapClient($wsdl_url, array("merchantID"=>pmpro_getOption("cybersource_merchantid"), "transactionKey"=>pmpro_getOption("cybersource_securitykey")));
|
704 |
-
$reply = $soapClient->runTransaction($request);
|
705 |
-
|
706 |
-
if($reply->reasonCode == "100")
|
707 |
-
{
|
708 |
-
//success
|
709 |
-
$order->subscription_transaction_id = $reply->requestID;
|
710 |
-
$order->status = "success";
|
711 |
-
return true;
|
712 |
-
}
|
713 |
-
else
|
714 |
-
{
|
715 |
-
//error
|
716 |
-
$order->status = "error";
|
717 |
-
$order->errorcode = $reply->reasonCode;
|
718 |
-
$order->error = $this->getErrorFromCode($reply->reasonCode);
|
719 |
-
$order->shorterror = $this->getErrorFromCode($reply->reasonCode);
|
720 |
-
return false;
|
721 |
-
}
|
722 |
-
}
|
723 |
-
|
724 |
-
function update(&$order)
|
725 |
-
{
|
726 |
-
//get wsdl
|
727 |
-
$wsdl_url = $this->getWSDL($order);
|
728 |
-
|
729 |
-
//to store our request
|
730 |
-
$request = new stdClass();
|
731 |
-
|
732 |
-
//set service type
|
733 |
-
$paySubscriptionUpdateService = new stdClass();
|
734 |
-
$paySubscriptionUpdateService ->run = "true";
|
735 |
-
$request->paySubscriptionUpdateService = $paySubscriptionUpdateService ;
|
736 |
-
|
737 |
-
//merchant id and order code
|
738 |
-
$request->merchantID = pmpro_getOption("cybersource_merchantid");
|
739 |
-
$request->merchantReferenceCode = $order->code;
|
740 |
-
|
741 |
-
//set subscription info for API
|
742 |
-
$recurringSubscriptionInfo = new stdClass();
|
743 |
-
$recurringSubscriptionInfo->subscriptionID = $order->subscription_transaction_id;
|
744 |
-
$request->recurringSubscriptionInfo = $recurringSubscriptionInfo;
|
745 |
-
|
746 |
-
//combine address
|
747 |
-
$address = $order->Address1;
|
748 |
-
if(!empty($order->Address2))
|
749 |
-
$address .= "\n" . $order->Address2;
|
750 |
-
|
751 |
-
//bill to
|
752 |
-
$billTo = new stdClass();
|
753 |
-
$billTo->firstName = $order->FirstName;
|
754 |
-
$billTo->lastName = $order->LastName;
|
755 |
-
$billTo->street1 = $address;
|
756 |
-
$billTo->city = $order->billing->city;
|
757 |
-
$billTo->state = $order->billing->state;
|
758 |
-
$billTo->postalCode = $order->billing->zip;
|
759 |
-
$billTo->country = $order->billing->country;
|
760 |
-
$billTo->email = $order->Email;
|
761 |
-
$billTo->ipAddress = $_SERVER['REMOTE_ADDR'];
|
762 |
-
$request->billTo = $billTo;
|
763 |
-
|
764 |
-
//card
|
765 |
-
$card = new stdClass();
|
766 |
-
$card->cardType = $this->getCardType($order->cardtype);
|
767 |
-
$card->accountNumber = $order->accountnumber;
|
768 |
-
$card->expirationMonth = $order->expirationmonth;
|
769 |
-
$card->expirationYear = $order->expirationyear;
|
770 |
-
$card->cvNumber = $order->CVV2;
|
771 |
-
$request->card = $card;
|
772 |
-
|
773 |
-
$soapClient = new CyberSourceSoapClient($wsdl_url, array("merchantID"=>pmpro_getOption("cybersource_merchantid"), "transactionKey"=>pmpro_getOption("cybersource_securitykey")));
|
774 |
-
$reply = $soapClient->runTransaction($request);
|
775 |
-
|
776 |
-
if($reply->reasonCode == "100")
|
777 |
-
{
|
778 |
-
//success
|
779 |
-
return true;
|
780 |
-
}
|
781 |
-
else
|
782 |
-
{
|
783 |
-
//error
|
784 |
-
$order->errorcode = $reply->reasonCode;
|
785 |
-
$order->error = $this->getErrorFromCode($reply->reasonCode);
|
786 |
-
$order->shorterror = $this->getErrorFromCode($reply->reasonCode);
|
787 |
-
return false;
|
788 |
-
}
|
789 |
-
}
|
790 |
-
|
791 |
-
function cancel(&$order)
|
792 |
-
{
|
793 |
-
//require a subscription id
|
794 |
-
if(empty($order->subscription_transaction_id))
|
795 |
-
return false;
|
796 |
-
|
797 |
-
//get wsdl
|
798 |
-
$wsdl_url = $this->getWSDL($order);
|
799 |
-
|
800 |
-
//to store our request
|
801 |
-
$request = new stdClass();
|
802 |
-
|
803 |
-
//which service?
|
804 |
-
$paySubscriptionDeleteService = new stdClass();
|
805 |
-
$paySubscriptionDeleteService ->run = "true";
|
806 |
-
$request->paySubscriptionDeleteService = $paySubscriptionDeleteService ;
|
807 |
-
|
808 |
-
//which order
|
809 |
-
$recurringSubscriptionInfo = new stdClass();
|
810 |
-
$recurringSubscriptionInfo->subscriptionID = $order->subscription_transaction_id;
|
811 |
-
$request->recurringSubscriptionInfo = $recurringSubscriptionInfo;
|
812 |
-
|
813 |
-
//merchant id and order code
|
814 |
-
$request->merchantID = pmpro_getOption("cybersource_merchantid");
|
815 |
-
$request->merchantReferenceCode = $order->code;
|
816 |
-
|
817 |
-
$soapClient = new CyberSourceSoapClient($wsdl_url, array("merchantID"=>pmpro_getOption("cybersource_merchantid"), "transactionKey"=>pmpro_getOption("cybersource_securitykey")));
|
818 |
-
$reply = $soapClient->runTransaction($request);
|
819 |
-
|
820 |
-
if($reply->reasonCode == "100")
|
821 |
-
{
|
822 |
-
//success
|
823 |
-
$order->updateStatus("cancelled");
|
824 |
-
return true;
|
825 |
-
}
|
826 |
-
else
|
827 |
-
{
|
828 |
-
//error
|
829 |
-
$order->errorcode = $reply->reasonCode;
|
830 |
-
$order->error = $this->getErrorFromCode($reply->reasonCode);
|
831 |
-
$order->shorterror = $this->getErrorFromCode($reply->reasonCode);
|
832 |
-
return false;
|
833 |
-
}
|
834 |
-
}
|
835 |
-
|
836 |
-
function getErrorFromCode($code)
|
837 |
-
{
|
838 |
-
$error_messages = array(
|
839 |
-
"100" => "Successful transaction.",
|
840 |
-
"101" => "The request is missing one or more required fields.",
|
841 |
-
"102" => "One or more fields in the request contains invalid data. Check that your billing address is valid.",
|
842 |
-
"104" => "Duplicate order detected.",
|
843 |
-
"110" => "Only partial amount was approved.",
|
844 |
-
"150" => "Error: General system failure.",
|
845 |
-
"151" => "Error: The request was received but there was a server timeout.",
|
846 |
-
"152" => "Error: The request was received, but a service did not finish running in time. ",
|
847 |
-
"200" => "Address Verification Service (AVS) failure.",
|
848 |
-
"201" => "Authorization failed.",
|
849 |
-
"202" => "Expired card or invalid expiration date.",
|
850 |
-
"203" => "The card was declined.",
|
851 |
-
"204" => "Insufficient funds in the account.",
|
852 |
-
"205" => "Stolen or lost card.",
|
853 |
-
"207" => "Issuing bank unavailable.",
|
854 |
-
"208" => "Inactive card or card not authorized for card-not-present transactions.",
|
855 |
-
"209" => "American Express Card Identification Digits (CID) did not match.",
|
856 |
-
"210" => "The card has reached the credit limit. ",
|
857 |
-
"211" => "Invalid card verification number.",
|
858 |
-
"221" => "The customer matched an entry on the processors negative file. ",
|
859 |
-
"230" => "Card verification (CV) check failed.",
|
860 |
-
"231" => "Invalid account number.",
|
861 |
-
"232" => "The card type is not accepted by the payment processor.",
|
862 |
-
"233" => "General decline by the processor.",
|
863 |
-
"234" => "There is a problem with your CyberSource merchant configuration.",
|
864 |
-
"235" => "The requested amount exceeds the originally authorized amount.",
|
865 |
-
"236" => "Processor failure.",
|
866 |
-
"237" => "The authorization has already been reversed.",
|
867 |
-
"238" => "The authorization has already been captured.",
|
868 |
-
"239" => "The requested transaction amount must match the previous transaction amount.",
|
869 |
-
"240" => "The card type sent is invalid or does not correlate with the credit card number.",
|
870 |
-
"241" => "The referenced request id is invalid for all follow-on transactions.",
|
871 |
-
"242" => "The request ID is invalid.",
|
872 |
-
"243" => "The transaction has already been settled or reversed.",
|
873 |
-
"246" => "The capture or credit is not voidable because the capture or credit information has already been submitted to your processor. Or, you requested a void for a type of transaction that cannot be voided.",
|
874 |
-
"247" => "You requested a credit for a capture that was previously voided.",
|
875 |
-
"250" => "Error: The request was received, but there was a timeout at the payment processor.",
|
876 |
-
"520" => "Smart Authorization failed."
|
877 |
-
);
|
878 |
-
|
879 |
-
if(isset($error_messages[$code]))
|
880 |
-
return $error_messages[$code];
|
881 |
-
else
|
882 |
-
return "Unknown error.";
|
883 |
-
}
|
884 |
-
}
|
1 |
+
<?php
|
2 |
+
//include pmprogateway
|
3 |
+
require_once(dirname(__FILE__) . "/class.pmprogateway.php");
|
4 |
+
|
5 |
+
//load classes init method
|
6 |
+
add_action('init', array('PMProGateway_cybersource', 'init'));
|
7 |
+
|
8 |
+
class PMProGateway_cybersource extends PMProGateway
|
9 |
+
{
|
10 |
+
function PMProGateway_cybersource($gateway = NULL)
|
11 |
+
{
|
12 |
+
if(!class_exists("CyberSourceSoapClient"))
|
13 |
+
require_once(dirname(__FILE__) . "/../../includes/lib/CyberSource/cyber_source_soap_client.php");
|
14 |
+
|
15 |
+
$this->gateway = $gateway;
|
16 |
+
return $this->gateway;
|
17 |
+
}
|
18 |
+
|
19 |
+
/**
|
20 |
+
* Run on WP init
|
21 |
+
*
|
22 |
+
* @since 1.8
|
23 |
+
*/
|
24 |
+
static function init()
|
25 |
+
{
|
26 |
+
//make sure CyberSource is a gateway option
|
27 |
+
add_filter('pmpro_gateways', array('PMProGateway_cybersource', 'pmpro_gateways'));
|
28 |
+
|
29 |
+
//add fields to payment settings
|
30 |
+
add_filter('pmpro_payment_options', array('PMProGateway_cybersource', 'pmpro_payment_options'));
|
31 |
+
add_filter('pmpro_payment_option_fields', array('PMProGateway_cybersource', 'pmpro_payment_option_fields'), 10, 2);
|
32 |
+
}
|
33 |
+
|
34 |
+
/**
|
35 |
+
* Make sure this gateway is in the gateways list
|
36 |
+
*
|
37 |
+
* @since 1.8
|
38 |
+
*/
|
39 |
+
static function pmpro_gateways($gateways)
|
40 |
+
{
|
41 |
+
if(empty($gateways['cybersource']))
|
42 |
+
$gateways['cybersource'] = __('CyberSource', 'pmpro');
|
43 |
+
|
44 |
+
return $gateways;
|
45 |
+
}
|
46 |
+
|
47 |
+
/**
|
48 |
+
* Get a list of payment options that the this gateway needs/supports.
|
49 |
+
*
|
50 |
+
* @since 1.8
|
51 |
+
*/
|
52 |
+
static function getGatewayOptions()
|
53 |
+
{
|
54 |
+
$options = array(
|
55 |
+
'sslseal',
|
56 |
+
'nuclear_HTTPS',
|
57 |
+
'gateway_environment',
|
58 |
+
'cybersource_merchantid',
|
59 |
+
'cybersource_securitykey',
|
60 |
+
'currency',
|
61 |
+
'use_ssl',
|
62 |
+
'tax_state',
|
63 |
+
'tax_rate',
|
64 |
+
'accepted_credit_cards'
|
65 |
+
);
|
66 |
+
|
67 |
+
return $options;
|
68 |
+
}
|
69 |
+
|
70 |
+
/**
|
71 |
+
* Set payment options for payment settings page.
|
72 |
+
*
|
73 |
+
* @since 1.8
|
74 |
+
*/
|
75 |
+
static function pmpro_payment_options($options)
|
76 |
+
{
|
77 |
+
//get stripe options
|
78 |
+
$cybersource_options = PMProGateway_cybersource::getGatewayOptions();
|
79 |
+
|
80 |
+
//merge with others.
|
81 |
+
$options = array_merge($cybersource_options, $options);
|
82 |
+
|
83 |
+
return $options;
|
84 |
+
}
|
85 |
+
|
86 |
+
/**
|
87 |
+
* Display fields for this gateway's options.
|
88 |
+
*
|
89 |
+
* @since 1.8
|
90 |
+
*/
|
91 |
+
static function pmpro_payment_option_fields($values, $gateway)
|
92 |
+
{
|
93 |
+
?>
|
94 |
+
<tr class="pmpro_settings_divider gateway gateway_cybersource" <?php if($gateway != "cybersource") { ?>style="display: none;"<?php } ?>>
|
95 |
+
<td colspan="2">
|
96 |
+
<?php _e('CyberSource Settings', 'pmpro'); ?>
|
97 |
+
</td>
|
98 |
+
</tr>
|
99 |
+
<tr class="gateway gateway_cybersource" <?php if($gateway != "cybersource") { ?>style="display: none;"<?php } ?>>
|
100 |
+
<td colspan="2">
|
101 |
+
<strong><?php _e('Note', 'pmpro');?>:</strong> <?php _e('This gateway option is in beta. Some functionality may not be available. Please contact Paid Memberships Pro with any issues you run into. <strong>Please be sure to upgrade Paid Memberships Pro to the latest versions when available.</strong>', 'pmpro');?>
|
102 |
+
</td>
|
103 |
+
</tr>
|
104 |
+
<tr class="gateway gateway_cybersource" <?php if($gateway != "cybersource") { ?>style="display: none;"<?php } ?>>
|
105 |
+
<th scope="row" valign="top">
|
106 |
+
<label for="cybersource_merchantid"><?php _e('Merchant ID', 'pmpro');?>:</label>
|
107 |
+
</th>
|
108 |
+
<td>
|
109 |
+
<input type="text" id="cybersource_merchantid" name="cybersource_merchantid" size="60" value="<?php echo esc_attr($values['cybersource_merchantid'])?>" />
|
110 |
+
</td>
|
111 |
+
</tr>
|
112 |
+
<tr class="gateway gateway_cybersource" <?php if($gateway != "cybersource") { ?>style="display: none;"<?php } ?>>
|
113 |
+
<th scope="row" valign="top">
|
114 |
+
<label for="cybersource_securitykey"><?php _e('Transaction Security Key', 'pmpro');?>:</label>
|
115 |
+
</th>
|
116 |
+
<td>
|
117 |
+
<textarea id="cybersource_securitykey" name="cybersource_securitykey" rows="3" cols="80"><?php echo esc_textarea($values['cybersource_securitykey']);?></textarea>
|
118 |
+
</td>
|
119 |
+
</tr>
|
120 |
+
<?php
|
121 |
+
}
|
122 |
+
|
123 |
+
/**
|
124 |
+
* Process checkout.
|
125 |
+
*
|
126 |
+
*/
|
127 |
+
function process(&$order)
|
128 |
+
{
|
129 |
+
//check for initial payment
|
130 |
+
if(floatval($order->InitialPayment) == 0)
|
131 |
+
{
|
132 |
+
//auth first, then process
|
133 |
+
if($this->authorize($order))
|
134 |
+
{
|
135 |
+
$this->void($order);
|
136 |
+
if(!pmpro_isLevelTrial($order->membership_level))
|
137 |
+
{
|
138 |
+
//subscription will start today with a 1 period trial
|
139 |
+
$order->ProfileStartDate = date("Y-m-d") . "T0:0:0";
|
140 |
+
$order->TrialBillingPeriod = $order->BillingPeriod;
|
141 |
+
$order->TrialBillingFrequency = $order->BillingFrequency;
|
142 |
+
$order->TrialBillingCycles = 1;
|
143 |
+
$order->TrialAmount = 0;
|
144 |
+
|
145 |
+
//add a billing cycle to make up for the trial, if applicable
|
146 |
+
if(!empty($order->TotalBillingCycles))
|
147 |
+
$order->TotalBillingCycles++;
|
148 |
+
}
|
149 |
+
elseif($order->InitialPayment == 0 && $order->TrialAmount == 0)
|
150 |
+
{
|
151 |
+
//it has a trial, but the amount is the same as the initial payment, so we can squeeze it in there
|
152 |
+
$order->ProfileStartDate = date("Y-m-d") . "T0:0:0";
|
153 |
+
$order->TrialBillingCycles++;
|
154 |
+
|
155 |
+
//add a billing cycle to make up for the trial, if applicable
|
156 |
+
if($order->TotalBillingCycles)
|
157 |
+
$order->TotalBillingCycles++;
|
158 |
+
}
|
159 |
+
else
|
160 |
+
{
|
161 |
+
//add a period to the start date to account for the initial payment
|
162 |
+
$order->ProfileStartDate = date("Y-m-d", strtotime("+ " . $order->BillingFrequency . " " . $order->BillingPeriod, current_time("timestamp"))) . "T0:0:0";
|
163 |
+
}
|
164 |
+
|
165 |
+
$order->ProfileStartDate = apply_filters("pmpro_profile_start_date", $order->ProfileStartDate, $order);
|
166 |
+
return $this->subscribe($order);
|
167 |
+
}
|
168 |
+
else
|
169 |
+
{
|
170 |
+
if(empty($order->error))
|
171 |
+
$order->error = __("Unknown error: Authorization failed.", "pmpro");
|
172 |
+
return false;
|
173 |
+
}
|
174 |
+
}
|
175 |
+
else
|
176 |
+
{
|
177 |
+
//charge first payment
|
178 |
+
if($this->charge($order))
|
179 |
+
{
|
180 |
+
//setup recurring billing
|
181 |
+
if(pmpro_isLevelRecurring($order->membership_level))
|
182 |
+
{
|
183 |
+
if(!pmpro_isLevelTrial($order->membership_level))
|
184 |
+
{
|
185 |
+
//subscription will start today with a 1 period trial
|
186 |
+
$order->ProfileStartDate = date("Y-m-d") . "T0:0:0";
|
187 |
+
$order->TrialBillingPeriod = $order->BillingPeriod;
|
188 |
+
$order->TrialBillingFrequency = $order->BillingFrequency;
|
189 |
+
$order->TrialBillingCycles = 1;
|
190 |
+
$order->TrialAmount = 0;
|
191 |
+
|
192 |
+
//add a billing cycle to make up for the trial, if applicable
|
193 |
+
if(!empty($order->TotalBillingCycles))
|
194 |
+
$order->TotalBillingCycles++;
|
195 |
+
}
|
196 |
+
elseif($order->InitialPayment == 0 && $order->TrialAmount == 0)
|
197 |
+
{
|
198 |
+
//it has a trial, but the amount is the same as the initial payment, so we can squeeze it in there
|
199 |
+
$order->ProfileStartDate = date("Y-m-d") . "T0:0:0";
|
200 |
+
$order->TrialBillingCycles++;
|
201 |
+
|
202 |
+
//add a billing cycle to make up for the trial, if applicable
|
203 |
+
if(!empty($order->TotalBillingCycles))
|
204 |
+
$order->TotalBillingCycles++;
|
205 |
+
}
|
206 |
+
else
|
207 |
+
{
|
208 |
+
//add a period to the start date to account for the initial payment
|
209 |
+
$order->ProfileStartDate = date("Y-m-d", strtotime("+ " . $this->BillingFrequency . " " . $this->BillingPeriod, current_time("timestamp"))) . "T0:0:0";
|
210 |
+
}
|
211 |
+
|
212 |
+
$order->ProfileStartDate = apply_filters("pmpro_profile_start_date", $order->ProfileStartDate, $order);
|
213 |
+
if($this->subscribe($order))
|
214 |
+
{
|
215 |
+
return true;
|
216 |
+
}
|
217 |
+
else
|
218 |
+
{
|
219 |
+
if($this->void($order))
|
220 |
+
{
|
221 |
+
if(!$order->error)
|
222 |
+
$order->error = __("Unknown error: Payment failed.", "pmpro");
|
223 |
+
}
|
224 |
+
else
|
225 |
+
{
|
226 |
+
if(!$order->error)
|
227 |
+
$order->error = __("Unknown error: Payment failed.", "pmpro");
|
228 |
+
|
229 |
+
$order->error .= " " . __("A partial payment was made that we could not void. Please contact the site owner immediately to correct this.", "pmpro");
|
230 |
+
}
|
231 |
+
|
232 |
+
return false;
|
233 |
+
}
|
234 |
+
}
|
235 |
+
else
|
236 |
+
{
|
237 |
+
//only a one time charge
|
238 |
+
$order->status = "success"; //saved on checkout page
|
239 |
+
return true;
|
240 |
+
}
|
241 |
+
}
|
242 |
+
else
|
243 |
+
{
|
244 |
+
if(empty($order->error))
|
245 |
+
$order->error = __("Unknown error: Payment failed.", "pmpro");
|
246 |
+
|
247 |
+
return false;
|
248 |
+
}
|
249 |
+
}
|
250 |
+
}
|
251 |
+
|
252 |
+
function getCardType($name)
|
253 |
+
{
|
254 |
+
$card_types = array(
|
255 |
+
'Visa' => '001',
|
256 |
+
'MasterCard' => '002',
|
257 |
+
'Master Card' => '002',
|
258 |
+
'AMEX' => '003',
|
259 |
+
'American Express' => '003',
|
260 |
+
'Discover' => '004',
|
261 |
+
'Diners Club' => '005',
|
262 |
+
'Carte Blanche' => '006',
|
263 |
+
'JCB' => '007'
|
264 |
+
);
|
265 |
+
|
266 |
+
if(isset($card_types[$name]))
|
267 |
+
return $card_types[$name];
|
268 |
+
else
|
269 |
+
return false;
|
270 |
+
}
|
271 |
+
|
272 |
+
function getWSDL($order)
|
273 |
+
{
|
274 |
+
//which gateway environment?
|
275 |
+
if(empty($order->gateway_environment))
|
276 |
+
$gateway_environment = pmpro_getOption("gateway_environment");
|
277 |
+
else
|
278 |
+
$gateway_environment = $order->gateway_environment;
|
279 |
+
|
280 |
+
//which host?
|
281 |
+
if($gateway_environment == "live")
|
282 |
+
$host = "ics2ws.ic3.com";
|
283 |
+
else
|
284 |
+
$host = "ics2wstest.ic3.com";
|
285 |
+
|
286 |
+
//path
|
287 |
+
$path = "/commerce/1.x/transactionProcessor/CyberSourceTransaction_1.90.wsdl";
|
288 |
+
|
289 |
+
//build url
|
290 |
+
$wsdl_url = "https://" . $host . $path;
|
291 |
+
|
292 |
+
//filter
|
293 |
+
$wsdl_url = apply_filters("pmpro_cybersource_wsdl_url", $wsdl_url, $gateway_environment);
|
294 |
+
|
295 |
+
return $wsdl_url;
|
296 |
+
}
|
297 |
+
|
298 |
+
function authorize(&$order)
|
299 |
+
{
|
300 |
+
global $pmpro_currency;
|
301 |
+
|
302 |
+
if(empty($order->code))
|
303 |
+
$order->code = $order->getRandomCode();
|
304 |
+
|
305 |
+
$wsdl_url = $this->getWSDL($order);
|
306 |
+
|
307 |
+
//what amount to authorize? just $1 to test
|
308 |
+
$amount = "1.00";
|
309 |
+
|
310 |
+
//combine address
|
311 |
+
$address = $order->Address1;
|
312 |
+
if(!empty($order->Address2))
|
313 |
+
$address .= "\n" . $order->Address2;
|
314 |
+
|
315 |
+
//customer stuff
|
316 |
+
$customer_email = $order->Email;
|
317 |
+
$customer_phone = $order->billing->phone;
|
318 |
+
|
319 |
+
if(!isset($order->membership_level->name))
|
320 |
+
$order->membership_level->name = "";
|
321 |
+
|
322 |
+
//to store our request
|
323 |
+
$request = new stdClass();
|
324 |
+
|
325 |
+
//which service?
|
326 |
+
$ccAuthService = new stdClass();
|
327 |
+
$ccAuthService->run = "true";
|
328 |
+
$request->ccAuthService = $ccAuthService;
|
329 |
+
|
330 |
+
//merchant id and order code
|
331 |
+
$request->merchantID = pmpro_getOption("cybersource_merchantid");
|
332 |
+
$request->merchantReferenceCode = $order->code;
|
333 |
+
|
334 |
+
//bill to
|
335 |
+
$billTo = new stdClass();
|
336 |
+
$billTo->firstName = $order->FirstName;
|
337 |
+
$billTo->lastName = $order->LastName;
|
338 |
+
$billTo->street1 = $address;
|
339 |
+
$billTo->city = $order->billing->city;
|
340 |
+
$billTo->state = $order->billing->state;
|
341 |
+
$billTo->postalCode = $order->billing->zip;
|
342 |
+
$billTo->country = $order->billing->country;
|
343 |
+
$billTo->email = $order->Email;
|
344 |
+
$billTo->ipAddress = $_SERVER['REMOTE_ADDR'];
|
345 |
+
$request->billTo = $billTo;
|
346 |
+
|
347 |
+
//card
|
348 |
+
$card = new stdClass();
|
349 |
+
$card->cardType = $this->getCardType($order->cardtype);
|
350 |
+
$card->accountNumber = $order->accountnumber;
|
351 |
+
$card->expirationMonth = $order->expirationmonth;
|
352 |
+
$card->expirationYear = $order->expirationyear;
|
353 |
+
$card->cvNumber = $order->CVV2;
|
354 |
+
$request->card = $card;
|
355 |
+
|
356 |
+
//currency
|
357 |
+
$purchaseTotals = new stdClass();
|
358 |
+
$purchaseTotals->currency = $pmpro_currency;
|
359 |
+
$request->purchaseTotals = $purchaseTotals;
|
360 |
+
|
361 |
+
//item/price
|
362 |
+
$item0 = new stdClass();
|
363 |
+
$item0->unitPrice = $amount;
|
364 |
+
$item0->quantity = "1";
|
365 |
+
$item0->productName = $order->membership_level->name . " Membership";
|
366 |
+
$item0->productSKU = $order->membership_level->id;
|
367 |
+
$item0->id = $order->membership_id;
|
368 |
+
$request->item = array($item0);
|
369 |
+
|
370 |
+
$soapClient = new CyberSourceSoapClient($wsdl_url, array("merchantID"=>pmpro_getOption("cybersource_merchantid"), "transactionKey"=>pmpro_getOption("cybersource_securitykey")));
|
371 |
+
$reply = $soapClient->runTransaction($request);
|
372 |
+
|
373 |
+
if($reply->reasonCode == "100")
|
374 |
+
{
|
375 |
+
//success
|
376 |
+
$order->payment_transaction_id = $reply->requestID;
|
377 |
+
$order->updateStatus("authorized");
|
378 |
+
return true;
|
379 |
+
}
|
380 |
+
else
|
381 |
+
{
|
382 |
+
//error
|
383 |
+
$order->errorcode = $reply->reasonCode;
|
384 |
+
$order->error = $this->getErrorFromCode($reply->reasonCode);
|
385 |
+
$order->shorterror = $this->getErrorFromCode($reply->reasonCode);
|
386 |
+
return false;
|
387 |
+
}
|
388 |
+
}
|
389 |
+
|
390 |
+
function void(&$order)
|
391 |
+
{
|
392 |
+
//need a transaction id
|
393 |
+
if(empty($order->payment_transaction_id))
|
394 |
+
return false;
|
395 |
+
|
396 |
+
//get wsdl
|
397 |
+
$wsdl_url = $this->getWSDL($order);
|
398 |
+
|
399 |
+
//to store our request
|
400 |
+
$request = new stdClass();
|
401 |
+
|
402 |
+
//which service?
|
403 |
+
$voidService = new stdClass();
|
404 |
+
$voidService->run = "true";
|
405 |
+
$voidService->voidRequestID = $order->payment_transaction_id;
|
406 |
+
$request->voidService = $voidService;
|
407 |
+
|
408 |
+
//merchant id and order code
|
409 |
+
$request->merchantID = pmpro_getOption("cybersource_merchantid");
|
410 |
+
$request->merchantReferenceCode = $order->code;
|
411 |
+
|
412 |
+
$soapClient = new CyberSourceSoapClient($wsdl_url, array("merchantID"=>pmpro_getOption("cybersource_merchantid"), "transactionKey"=>pmpro_getOption("cybersource_securitykey")));
|
413 |
+
$reply = $soapClient->runTransaction($request);
|
414 |
+
|
415 |
+
if($reply->reasonCode == "100")
|
416 |
+
{
|
417 |
+
//success
|
418 |
+
$order->payment_transaction_id = $reply->requestID;
|
419 |
+
$order->updateStatus("voided");
|
420 |
+
return true;
|
421 |
+
}
|
422 |
+
else
|
423 |
+
{
|
424 |
+
//error
|
425 |
+
$order->errorcode = $reply->reasonCode;
|
426 |
+
$order->error = $this->getErrorFromCode($reply->reasonCode);
|
427 |
+
$order->shorterror = $this->getErrorFromCode($reply->reasonCode);
|
428 |
+
return false;
|
429 |
+
}
|
430 |
+
}
|
431 |
+
|
432 |
+
function charge(&$order)
|
433 |
+
{
|
434 |
+
global $pmpro_currency;
|
435 |
+
|
436 |
+
//get a code
|
437 |
+
if(empty($order->code))
|
438 |
+
$order->code = $order->getRandomCode();
|
439 |
+
|
440 |
+
//get wsdl
|
441 |
+
$wsdl_url = $this->getWSDL($order);
|
442 |
+
|
443 |
+
//what amount to charge?
|
444 |
+
$amount = $order->InitialPayment;
|
445 |
+
|
446 |
+
//tax
|
447 |
+
$order->subtotal = $amount;
|
448 |
+
$tax = $order->getTax(true);
|
449 |
+
$amount = round((float)$order->subtotal + (float)$tax, 2);
|
450 |
+
|
451 |
+
//combine address
|
452 |
+
$address = $order->Address1;
|
453 |
+
if(!empty($order->Address2))
|
454 |
+
$address .= "\n" . $order->Address2;
|
455 |
+
|
456 |
+
//customer stuff
|
457 |
+
$customer_email = $order->Email;
|
458 |
+
$customer_phone = $order->billing->phone;
|
459 |
+
|
460 |
+
if(!isset($order->membership_level->name))
|
461 |
+
$order->membership_level->name = "";
|
462 |
+
|
463 |
+
//to store our request
|
464 |
+
$request = new stdClass();
|
465 |
+
|
466 |
+
//authorize and capture
|
467 |
+
$ccAuthService = new stdClass();
|
468 |
+
$ccAuthService->run = "true";
|
469 |
+
$request->ccAuthService = $ccAuthService;
|
470 |
+
|
471 |
+
$ccCaptureService = new stdClass();
|
472 |
+
$ccCaptureService->run = "true";
|
473 |
+
$request->ccCaptureService = $ccCaptureService;
|
474 |
+
|
475 |
+
//merchant id and order code
|
476 |
+
$request->merchantID = pmpro_getOption("cybersource_merchantid");
|
477 |
+
$request->merchantReferenceCode = $order->code;
|
478 |
+
|
479 |
+
//bill to
|
480 |
+
$billTo = new stdClass();
|
481 |
+
$billTo->firstName = $order->FirstName;
|
482 |
+
$billTo->lastName = $order->LastName;
|
483 |
+
$billTo->street1 = $address;
|
484 |
+
$billTo->city = $order->billing->city;
|
485 |
+
$billTo->state = $order->billing->state;
|
486 |
+
$billTo->postalCode = $order->billing->zip;
|
487 |
+
$billTo->country = $order->billing->country;
|
488 |
+
$billTo->email = $order->Email;
|
489 |
+
$billTo->ipAddress = $_SERVER['REMOTE_ADDR'];
|
490 |
+
$request->billTo = $billTo;
|
491 |
+
|
492 |
+
//card
|
493 |
+
$card = new stdClass();
|
494 |
+
$card->cardType = $this->getCardType($order->cardtype);
|
495 |
+
$card->accountNumber = $order->accountnumber;
|
496 |
+
$card->expirationMonth = $order->expirationmonth;
|
497 |
+
$card->expirationYear = $order->expirationyear;
|
498 |
+
$card->cvNumber = $order->CVV2;
|
499 |
+
$request->card = $card;
|
500 |
+
|
501 |
+
//currency
|
502 |
+
$purchaseTotals = new stdClass();
|
503 |
+
$purchaseTotals->currency = $pmpro_currency;
|
504 |
+
$request->purchaseTotals = $purchaseTotals;
|
505 |
+
|
506 |
+
//item/price
|
507 |
+
$item0 = new stdClass();
|
508 |
+
$item0->unitPrice = $amount;
|
509 |
+
$item0->quantity = "1";
|
510 |
+
$item0->productName = $order->membership_level->name . " Membership";
|
511 |
+
$item0->productSKU = $order->membership_level->id;
|
512 |
+
$item0->id = $order->membership_id;
|
513 |
+
$request->item = array($item0);
|
514 |
+
|
515 |
+
$soapClient = new CyberSourceSoapClient($wsdl_url, array("merchantID"=>pmpro_getOption("cybersource_merchantid"), "transactionKey"=>pmpro_getOption("cybersource_securitykey")));
|
516 |
+
$reply = $soapClient->runTransaction($request);
|
517 |
+
|
518 |
+
if($reply->reasonCode == "100")
|
519 |
+
{
|
520 |
+
//success
|
521 |
+
$order->payment_transaction_id = $reply->requestID;
|
522 |
+
$order->updateStatus("success");
|
523 |
+
return true;
|
524 |
+
}
|
525 |
+
else
|
526 |
+
{
|
527 |
+
//error
|
528 |
+
$order->errorcode = $reply->reasonCode;
|
529 |
+
$order->error = $this->getErrorFromCode($reply->reasonCode);
|
530 |
+
$order->shorterror = $this->getErrorFromCode($reply->reasonCode);
|
531 |
+
return false;
|
532 |
+
}
|
533 |
+
}
|
534 |
+
|
535 |
+
function subscribe(&$order)
|
536 |
+
{
|
537 |
+
global $currency;
|
538 |
+
|
539 |
+
//create a code for the order
|
540 |
+
if(empty($order->code))
|
541 |
+
$order->code = $order->getRandomCode();
|
542 |
+
|
543 |
+
//filter order before subscription. use with care.
|
544 |
+
$order = apply_filters("pmpro_subscribe_order", $order, $this);
|
545 |
+
|
546 |
+
//get wsdl
|
547 |
+
$wsdl_url = $this->getWSDL($order);
|
548 |
+
|
549 |
+
//to store our request
|
550 |
+
$request = new stdClass();
|
551 |
+
|
552 |
+
//set service type
|
553 |
+
$paySubscriptionCreateService = new stdClass();
|
554 |
+
$paySubscriptionCreateService->run = 'true';
|
555 |
+
$paySubscriptionCreateService->disableAutoAuth = 'true'; //we do our own auth check
|
556 |
+
$request->paySubscriptionCreateService = $paySubscriptionCreateService;
|
557 |
+
|
558 |
+
//merchant id and order code
|
559 |
+
$request->merchantID = pmpro_getOption("cybersource_merchantid");
|
560 |
+
$request->merchantReferenceCode = $order->code;
|
561 |
+
|
562 |
+
/*
|
563 |
+
setup billing amount/etc
|
564 |
+
*/
|
565 |
+
//figure out the amounts
|
566 |
+
$amount = $order->PaymentAmount;
|
567 |
+
$amount_tax = $order->getTaxForPrice($amount);
|
568 |
+
$amount = round((float)$amount + (float)$amount_tax, 2);
|
569 |
+
|
570 |
+
/*
|
571 |
+
There are two parts to the trial. Part 1 is simply the delay until the first payment
|
572 |
+
since we are doing the first payment as a separate transaction.
|
573 |
+
The second part is the actual "trial" set by the admin.
|
574 |
+
*/
|
575 |
+
//figure out the trial length (first payment handled by initial charge)
|
576 |
+
if($order->BillingPeriod == "Year")
|
577 |
+
$trial_period_days = $order->BillingFrequency * 365; //annual
|
578 |
+
elseif($order->BillingPeriod == "Day")
|
579 |
+
$trial_period_days = $order->BillingFrequency * 1; //daily
|
580 |
+
elseif($order->BillingPeriod == "Week")
|
581 |
+
$trial_period_days = $order->BillingFrequency * 7; //weekly
|
582 |
+
else
|
583 |
+
$trial_period_days = $order->BillingFrequency * 30; //assume monthly
|
584 |
+
|
585 |
+
//convert to a profile start date
|
586 |
+
$order->ProfileStartDate = date("Y-m-d", strtotime("+ " . $trial_period_days . " Day", current_time("timestamp"))) . "T0:0:0";
|
587 |
+
|
588 |
+
//filter the start date
|
589 |
+
$order->ProfileStartDate = apply_filters("pmpro_profile_start_date", $order->ProfileStartDate, $order);
|
590 |
+
|
591 |
+
//convert back to days
|
592 |
+
$trial_period_days = ceil(abs(strtotime(date("Y-m-d"), current_time('timestamp')) - strtotime($order->ProfileStartDate, current_time("timestamp"))) / 86400);
|
593 |
+
|
594 |
+
//now add the actual trial set by the site
|
595 |
+
if(!empty($order->TrialBillingCycles))
|
596 |
+
{
|
597 |
+
$trialOccurrences = (int)$order->TrialBillingCycles;
|
598 |
+
if($order->BillingPeriod == "Year")
|
599 |
+
$trial_period_days = $trial_period_days + (365 * $order->BillingFrequency * $trialOccurrences); //annual
|
600 |
+
elseif($order->BillingPeriod == "Day")
|
601 |
+
$trial_period_days = $trial_period_days + (1 * $order->BillingFrequency * $trialOccurrences); //daily
|
602 |
+
elseif($order->BillingPeriod == "Week")
|
603 |
+
$trial_period_days = $trial_period_days + (7 * $order->BillingFrequency * $trialOccurrences); //weekly
|
604 |
+
else
|
605 |
+
$trial_period_days = $trial_period_days + (30 * $order->BillingFrequency * $trialOccurrences); //assume monthly
|
606 |
+
}
|
607 |
+
|
608 |
+
//convert back into a date
|
609 |
+
$profile_start_date = date("Ymd", strtotime("+ " . $trial_period_days . " Days"));
|
610 |
+
|
611 |
+
//figure out the frequency
|
612 |
+
if($order->BillingPeriod == "Year")
|
613 |
+
{
|
614 |
+
$frequency = "annually"; //ignoring BillingFrequency set on level.
|
615 |
+
}
|
616 |
+
elseif($order->BillingPeriod == "Month")
|
617 |
+
{
|
618 |
+
if($order->BillingFrequency == 6)
|
619 |
+
$frequency = "semi annually";
|
620 |
+
elseif($order->BillingFrequency == 3)
|
621 |
+
$frequency = "quarterly";
|
622 |
+
else
|
623 |
+
$frequency = "monthly";
|
624 |
+
}
|
625 |
+
elseif($order->BillingPeriod == "Week")
|
626 |
+
{
|
627 |
+
if($order->BillingFrequency == 4)
|
628 |
+
$frequency = "quad-weekly";
|
629 |
+
elseif($order->BillingFrequency == 2)
|
630 |
+
$frequency = "bi-weekly";
|
631 |
+
else
|
632 |
+
$frequency = "weekly";
|
633 |
+
}
|
634 |
+
elseif($order->BillingPeriod == "Day")
|
635 |
+
{
|
636 |
+
if($order->BillingFrequency == 365)
|
637 |
+
$frequency = "annually";
|
638 |
+
elseif($order->BillingFrequency == 182)
|
639 |
+
$frequency = "semi annually";
|
640 |
+
elseif($order->BillingFrequency == 183)
|
641 |
+
$frequency = "semi annually";
|
642 |
+
elseif($order->BillingFrequency == 90)
|
643 |
+
$frequency = "quaterly";
|
644 |
+
elseif($order->BillingFrequency == 30)
|
645 |
+
$frequency = "monthly";
|
646 |
+
elseif($order->BillingFrequency == 15)
|
647 |
+
$frequency = "semi-monthly";
|
648 |
+
elseif($order->BillingFrequency == 28)
|
649 |
+
$frequency = "quad-weekly";
|
650 |
+
elseif($order->BillingFrequency == 14)
|
651 |
+
$frequency = "bi-weekly";
|
652 |
+
elseif($order->BillingFrequency == 7)
|
653 |
+
$frequency = "weekly";
|
654 |
+
}
|
655 |
+
|
656 |
+
//set subscription info for API
|
657 |
+
$subscription = new stdClass();
|
658 |
+
$subscription->title = $order->membership_level->name;
|
659 |
+
$subscription->paymentMethod = "credit card";
|
660 |
+
$request->subscription = $subscription;
|
661 |
+
|
662 |
+
//recurring info
|
663 |
+
$recurringSubscriptionInfo = new stdClass();
|
664 |
+
$recurringSubscriptionInfo->amount = number_format($amount, 2);
|
665 |
+
$recurringSubscriptionInfo->startDate = $profile_start_date;
|
666 |
+
$recurringSubscriptionInfo->frequency = $frequency;
|
667 |
+
if(!empty($order->TotalBillingCycles))
|
668 |
+
$recurringSubscriptionInfo->numberOfPayments = $order->TotalBillingCycles;
|
669 |
+
$request->recurringSubscriptionInfo = $recurringSubscriptionInfo;
|
670 |
+
|
671 |
+
//combine address
|
672 |
+
$address = $order->Address1;
|
673 |
+
if(!empty($order->Address2))
|
674 |
+
$address .= "\n" . $order->Address2;
|
675 |
+
|
676 |
+
//bill to
|
677 |
+
$billTo = new stdClass();
|
678 |
+
$billTo->firstName = $order->FirstName;
|
679 |
+
$billTo->lastName = $order->LastName;
|
680 |
+
$billTo->street1 = $address;
|
681 |
+
$billTo->city = $order->billing->city;
|
682 |
+
$billTo->state = $order->billing->state;
|
683 |
+
$billTo->postalCode = $order->billing->zip;
|
684 |
+
$billTo->country = $order->billing->country;
|
685 |
+
$billTo->email = $order->Email;
|
686 |
+
$billTo->ipAddress = $_SERVER['REMOTE_ADDR'];
|
687 |
+
$request->billTo = $billTo;
|
688 |
+
|
689 |
+
//card
|
690 |
+
$card = new stdClass();
|
691 |
+
$card->cardType = $this->getCardType($order->cardtype);
|
692 |
+
$card->accountNumber = $order->accountnumber;
|
693 |
+
$card->expirationMonth = $order->expirationmonth;
|
694 |
+
$card->expirationYear = $order->expirationyear;
|
695 |
+
$card->cvNumber = $order->CVV2;
|
696 |
+
$request->card = $card;
|
697 |
+
|
698 |
+
//currency
|
699 |
+
$purchaseTotals = new stdClass();
|
700 |
+
$purchaseTotals->currency = $pmpro_currency;
|
701 |
+
$request->purchaseTotals = $purchaseTotals;
|
702 |
+
|
703 |
+
$soapClient = new CyberSourceSoapClient($wsdl_url, array("merchantID"=>pmpro_getOption("cybersource_merchantid"), "transactionKey"=>pmpro_getOption("cybersource_securitykey")));
|
704 |
+
$reply = $soapClient->runTransaction($request);
|
705 |
+
|
706 |
+
if($reply->reasonCode == "100")
|
707 |
+
{
|
708 |
+
//success
|
709 |
+
$order->subscription_transaction_id = $reply->requestID;
|
710 |
+
$order->status = "success";
|
711 |
+
return true;
|
712 |
+
}
|
713 |
+
else
|
714 |
+
{
|
715 |
+
//error
|
716 |
+
$order->status = "error";
|
717 |
+
$order->errorcode = $reply->reasonCode;
|
718 |
+
$order->error = $this->getErrorFromCode($reply->reasonCode);
|
719 |
+
$order->shorterror = $this->getErrorFromCode($reply->reasonCode);
|
720 |
+
return false;
|
721 |
+
}
|
722 |
+
}
|
723 |
+
|
724 |
+
function update(&$order)
|
725 |
+
{
|
726 |
+
//get wsdl
|
727 |
+
$wsdl_url = $this->getWSDL($order);
|
728 |
+
|
729 |
+
//to store our request
|
730 |
+
$request = new stdClass();
|
731 |
+
|
732 |
+
//set service type
|
733 |
+
$paySubscriptionUpdateService = new stdClass();
|
734 |
+
$paySubscriptionUpdateService ->run = "true";
|
735 |
+
$request->paySubscriptionUpdateService = $paySubscriptionUpdateService ;
|
736 |
+
|
737 |
+
//merchant id and order code
|
738 |
+
$request->merchantID = pmpro_getOption("cybersource_merchantid");
|
739 |
+
$request->merchantReferenceCode = $order->code;
|
740 |
+
|
741 |
+
//set subscription info for API
|
742 |
+
$recurringSubscriptionInfo = new stdClass();
|
743 |
+
$recurringSubscriptionInfo->subscriptionID = $order->subscription_transaction_id;
|
744 |
+
$request->recurringSubscriptionInfo = $recurringSubscriptionInfo;
|
745 |
+
|
746 |
+
//combine address
|
747 |
+
$address = $order->Address1;
|
748 |
+
if(!empty($order->Address2))
|
749 |
+
$address .= "\n" . $order->Address2;
|
750 |
+
|
751 |
+
//bill to
|
752 |
+
$billTo = new stdClass();
|
753 |
+
$billTo->firstName = $order->FirstName;
|
754 |
+
$billTo->lastName = $order->LastName;
|
755 |
+
$billTo->street1 = $address;
|
756 |
+
$billTo->city = $order->billing->city;
|
757 |
+
$billTo->state = $order->billing->state;
|
758 |
+
$billTo->postalCode = $order->billing->zip;
|
759 |
+
$billTo->country = $order->billing->country;
|
760 |
+
$billTo->email = $order->Email;
|
761 |
+
$billTo->ipAddress = $_SERVER['REMOTE_ADDR'];
|
762 |
+
$request->billTo = $billTo;
|
763 |
+
|
764 |
+
//card
|
765 |
+
$card = new stdClass();
|
766 |
+
$card->cardType = $this->getCardType($order->cardtype);
|
767 |
+
$card->accountNumber = $order->accountnumber;
|
768 |
+
$card->expirationMonth = $order->expirationmonth;
|
769 |
+
$card->expirationYear = $order->expirationyear;
|
770 |
+
$card->cvNumber = $order->CVV2;
|
771 |
+
$request->card = $card;
|
772 |
+
|
773 |
+
$soapClient = new CyberSourceSoapClient($wsdl_url, array("merchantID"=>pmpro_getOption("cybersource_merchantid"), "transactionKey"=>pmpro_getOption("cybersource_securitykey")));
|
774 |
+
$reply = $soapClient->runTransaction($request);
|
775 |
+
|
776 |
+
if($reply->reasonCode == "100")
|
777 |
+
{
|
778 |
+
//success
|
779 |
+
return true;
|
780 |
+
}
|
781 |
+
else
|
782 |
+
{
|
783 |
+
//error
|
784 |
+
$order->errorcode = $reply->reasonCode;
|
785 |
+
$order->error = $this->getErrorFromCode($reply->reasonCode);
|
786 |
+
$order->shorterror = $this->getErrorFromCode($reply->reasonCode);
|
787 |
+
return false;
|
788 |
+
}
|
789 |
+
}
|
790 |
+
|
791 |
+
function cancel(&$order)
|
792 |
+
{
|
793 |
+
//require a subscription id
|
794 |
+
if(empty($order->subscription_transaction_id))
|
795 |
+
return false;
|
796 |
+
|
797 |
+
//get wsdl
|
798 |
+
$wsdl_url = $this->getWSDL($order);
|
799 |
+
|
800 |
+
//to store our request
|
801 |
+
$request = new stdClass();
|
802 |
+
|
803 |
+
//which service?
|
804 |
+
$paySubscriptionDeleteService = new stdClass();
|
805 |
+
$paySubscriptionDeleteService ->run = "true";
|
806 |
+
$request->paySubscriptionDeleteService = $paySubscriptionDeleteService ;
|
807 |
+
|
808 |
+
//which order
|
809 |
+
$recurringSubscriptionInfo = new stdClass();
|
810 |
+
$recurringSubscriptionInfo->subscriptionID = $order->subscription_transaction_id;
|
811 |
+
$request->recurringSubscriptionInfo = $recurringSubscriptionInfo;
|
812 |
+
|
813 |
+
//merchant id and order code
|
814 |
+
$request->merchantID = pmpro_getOption("cybersource_merchantid");
|
815 |
+
$request->merchantReferenceCode = $order->code;
|
816 |
+
|
817 |
+
$soapClient = new CyberSourceSoapClient($wsdl_url, array("merchantID"=>pmpro_getOption("cybersource_merchantid"), "transactionKey"=>pmpro_getOption("cybersource_securitykey")));
|
818 |
+
$reply = $soapClient->runTransaction($request);
|
819 |
+
|
820 |
+
if($reply->reasonCode == "100")
|
821 |
+
{
|
822 |
+
//success
|
823 |
+
$order->updateStatus("cancelled");
|
824 |
+
return true;
|
825 |
+
}
|
826 |
+
else
|
827 |
+
{
|
828 |
+
//error
|
829 |
+
$order->errorcode = $reply->reasonCode;
|
830 |
+
$order->error = $this->getErrorFromCode($reply->reasonCode);
|
831 |
+
$order->shorterror = $this->getErrorFromCode($reply->reasonCode);
|
832 |
+
return false;
|
833 |
+
}
|
834 |
+
}
|
835 |
+
|
836 |
+
function getErrorFromCode($code)
|
837 |
+
{
|
838 |
+
$error_messages = array(
|
839 |
+
"100" => "Successful transaction.",
|
840 |
+
"101" => "The request is missing one or more required fields.",
|
841 |
+
"102" => "One or more fields in the request contains invalid data. Check that your billing address is valid.",
|
842 |
+
"104" => "Duplicate order detected.",
|
843 |
+
"110" => "Only partial amount was approved.",
|
844 |
+
"150" => "Error: General system failure.",
|
845 |
+
"151" => "Error: The request was received but there was a server timeout.",
|
846 |
+
"152" => "Error: The request was received, but a service did not finish running in time. ",
|
847 |
+
"200" => "Address Verification Service (AVS) failure.",
|
848 |
+
"201" => "Authorization failed.",
|
849 |
+
"202" => "Expired card or invalid expiration date.",
|
850 |
+
"203" => "The card was declined.",
|
851 |
+
"204" => "Insufficient funds in the account.",
|
852 |
+
"205" => "Stolen or lost card.",
|
853 |
+
"207" => "Issuing bank unavailable.",
|
854 |
+
"208" => "Inactive card or card not authorized for card-not-present transactions.",
|
855 |
+
"209" => "American Express Card Identification Digits (CID) did not match.",
|
856 |
+
"210" => "The card has reached the credit limit. ",
|
857 |
+
"211" => "Invalid card verification number.",
|
858 |
+
"221" => "The customer matched an entry on the processors negative file. ",
|
859 |
+
"230" => "Card verification (CV) check failed.",
|
860 |
+
"231" => "Invalid account number.",
|
861 |
+
"232" => "The card type is not accepted by the payment processor.",
|
862 |
+
"233" => "General decline by the processor.",
|
863 |
+
"234" => "There is a problem with your CyberSource merchant configuration.",
|
864 |
+
"235" => "The requested amount exceeds the originally authorized amount.",
|
865 |
+
"236" => "Processor failure.",
|
866 |
+
"237" => "The authorization has already been reversed.",
|
867 |
+
"238" => "The authorization has already been captured.",
|
868 |
+
"239" => "The requested transaction amount must match the previous transaction amount.",
|
869 |
+
"240" => "The card type sent is invalid or does not correlate with the credit card number.",
|
870 |
+
"241" => "The referenced request id is invalid for all follow-on transactions.",
|
871 |
+
"242" => "The request ID is invalid.",
|
872 |
+
"243" => "The transaction has already been settled or reversed.",
|
873 |
+
"246" => "The capture or credit is not voidable because the capture or credit information has already been submitted to your processor. Or, you requested a void for a type of transaction that cannot be voided.",
|
874 |
+
"247" => "You requested a credit for a capture that was previously voided.",
|
875 |
+
"250" => "Error: The request was received, but there was a timeout at the payment processor.",
|
876 |
+
"520" => "Smart Authorization failed."
|
877 |
+
);
|
878 |
+
|
879 |
+
if(isset($error_messages[$code]))
|
880 |
+
return $error_messages[$code];
|
881 |
+
else
|
882 |
+
return "Unknown error.";
|
883 |
+
}
|
884 |
+
}
|
classes/gateways/class.pmprogateway_payflowpro.php
CHANGED
@@ -1,53 +1,53 @@
|
|
1 |
<?php
|
2 |
//include pmprogateway
|
3 |
require_once(dirname(__FILE__) . "/class.pmprogateway.php");
|
4 |
-
|
5 |
//load classes init method
|
6 |
add_action('init', array('PMProGateway_payflowpro', 'init'));
|
7 |
-
|
8 |
class PMProGateway_payflowpro extends PMProGateway
|
9 |
{
|
10 |
function PMProGateway_payflowpro($gateway = NULL)
|
11 |
{
|
12 |
$this->gateway = $gateway;
|
13 |
return $this->gateway;
|
14 |
-
}
|
15 |
-
|
16 |
/**
|
17 |
* Run on WP init
|
18 |
-
*
|
19 |
* @since 1.8
|
20 |
*/
|
21 |
static function init()
|
22 |
-
{
|
23 |
//make sure Payflow Pro/PayPal Pro is a gateway option
|
24 |
add_filter('pmpro_gateways', array('PMProGateway_payflowpro', 'pmpro_gateways'));
|
25 |
-
|
26 |
//add fields to payment settings
|
27 |
add_filter('pmpro_payment_options', array('PMProGateway_payflowpro', 'pmpro_payment_options'));
|
28 |
-
add_filter('pmpro_payment_option_fields', array('PMProGateway_payflowpro', 'pmpro_payment_option_fields'), 10, 2);
|
29 |
}
|
30 |
-
|
31 |
/**
|
32 |
* Make sure this gateway is in the gateways list
|
33 |
-
*
|
34 |
* @since 1.8
|
35 |
*/
|
36 |
static function pmpro_gateways($gateways)
|
37 |
{
|
38 |
if(empty($gateways['payflowpro']))
|
39 |
$gateways['payflowpro'] = __('Payflow Pro/PayPal Pro', 'pmpro');
|
40 |
-
|
41 |
return $gateways;
|
42 |
}
|
43 |
-
|
44 |
/**
|
45 |
* Get a list of payment options that the this gateway needs/supports.
|
46 |
-
*
|
47 |
* @since 1.8
|
48 |
*/
|
49 |
static function getGatewayOptions()
|
50 |
-
{
|
51 |
$options = array(
|
52 |
'sslseal',
|
53 |
'nuclear_HTTPS',
|
@@ -62,29 +62,29 @@
|
|
62 |
'tax_rate',
|
63 |
'accepted_credit_cards'
|
64 |
);
|
65 |
-
|
66 |
return $options;
|
67 |
}
|
68 |
-
|
69 |
/**
|
70 |
* Set payment options for payment settings page.
|
71 |
-
*
|
72 |
* @since 1.8
|
73 |
*/
|
74 |
static function pmpro_payment_options($options)
|
75 |
-
{
|
76 |
//get stripe options
|
77 |
$payflowpro_options = PMProGateway_payflowpro::getGatewayOptions();
|
78 |
-
|
79 |
//merge with others.
|
80 |
$options = array_merge($payflowpro_options, $options);
|
81 |
-
|
82 |
return $options;
|
83 |
}
|
84 |
-
|
85 |
/**
|
86 |
* Display fields for this gateway's options.
|
87 |
-
*
|
88 |
* @since 1.8
|
89 |
*/
|
90 |
static function pmpro_payment_option_fields($values, $gateway)
|
@@ -96,7 +96,7 @@
|
|
96 |
</td>
|
97 |
</tr>
|
98 |
<tr class="gateway gateway_payflowpro" <?php if($gateway != "payflowpro") { ?>style="display: none;"<?php } ?>>
|
99 |
-
<th scope="row" valign="top">
|
100 |
<label for="payflow_partner"><?php _e('Partner', 'pmpro');?>:</label>
|
101 |
</th>
|
102 |
<td>
|
@@ -104,7 +104,7 @@
|
|
104 |
</td>
|
105 |
</tr>
|
106 |
<tr class="gateway gateway_payflowpro" <?php if($gateway != "payflowpro") { ?>style="display: none;"<?php } ?>>
|
107 |
-
<th scope="row" valign="top">
|
108 |
<label for="payflow_vendor"><?php _e('Vendor', 'pmpro');?>:</label>
|
109 |
</th>
|
110 |
<td>
|
@@ -112,7 +112,7 @@
|
|
112 |
</td>
|
113 |
</tr>
|
114 |
<tr class="gateway gateway_payflowpro" <?php if($gateway != "payflowpro") { ?>style="display: none;"<?php } ?>>
|
115 |
-
<th scope="row" valign="top">
|
116 |
<label for="payflow_user"><?php _e('User', 'pmpro');?>:</label>
|
117 |
</th>
|
118 |
<td>
|
@@ -120,7 +120,7 @@
|
|
120 |
</td>
|
121 |
</tr>
|
122 |
<tr class="gateway gateway_payflowpro" <?php if($gateway != "payflowpro") { ?>style="display: none;"<?php } ?>>
|
123 |
-
<th scope="row" valign="top">
|
124 |
<label for="payflow_pwd"><?php _e('Password', 'pmpro');?>:</label>
|
125 |
</th>
|
126 |
<td>
|
@@ -132,7 +132,7 @@
|
|
132 |
<label><?php _e('IPN Handler', 'pmpro');?>:</label>
|
133 |
</th>
|
134 |
<td>
|
135 |
-
<p><?php
|
136 |
$addon_url = "http://www.paidmembershipspro.com/add-ons/plugins-on-github/payflow-recurring-orders-addon/";
|
137 |
printf(__('Payflow does not use IPN. To sync recurring subscriptions, please see <a target="_blank" href="%s">this addon</a>.', 'pmpro'), $addon_url);?>
|
138 |
</p>
|
@@ -140,20 +140,20 @@
|
|
140 |
</tr>
|
141 |
<?php
|
142 |
}
|
143 |
-
|
144 |
/**
|
145 |
* Process checkout.
|
146 |
-
*
|
147 |
*/
|
148 |
function process(&$order)
|
149 |
{
|
150 |
if(floatval($order->InitialPayment) == 0)
|
151 |
{
|
152 |
//auth first, then process
|
153 |
-
$authorization_id = $this->authorize($order);
|
154 |
if($authorization_id)
|
155 |
{
|
156 |
-
$this->void($order, $authorization_id);
|
157 |
$order->ProfileStartDate = date("Y-m-d", strtotime("+ " . $order->BillingFrequency . " " . $order->BillingPeriod, current_time("timestamp"))) . "T0:0:0";
|
158 |
$order->ProfileStartDate = apply_filters("pmpro_profile_start_date", $order->ProfileStartDate, $order);
|
159 |
return $this->subscribe($order);
|
@@ -166,21 +166,21 @@
|
|
166 |
}
|
167 |
}
|
168 |
else
|
169 |
-
{
|
170 |
//charge first payment
|
171 |
if($this->charge($order))
|
172 |
-
{
|
173 |
//setup recurring billing
|
174 |
if(pmpro_isLevelRecurring($order->membership_level))
|
175 |
{
|
176 |
$order->ProfileStartDate = date("Y-m-d", strtotime("+ " . $order->BillingFrequency . " " . $order->BillingPeriod, current_time("timestamp"))) . "T0:0:0";
|
177 |
$order->ProfileStartDate = apply_filters("pmpro_profile_start_date", $order->ProfileStartDate, $order);
|
178 |
if($this->subscribe($order))
|
179 |
-
{
|
180 |
return true;
|
181 |
}
|
182 |
else
|
183 |
-
{
|
184 |
if($this->void($order, $order->payment_transaction_id))
|
185 |
{
|
186 |
if(empty($order->error))
|
@@ -190,195 +190,195 @@
|
|
190 |
{
|
191 |
if(empty($order->error))
|
192 |
$order->error = __("Unknown error: Payment failed.", "pmpro");
|
193 |
-
|
194 |
$order->error .= " " . __("A partial payment was made that we could not refund. Please contact the site owner immediately to correct this.", "pmpro");
|
195 |
}
|
196 |
-
|
197 |
-
return false;
|
198 |
}
|
199 |
}
|
200 |
else
|
201 |
{
|
202 |
-
//only a one time charge
|
203 |
-
$order->status = "success"; //saved on checkout page
|
204 |
$order->saveOrder();
|
205 |
return true;
|
206 |
}
|
207 |
-
}
|
208 |
-
}
|
209 |
}
|
210 |
-
|
211 |
function authorize(&$order)
|
212 |
{
|
213 |
if(empty($order->code))
|
214 |
$order->code = $order->getRandomCode();
|
215 |
-
|
216 |
//paypal profile stuff
|
217 |
$nvpStr = "";
|
218 |
-
|
219 |
-
$nvpStr .="&AMT=1.00";
|
220 |
$nvpStr .= "&NOTIFYURL=" . urlencode(admin_url('admin-ajax.php') . "?action=ipnhandler");
|
221 |
//$nvpStr .= "&L_BILLINGTYPE0=RecurringPayments&L_BILLINGAGREEMENTDESCRIPTION0=" . $order->PaymentAmount;
|
222 |
-
|
223 |
$nvpStr .= "&CUSTIP=" . $_SERVER['REMOTE_ADDR'] . "&INVNUM=" . $order->code;
|
224 |
-
|
225 |
//credit card fields
|
226 |
if($order->cardtype == "American Express")
|
227 |
$cardtype = "Amex";
|
228 |
else
|
229 |
$cardtype = $order->cardtype;
|
230 |
-
|
231 |
if(!empty($order->accountnumber))
|
232 |
$nvpStr .= "&ACCT=" . $order->accountnumber . "&EXPDATE=" . $order->expirationmonth . substr($order->expirationyear, 2, 2) . "&CVV2=" . $order->CVV2;
|
233 |
-
|
234 |
//billing address, etc
|
235 |
if(!empty($order->Address1))
|
236 |
{
|
237 |
$nvpStr .= "&EMAIL=" . $order->Email . "&FIRSTNAME=" . $order->FirstName . "&LASTNAME=" . $order->LastName . "&STREET=" . $order->Address1;
|
238 |
-
|
239 |
if($order->Address2)
|
240 |
$nvpStr .= " " . $order->Address2;
|
241 |
-
|
242 |
$nvpStr .= "&CITY=" . $order->billing->city . "&STATE=" . $order->billing->state . "&BILLTOCOUNTRY=" . $order->billing->country . "&ZIP=" . $order->billing->zip . "&PHONENUM=" . $order->billing->phone;
|
243 |
}
|
244 |
|
245 |
//for debugging, let's attach this to the class object
|
246 |
$this->nvpStr = $nvpStr;
|
247 |
-
|
248 |
$this->httpParsedResponseAr = $this->PPHttpPost('A', $nvpStr);
|
249 |
-
|
250 |
if("0" == strtoupper($this->httpParsedResponseAr["RESULT"])) {
|
251 |
$order->authorization_id = $this->httpParsedResponseAr['PNREF'];
|
252 |
-
$order->updateStatus("authorized");
|
253 |
-
return $order->authorization_id;
|
254 |
-
} else {
|
255 |
$order->status = "error";
|
256 |
$order->errorcode = $this->httpParsedResponseAr['RESULT'];
|
257 |
$order->error = urldecode($this->httpParsedResponseAr['RESPMSG']);
|
258 |
$order->shorterror = urldecode($this->httpParsedResponseAr['RESPMSG']);
|
259 |
-
return false;
|
260 |
-
}
|
261 |
}
|
262 |
-
|
263 |
function void(&$order, $authorization_id = null)
|
264 |
{
|
265 |
if(empty($authorization_id))
|
266 |
return false;
|
267 |
-
|
268 |
//paypal profile stuff
|
269 |
$nvpStr="&ORIGID=" . $authorization_id;
|
270 |
-
|
271 |
-
$this->httpParsedResponseAr = $this->PPHttpPost('V', $nvpStr);
|
272 |
-
|
273 |
-
if("0" == strtoupper($this->httpParsedResponseAr["RESULT"])) {
|
274 |
-
return true;
|
275 |
-
} else {
|
276 |
$order->status = "error";
|
277 |
$order->errorcode = $this->httpParsedResponseAr['RESULT'];
|
278 |
$order->error = urldecode($this->httpParsedResponseAr['RESPMSG']);
|
279 |
$order->shorterror = urldecode($this->httpParsedResponseAr['RESPMSG']);
|
280 |
-
return false;
|
281 |
-
}
|
282 |
-
}
|
283 |
-
|
284 |
function charge(&$order)
|
285 |
{
|
286 |
global $pmpro_currency;
|
287 |
-
|
288 |
if(empty($order->code))
|
289 |
$order->code = $order->getRandomCode();
|
290 |
-
|
291 |
//taxes on the amount
|
292 |
$amount = $order->InitialPayment;
|
293 |
-
$amount_tax = $order->getTaxForPrice($amount);
|
294 |
$order->subtotal = $amount;
|
295 |
$amount = round((float)$amount + (float)$amount_tax, 2);
|
296 |
-
|
297 |
//paypal profile stuff
|
298 |
-
$nvpStr = "";
|
299 |
-
$nvpStr .="&AMT=" . $amount . "&TAXAMT=" . $amount_tax . "&CURRENCY=" . $pmpro_currency;
|
300 |
$nvpStr .= "&NOTIFYURL=" . urlencode(admin_url('admin-ajax.php') . "?action=ipnhandler");
|
301 |
//$nvpStr .= "&L_BILLINGTYPE0=RecurringPayments&L_BILLINGAGREEMENTDESCRIPTION0=" . $order->PaymentAmount;
|
302 |
-
|
303 |
-
$nvpStr .= "&CUSTIP=" . $_SERVER['REMOTE_ADDR'] . "&INVNUM=" . $order->code;
|
304 |
-
|
305 |
if(!empty($order->accountnumber))
|
306 |
$nvpStr .= "&ACCT=" . $order->accountnumber . "&EXPDATE=" . $order->expirationmonth . substr($order->expirationyear, 2, 2) . "&CVV2=" . $order->CVV2;
|
307 |
-
|
308 |
//billing address, etc
|
309 |
if($order->Address1)
|
310 |
{
|
311 |
$nvpStr .= "&EMAIL=" . $order->Email . "&FIRSTNAME=" . $order->FirstName . "&LASTNAME=" . $order->LastName . "&STREET=" . $order->Address1;
|
312 |
-
|
313 |
if($order->Address2)
|
314 |
$nvpStr .= " " . $order->Address2;
|
315 |
-
|
316 |
$nvpStr .= "&CITY=" . $order->billing->city . "&STATE=" . $order->billing->state . "&BILLTOCOUNTRY=" . $order->billing->country . "&ZIP=" . $order->billing->zip . "&PHONENUM=" . $order->billing->phone;
|
317 |
}
|
318 |
|
319 |
-
$this->nvpStr = $nvpStr;
|
320 |
$this->httpParsedResponseAr = $this->PPHttpPost('S', $nvpStr);
|
321 |
-
|
322 |
if("0" == strtoupper($this->httpParsedResponseAr["RESULT"])) {
|
323 |
$order->payment_transaction_id = $this->httpParsedResponseAr['PNREF'];
|
324 |
-
$order->updateStatus("success");
|
325 |
-
return true;
|
326 |
-
} else {
|
327 |
$order->status = "error";
|
328 |
$order->errorcode = $this->httpParsedResponseAr['RESULT'];
|
329 |
$order->error = urldecode($this->httpParsedResponseAr['RESPMSG']);
|
330 |
-
$order->shorterror = urldecode($this->httpParsedResponseAr['RESPMSG']);
|
331 |
-
return false;
|
332 |
-
}
|
333 |
}
|
334 |
-
|
335 |
function subscribe(&$order)
|
336 |
{
|
337 |
global $pmpro_currency;
|
338 |
-
|
339 |
if(empty($order->code))
|
340 |
-
$order->code = $order->getRandomCode();
|
341 |
-
|
342 |
//filter order before subscription. use with care.
|
343 |
$order = apply_filters("pmpro_subscribe_order", $order, $this);
|
344 |
-
|
345 |
//taxes on the amount
|
346 |
$amount = $order->PaymentAmount;
|
347 |
-
$amount_tax = $order->getTaxForPrice($amount);
|
348 |
$amount = round((float)$amount + (float)$amount_tax, 2);
|
349 |
-
|
350 |
if($order->BillingPeriod == "Week")
|
351 |
$payperiod = "WEEK";
|
352 |
elseif($order->BillingPeriod == "Month")
|
353 |
$payperiod = "MONT";
|
354 |
elseif($order->BillingPeriod == "Year")
|
355 |
$payperiod = "YEAR";
|
356 |
-
|
357 |
//paypal profile stuff
|
358 |
-
$nvpStr = "&ACTION=A";
|
359 |
$nvpStr .="&AMT=" . $amount . "&TAXAMT=" . $amount_tax . "&CURRENCY=" . $pmpro_currency;
|
360 |
$nvpStr .= "&NOTIFYURL=" . urlencode(admin_url('admin-ajax.php') . "?action=ipnhandler");
|
361 |
//$nvpStr .= "&L_BILLINGTYPE0=RecurringPayments&L_BILLINGAGREEMENTDESCRIPTION0=" . $order->PaymentAmount;
|
362 |
-
|
363 |
$nvpStr .= "&PROFILENAME=" . urlencode(substr($order->membership_level->name . " at " . get_bloginfo("name"), 0, 127));
|
364 |
-
|
365 |
$nvpStr .= "&PAYPERIOD=" . $payperiod;
|
366 |
-
|
367 |
-
$nvpStr .= "&CUSTIP=" . $_SERVER['REMOTE_ADDR']; // . "&INVNUM=" . $order->code;
|
368 |
|
369 |
-
//
|
|
|
|
|
370 |
if(!empty($order->TotalBillingCycles))
|
371 |
$nvpStr .= "&TERM=" . $order->TotalBillingCycles;
|
372 |
else
|
373 |
$nvpStr .= "&TERM=0";
|
374 |
-
|
375 |
if(!empty($order->accountnumber))
|
376 |
$nvpStr .= "&ACCT=" . $order->accountnumber . "&EXPDATE=" . $order->expirationmonth . substr($order->expirationyear, 2, 2) . "&CVV2=" . $order->CVV2;
|
377 |
-
|
378 |
/*
|
379 |
Let's figure out the start date. There are two parts.
|
380 |
1. We need to add the billing period to the start date to account for the initial payment.
|
381 |
-
2. We can allow for free trials by further delaying the start date of the subscription.
|
382 |
*/
|
383 |
if($order->BillingPeriod == "Year")
|
384 |
$trial_period_days = $order->BillingFrequency * 365; //annual
|
@@ -388,18 +388,18 @@
|
|
388 |
$trial_period_days = $order->BillingFrequency * 7; //weekly
|
389 |
else
|
390 |
$trial_period_days = $order->BillingFrequency * 30; //assume monthly
|
391 |
-
|
392 |
//convert to a profile start date
|
393 |
$order->ProfileStartDate = date("Y-m-d", strtotime("+ " . $trial_period_days . " Day", current_time("timestamp"))) . "T0:0:0";
|
394 |
-
|
395 |
//filter the start date
|
396 |
-
$order->ProfileStartDate = apply_filters("pmpro_profile_start_date", $order->ProfileStartDate, $order);
|
397 |
|
398 |
//convert back to days
|
399 |
$trial_period_days = ceil(abs(strtotime(date("Y-m-d"), current_time('timestamp')) - strtotime($order->ProfileStartDate, current_time("timestamp"))) / 86400);
|
400 |
|
401 |
//now add the actual trial set by the site
|
402 |
-
if(!empty($order->TrialBillingCycles))
|
403 |
{
|
404 |
$trialOccurrences = (int)$order->TrialBillingCycles;
|
405 |
if($order->BillingPeriod == "Year")
|
@@ -409,114 +409,114 @@
|
|
409 |
elseif($order->BillingPeriod == "Week")
|
410 |
$trial_period_days = $trial_period_days + (7 * $order->BillingFrequency * $trialOccurrences); //weekly
|
411 |
else
|
412 |
-
$trial_period_days = $trial_period_days + (30 * $order->BillingFrequency * $trialOccurrences); //assume monthly
|
413 |
-
}
|
414 |
-
|
415 |
//convert back into a date
|
416 |
$order->ProfileStartDate = date("Y-m-d", strtotime("+ " . $trial_period_days . " Day", current_time("timestamp"))) . "T0:0:0";
|
417 |
-
|
418 |
//start date
|
419 |
$nvpStr .= "&START=" . date("mdY", strtotime($order->ProfileStartDate));
|
420 |
-
|
421 |
if(!empty($order->accountnumber))
|
422 |
$nvpStr .= "&ACCT=" . $order->accountnumber . "&EXPDATE=" . $order->expirationmonth . substr($order->expirationyear, 2, 2) . "&CVV2=" . $order->CVV2;
|
423 |
-
|
424 |
//billing address, etc
|
425 |
if($order->Address1)
|
426 |
{
|
427 |
$nvpStr .= "&EMAIL=" . $order->Email . "&FIRSTNAME=" . $order->FirstName . "&LASTNAME=" . $order->LastName . "&STREET=" . $order->Address1;
|
428 |
-
|
429 |
if($order->Address2)
|
430 |
$nvpStr .= " " . $order->Address2;
|
431 |
-
|
432 |
$nvpStr .= "&CITY=" . $order->billing->city . "&STATE=" . $order->billing->state . "&BILLTOCOUNTRY=" . $order->billing->country . "&ZIP=" . $order->billing->zip . "&PHONENUM=" . $order->billing->phone;
|
433 |
}
|
434 |
|
435 |
-
$this->nvpStr = $nvpStr;
|
436 |
$this->httpParsedResponseAr = $this->PPHttpPost('R', $nvpStr);
|
437 |
-
|
438 |
if("0" == strtoupper($this->httpParsedResponseAr["RESULT"])) {
|
439 |
$order->subscription_transaction_id = $this->httpParsedResponseAr['PROFILEID'];
|
440 |
-
$order->status = "success";
|
441 |
-
return true;
|
442 |
-
} else {
|
443 |
$order->status = "error";
|
444 |
$order->errorcode = $this->httpParsedResponseAr['RESULT'];
|
445 |
$order->error = urldecode($this->httpParsedResponseAr['RESPMSG']);
|
446 |
-
$order->shorterror = urldecode($this->httpParsedResponseAr['RESPMSG']);
|
447 |
-
return false;
|
448 |
-
}
|
449 |
-
}
|
450 |
-
|
451 |
function update(&$order)
|
452 |
{
|
453 |
$order->getMembershipLevel();
|
454 |
-
|
455 |
//paypal profile stuff
|
456 |
-
$nvpStr = "&ORIGPROFILEID=" . $order->subscription_transaction_id . "&ACTION=M";
|
457 |
$nvpStr .= "&NOTIFYURL=" . urlencode(admin_url('admin-ajax.php') . "?action=ipnhandler");
|
458 |
-
|
459 |
$nvpStr .= "&PROFILENAME=" . urlencode(substr($order->membership_level->name . " at " . get_bloginfo("name"), 0, 127));
|
460 |
-
|
461 |
-
$nvpStr .= "&CUSTIP=" . $_SERVER['REMOTE_ADDR']; // . "&INVNUM=" . $order->code;
|
462 |
-
|
463 |
if(!empty($order->accountnumber))
|
464 |
$nvpStr .= "&ACCT=" . $order->accountnumber . "&EXPDATE=" . $order->expirationmonth . substr($order->expirationyear, 2, 2) . "&CVV2=" . $order->CVV2;
|
465 |
-
|
466 |
//billing address, etc
|
467 |
if($order->Address1)
|
468 |
{
|
469 |
$nvpStr .= "&EMAIL=" . $order->Email . "&FIRSTNAME=" . $order->FirstName . "&LASTNAME=" . $order->LastName . "&STREET=" . $order->Address1;
|
470 |
-
|
471 |
if($order->Address2)
|
472 |
$nvpStr .= " " . $order->Address2;
|
473 |
-
|
474 |
$nvpStr .= "&CITY=" . $order->billing->city . "&STATE=" . $order->billing->state . "&BILLTOCOUNTRY=" . $order->billing->country . "&ZIP=" . $order->billing->zip . "&PHONENUM=" . $order->billing->phone;
|
475 |
}
|
476 |
|
477 |
$this->nvpStr = $nvpStr;
|
478 |
$this->httpParsedResponseAr = $this->PPHttpPost('R', $nvpStr);
|
479 |
-
|
480 |
if("0" == strtoupper($this->httpParsedResponseAr["RESULT"])) {
|
481 |
$order->subscription_transaction_id = $this->httpParsedResponseAr['PROFILEID'];
|
482 |
-
$order->updateStatus("success");
|
483 |
-
return true;
|
484 |
-
} else {
|
485 |
$order->status = "error";
|
486 |
$order->errorcode = $this->httpParsedResponseAr['RESULT'];
|
487 |
$order->error = urldecode($this->httpParsedResponseAr['RESPMSG']);
|
488 |
-
$order->shorterror = urldecode($this->httpParsedResponseAr['RESPMSG']);
|
489 |
-
return false;
|
490 |
-
}
|
491 |
}
|
492 |
-
|
493 |
function cancel(&$order)
|
494 |
{
|
495 |
//require a subscription id
|
496 |
if(empty($order->subscription_transaction_id))
|
497 |
return false;
|
498 |
-
|
499 |
//paypal profile stuff
|
500 |
-
$nvpStr = "&ORIGPROFILEID=" . $order->subscription_transaction_id . "&ACTION=C";
|
501 |
-
|
502 |
$this->nvpStr = $nvpStr;
|
503 |
$this->httpParsedResponseAr = $this->PPHttpPost('R', $nvpStr);
|
504 |
-
|
505 |
-
if("0" == strtoupper($this->httpParsedResponseAr["RESULT"]))
|
506 |
-
{
|
507 |
-
$order->updateStatus("cancelled");
|
508 |
-
return true;
|
509 |
}
|
510 |
else
|
511 |
-
{
|
512 |
$order->status = "error";
|
513 |
$order->errorcode = $this->httpParsedResponseAr['RESULT'];
|
514 |
$order->error = urldecode($this->httpParsedResponseAr['RESPMSG']);
|
515 |
-
$order->shorterror = urldecode($this->httpParsedResponseAr['RESPMSG']);
|
516 |
return false;
|
517 |
}
|
518 |
-
}
|
519 |
-
|
520 |
/**
|
521 |
* PAYPAL Function
|
522 |
* Send HTTP POST Request
|
@@ -527,8 +527,8 @@
|
|
527 |
*/
|
528 |
function PPHttpPost($methodName_, $nvpStr_) {
|
529 |
global $gateway_environment;
|
530 |
-
$environment = $gateway_environment;
|
531 |
-
|
532 |
$PARTNER = pmpro_getOption("payflow_partner");
|
533 |
$VENDOR = pmpro_getOption("payflow_vendor");
|
534 |
$USER = pmpro_getOption("payflow_user");
|
@@ -536,40 +536,40 @@
|
|
536 |
$API_Endpoint = "https://payflowpro.paypal.com";
|
537 |
if("sandbox" === $environment || "beta-sandbox" === $environment) {
|
538 |
$API_Endpoint = "https://pilot-payflowpro.paypal.com";
|
539 |
-
}
|
540 |
-
|
541 |
$version = urlencode('4');
|
542 |
-
|
543 |
// setting the curl parameters.
|
544 |
$ch = curl_init();
|
545 |
curl_setopt($ch, CURLOPT_URL, $API_Endpoint);
|
546 |
curl_setopt($ch, CURLOPT_VERBOSE, 1);
|
547 |
-
|
548 |
// turning off the server and peer verification(TrustManager Concept).
|
549 |
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
|
550 |
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
|
551 |
-
|
552 |
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
|
553 |
curl_setopt($ch, CURLOPT_POST, 1);
|
554 |
-
|
555 |
// NVPRequest for submitting to server
|
556 |
$nvpreq = "TRXTYPE=" . $methodName_ . "&TENDER=C&PARTNER=" . $PARTNER . "&VENDOR=" . $VENDOR . "&USER=" . $USER . "&PWD=" . $PWD . "&VERBOSITY=medium" . "&BUTTONSOURCE=" . urlencode(PAYPAL_BN_CODE) . $nvpStr_;
|
557 |
-
|
558 |
//$nvpreq = "TRXTYPE=" . urlencode($methodName_) . "&TENDER=C&PARTNER=" . urlencode($PARTNER) . "&VENDOR=" . urlencode($VENDOR) . "&USER=" . urlencode($USER) . "&PWD=" . urlencode($PWD) . "&VERBOSITY=medium" . $nvpStr_;
|
559 |
-
|
560 |
// setting the nvpreq as POST FIELD to curl
|
561 |
curl_setopt($ch, CURLOPT_POSTFIELDS, $nvpreq);
|
562 |
-
|
563 |
// getting response from server
|
564 |
$httpResponse = curl_exec($ch);
|
565 |
-
|
566 |
if(empty($httpResponse)) {
|
567 |
exit("$methodName_ failed: ".curl_error($ch).'('.curl_errno($ch).')');
|
568 |
}
|
569 |
-
|
570 |
// Extract the RefundTransaction response details
|
571 |
$httpResponseAr = explode("&", $httpResponse);
|
572 |
-
|
573 |
$httpParsedResponseAr = array();
|
574 |
foreach ($httpResponseAr as $i => $value) {
|
575 |
$tmpAr = explode("=", $value);
|
@@ -577,11 +577,11 @@
|
|
577 |
$httpParsedResponseAr[$tmpAr[0]] = $tmpAr[1];
|
578 |
}
|
579 |
}
|
580 |
-
|
581 |
if((0 == sizeof($httpParsedResponseAr)) || !array_key_exists('RESULT', $httpParsedResponseAr)) {
|
582 |
exit("Invalid HTTP Response for POST request($nvpreq) to $API_Endpoint.");
|
583 |
}
|
584 |
-
|
585 |
return $httpParsedResponseAr;
|
586 |
}
|
587 |
}
|
1 |
<?php
|
2 |
//include pmprogateway
|
3 |
require_once(dirname(__FILE__) . "/class.pmprogateway.php");
|
4 |
+
|
5 |
//load classes init method
|
6 |
add_action('init', array('PMProGateway_payflowpro', 'init'));
|
7 |
+
|
8 |
class PMProGateway_payflowpro extends PMProGateway
|
9 |
{
|
10 |
function PMProGateway_payflowpro($gateway = NULL)
|
11 |
{
|
12 |
$this->gateway = $gateway;
|
13 |
return $this->gateway;
|
14 |
+
}
|
15 |
+
|
16 |
/**
|
17 |
* Run on WP init
|
18 |
+
*
|
19 |
* @since 1.8
|
20 |
*/
|
21 |
static function init()
|
22 |
+
{
|
23 |
//make sure Payflow Pro/PayPal Pro is a gateway option
|
24 |
add_filter('pmpro_gateways', array('PMProGateway_payflowpro', 'pmpro_gateways'));
|
25 |
+
|
26 |
//add fields to payment settings
|
27 |
add_filter('pmpro_payment_options', array('PMProGateway_payflowpro', 'pmpro_payment_options'));
|
28 |
+
add_filter('pmpro_payment_option_fields', array('PMProGateway_payflowpro', 'pmpro_payment_option_fields'), 10, 2);
|
29 |
}
|
30 |
+
|
31 |
/**
|
32 |
* Make sure this gateway is in the gateways list
|
33 |
+
*
|
34 |
* @since 1.8
|
35 |
*/
|
36 |
static function pmpro_gateways($gateways)
|
37 |
{
|
38 |
if(empty($gateways['payflowpro']))
|
39 |
$gateways['payflowpro'] = __('Payflow Pro/PayPal Pro', 'pmpro');
|
40 |
+
|
41 |
return $gateways;
|
42 |
}
|
43 |
+
|
44 |
/**
|
45 |
* Get a list of payment options that the this gateway needs/supports.
|
46 |
+
*
|
47 |
* @since 1.8
|
48 |
*/
|
49 |
static function getGatewayOptions()
|
50 |
+
{
|
51 |
$options = array(
|
52 |
'sslseal',
|
53 |
'nuclear_HTTPS',
|
62 |
'tax_rate',
|
63 |
'accepted_credit_cards'
|
64 |
);
|
65 |
+
|
66 |
return $options;
|
67 |
}
|
68 |
+
|
69 |
/**
|
70 |
* Set payment options for payment settings page.
|
71 |
+
*
|
72 |
* @since 1.8
|
73 |
*/
|
74 |
static function pmpro_payment_options($options)
|
75 |
+
{
|
76 |
//get stripe options
|
77 |
$payflowpro_options = PMProGateway_payflowpro::getGatewayOptions();
|
78 |
+
|
79 |
//merge with others.
|
80 |
$options = array_merge($payflowpro_options, $options);
|
81 |
+
|
82 |
return $options;
|
83 |
}
|
84 |
+
|
85 |
/**
|
86 |
* Display fields for this gateway's options.
|
87 |
+
*
|
88 |
* @since 1.8
|
89 |
*/
|
90 |
static function pmpro_payment_option_fields($values, $gateway)
|
96 |
</td>
|
97 |
</tr>
|
98 |
<tr class="gateway gateway_payflowpro" <?php if($gateway != "payflowpro") { ?>style="display: none;"<?php } ?>>
|
99 |
+
<th scope="row" valign="top">
|
100 |
<label for="payflow_partner"><?php _e('Partner', 'pmpro');?>:</label>
|
101 |
</th>
|
102 |
<td>
|
104 |
</td>
|
105 |
</tr>
|
106 |
<tr class="gateway gateway_payflowpro" <?php if($gateway != "payflowpro") { ?>style="display: none;"<?php } ?>>
|
107 |
+
<th scope="row" valign="top">
|
108 |
<label for="payflow_vendor"><?php _e('Vendor', 'pmpro');?>:</label>
|
109 |
</th>
|
110 |
<td>
|
112 |
</td>
|
113 |
</tr>
|
114 |
<tr class="gateway gateway_payflowpro" <?php if($gateway != "payflowpro") { ?>style="display: none;"<?php } ?>>
|
115 |
+
<th scope="row" valign="top">
|
116 |
<label for="payflow_user"><?php _e('User', 'pmpro');?>:</label>
|
117 |
</th>
|
118 |
<td>
|
120 |
</td>
|
121 |
</tr>
|
122 |
<tr class="gateway gateway_payflowpro" <?php if($gateway != "payflowpro") { ?>style="display: none;"<?php } ?>>
|
123 |
+
<th scope="row" valign="top">
|
124 |
<label for="payflow_pwd"><?php _e('Password', 'pmpro');?>:</label>
|
125 |
</th>
|
126 |
<td>
|
132 |
<label><?php _e('IPN Handler', 'pmpro');?>:</label>
|
133 |
</th>
|
134 |
<td>
|
135 |
+
<p><?php
|
136 |
$addon_url = "http://www.paidmembershipspro.com/add-ons/plugins-on-github/payflow-recurring-orders-addon/";
|
137 |
printf(__('Payflow does not use IPN. To sync recurring subscriptions, please see <a target="_blank" href="%s">this addon</a>.', 'pmpro'), $addon_url);?>
|
138 |
</p>
|
140 |
</tr>
|
141 |
<?php
|
142 |
}
|
143 |
+
|
144 |
/**
|
145 |
* Process checkout.
|
146 |
+
*
|
147 |
*/
|
148 |
function process(&$order)
|
149 |
{
|
150 |
if(floatval($order->InitialPayment) == 0)
|
151 |
{
|
152 |
//auth first, then process
|
153 |
+
$authorization_id = $this->authorize($order);
|
154 |
if($authorization_id)
|
155 |
{
|
156 |
+
$this->void($order, $authorization_id);
|
157 |
$order->ProfileStartDate = date("Y-m-d", strtotime("+ " . $order->BillingFrequency . " " . $order->BillingPeriod, current_time("timestamp"))) . "T0:0:0";
|
158 |
$order->ProfileStartDate = apply_filters("pmpro_profile_start_date", $order->ProfileStartDate, $order);
|
159 |
return $this->subscribe($order);
|
166 |
}
|
167 |
}
|
168 |
else
|
169 |
+
{
|
170 |
//charge first payment
|
171 |
if($this->charge($order))
|
172 |
+
{
|
173 |
//setup recurring billing
|
174 |
if(pmpro_isLevelRecurring($order->membership_level))
|
175 |
{
|
176 |
$order->ProfileStartDate = date("Y-m-d", strtotime("+ " . $order->BillingFrequency . " " . $order->BillingPeriod, current_time("timestamp"))) . "T0:0:0";
|
177 |
$order->ProfileStartDate = apply_filters("pmpro_profile_start_date", $order->ProfileStartDate, $order);
|
178 |
if($this->subscribe($order))
|
179 |
+
{
|
180 |
return true;
|
181 |
}
|
182 |
else
|
183 |
+
{
|
184 |
if($this->void($order, $order->payment_transaction_id))
|
185 |
{
|
186 |
if(empty($order->error))
|
190 |
{
|
191 |
if(empty($order->error))
|
192 |
$order->error = __("Unknown error: Payment failed.", "pmpro");
|
193 |
+
|
194 |
$order->error .= " " . __("A partial payment was made that we could not refund. Please contact the site owner immediately to correct this.", "pmpro");
|
195 |
}
|
196 |
+
|
197 |
+
return false;
|
198 |
}
|
199 |
}
|
200 |
else
|
201 |
{
|
202 |
+
//only a one time charge
|
203 |
+
$order->status = "success"; //saved on checkout page
|
204 |
$order->saveOrder();
|
205 |
return true;
|
206 |
}
|
207 |
+
}
|
208 |
+
}
|
209 |
}
|
210 |
+
|
211 |
function authorize(&$order)
|
212 |
{
|
213 |
if(empty($order->code))
|
214 |
$order->code = $order->getRandomCode();
|
215 |
+
|
216 |
//paypal profile stuff
|
217 |
$nvpStr = "";
|
218 |
+
|
219 |
+
$nvpStr .="&AMT=1.00";
|
220 |
$nvpStr .= "&NOTIFYURL=" . urlencode(admin_url('admin-ajax.php') . "?action=ipnhandler");
|
221 |
//$nvpStr .= "&L_BILLINGTYPE0=RecurringPayments&L_BILLINGAGREEMENTDESCRIPTION0=" . $order->PaymentAmount;
|
222 |
+
|
223 |
$nvpStr .= "&CUSTIP=" . $_SERVER['REMOTE_ADDR'] . "&INVNUM=" . $order->code;
|
224 |
+
|
225 |
//credit card fields
|
226 |
if($order->cardtype == "American Express")
|
227 |
$cardtype = "Amex";
|
228 |
else
|
229 |
$cardtype = $order->cardtype;
|
230 |
+
|
231 |
if(!empty($order->accountnumber))
|
232 |
$nvpStr .= "&ACCT=" . $order->accountnumber . "&EXPDATE=" . $order->expirationmonth . substr($order->expirationyear, 2, 2) . "&CVV2=" . $order->CVV2;
|
233 |
+
|
234 |
//billing address, etc
|
235 |
if(!empty($order->Address1))
|
236 |
{
|
237 |
$nvpStr .= "&EMAIL=" . $order->Email . "&FIRSTNAME=" . $order->FirstName . "&LASTNAME=" . $order->LastName . "&STREET=" . $order->Address1;
|
238 |
+
|
239 |
if($order->Address2)
|
240 |
$nvpStr .= " " . $order->Address2;
|
241 |
+
|
242 |
$nvpStr .= "&CITY=" . $order->billing->city . "&STATE=" . $order->billing->state . "&BILLTOCOUNTRY=" . $order->billing->country . "&ZIP=" . $order->billing->zip . "&PHONENUM=" . $order->billing->phone;
|
243 |
}
|
244 |
|
245 |
//for debugging, let's attach this to the class object
|
246 |
$this->nvpStr = $nvpStr;
|
247 |
+
|
248 |
$this->httpParsedResponseAr = $this->PPHttpPost('A', $nvpStr);
|
249 |
+
|
250 |
if("0" == strtoupper($this->httpParsedResponseAr["RESULT"])) {
|
251 |
$order->authorization_id = $this->httpParsedResponseAr['PNREF'];
|
252 |
+
$order->updateStatus("authorized");
|
253 |
+
return $order->authorization_id;
|
254 |
+
} else {
|
255 |
$order->status = "error";
|
256 |
$order->errorcode = $this->httpParsedResponseAr['RESULT'];
|
257 |
$order->error = urldecode($this->httpParsedResponseAr['RESPMSG']);
|
258 |
$order->shorterror = urldecode($this->httpParsedResponseAr['RESPMSG']);
|
259 |
+
return false;
|
260 |
+
}
|
261 |
}
|
262 |
+
|
263 |
function void(&$order, $authorization_id = null)
|
264 |
{
|
265 |
if(empty($authorization_id))
|
266 |
return false;
|
267 |
+
|
268 |
//paypal profile stuff
|
269 |
$nvpStr="&ORIGID=" . $authorization_id;
|
270 |
+
|
271 |
+
$this->httpParsedResponseAr = $this->PPHttpPost('V', $nvpStr);
|
272 |
+
|
273 |
+
if("0" == strtoupper($this->httpParsedResponseAr["RESULT"])) {
|
274 |
+
return true;
|
275 |
+
} else {
|
276 |
$order->status = "error";
|
277 |
$order->errorcode = $this->httpParsedResponseAr['RESULT'];
|
278 |
$order->error = urldecode($this->httpParsedResponseAr['RESPMSG']);
|
279 |
$order->shorterror = urldecode($this->httpParsedResponseAr['RESPMSG']);
|
280 |
+
return false;
|
281 |
+
}
|
282 |
+
}
|
283 |
+
|
284 |
function charge(&$order)
|
285 |
{
|
286 |
global $pmpro_currency;
|
287 |
+
|
288 |
if(empty($order->code))
|
289 |
$order->code = $order->getRandomCode();
|
290 |
+
|
291 |
//taxes on the amount
|
292 |
$amount = $order->InitialPayment;
|
293 |
+
$amount_tax = $order->getTaxForPrice($amount);
|
294 |
$order->subtotal = $amount;
|
295 |
$amount = round((float)$amount + (float)$amount_tax, 2);
|
296 |
+
|
297 |
//paypal profile stuff
|
298 |
+
$nvpStr = "";
|
299 |
+
$nvpStr .="&AMT=" . $amount . "&TAXAMT=" . $amount_tax . "&CURRENCY=" . $pmpro_currency;
|
300 |
$nvpStr .= "&NOTIFYURL=" . urlencode(admin_url('admin-ajax.php') . "?action=ipnhandler");
|
301 |
//$nvpStr .= "&L_BILLINGTYPE0=RecurringPayments&L_BILLINGAGREEMENTDESCRIPTION0=" . $order->PaymentAmount;
|
302 |
+
|
303 |
+
$nvpStr .= "&CUSTIP=" . $_SERVER['REMOTE_ADDR'] . "&INVNUM=" . $order->code;
|
304 |
+
|
305 |
if(!empty($order->accountnumber))
|
306 |
$nvpStr .= "&ACCT=" . $order->accountnumber . "&EXPDATE=" . $order->expirationmonth . substr($order->expirationyear, 2, 2) . "&CVV2=" . $order->CVV2;
|
307 |
+
|
308 |
//billing address, etc
|
309 |
if($order->Address1)
|
310 |
{
|
311 |
$nvpStr .= "&EMAIL=" . $order->Email . "&FIRSTNAME=" . $order->FirstName . "&LASTNAME=" . $order->LastName . "&STREET=" . $order->Address1;
|
312 |
+
|
313 |
if($order->Address2)
|
314 |
$nvpStr .= " " . $order->Address2;
|
315 |
+
|
316 |
$nvpStr .= "&CITY=" . $order->billing->city . "&STATE=" . $order->billing->state . "&BILLTOCOUNTRY=" . $order->billing->country . "&ZIP=" . $order->billing->zip . "&PHONENUM=" . $order->billing->phone;
|
317 |
}
|
318 |
|
319 |
+
$this->nvpStr = $nvpStr;
|
320 |
$this->httpParsedResponseAr = $this->PPHttpPost('S', $nvpStr);
|
321 |
+
|
322 |
if("0" == strtoupper($this->httpParsedResponseAr["RESULT"])) {
|
323 |
$order->payment_transaction_id = $this->httpParsedResponseAr['PNREF'];
|
324 |
+
$order->updateStatus("success");
|
325 |
+
return true;
|
326 |
+
} else {
|
327 |
$order->status = "error";
|
328 |
$order->errorcode = $this->httpParsedResponseAr['RESULT'];
|
329 |
$order->error = urldecode($this->httpParsedResponseAr['RESPMSG']);
|
330 |
+
$order->shorterror = urldecode($this->httpParsedResponseAr['RESPMSG']);
|
331 |
+
return false;
|
332 |
+
}
|
333 |
}
|
334 |
+
|
335 |
function subscribe(&$order)
|
336 |
{
|
337 |
global $pmpro_currency;
|
338 |
+
|
339 |
if(empty($order->code))
|
340 |
+
$order->code = $order->getRandomCode();
|
341 |
+
|
342 |
//filter order before subscription. use with care.
|
343 |
$order = apply_filters("pmpro_subscribe_order", $order, $this);
|
344 |
+
|
345 |
//taxes on the amount
|
346 |
$amount = $order->PaymentAmount;
|
347 |
+
$amount_tax = $order->getTaxForPrice($amount);
|
348 |
$amount = round((float)$amount + (float)$amount_tax, 2);
|
349 |
+
|
350 |
if($order->BillingPeriod == "Week")
|
351 |
$payperiod = "WEEK";
|
352 |
elseif($order->BillingPeriod == "Month")
|
353 |
$payperiod = "MONT";
|
354 |
elseif($order->BillingPeriod == "Year")
|
355 |
$payperiod = "YEAR";
|
356 |
+
|
357 |
//paypal profile stuff
|
358 |
+
$nvpStr = "&ACTION=A";
|
359 |
$nvpStr .="&AMT=" . $amount . "&TAXAMT=" . $amount_tax . "&CURRENCY=" . $pmpro_currency;
|
360 |
$nvpStr .= "&NOTIFYURL=" . urlencode(admin_url('admin-ajax.php') . "?action=ipnhandler");
|
361 |
//$nvpStr .= "&L_BILLINGTYPE0=RecurringPayments&L_BILLINGAGREEMENTDESCRIPTION0=" . $order->PaymentAmount;
|
362 |
+
|
363 |
$nvpStr .= "&PROFILENAME=" . urlencode(substr($order->membership_level->name . " at " . get_bloginfo("name"), 0, 127));
|
364 |
+
|
365 |
$nvpStr .= "&PAYPERIOD=" . $payperiod;
|
|
|
|
|
366 |
|
367 |
+
$nvpStr .= "&CUSTIP=" . $_SERVER['REMOTE_ADDR']; // . "&INVNUM=" . $order->code;
|
368 |
+
|
369 |
+
//if billing cycles are defined
|
370 |
if(!empty($order->TotalBillingCycles))
|
371 |
$nvpStr .= "&TERM=" . $order->TotalBillingCycles;
|
372 |
else
|
373 |
$nvpStr .= "&TERM=0";
|
374 |
+
|
375 |
if(!empty($order->accountnumber))
|
376 |
$nvpStr .= "&ACCT=" . $order->accountnumber . "&EXPDATE=" . $order->expirationmonth . substr($order->expirationyear, 2, 2) . "&CVV2=" . $order->CVV2;
|
377 |
+
|
378 |
/*
|
379 |
Let's figure out the start date. There are two parts.
|
380 |
1. We need to add the billing period to the start date to account for the initial payment.
|
381 |
+
2. We can allow for free trials by further delaying the start date of the subscription.
|
382 |
*/
|
383 |
if($order->BillingPeriod == "Year")
|
384 |
$trial_period_days = $order->BillingFrequency * 365; //annual
|
388 |
$trial_period_days = $order->BillingFrequency * 7; //weekly
|
389 |
else
|
390 |
$trial_period_days = $order->BillingFrequency * 30; //assume monthly
|
391 |
+
|
392 |
//convert to a profile start date
|
393 |
$order->ProfileStartDate = date("Y-m-d", strtotime("+ " . $trial_period_days . " Day", current_time("timestamp"))) . "T0:0:0";
|
394 |
+
|
395 |
//filter the start date
|
396 |
+
$order->ProfileStartDate = apply_filters("pmpro_profile_start_date", $order->ProfileStartDate, $order);
|
397 |
|
398 |
//convert back to days
|
399 |
$trial_period_days = ceil(abs(strtotime(date("Y-m-d"), current_time('timestamp')) - strtotime($order->ProfileStartDate, current_time("timestamp"))) / 86400);
|
400 |
|
401 |
//now add the actual trial set by the site
|
402 |
+
if(!empty($order->TrialBillingCycles))
|
403 |
{
|
404 |
$trialOccurrences = (int)$order->TrialBillingCycles;
|
405 |
if($order->BillingPeriod == "Year")
|
409 |
elseif($order->BillingPeriod == "Week")
|
410 |
$trial_period_days = $trial_period_days + (7 * $order->BillingFrequency * $trialOccurrences); //weekly
|
411 |
else
|
412 |
+
$trial_period_days = $trial_period_days + (30 * $order->BillingFrequency * $trialOccurrences); //assume monthly
|
413 |
+
}
|
414 |
+
|
415 |
//convert back into a date
|
416 |
$order->ProfileStartDate = date("Y-m-d", strtotime("+ " . $trial_period_days . " Day", current_time("timestamp"))) . "T0:0:0";
|
417 |
+
|
418 |
//start date
|
419 |
$nvpStr .= "&START=" . date("mdY", strtotime($order->ProfileStartDate));
|
420 |
+
|
421 |
if(!empty($order->accountnumber))
|
422 |
$nvpStr .= "&ACCT=" . $order->accountnumber . "&EXPDATE=" . $order->expirationmonth . substr($order->expirationyear, 2, 2) . "&CVV2=" . $order->CVV2;
|
423 |
+
|
424 |
//billing address, etc
|
425 |
if($order->Address1)
|
426 |
{
|
427 |
$nvpStr .= "&EMAIL=" . $order->Email . "&FIRSTNAME=" . $order->FirstName . "&LASTNAME=" . $order->LastName . "&STREET=" . $order->Address1;
|
428 |
+
|
429 |
if($order->Address2)
|
430 |
$nvpStr .= " " . $order->Address2;
|
431 |
+
|
432 |
$nvpStr .= "&CITY=" . $order->billing->city . "&STATE=" . $order->billing->state . "&BILLTOCOUNTRY=" . $order->billing->country . "&ZIP=" . $order->billing->zip . "&PHONENUM=" . $order->billing->phone;
|
433 |
}
|
434 |
|
435 |
+
$this->nvpStr = $nvpStr;
|
436 |
$this->httpParsedResponseAr = $this->PPHttpPost('R', $nvpStr);
|
437 |
+
|
438 |
if("0" == strtoupper($this->httpParsedResponseAr["RESULT"])) {
|
439 |
$order->subscription_transaction_id = $this->httpParsedResponseAr['PROFILEID'];
|
440 |
+
$order->status = "success";
|
441 |
+
return true;
|
442 |
+
} else {
|
443 |
$order->status = "error";
|
444 |
$order->errorcode = $this->httpParsedResponseAr['RESULT'];
|
445 |
$order->error = urldecode($this->httpParsedResponseAr['RESPMSG']);
|
446 |
+
$order->shorterror = urldecode($this->httpParsedResponseAr['RESPMSG']);
|
447 |
+
return false;
|
448 |
+
}
|
449 |
+
}
|
450 |
+
|
451 |
function update(&$order)
|
452 |
{
|
453 |
$order->getMembershipLevel();
|
454 |
+
|
455 |
//paypal profile stuff
|
456 |
+
$nvpStr = "&ORIGPROFILEID=" . $order->subscription_transaction_id . "&ACTION=M";
|
457 |
$nvpStr .= "&NOTIFYURL=" . urlencode(admin_url('admin-ajax.php') . "?action=ipnhandler");
|
458 |
+
|
459 |
$nvpStr .= "&PROFILENAME=" . urlencode(substr($order->membership_level->name . " at " . get_bloginfo("name"), 0, 127));
|
460 |
+
|
461 |
+
$nvpStr .= "&CUSTIP=" . $_SERVER['REMOTE_ADDR']; // . "&INVNUM=" . $order->code;
|
462 |
+
|
463 |
if(!empty($order->accountnumber))
|
464 |
$nvpStr .= "&ACCT=" . $order->accountnumber . "&EXPDATE=" . $order->expirationmonth . substr($order->expirationyear, 2, 2) . "&CVV2=" . $order->CVV2;
|
465 |
+
|
466 |
//billing address, etc
|
467 |
if($order->Address1)
|
468 |
{
|
469 |
$nvpStr .= "&EMAIL=" . $order->Email . "&FIRSTNAME=" . $order->FirstName . "&LASTNAME=" . $order->LastName . "&STREET=" . $order->Address1;
|
470 |
+
|
471 |
if($order->Address2)
|
472 |
$nvpStr .= " " . $order->Address2;
|
473 |
+
|
474 |
$nvpStr .= "&CITY=" . $order->billing->city . "&STATE=" . $order->billing->state . "&BILLTOCOUNTRY=" . $order->billing->country . "&ZIP=" . $order->billing->zip . "&PHONENUM=" . $order->billing->phone;
|
475 |
}
|
476 |
|
477 |
$this->nvpStr = $nvpStr;
|
478 |
$this->httpParsedResponseAr = $this->PPHttpPost('R', $nvpStr);
|
479 |
+
|
480 |
if("0" == strtoupper($this->httpParsedResponseAr["RESULT"])) {
|
481 |
$order->subscription_transaction_id = $this->httpParsedResponseAr['PROFILEID'];
|
482 |
+
$order->updateStatus("success");
|
483 |
+
return true;
|
484 |
+
} else {
|
485 |
$order->status = "error";
|
486 |
$order->errorcode = $this->httpParsedResponseAr['RESULT'];
|
487 |
$order->error = urldecode($this->httpParsedResponseAr['RESPMSG']);
|
488 |
+
$order->shorterror = urldecode($this->httpParsedResponseAr['RESPMSG']);
|
489 |
+
return false;
|
490 |
+
}
|
491 |
}
|
492 |
+
|
493 |
function cancel(&$order)
|
494 |
{
|
495 |
//require a subscription id
|
496 |
if(empty($order->subscription_transaction_id))
|
497 |
return false;
|
498 |
+
|
499 |
//paypal profile stuff
|
500 |
+
$nvpStr = "&ORIGPROFILEID=" . $order->subscription_transaction_id . "&ACTION=C";
|
501 |
+
|
502 |
$this->nvpStr = $nvpStr;
|
503 |
$this->httpParsedResponseAr = $this->PPHttpPost('R', $nvpStr);
|
504 |
+
|
505 |
+
if("0" == strtoupper($this->httpParsedResponseAr["RESULT"]))
|
506 |
+
{
|
507 |
+
$order->updateStatus("cancelled");
|
508 |
+
return true;
|
509 |
}
|
510 |
else
|
511 |
+
{
|
512 |
$order->status = "error";
|
513 |
$order->errorcode = $this->httpParsedResponseAr['RESULT'];
|
514 |
$order->error = urldecode($this->httpParsedResponseAr['RESPMSG']);
|
515 |
+
$order->shorterror = urldecode($this->httpParsedResponseAr['RESPMSG']);
|
516 |
return false;
|
517 |
}
|
518 |
+
}
|
519 |
+
|
520 |
/**
|
521 |
* PAYPAL Function
|
522 |
* Send HTTP POST Request
|
527 |
*/
|
528 |
function PPHttpPost($methodName_, $nvpStr_) {
|
529 |
global $gateway_environment;
|
530 |
+
$environment = $gateway_environment;
|
531 |
+
|
532 |
$PARTNER = pmpro_getOption("payflow_partner");
|
533 |
$VENDOR = pmpro_getOption("payflow_vendor");
|
534 |
$USER = pmpro_getOption("payflow_user");
|
536 |
$API_Endpoint = "https://payflowpro.paypal.com";
|
537 |
if("sandbox" === $environment || "beta-sandbox" === $environment) {
|
538 |
$API_Endpoint = "https://pilot-payflowpro.paypal.com";
|
539 |
+
}
|
540 |
+
|
541 |
$version = urlencode('4');
|
542 |
+
|
543 |
// setting the curl parameters.
|
544 |
$ch = curl_init();
|
545 |
curl_setopt($ch, CURLOPT_URL, $API_Endpoint);
|
546 |
curl_setopt($ch, CURLOPT_VERBOSE, 1);
|
547 |
+
|
548 |
// turning off the server and peer verification(TrustManager Concept).
|
549 |
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
|
550 |
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
|
551 |
+
|
552 |
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
|
553 |
curl_setopt($ch, CURLOPT_POST, 1);
|
554 |
+
|
555 |
// NVPRequest for submitting to server
|
556 |
$nvpreq = "TRXTYPE=" . $methodName_ . "&TENDER=C&PARTNER=" . $PARTNER . "&VENDOR=" . $VENDOR . "&USER=" . $USER . "&PWD=" . $PWD . "&VERBOSITY=medium" . "&BUTTONSOURCE=" . urlencode(PAYPAL_BN_CODE) . $nvpStr_;
|
557 |
+
|
558 |
//$nvpreq = "TRXTYPE=" . urlencode($methodName_) . "&TENDER=C&PARTNER=" . urlencode($PARTNER) . "&VENDOR=" . urlencode($VENDOR) . "&USER=" . urlencode($USER) . "&PWD=" . urlencode($PWD) . "&VERBOSITY=medium" . $nvpStr_;
|
559 |
+
|
560 |
// setting the nvpreq as POST FIELD to curl
|
561 |
curl_setopt($ch, CURLOPT_POSTFIELDS, $nvpreq);
|
562 |
+
|
563 |
// getting response from server
|
564 |
$httpResponse = curl_exec($ch);
|
565 |
+
|
566 |
if(empty($httpResponse)) {
|
567 |
exit("$methodName_ failed: ".curl_error($ch).'('.curl_errno($ch).')');
|
568 |
}
|
569 |
+
|
570 |
// Extract the RefundTransaction response details
|
571 |
$httpResponseAr = explode("&", $httpResponse);
|
572 |
+
|
573 |
$httpParsedResponseAr = array();
|
574 |
foreach ($httpResponseAr as $i => $value) {
|
575 |
$tmpAr = explode("=", $value);
|
577 |
$httpParsedResponseAr[$tmpAr[0]] = $tmpAr[1];
|
578 |
}
|
579 |
}
|
580 |
+
|
581 |
if((0 == sizeof($httpParsedResponseAr)) || !array_key_exists('RESULT', $httpParsedResponseAr)) {
|
582 |
exit("Invalid HTTP Response for POST request($nvpreq) to $API_Endpoint.");
|
583 |
}
|
584 |
+
|
585 |
return $httpParsedResponseAr;
|
586 |
}
|
587 |
}
|
classes/gateways/class.pmprogateway_paypal.php
CHANGED
@@ -1,71 +1,71 @@
|
|
1 |
<?php
|
2 |
//include pmprogateway
|
3 |
require_once(dirname(__FILE__) . "/class.pmprogateway.php");
|
4 |
-
|
5 |
//load classes init method
|
6 |
add_action('init', array('PMProGateway_paypal', 'init'));
|
7 |
-
|
8 |
class PMProGateway_paypal extends PMProGateway
|
9 |
{
|
10 |
function PMProGateway_paypal($gateway = NULL)
|
11 |
{
|
12 |
$this->gateway = $gateway;
|
13 |
return $this->gateway;
|
14 |
-
}
|
15 |
-
|
16 |
/**
|
17 |
* Run on WP init
|
18 |
-
*
|
19 |
* @since 1.8
|
20 |
*/
|
21 |
static function init()
|
22 |
-
{
|
23 |
//make sure PayPal Website Payments Pro is a gateway option
|
24 |
add_filter('pmpro_gateways', array('PMProGateway_paypal', 'pmpro_gateways'));
|
25 |
-
|
26 |
//add fields to payment settings
|
27 |
add_filter('pmpro_payment_options', array('PMProGateway_paypal', 'pmpro_payment_options'));
|
28 |
-
|
29 |
/*
|
30 |
This code is the same for PayPal Website Payments Pro, PayPal Express, and PayPal Standard
|
31 |
So we only load it if we haven't already.
|
32 |
*/
|
33 |
global $pmpro_payment_option_fields_for_paypal;
|
34 |
if(empty($pmpro_payment_option_fields_for_paypal))
|
35 |
-
{
|
36 |
-
add_filter('pmpro_payment_option_fields', array('PMProGateway_paypal', 'pmpro_payment_option_fields'), 10, 2);
|
37 |
$pmpro_payment_option_fields_for_paypal = true;
|
38 |
}
|
39 |
-
|
40 |
//code to add at checkout
|
41 |
$gateway = pmpro_getGateway();
|
42 |
if($gateway == "paypal")
|
43 |
-
{
|
44 |
add_filter('pmpro_checkout_default_submit_button', array('PMProGateway_paypal', 'pmpro_checkout_default_submit_button'));
|
45 |
add_action('pmpro_checkout_after_form', array('PMProGateway_paypal', 'pmpro_checkout_after_form'));
|
46 |
}
|
47 |
}
|
48 |
-
|
49 |
/**
|
50 |
* Make sure this gateway is in the gateways list
|
51 |
-
*
|
52 |
* @since 1.8
|
53 |
*/
|
54 |
static function pmpro_gateways($gateways)
|
55 |
{
|
56 |
if(empty($gateways['paypal']))
|
57 |
$gateways['paypal'] = __('PayPal Website Payments Pro', 'pmpro');
|
58 |
-
|
59 |
return $gateways;
|
60 |
}
|
61 |
-
|
62 |
/**
|
63 |
* Get a list of payment options that the this gateway needs/supports.
|
64 |
-
*
|
65 |
* @since 1.8
|
66 |
*/
|
67 |
static function getGatewayOptions()
|
68 |
-
{
|
69 |
$options = array(
|
70 |
'sslseal',
|
71 |
'nuclear_HTTPS',
|
@@ -80,29 +80,29 @@
|
|
80 |
'tax_rate',
|
81 |
'accepted_credit_cards'
|
82 |
);
|
83 |
-
|
84 |
return $options;
|
85 |
}
|
86 |
-
|
87 |
/**
|
88 |
* Set payment options for payment settings page.
|
89 |
-
*
|
90 |
* @since 1.8
|
91 |
*/
|
92 |
static function pmpro_payment_options($options)
|
93 |
-
{
|
94 |
//get stripe options
|
95 |
$paypal_options = PMProGateway_paypal::getGatewayOptions();
|
96 |
-
|
97 |
//merge with others.
|
98 |
$options = array_merge($paypal_options, $options);
|
99 |
-
|
100 |
return $options;
|
101 |
}
|
102 |
-
|
103 |
/**
|
104 |
* Display fields for this gateway's options.
|
105 |
-
*
|
106 |
* @since 1.8
|
107 |
*/
|
108 |
static function pmpro_payment_option_fields($values, $gateway)
|
@@ -112,20 +112,20 @@
|
|
112 |
<td colspan="2">
|
113 |
<?php _e('PayPal Settings', 'pmpro'); ?>
|
114 |
</td>
|
115 |
-
</tr>
|
116 |
<tr class="gateway gateway_paypalstandard" <?php if($gateway != "paypalstandard") { ?>style="display: none;"<?php } ?>>
|
117 |
<td colspan="2">
|
118 |
<strong><?php _e('Note', 'pmpro');?>:</strong> <?php _e('We do not recommend using PayPal Standard. We suggest using PayPal Express, Website Payments Pro (Legacy), or PayPal Pro (Payflow Pro). <a target="_blank" href="http://www.paidmembershipspro.com/2013/09/read-using-paypal-standard-paid-memberships-pro/">More information on why can be found here.</a>', 'pmpro');?>
|
119 |
-
</td>
|
120 |
-
</tr>
|
121 |
<tr class="gateway gateway_paypal gateway_paypalexpress gateway_paypalstandard" <?php if($gateway != "paypal" && $gateway != "paypalexpress" && $gateway != "paypalstandard") { ?>style="display: none;"<?php } ?>>
|
122 |
-
<th scope="row" valign="top">
|
123 |
<label for="gateway_email"><?php _e('Gateway Account Email', 'pmpro');?>:</label>
|
124 |
</th>
|
125 |
<td>
|
126 |
<input type="text" id="gateway_email" name="gateway_email" size="60" value="<?php echo esc_attr($values['gateway_email'])?>" />
|
127 |
</td>
|
128 |
-
</tr>
|
129 |
<tr class="gateway gateway_paypal gateway_paypalexpress" <?php if($gateway != "paypal" && $gateway != "paypalexpress") { ?>style="display: none;"<?php } ?>>
|
130 |
<th scope="row" valign="top">
|
131 |
<label for="apiusername"><?php _e('API Username', 'pmpro');?>:</label>
|
@@ -141,7 +141,7 @@
|
|
141 |
<td>
|
142 |
<input type="text" id="apipassword" name="apipassword" size="60" value="<?php echo esc_attr($values['apipassword'])?>" />
|
143 |
</td>
|
144 |
-
</tr>
|
145 |
<tr class="gateway gateway_paypal gateway_paypalexpress" <?php if($gateway != "paypal" && $gateway != "paypalexpress") { ?>style="display: none;"<?php } ?>>
|
146 |
<th scope="row" valign="top">
|
147 |
<label for="apisignature"><?php _e('API Signature', 'pmpro');?>:</label>
|
@@ -149,7 +149,7 @@
|
|
149 |
<td>
|
150 |
<input type="text" id="apisignature" name="apisignature" size="60" value="<?php echo esc_attr($values['apisignature'])?>" />
|
151 |
</td>
|
152 |
-
</tr>
|
153 |
<tr class="gateway gateway_paypal gateway_paypalexpress gateway_paypalstandard" <?php if($gateway != "paypal" && $gateway != "paypalexpress" && $gateway != "paypalstandard") { ?>style="display: none;"<?php } ?>>
|
154 |
<th scope="row" valign="top">
|
155 |
<label><?php _e('IPN Handler URL', 'pmpro');?>:</label>
|
@@ -160,7 +160,7 @@
|
|
160 |
</tr>
|
161 |
<?php
|
162 |
}
|
163 |
-
|
164 |
/**
|
165 |
* Swap in our submit buttons.
|
166 |
*
|
@@ -169,26 +169,26 @@
|
|
169 |
static function pmpro_checkout_default_submit_button($show)
|
170 |
{
|
171 |
global $gateway, $pmpro_requirebilling;
|
172 |
-
|
173 |
//show our submit buttons
|
174 |
?>
|
175 |
<?php if($gateway == "paypal" || $gateway == "paypalexpress" || $gateway == "paypalstandard") { ?>
|
176 |
<span id="pmpro_paypalexpress_checkout" <?php if(($gateway != "paypalexpress" && $gateway != "paypalstandard") || !$pmpro_requirebilling) { ?>style="display: none;"<?php } ?>>
|
177 |
-
<input type="hidden" name="submit-checkout" value="1" />
|
178 |
<input type="image" value="<?php _e('Check Out with PayPal', 'pmpro');?> »" src="<?php echo apply_filters("pmpro_paypal_button_image", "https://www.paypal.com/en_US/i/btn/btn_xpressCheckout.gif");?>" />
|
179 |
</span>
|
180 |
<?php } ?>
|
181 |
-
|
182 |
<span id="pmpro_submit_span" <?php if(($gateway == "paypalexpress" || $gateway == "paypalstandard") && $pmpro_requirebilling) { ?>style="display: none;"<?php } ?>>
|
183 |
-
<input type="hidden" name="submit-checkout" value="1" />
|
184 |
-
<input type="submit" class="pmpro_btn pmpro_btn-submit-checkout" value="<?php if($pmpro_requirebilling) { _e('Submit and Check Out', 'pmpro'); } else { _e('Submit and Confirm', 'pmpro');}?> »" />
|
185 |
</span>
|
186 |
<?php
|
187 |
-
|
188 |
//don't show the default
|
189 |
return false;
|
190 |
}
|
191 |
-
|
192 |
/**
|
193 |
* Scripts for checkout page.
|
194 |
*
|
@@ -197,25 +197,25 @@
|
|
197 |
static function pmpro_checkout_after_form()
|
198 |
{
|
199 |
?>
|
200 |
-
<script>
|
201 |
//choosing payment method
|
202 |
-
jQuery('input[name=gateway]').click(function() {
|
203 |
if(jQuery(this).val() == 'paypal')
|
204 |
{
|
205 |
jQuery('#pmpro_paypalexpress_checkout').hide();
|
206 |
jQuery('#pmpro_billing_address_fields').show();
|
207 |
-
jQuery('#pmpro_payment_information_fields').show();
|
208 |
jQuery('#pmpro_submit_span').show();
|
209 |
}
|
210 |
else
|
211 |
-
{
|
212 |
jQuery('#pmpro_billing_address_fields').hide();
|
213 |
-
jQuery('#pmpro_payment_information_fields').hide();
|
214 |
jQuery('#pmpro_submit_span').hide();
|
215 |
jQuery('#pmpro_paypalexpress_checkout').show();
|
216 |
}
|
217 |
});
|
218 |
-
|
219 |
//select the radio button if the label is clicked on
|
220 |
jQuery('a.pmpro_radio').click(function() {
|
221 |
jQuery(this).prev().click();
|
@@ -223,20 +223,20 @@
|
|
223 |
</script>
|
224 |
<?php
|
225 |
}
|
226 |
-
|
227 |
/**
|
228 |
* Process checkout.
|
229 |
-
*
|
230 |
*/
|
231 |
function process(&$order)
|
232 |
{
|
233 |
if(floatval($order->InitialPayment) == 0)
|
234 |
{
|
235 |
//auth first, then process
|
236 |
-
$authorization_id = $this->authorize($order);
|
237 |
if($authorization_id)
|
238 |
{
|
239 |
-
$this->void($order, $authorization_id);
|
240 |
$order->ProfileStartDate = date("Y-m-d", strtotime("+ " . $order->BillingFrequency . " " . $order->BillingPeriod, current_time("timestamp"))) . "T0:0:0";
|
241 |
$order->ProfileStartDate = apply_filters("pmpro_profile_start_date", $order->ProfileStartDate, $order);
|
242 |
return $this->subscribe($order);
|
@@ -252,18 +252,18 @@
|
|
252 |
{
|
253 |
//charge first payment
|
254 |
if($this->charge($order))
|
255 |
-
{
|
256 |
//setup recurring billing
|
257 |
if(pmpro_isLevelRecurring($order->membership_level))
|
258 |
{
|
259 |
$order->ProfileStartDate = date("Y-m-d", strtotime("+ " . $order->BillingFrequency . " " . $order->BillingPeriod, current_time("timestamp"))) . "T0:0:0";
|
260 |
$order->ProfileStartDate = apply_filters("pmpro_profile_start_date", $order->ProfileStartDate, $order);
|
261 |
if($this->subscribe($order))
|
262 |
-
{
|
263 |
return true;
|
264 |
}
|
265 |
else
|
266 |
-
{
|
267 |
if($this->refund($order, $order->payment_transaction_id))
|
268 |
{
|
269 |
if(empty($order->error))
|
@@ -273,146 +273,146 @@
|
|
273 |
{
|
274 |
if(empty($order->error))
|
275 |
$order->error = "Unknown error: Payment failed.";
|
276 |
-
|
277 |
$order->error .= " " . __("A partial payment was made that we could not refund. Please contact the site owner immediately to correct this.", "pmpro");
|
278 |
}
|
279 |
-
|
280 |
-
return false;
|
281 |
}
|
282 |
}
|
283 |
else
|
284 |
{
|
285 |
-
//only a one time charge
|
286 |
-
$order->status = "success"; //saved on checkout page
|
287 |
$order->saveOrder();
|
288 |
return true;
|
289 |
}
|
290 |
-
}
|
291 |
-
}
|
292 |
}
|
293 |
-
|
294 |
function authorize(&$order)
|
295 |
{
|
296 |
if(empty($order->code))
|
297 |
$order->code = $order->getRandomCode();
|
298 |
-
|
299 |
//paypal profile stuff
|
300 |
$nvpStr = "";
|
301 |
if(!empty($order->Token))
|
302 |
$nvpStr .= "&TOKEN=" . $order->Token;
|
303 |
-
$nvpStr .="&AMT=1.00&CURRENCYCODE=" . pmpro_getOption("currency");
|
304 |
$nvpStr .= "&NOTIFYURL=" . urlencode(admin_url('admin-ajax.php') . "?action=ipnhandler");
|
305 |
//$nvpStr .= "&L_BILLINGTYPE0=RecurringPayments&L_BILLINGAGREEMENTDESCRIPTION0=" . $order->PaymentAmount;
|
306 |
-
|
307 |
$nvpStr .= "&PAYMENTACTION=Authorization&IPADDRESS=" . $_SERVER['REMOTE_ADDR'] . "&INVNUM=" . $order->code;
|
308 |
-
|
309 |
//credit card fields
|
310 |
if($order->cardtype == "American Express")
|
311 |
$cardtype = "Amex";
|
312 |
else
|
313 |
$cardtype = $order->cardtype;
|
314 |
-
|
315 |
if(!empty($cardtype))
|
316 |
$nvpStr .= "&CREDITCARDTYPE=" . $cardtype . "&ACCT=" . $order->accountnumber . "&EXPDATE=" . $order->ExpirationDate . "&CVV2=" . $order->CVV2;
|
317 |
|
318 |
//Maestro/Solo card fields. (Who uses these?) :)
|
319 |
if(!empty($order->StartDate))
|
320 |
$nvpStr .= "&STARTDATE=" . $order->StartDate . "&ISSUENUMBER=" . $order->IssueNumber;
|
321 |
-
|
322 |
//billing address, etc
|
323 |
if(!empty($order->Address1))
|
324 |
{
|
325 |
$nvpStr .= "&EMAIL=" . $order->Email . "&FIRSTNAME=" . $order->FirstName . "&LASTNAME=" . $order->LastName . "&STREET=" . $order->Address1;
|
326 |
-
|
327 |
if($order->Address2)
|
328 |
$nvpStr .= "&STREET2=" . $order->Address2;
|
329 |
-
|
330 |
$nvpStr .= "&CITY=" . $order->billing->city . "&STATE=" . $order->billing->state . "&COUNTRYCODE=" . $order->billing->country . "&ZIP=" . $order->billing->zip . "&SHIPTOPHONENUM=" . $order->billing->phone;
|
331 |
}
|
332 |
|
333 |
//for debugging, let's attach this to the class object
|
334 |
$this->nvpStr = $nvpStr;
|
335 |
-
|
336 |
$this->httpParsedResponseAr = $this->PPHttpPost('DoDirectPayment', $nvpStr);
|
337 |
-
|
338 |
if("SUCCESS" == strtoupper($this->httpParsedResponseAr["ACK"]) || "SUCCESSWITHWARNING" == strtoupper($this->httpParsedResponseAr["ACK"])) {
|
339 |
$order->authorization_id = $this->httpParsedResponseAr['TRANSACTIONID'];
|
340 |
-
$order->updateStatus("authorized");
|
341 |
-
return $order->authorization_id;
|
342 |
-
} else {
|
343 |
$order->status = "error";
|
344 |
$order->errorcode = $this->httpParsedResponseAr['L_ERRORCODE0'];
|
345 |
$order->error = urldecode($this->httpParsedResponseAr['L_LONGMESSAGE0']);
|
346 |
$order->shorterror = urldecode($this->httpParsedResponseAr['L_SHORTMESSAGE0']);
|
347 |
-
return false;
|
348 |
-
}
|
349 |
}
|
350 |
-
|
351 |
function void(&$order, $authorization_id = null)
|
352 |
{
|
353 |
if(empty($authorization_id))
|
354 |
return false;
|
355 |
-
|
356 |
//paypal profile stuff
|
357 |
$nvpStr="&AUTHORIZATIONID=" . $authorization_id . "&NOTE=Voiding an authorization for a recurring payment setup.";
|
358 |
-
|
359 |
$this->httpParsedResponseAr = $this->PPHttpPost('DoVoid', $nvpStr);
|
360 |
-
|
361 |
-
if("SUCCESS" == strtoupper($this->httpParsedResponseAr["ACK"]) || "SUCCESSWITHWARNING" == strtoupper($this->httpParsedResponseAr["ACK"])) {
|
362 |
-
return true;
|
363 |
-
} else {
|
364 |
$order->status = "error";
|
365 |
$order->errorcode = $this->httpParsedResponseAr['L_ERRORCODE0'];
|
366 |
$order->error = urldecode($this->httpParsedResponseAr['L_LONGMESSAGE0']);
|
367 |
$order->shorterror = urldecode($this->httpParsedResponseAr['L_SHORTMESSAGE0']);
|
368 |
-
return false;
|
369 |
-
}
|
370 |
-
}
|
371 |
-
|
372 |
function refund(&$order, $transaction_id)
|
373 |
{
|
374 |
if(empty($transaction_id))
|
375 |
return false;
|
376 |
-
|
377 |
//paypal profile stuff
|
378 |
$nvpStr="&TRANSACTIONID=" . $transaction_id . "&NOTE=Refunding a charge.";
|
379 |
-
|
380 |
$this->httpParsedResponseAr = $this->PPHttpPost('RefundTransaction', $nvpStr);
|
381 |
-
|
382 |
-
if("SUCCESS" == strtoupper($this->httpParsedResponseAr["ACK"]) || "SUCCESSWITHWARNING" == strtoupper($this->httpParsedResponseAr["ACK"])) {
|
383 |
-
return true;
|
384 |
-
} else {
|
385 |
$order->status = "error";
|
386 |
$order->errorcode = $this->httpParsedResponseAr['L_ERRORCODE0'];
|
387 |
$order->error = urldecode($this->httpParsedResponseAr['L_LONGMESSAGE0']);
|
388 |
$order->shorterror = urldecode($this->httpParsedResponseAr['L_SHORTMESSAGE0']);
|
389 |
-
return false;
|
390 |
-
}
|
391 |
}
|
392 |
-
|
393 |
function charge(&$order)
|
394 |
{
|
395 |
global $pmpro_currency;
|
396 |
-
|
397 |
if(empty($order->code))
|
398 |
$order->code = $order->getRandomCode();
|
399 |
-
|
400 |
//taxes on the amount
|
401 |
$amount = $order->InitialPayment;
|
402 |
-
$amount_tax = $order->getTaxForPrice($amount);
|
403 |
$order->subtotal = $amount;
|
404 |
$amount = round((float)$amount + (float)$amount_tax, 2);
|
405 |
-
|
406 |
//paypal profile stuff
|
407 |
$nvpStr = "";
|
408 |
if(!empty($order->Token))
|
409 |
$nvpStr .= "&TOKEN=" . $order->Token;
|
410 |
-
$nvpStr .="&AMT=" . $amount . "&ITEMAMT=" . $order->InitialPayment . "&TAXAMT=" . $amount_tax . "&CURRENCYCODE=" . $pmpro_currency;
|
411 |
$nvpStr .= "&NOTIFYURL=" . urlencode(admin_url('admin-ajax.php') . "?action=ipnhandler");
|
412 |
//$nvpStr .= "&L_BILLINGTYPE0=RecurringPayments&L_BILLINGAGREEMENTDESCRIPTION0=" . $order->PaymentAmount;
|
413 |
-
|
414 |
-
$nvpStr .= "&PAYMENTACTION=Sale&IPADDRESS=" . $_SERVER['REMOTE_ADDR'] . "&INVNUM=" . $order->code;
|
415 |
-
|
416 |
//credit card fields
|
417 |
if($order->cardtype == "American Express")
|
418 |
$cardtype = "Amex";
|
@@ -425,48 +425,48 @@
|
|
425 |
//Maestro/Solo card fields. (Who uses these?) :)
|
426 |
if(!empty($order->StartDate))
|
427 |
$nvpStr .= "&STARTDATE=" . $order->StartDate . "&ISSUENUMBER=" . $order->IssueNumber;
|
428 |
-
|
429 |
//billing address, etc
|
430 |
if($order->Address1)
|
431 |
{
|
432 |
$nvpStr .= "&EMAIL=" . $order->Email . "&FIRSTNAME=" . $order->FirstName . "&LASTNAME=" . $order->LastName . "&STREET=" . $order->Address1;
|
433 |
-
|
434 |
if($order->Address2)
|
435 |
$nvpStr .= "&STREET2=" . $order->Address2;
|
436 |
-
|
437 |
$nvpStr .= "&CITY=" . $order->billing->city . "&STATE=" . $order->billing->state . "&COUNTRYCODE=" . $order->billing->country . "&ZIP=" . $order->billing->zip . "&SHIPTOPHONENUM=" . $order->billing->phone;
|
438 |
}
|
439 |
|
440 |
$this->httpParsedResponseAr = $this->PPHttpPost('DoDirectPayment', $nvpStr);
|
441 |
-
|
442 |
if("SUCCESS" == strtoupper($this->httpParsedResponseAr["ACK"]) || "SUCCESSWITHWARNING" == strtoupper($this->httpParsedResponseAr["ACK"])) {
|
443 |
$order->payment_transaction_id = $this->httpParsedResponseAr['TRANSACTIONID'];
|
444 |
-
$order->updateStatus("success");
|
445 |
-
return true;
|
446 |
-
} else {
|
447 |
$order->status = "error";
|
448 |
$order->errorcode = $this->httpParsedResponseAr['L_ERRORCODE0'];
|
449 |
$order->error = urldecode($this->httpParsedResponseAr['L_LONGMESSAGE0']);
|
450 |
-
$order->shorterror = urldecode($this->httpParsedResponseAr['L_SHORTMESSAGE0']);
|
451 |
-
return false;
|
452 |
-
}
|
453 |
}
|
454 |
-
|
455 |
function subscribe(&$order)
|
456 |
{
|
457 |
global $pmpro_currency;
|
458 |
-
|
459 |
if(empty($order->code))
|
460 |
-
$order->code = $order->getRandomCode();
|
461 |
-
|
462 |
//filter order before subscription. use with care.
|
463 |
$order = apply_filters("pmpro_subscribe_order", $order, $this);
|
464 |
-
|
465 |
//taxes on the amount
|
466 |
$amount = $order->PaymentAmount;
|
467 |
-
$amount_tax = $order->getTaxForPrice($amount);
|
468 |
$amount = round((float)$amount + (float)$amount_tax, 2);
|
469 |
-
|
470 |
//paypal profile stuff
|
471 |
$nvpStr = "";
|
472 |
if(!empty($order->Token))
|
@@ -476,58 +476,58 @@
|
|
476 |
$nvpStr .= "&DESC=" . urlencode(substr($order->membership_level->name . " at " . get_bloginfo("name"), 0, 127));
|
477 |
$nvpStr .= "&NOTIFYURL=" . urlencode(admin_url('admin-ajax.php') . "?action=ipnhandler");
|
478 |
//$nvpStr .= "&L_BILLINGTYPE0=RecurringPayments&L_BILLINGAGREEMENTDESCRIPTION0=" . $order->PaymentAmount;
|
479 |
-
|
480 |
-
//if billing cycles are defined
|
481 |
if(!empty($order->TotalBillingCycles))
|
482 |
$nvpStr .= "&TOTALBILLINGCYCLES=" . $order->TotalBillingCycles;
|
483 |
-
|
484 |
//if a trial period is defined
|
485 |
if(!empty($order->TrialBillingPeriod))
|
486 |
{
|
487 |
-
$trial_amount = $order->TrialAmount;
|
488 |
$trial_tax = $order->getTaxForPrice($trial_amount);
|
489 |
$trial_amount = round((float)$trial_amount + (float)$trial_tax, 2);
|
490 |
-
|
491 |
$nvpStr .= "&TRIALBILLINGPERIOD=" . $order->TrialBillingPeriod . "&TRIALBILLINGFREQUENCY=" . $order->TrialBillingFrequency . "&TRIALAMT=" . $trial_amount;
|
492 |
}
|
493 |
if(!empty($order->TrialBillingCycles))
|
494 |
$nvpStr .= "&TRIALTOTALBILLINGCYCLES=" . $order->TrialBillingCycles;
|
495 |
-
|
496 |
//credit card fields
|
497 |
if($order->cardtype == "American Express")
|
498 |
$cardtype = "Amex";
|
499 |
else
|
500 |
$cardtype = $order->cardtype;
|
501 |
-
|
502 |
-
if($cardtype)
|
503 |
$nvpStr .= "&CREDITCARDTYPE=" . $cardtype . "&ACCT=" . $order->accountnumber . "&EXPDATE=" . $order->ExpirationDate . "&CVV2=" . $order->CVV2;
|
504 |
|
505 |
//Maestro/Solo card fields. (Who uses these?) :)
|
506 |
if(!empty($order->StartDate))
|
507 |
$nvpStr .= "&STARTDATE=" . $order->StartDate . "&ISSUENUMBER=" . $order->IssueNumber;
|
508 |
-
|
509 |
//billing address, etc
|
510 |
if($order->Address1)
|
511 |
{
|
512 |
$nvpStr .= "&EMAIL=" . $order->Email . "&FIRSTNAME=" . $order->FirstName . "&LASTNAME=" . $order->LastName . "&STREET=" . $order->Address1;
|
513 |
-
|
514 |
if($order->Address2)
|
515 |
$nvpStr .= "&STREET2=" . $order->Address2;
|
516 |
-
|
517 |
$nvpStr .= "&CITY=" . $order->billing->city . "&STATE=" . $order->billing->state . "&COUNTRYCODE=" . $order->billing->country . "&ZIP=" . $order->billing->zip . "&SHIPTOPHONENUM=" . $order->billing->phone;
|
518 |
}
|
519 |
|
520 |
//for debugging let's add this to the class object
|
521 |
$this->nvpStr = $nvpStr;
|
522 |
-
|
523 |
$this->httpParsedResponseAr = $this->PPHttpPost('CreateRecurringPaymentsProfile', $nvpStr);
|
524 |
-
|
525 |
if("SUCCESS" == strtoupper($this->httpParsedResponseAr["ACK"]) || "SUCCESSWITHWARNING" == strtoupper($this->httpParsedResponseAr["ACK"])) {
|
526 |
-
$order->status = "success";
|
527 |
$order->subscription_transaction_id = urldecode($this->httpParsedResponseAr['PROFILEID']);
|
528 |
return true;
|
529 |
//exit('CreateRecurringPaymentsProfile Completed Successfully: '.print_r($this->httpParsedResponseAr, true));
|
530 |
-
} else {
|
531 |
$order->status = "error";
|
532 |
$order->errorcode = $this->httpParsedResponseAr['L_ERRORCODE0'];
|
533 |
$order->error = urldecode($this->httpParsedResponseAr['L_LONGMESSAGE0']);
|
@@ -535,47 +535,47 @@
|
|
535 |
return false;
|
536 |
//exit('CreateRecurringPaymentsProfile failed: ' . print_r($httpParsedResponseAr, true));
|
537 |
}
|
538 |
-
}
|
539 |
-
|
540 |
function update(&$order)
|
541 |
{
|
542 |
//paypal profile stuff
|
543 |
-
$nvpStr = "";
|
544 |
$nvpStr .= "&PROFILEID=" . $order->subscription_transaction_id;
|
545 |
-
|
546 |
//credit card fields
|
547 |
if($order->cardtype == "American Express")
|
548 |
$cardtype = "Amex";
|
549 |
else
|
550 |
$cardtype = $order->cardtype;
|
551 |
-
|
552 |
//credit card fields
|
553 |
-
if($cardtype)
|
554 |
$nvpStr .= "&CREDITCARDTYPE=" . $cardtype . "&ACCT=" . $order->accountnumber . "&EXPDATE=" . $order->ExpirationDate . "&CVV2=" . $order->CVV2;
|
555 |
|
556 |
//Maestro/Solo card fields. (Who uses these?) :)
|
557 |
if($order->StartDate)
|
558 |
$nvpStr .= "&STARTDATE=" . $order->StartDate . "&ISSUENUMBER=" . $order->IssueNumber;
|
559 |
-
|
560 |
//billing address, etc
|
561 |
if($order->Address1)
|
562 |
{
|
563 |
$nvpStr .= "&EMAIL=" . $order->Email . "&FIRSTNAME=" . $order->FirstName . "&LASTNAME=" . $order->LastName . "&STREET=" . $order->Address1;
|
564 |
-
|
565 |
if($order->Address2)
|
566 |
$nvpStr .= "&STREET2=" . $order->Address2;
|
567 |
-
|
568 |
$nvpStr .= "&CITY=" . $order->billing->city . "&STATE=" . $order->billing->state . "&COUNTRYCODE=" . $order->billing->country . "&ZIP=" . $order->billing->zip;
|
569 |
-
}
|
570 |
-
|
571 |
$this->httpParsedResponseAr = $this->PPHttpPost('UpdateRecurringPaymentsProfile', $nvpStr);
|
572 |
-
|
573 |
if("SUCCESS" == strtoupper($this->httpParsedResponseAr["ACK"]) || "SUCCESSWITHWARNING" == strtoupper($this->httpParsedResponseAr["ACK"])) {
|
574 |
$order->status = "success";
|
575 |
$order->subscription_transaction_id = urldecode($this->httpParsedResponseAr['PROFILEID']);
|
576 |
return true;
|
577 |
//exit('CreateRecurringPaymentsProfile Completed Successfully: '.print_r($this->httpParsedResponseAr, true));
|
578 |
-
} else {
|
579 |
$order->status = "error";
|
580 |
$order->errorcode = $this->httpParsedResponseAr['L_ERRORCODE0'];
|
581 |
$order->error = urldecode($this->httpParsedResponseAr['L_LONGMESSAGE0']);
|
@@ -584,31 +584,31 @@
|
|
584 |
//exit('CreateRecurringPaymentsProfile failed: ' . print_r($httpParsedResponseAr, true));
|
585 |
}
|
586 |
}
|
587 |
-
|
588 |
function cancel(&$order)
|
589 |
{
|
590 |
//paypal profile stuff
|
591 |
-
$nvpStr = "";
|
592 |
-
$nvpStr .= "&PROFILEID=" . urlencode($order->subscription_transaction_id) . "&ACTION=Cancel&NOTE=" . urlencode("User requested cancel.");
|
593 |
-
|
594 |
$this->httpParsedResponseAr = $this->PPHttpPost('ManageRecurringPaymentsProfileStatus', $nvpStr);
|
595 |
-
|
596 |
if("SUCCESS" == strtoupper($this->httpParsedResponseAr["ACK"]) || "SUCCESSWITHWARNING" == strtoupper($this->httpParsedResponseAr["ACK"]))
|
597 |
-
{
|
598 |
-
$order->updateStatus("cancelled");
|
599 |
-
return true;
|
600 |
}
|
601 |
else
|
602 |
-
{
|
603 |
$order->status = "error";
|
604 |
$order->errorcode = $this->httpParsedResponseAr['L_ERRORCODE0'];
|
605 |
$order->error = urldecode($this->httpParsedResponseAr['L_LONGMESSAGE0']) . ". " . __("Please contact the site owner or cancel your subscription from within PayPal to make sure you are not charged going forward.", "pmpro");
|
606 |
$order->shorterror = urldecode($this->httpParsedResponseAr['L_SHORTMESSAGE0']);
|
607 |
-
|
608 |
-
return false;
|
609 |
}
|
610 |
-
}
|
611 |
-
|
612 |
/**
|
613 |
* PAYPAL Function
|
614 |
* Send HTTP POST Request
|
@@ -619,46 +619,46 @@
|
|
619 |
*/
|
620 |
function PPHttpPost($methodName_, $nvpStr_) {
|
621 |
global $gateway_environment;
|
622 |
-
$environment = $gateway_environment;
|
623 |
-
|
624 |
$API_UserName = pmpro_getOption("apiusername");
|
625 |
$API_Password = pmpro_getOption("apipassword");
|
626 |
$API_Signature = pmpro_getOption("apisignature");
|
627 |
$API_Endpoint = "https://api-3t.paypal.com/nvp";
|
628 |
if("sandbox" === $environment || "beta-sandbox" === $environment) {
|
629 |
$API_Endpoint = "https://api-3t.$environment.paypal.com/nvp";
|
630 |
-
}
|
631 |
-
|
632 |
$version = urlencode('72.0');
|
633 |
-
|
634 |
// setting the curl parameters.
|
635 |
$ch = curl_init();
|
636 |
curl_setopt($ch, CURLOPT_URL, $API_Endpoint);
|
637 |
curl_setopt($ch, CURLOPT_VERBOSE, 1);
|
638 |
-
|
639 |
// turning off the server and peer verification(TrustManager Concept).
|
640 |
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
|
641 |
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
|
642 |
-
|
643 |
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
|
644 |
curl_setopt($ch, CURLOPT_POST, 1);
|
645 |
-
|
646 |
// NVPRequest for submitting to server
|
647 |
$nvpreq = "METHOD=" . urlencode($methodName_) . "&VERSION=" . urlencode($version) . "&PWD=" . urlencode($API_Password) . "&USER=" . urlencode($API_UserName) . "&SIGNATURE=" . urlencode($API_Signature) . "&BUTTONSOURCE=" . urlencode(PAYPAL_BN_CODE) . $nvpStr_;
|
648 |
-
|
649 |
// setting the nvpreq as POST FIELD to curl
|
650 |
curl_setopt($ch, CURLOPT_POSTFIELDS, $nvpreq);
|
651 |
-
|
652 |
// getting response from server
|
653 |
$httpResponse = curl_exec($ch);
|
654 |
-
|
655 |
if(empty($httpResponse)) {
|
656 |
exit("$methodName_ failed: ".curl_error($ch).'('.curl_errno($ch).')');
|
657 |
}
|
658 |
-
|
659 |
// Extract the RefundTransaction response details
|
660 |
$httpResponseAr = explode("&", $httpResponse);
|
661 |
-
|
662 |
$httpParsedResponseAr = array();
|
663 |
foreach ($httpResponseAr as $i => $value) {
|
664 |
$tmpAr = explode("=", $value);
|
@@ -666,11 +666,11 @@
|
|
666 |
$httpParsedResponseAr[$tmpAr[0]] = $tmpAr[1];
|
667 |
}
|
668 |
}
|
669 |
-
|
670 |
if((0 == sizeof($httpParsedResponseAr)) || !array_key_exists('ACK', $httpParsedResponseAr)) {
|
671 |
exit("Invalid HTTP Response for POST request($nvpreq) to $API_Endpoint.");
|
672 |
}
|
673 |
-
|
674 |
return $httpParsedResponseAr;
|
675 |
}
|
676 |
}
|
1 |
<?php
|
2 |
//include pmprogateway
|
3 |
require_once(dirname(__FILE__) . "/class.pmprogateway.php");
|
4 |
+
|
5 |
//load classes init method
|
6 |
add_action('init', array('PMProGateway_paypal', 'init'));
|
7 |
+
|
8 |
class PMProGateway_paypal extends PMProGateway
|
9 |
{
|
10 |
function PMProGateway_paypal($gateway = NULL)
|
11 |
{
|
12 |
$this->gateway = $gateway;
|
13 |
return $this->gateway;
|
14 |
+
}
|
15 |
+
|
16 |
/**
|
17 |
* Run on WP init
|
18 |
+
*
|
19 |
* @since 1.8
|
20 |
*/
|
21 |
static function init()
|
22 |
+
{
|
23 |
//make sure PayPal Website Payments Pro is a gateway option
|
24 |
add_filter('pmpro_gateways', array('PMProGateway_paypal', 'pmpro_gateways'));
|
25 |
+
|
26 |
//add fields to payment settings
|
27 |
add_filter('pmpro_payment_options', array('PMProGateway_paypal', 'pmpro_payment_options'));
|
28 |
+
|
29 |
/*
|
30 |
This code is the same for PayPal Website Payments Pro, PayPal Express, and PayPal Standard
|
31 |
So we only load it if we haven't already.
|
32 |
*/
|
33 |
global $pmpro_payment_option_fields_for_paypal;
|
34 |
if(empty($pmpro_payment_option_fields_for_paypal))
|
35 |
+
{
|
36 |
+
add_filter('pmpro_payment_option_fields', array('PMProGateway_paypal', 'pmpro_payment_option_fields'), 10, 2);
|
37 |
$pmpro_payment_option_fields_for_paypal = true;
|
38 |
}
|
39 |
+
|
40 |
//code to add at checkout
|
41 |
$gateway = pmpro_getGateway();
|
42 |
if($gateway == "paypal")
|
43 |
+
{
|
44 |
add_filter('pmpro_checkout_default_submit_button', array('PMProGateway_paypal', 'pmpro_checkout_default_submit_button'));
|
45 |
add_action('pmpro_checkout_after_form', array('PMProGateway_paypal', 'pmpro_checkout_after_form'));
|
46 |
}
|
47 |
}
|
48 |
+
|
49 |
/**
|
50 |
* Make sure this gateway is in the gateways list
|
51 |
+
*
|
52 |
* @since 1.8
|
53 |
*/
|
54 |
static function pmpro_gateways($gateways)
|
55 |
{
|
56 |
if(empty($gateways['paypal']))
|
57 |
$gateways['paypal'] = __('PayPal Website Payments Pro', 'pmpro');
|
58 |
+
|
59 |
return $gateways;
|
60 |
}
|
61 |
+
|
62 |
/**
|
63 |
* Get a list of payment options that the this gateway needs/supports.
|
64 |
+
*
|
65 |
* @since 1.8
|
66 |
*/
|
67 |
static function getGatewayOptions()
|
68 |
+
{
|
69 |
$options = array(
|
70 |
'sslseal',
|
71 |
'nuclear_HTTPS',
|
80 |
'tax_rate',
|
81 |
'accepted_credit_cards'
|
82 |
);
|
83 |
+
|
84 |
return $options;
|
85 |
}
|
86 |
+
|
87 |
/**
|
88 |
* Set payment options for payment settings page.
|
89 |
+
*
|
90 |
* @since 1.8
|
91 |
*/
|
92 |
static function pmpro_payment_options($options)
|
93 |
+
{
|
94 |
//get stripe options
|
95 |
$paypal_options = PMProGateway_paypal::getGatewayOptions();
|
96 |
+
|
97 |
//merge with others.
|
98 |
$options = array_merge($paypal_options, $options);
|
99 |
+
|
100 |
return $options;
|
101 |
}
|
102 |
+
|
103 |
/**
|
104 |
* Display fields for this gateway's options.
|
105 |
+
*
|
106 |
* @since 1.8
|
107 |
*/
|
108 |
static function pmpro_payment_option_fields($values, $gateway)
|
112 |
<td colspan="2">
|
113 |
<?php _e('PayPal Settings', 'pmpro'); ?>
|
114 |
</td>
|
115 |
+
</tr>
|
116 |
<tr class="gateway gateway_paypalstandard" <?php if($gateway != "paypalstandard") { ?>style="display: none;"<?php } ?>>
|
117 |
<td colspan="2">
|
118 |
<strong><?php _e('Note', 'pmpro');?>:</strong> <?php _e('We do not recommend using PayPal Standard. We suggest using PayPal Express, Website Payments Pro (Legacy), or PayPal Pro (Payflow Pro). <a target="_blank" href="http://www.paidmembershipspro.com/2013/09/read-using-paypal-standard-paid-memberships-pro/">More information on why can be found here.</a>', 'pmpro');?>
|
119 |
+
</td>
|
120 |
+
</tr>
|
121 |
<tr class="gateway gateway_paypal gateway_paypalexpress gateway_paypalstandard" <?php if($gateway != "paypal" && $gateway != "paypalexpress" && $gateway != "paypalstandard") { ?>style="display: none;"<?php } ?>>
|
122 |
+
<th scope="row" valign="top">
|
123 |
<label for="gateway_email"><?php _e('Gateway Account Email', 'pmpro');?>:</label>
|
124 |
</th>
|
125 |
<td>
|
126 |
<input type="text" id="gateway_email" name="gateway_email" size="60" value="<?php echo esc_attr($values['gateway_email'])?>" />
|
127 |
</td>
|
128 |
+
</tr>
|
129 |
<tr class="gateway gateway_paypal gateway_paypalexpress" <?php if($gateway != "paypal" && $gateway != "paypalexpress") { ?>style="display: none;"<?php } ?>>
|
130 |
<th scope="row" valign="top">
|
131 |
<label for="apiusername"><?php _e('API Username', 'pmpro');?>:</label>
|
141 |
<td>
|
142 |
<input type="text" id="apipassword" name="apipassword" size="60" value="<?php echo esc_attr($values['apipassword'])?>" />
|
143 |
</td>
|
144 |
+
</tr>
|
145 |
<tr class="gateway gateway_paypal gateway_paypalexpress" <?php if($gateway != "paypal" && $gateway != "paypalexpress") { ?>style="display: none;"<?php } ?>>
|
146 |
<th scope="row" valign="top">
|
147 |
<label for="apisignature"><?php _e('API Signature', 'pmpro');?>:</label>
|
149 |
<td>
|
150 |
<input type="text" id="apisignature" name="apisignature" size="60" value="<?php echo esc_attr($values['apisignature'])?>" />
|
151 |
</td>
|
152 |
+
</tr>
|
153 |
<tr class="gateway gateway_paypal gateway_paypalexpress gateway_paypalstandard" <?php if($gateway != "paypal" && $gateway != "paypalexpress" && $gateway != "paypalstandard") { ?>style="display: none;"<?php } ?>>
|
154 |
<th scope="row" valign="top">
|
155 |
<label><?php _e('IPN Handler URL', 'pmpro');?>:</label>
|
160 |
</tr>
|
161 |
<?php
|
162 |
}
|
163 |
+
|
164 |
/**
|
165 |
* Swap in our submit buttons.
|
166 |
*
|
169 |
static function pmpro_checkout_default_submit_button($show)
|
170 |
{
|
171 |
global $gateway, $pmpro_requirebilling;
|
172 |
+
|
173 |
//show our submit buttons
|
174 |
?>
|
175 |
<?php if($gateway == "paypal" || $gateway == "paypalexpress" || $gateway == "paypalstandard") { ?>
|
176 |
<span id="pmpro_paypalexpress_checkout" <?php if(($gateway != "paypalexpress" && $gateway != "paypalstandard") || !$pmpro_requirebilling) { ?>style="display: none;"<?php } ?>>
|
177 |
+
<input type="hidden" name="submit-checkout" value="1" />
|
178 |
<input type="image" value="<?php _e('Check Out with PayPal', 'pmpro');?> »" src="<?php echo apply_filters("pmpro_paypal_button_image", "https://www.paypal.com/en_US/i/btn/btn_xpressCheckout.gif");?>" />
|
179 |
</span>
|
180 |
<?php } ?>
|
181 |
+
|
182 |
<span id="pmpro_submit_span" <?php if(($gateway == "paypalexpress" || $gateway == "paypalstandard") && $pmpro_requirebilling) { ?>style="display: none;"<?php } ?>>
|
183 |
+
<input type="hidden" name="submit-checkout" value="1" />
|
184 |
+
<input type="submit" class="pmpro_btn pmpro_btn-submit-checkout" value="<?php if($pmpro_requirebilling) { _e('Submit and Check Out', 'pmpro'); } else { _e('Submit and Confirm', 'pmpro');}?> »" />
|
185 |
</span>
|
186 |
<?php
|
187 |
+
|
188 |
//don't show the default
|
189 |
return false;
|
190 |
}
|
191 |
+
|
192 |
/**
|
193 |
* Scripts for checkout page.
|
194 |
*
|
197 |
static function pmpro_checkout_after_form()
|
198 |
{
|
199 |
?>
|
200 |
+
<script>
|
201 |
//choosing payment method
|
202 |
+
jQuery('input[name=gateway]').click(function() {
|
203 |
if(jQuery(this).val() == 'paypal')
|
204 |
{
|
205 |
jQuery('#pmpro_paypalexpress_checkout').hide();
|
206 |
jQuery('#pmpro_billing_address_fields').show();
|
207 |
+
jQuery('#pmpro_payment_information_fields').show();
|
208 |
jQuery('#pmpro_submit_span').show();
|
209 |
}
|
210 |
else
|
211 |
+
{
|
212 |
jQuery('#pmpro_billing_address_fields').hide();
|
213 |
+
jQuery('#pmpro_payment_information_fields').hide();
|
214 |
jQuery('#pmpro_submit_span').hide();
|
215 |
jQuery('#pmpro_paypalexpress_checkout').show();
|
216 |
}
|
217 |
});
|
218 |
+
|
219 |
//select the radio button if the label is clicked on
|
220 |
jQuery('a.pmpro_radio').click(function() {
|
221 |
jQuery(this).prev().click();
|
223 |
</script>
|
224 |
<?php
|
225 |
}
|
226 |
+
|
227 |
/**
|
228 |
* Process checkout.
|
229 |
+
*
|
230 |
*/
|
231 |
function process(&$order)
|
232 |
{
|
233 |
if(floatval($order->InitialPayment) == 0)
|
234 |
{
|
235 |
//auth first, then process
|
236 |
+
$authorization_id = $this->authorize($order);
|
237 |
if($authorization_id)
|
238 |
{
|
239 |
+
$this->void($order, $authorization_id);
|
240 |
$order->ProfileStartDate = date("Y-m-d", strtotime("+ " . $order->BillingFrequency . " " . $order->BillingPeriod, current_time("timestamp"))) . "T0:0:0";
|
241 |
$order->ProfileStartDate = apply_filters("pmpro_profile_start_date", $order->ProfileStartDate, $order);
|
242 |
return $this->subscribe($order);
|
252 |
{
|
253 |
//charge first payment
|
254 |
if($this->charge($order))
|
255 |
+
{
|
256 |
//setup recurring billing
|
257 |
if(pmpro_isLevelRecurring($order->membership_level))
|
258 |
{
|
259 |
$order->ProfileStartDate = date("Y-m-d", strtotime("+ " . $order->BillingFrequency . " " . $order->BillingPeriod, current_time("timestamp"))) . "T0:0:0";
|
260 |
$order->ProfileStartDate = apply_filters("pmpro_profile_start_date", $order->ProfileStartDate, $order);
|
261 |
if($this->subscribe($order))
|
262 |
+
{
|
263 |
return true;
|
264 |
}
|
265 |
else
|
266 |
+
{
|
267 |
if($this->refund($order, $order->payment_transaction_id))
|
268 |
{
|
269 |
if(empty($order->error))
|
273 |
{
|
274 |
if(empty($order->error))
|
275 |
$order->error = "Unknown error: Payment failed.";
|
276 |
+
|
277 |
$order->error .= " " . __("A partial payment was made that we could not refund. Please contact the site owner immediately to correct this.", "pmpro");
|
278 |
}
|
279 |
+
|
280 |
+
return false;
|
281 |
}
|
282 |
}
|
283 |
else
|
284 |
{
|
285 |
+
//only a one time charge
|
286 |
+
$order->status = "success"; //saved on checkout page
|
287 |
$order->saveOrder();
|
288 |
return true;
|
289 |
}
|
290 |
+
}
|
291 |
+
}
|
292 |
}
|
293 |
+
|
294 |
function authorize(&$order)
|
295 |
{
|
296 |
if(empty($order->code))
|
297 |
$order->code = $order->getRandomCode();
|
298 |
+
|
299 |
//paypal profile stuff
|
300 |
$nvpStr = "";
|
301 |
if(!empty($order->Token))
|
302 |
$nvpStr .= "&TOKEN=" . $order->Token;
|
303 |
+
$nvpStr .="&AMT=1.00&CURRENCYCODE=" . pmpro_getOption("currency");
|
304 |
$nvpStr .= "&NOTIFYURL=" . urlencode(admin_url('admin-ajax.php') . "?action=ipnhandler");
|
305 |
//$nvpStr .= "&L_BILLINGTYPE0=RecurringPayments&L_BILLINGAGREEMENTDESCRIPTION0=" . $order->PaymentAmount;
|
306 |
+
|
307 |
$nvpStr .= "&PAYMENTACTION=Authorization&IPADDRESS=" . $_SERVER['REMOTE_ADDR'] . "&INVNUM=" . $order->code;
|
308 |
+
|
309 |
//credit card fields
|
310 |
if($order->cardtype == "American Express")
|
311 |
$cardtype = "Amex";
|
312 |
else
|
313 |
$cardtype = $order->cardtype;
|
314 |
+
|
315 |
if(!empty($cardtype))
|
316 |
$nvpStr .= "&CREDITCARDTYPE=" . $cardtype . "&ACCT=" . $order->accountnumber . "&EXPDATE=" . $order->ExpirationDate . "&CVV2=" . $order->CVV2;
|
317 |
|
318 |
//Maestro/Solo card fields. (Who uses these?) :)
|
319 |
if(!empty($order->StartDate))
|
320 |
$nvpStr .= "&STARTDATE=" . $order->StartDate . "&ISSUENUMBER=" . $order->IssueNumber;
|
321 |
+
|
322 |
//billing address, etc
|
323 |
if(!empty($order->Address1))
|
324 |
{
|
325 |
$nvpStr .= "&EMAIL=" . $order->Email . "&FIRSTNAME=" . $order->FirstName . "&LASTNAME=" . $order->LastName . "&STREET=" . $order->Address1;
|
326 |
+
|
327 |
if($order->Address2)
|
328 |
$nvpStr .= "&STREET2=" . $order->Address2;
|
329 |
+
|
330 |
$nvpStr .= "&CITY=" . $order->billing->city . "&STATE=" . $order->billing->state . "&COUNTRYCODE=" . $order->billing->country . "&ZIP=" . $order->billing->zip . "&SHIPTOPHONENUM=" . $order->billing->phone;
|
331 |
}
|
332 |
|
333 |
//for debugging, let's attach this to the class object
|
334 |
$this->nvpStr = $nvpStr;
|
335 |
+
|
336 |
$this->httpParsedResponseAr = $this->PPHttpPost('DoDirectPayment', $nvpStr);
|
337 |
+
|
338 |
if("SUCCESS" == strtoupper($this->httpParsedResponseAr["ACK"]) || "SUCCESSWITHWARNING" == strtoupper($this->httpParsedResponseAr["ACK"])) {
|
339 |
$order->authorization_id = $this->httpParsedResponseAr['TRANSACTIONID'];
|
340 |
+
$order->updateStatus("authorized");
|
341 |
+
return $order->authorization_id;
|
342 |
+
} else {
|
343 |
$order->status = "error";
|
344 |
$order->errorcode = $this->httpParsedResponseAr['L_ERRORCODE0'];
|
345 |
$order->error = urldecode($this->httpParsedResponseAr['L_LONGMESSAGE0']);
|
346 |
$order->shorterror = urldecode($this->httpParsedResponseAr['L_SHORTMESSAGE0']);
|
347 |
+
return false;
|
348 |
+
}
|
349 |
}
|
350 |
+
|
351 |
function void(&$order, $authorization_id = null)
|
352 |
{
|
353 |
if(empty($authorization_id))
|
354 |
return false;
|
355 |
+
|
356 |
//paypal profile stuff
|
357 |
$nvpStr="&AUTHORIZATIONID=" . $authorization_id . "&NOTE=Voiding an authorization for a recurring payment setup.";
|
358 |
+
|
359 |
$this->httpParsedResponseAr = $this->PPHttpPost('DoVoid', $nvpStr);
|
360 |
+
|
361 |
+
if("SUCCESS" == strtoupper($this->httpParsedResponseAr["ACK"]) || "SUCCESSWITHWARNING" == strtoupper($this->httpParsedResponseAr["ACK"])) {
|
362 |
+
return true;
|
363 |
+
} else {
|
364 |
$order->status = "error";
|
365 |
$order->errorcode = $this->httpParsedResponseAr['L_ERRORCODE0'];
|
366 |
$order->error = urldecode($this->httpParsedResponseAr['L_LONGMESSAGE0']);
|
367 |
$order->shorterror = urldecode($this->httpParsedResponseAr['L_SHORTMESSAGE0']);
|
368 |
+
return false;
|
369 |
+
}
|
370 |
+
}
|
371 |
+
|
372 |
function refund(&$order, $transaction_id)
|
373 |
{
|
374 |
if(empty($transaction_id))
|
375 |
return false;
|
376 |
+
|
377 |
//paypal profile stuff
|
378 |
$nvpStr="&TRANSACTIONID=" . $transaction_id . "&NOTE=Refunding a charge.";
|
379 |
+
|
380 |
$this->httpParsedResponseAr = $this->PPHttpPost('RefundTransaction', $nvpStr);
|
381 |
+
|
382 |
+
if("SUCCESS" == strtoupper($this->httpParsedResponseAr["ACK"]) || "SUCCESSWITHWARNING" == strtoupper($this->httpParsedResponseAr["ACK"])) {
|
383 |
+
return true;
|
384 |
+
} else {
|
385 |
$order->status = "error";
|
386 |
$order->errorcode = $this->httpParsedResponseAr['L_ERRORCODE0'];
|
387 |
$order->error = urldecode($this->httpParsedResponseAr['L_LONGMESSAGE0']);
|
388 |
$order->shorterror = urldecode($this->httpParsedResponseAr['L_SHORTMESSAGE0']);
|
389 |
+
return false;
|
390 |
+
}
|
391 |
}
|
392 |
+
|
393 |
function charge(&$order)
|
394 |
{
|
395 |
global $pmpro_currency;
|
396 |
+
|
397 |
if(empty($order->code))
|
398 |
$order->code = $order->getRandomCode();
|
399 |
+
|
400 |
//taxes on the amount
|
401 |
$amount = $order->InitialPayment;
|
402 |
+
$amount_tax = $order->getTaxForPrice($amount);
|
403 |
$order->subtotal = $amount;
|
404 |
$amount = round((float)$amount + (float)$amount_tax, 2);
|
405 |
+
|
406 |
//paypal profile stuff
|
407 |
$nvpStr = "";
|
408 |
if(!empty($order->Token))
|
409 |
$nvpStr .= "&TOKEN=" . $order->Token;
|
410 |
+
$nvpStr .="&AMT=" . $amount . "&ITEMAMT=" . $order->InitialPayment . "&TAXAMT=" . $amount_tax . "&CURRENCYCODE=" . $pmpro_currency;
|
411 |
$nvpStr .= "&NOTIFYURL=" . urlencode(admin_url('admin-ajax.php') . "?action=ipnhandler");
|
412 |
//$nvpStr .= "&L_BILLINGTYPE0=RecurringPayments&L_BILLINGAGREEMENTDESCRIPTION0=" . $order->PaymentAmount;
|
413 |
+
|
414 |
+
$nvpStr .= "&PAYMENTACTION=Sale&IPADDRESS=" . $_SERVER['REMOTE_ADDR'] . "&INVNUM=" . $order->code;
|
415 |
+
|
416 |
//credit card fields
|
417 |
if($order->cardtype == "American Express")
|
418 |
$cardtype = "Amex";
|
425 |
//Maestro/Solo card fields. (Who uses these?) :)
|
426 |
if(!empty($order->StartDate))
|
427 |
$nvpStr .= "&STARTDATE=" . $order->StartDate . "&ISSUENUMBER=" . $order->IssueNumber;
|
428 |
+
|
429 |
//billing address, etc
|
430 |
if($order->Address1)
|
431 |
{
|
432 |
$nvpStr .= "&EMAIL=" . $order->Email . "&FIRSTNAME=" . $order->FirstName . "&LASTNAME=" . $order->LastName . "&STREET=" . $order->Address1;
|
433 |
+
|
434 |
if($order->Address2)
|
435 |
$nvpStr .= "&STREET2=" . $order->Address2;
|
436 |
+
|
437 |
$nvpStr .= "&CITY=" . $order->billing->city . "&STATE=" . $order->billing->state . "&COUNTRYCODE=" . $order->billing->country . "&ZIP=" . $order->billing->zip . "&SHIPTOPHONENUM=" . $order->billing->phone;
|
438 |
}
|
439 |
|
440 |
$this->httpParsedResponseAr = $this->PPHttpPost('DoDirectPayment', $nvpStr);
|
441 |
+
|
442 |
if("SUCCESS" == strtoupper($this->httpParsedResponseAr["ACK"]) || "SUCCESSWITHWARNING" == strtoupper($this->httpParsedResponseAr["ACK"])) {
|
443 |
$order->payment_transaction_id = $this->httpParsedResponseAr['TRANSACTIONID'];
|
444 |
+
$order->updateStatus("success");
|
445 |
+
return true;
|
446 |
+
} else {
|
447 |
$order->status = "error";
|
448 |
$order->errorcode = $this->httpParsedResponseAr['L_ERRORCODE0'];
|
449 |
$order->error = urldecode($this->httpParsedResponseAr['L_LONGMESSAGE0']);
|
450 |
+
$order->shorterror = urldecode($this->httpParsedResponseAr['L_SHORTMESSAGE0']);
|
451 |
+
return false;
|
452 |
+
}
|
453 |
}
|
454 |
+
|
455 |
function subscribe(&$order)
|
456 |
{
|
457 |
global $pmpro_currency;
|
458 |
+
|
459 |
if(empty($order->code))
|
460 |
+
$order->code = $order->getRandomCode();
|
461 |
+
|
462 |
//filter order before subscription. use with care.
|
463 |
$order = apply_filters("pmpro_subscribe_order", $order, $this);
|
464 |
+
|
465 |
//taxes on the amount
|
466 |
$amount = $order->PaymentAmount;
|
467 |
+
$amount_tax = $order->getTaxForPrice($amount);
|
468 |
$amount = round((float)$amount + (float)$amount_tax, 2);
|
469 |
+
|
470 |
//paypal profile stuff
|
471 |
$nvpStr = "";
|
472 |
if(!empty($order->Token))
|
476 |
$nvpStr .= "&DESC=" . urlencode(substr($order->membership_level->name . " at " . get_bloginfo("name"), 0, 127));
|
477 |
$nvpStr .= "&NOTIFYURL=" . urlencode(admin_url('admin-ajax.php') . "?action=ipnhandler");
|
478 |
//$nvpStr .= "&L_BILLINGTYPE0=RecurringPayments&L_BILLINGAGREEMENTDESCRIPTION0=" . $order->PaymentAmount;
|
479 |
+
|
480 |
+
//if billing cycles are defined
|
481 |
if(!empty($order->TotalBillingCycles))
|
482 |
$nvpStr .= "&TOTALBILLINGCYCLES=" . $order->TotalBillingCycles;
|
483 |
+
|
484 |
//if a trial period is defined
|
485 |
if(!empty($order->TrialBillingPeriod))
|
486 |
{
|
487 |
+
$trial_amount = $order->TrialAmount;
|
488 |
$trial_tax = $order->getTaxForPrice($trial_amount);
|
489 |
$trial_amount = round((float)$trial_amount + (float)$trial_tax, 2);
|
490 |
+
|
491 |
$nvpStr .= "&TRIALBILLINGPERIOD=" . $order->TrialBillingPeriod . "&TRIALBILLINGFREQUENCY=" . $order->TrialBillingFrequency . "&TRIALAMT=" . $trial_amount;
|
492 |
}
|
493 |
if(!empty($order->TrialBillingCycles))
|
494 |
$nvpStr .= "&TRIALTOTALBILLINGCYCLES=" . $order->TrialBillingCycles;
|
495 |
+
|
496 |
//credit card fields
|
497 |
if($order->cardtype == "American Express")
|
498 |
$cardtype = "Amex";
|
499 |
else
|
500 |
$cardtype = $order->cardtype;
|
501 |
+
|
502 |
+
if($cardtype)
|
503 |
$nvpStr .= "&CREDITCARDTYPE=" . $cardtype . "&ACCT=" . $order->accountnumber . "&EXPDATE=" . $order->ExpirationDate . "&CVV2=" . $order->CVV2;
|
504 |
|
505 |
//Maestro/Solo card fields. (Who uses these?) :)
|
506 |
if(!empty($order->StartDate))
|
507 |
$nvpStr .= "&STARTDATE=" . $order->StartDate . "&ISSUENUMBER=" . $order->IssueNumber;
|
508 |
+
|
509 |
//billing address, etc
|
510 |
if($order->Address1)
|
511 |
{
|
512 |
$nvpStr .= "&EMAIL=" . $order->Email . "&FIRSTNAME=" . $order->FirstName . "&LASTNAME=" . $order->LastName . "&STREET=" . $order->Address1;
|
513 |
+
|
514 |
if($order->Address2)
|
515 |
$nvpStr .= "&STREET2=" . $order->Address2;
|
516 |
+
|
517 |
$nvpStr .= "&CITY=" . $order->billing->city . "&STATE=" . $order->billing->state . "&COUNTRYCODE=" . $order->billing->country . "&ZIP=" . $order->billing->zip . "&SHIPTOPHONENUM=" . $order->billing->phone;
|
518 |
}
|
519 |
|
520 |
//for debugging let's add this to the class object
|
521 |
$this->nvpStr = $nvpStr;
|
522 |
+
|
523 |
$this->httpParsedResponseAr = $this->PPHttpPost('CreateRecurringPaymentsProfile', $nvpStr);
|
524 |
+
|
525 |
if("SUCCESS" == strtoupper($this->httpParsedResponseAr["ACK"]) || "SUCCESSWITHWARNING" == strtoupper($this->httpParsedResponseAr["ACK"])) {
|
526 |
+
$order->status = "success";
|
527 |
$order->subscription_transaction_id = urldecode($this->httpParsedResponseAr['PROFILEID']);
|
528 |
return true;
|
529 |
//exit('CreateRecurringPaymentsProfile Completed Successfully: '.print_r($this->httpParsedResponseAr, true));
|
530 |
+
} else {
|
531 |
$order->status = "error";
|
532 |
$order->errorcode = $this->httpParsedResponseAr['L_ERRORCODE0'];
|
533 |
$order->error = urldecode($this->httpParsedResponseAr['L_LONGMESSAGE0']);
|
535 |
return false;
|
536 |
//exit('CreateRecurringPaymentsProfile failed: ' . print_r($httpParsedResponseAr, true));
|
537 |
}
|
538 |
+
}
|
539 |
+
|
540 |
function update(&$order)
|
541 |
{
|
542 |
//paypal profile stuff
|
543 |
+
$nvpStr = "";
|
544 |
$nvpStr .= "&PROFILEID=" . $order->subscription_transaction_id;
|
545 |
+
|
546 |
//credit card fields
|
547 |
if($order->cardtype == "American Express")
|
548 |
$cardtype = "Amex";
|
549 |
else
|
550 |
$cardtype = $order->cardtype;
|
551 |
+
|
552 |
//credit card fields
|
553 |
+
if($cardtype)
|
554 |
$nvpStr .= "&CREDITCARDTYPE=" . $cardtype . "&ACCT=" . $order->accountnumber . "&EXPDATE=" . $order->ExpirationDate . "&CVV2=" . $order->CVV2;
|
555 |
|
556 |
//Maestro/Solo card fields. (Who uses these?) :)
|
557 |
if($order->StartDate)
|
558 |
$nvpStr .= "&STARTDATE=" . $order->StartDate . "&ISSUENUMBER=" . $order->IssueNumber;
|
559 |
+
|
560 |
//billing address, etc
|
561 |
if($order->Address1)
|
562 |
{
|
563 |
$nvpStr .= "&EMAIL=" . $order->Email . "&FIRSTNAME=" . $order->FirstName . "&LASTNAME=" . $order->LastName . "&STREET=" . $order->Address1;
|
564 |
+
|
565 |
if($order->Address2)
|
566 |
$nvpStr .= "&STREET2=" . $order->Address2;
|
567 |
+
|
568 |
$nvpStr .= "&CITY=" . $order->billing->city . "&STATE=" . $order->billing->state . "&COUNTRYCODE=" . $order->billing->country . "&ZIP=" . $order->billing->zip;
|
569 |
+
}
|
570 |
+
|
571 |
$this->httpParsedResponseAr = $this->PPHttpPost('UpdateRecurringPaymentsProfile', $nvpStr);
|
572 |
+
|
573 |
if("SUCCESS" == strtoupper($this->httpParsedResponseAr["ACK"]) || "SUCCESSWITHWARNING" == strtoupper($this->httpParsedResponseAr["ACK"])) {
|
574 |
$order->status = "success";
|
575 |
$order->subscription_transaction_id = urldecode($this->httpParsedResponseAr['PROFILEID']);
|
576 |
return true;
|
577 |
//exit('CreateRecurringPaymentsProfile Completed Successfully: '.print_r($this->httpParsedResponseAr, true));
|
578 |
+
} else {
|
579 |
$order->status = "error";
|
580 |
$order->errorcode = $this->httpParsedResponseAr['L_ERRORCODE0'];
|
581 |
$order->error = urldecode($this->httpParsedResponseAr['L_LONGMESSAGE0']);
|
584 |
//exit('CreateRecurringPaymentsProfile failed: ' . print_r($httpParsedResponseAr, true));
|
585 |
}
|
586 |
}
|
587 |
+
|
588 |
function cancel(&$order)
|
589 |
{
|
590 |
//paypal profile stuff
|
591 |
+
$nvpStr = "";
|
592 |
+
$nvpStr .= "&PROFILEID=" . urlencode($order->subscription_transaction_id) . "&ACTION=Cancel&NOTE=" . urlencode("User requested cancel.");
|
593 |
+
|
594 |
$this->httpParsedResponseAr = $this->PPHttpPost('ManageRecurringPaymentsProfileStatus', $nvpStr);
|
595 |
+
|
596 |
if("SUCCESS" == strtoupper($this->httpParsedResponseAr["ACK"]) || "SUCCESSWITHWARNING" == strtoupper($this->httpParsedResponseAr["ACK"]))
|
597 |
+
{
|
598 |
+
$order->updateStatus("cancelled");
|
599 |
+
return true;
|
600 |
}
|
601 |
else
|
602 |
+
{
|
603 |
$order->status = "error";
|
604 |
$order->errorcode = $this->httpParsedResponseAr['L_ERRORCODE0'];
|
605 |
$order->error = urldecode($this->httpParsedResponseAr['L_LONGMESSAGE0']) . ". " . __("Please contact the site owner or cancel your subscription from within PayPal to make sure you are not charged going forward.", "pmpro");
|
606 |
$order->shorterror = urldecode($this->httpParsedResponseAr['L_SHORTMESSAGE0']);
|
607 |
+
|
608 |
+
return false;
|
609 |
}
|
610 |
+
}
|
611 |
+
|
612 |
/**
|
613 |
* PAYPAL Function
|
614 |
* Send HTTP POST Request
|
619 |
*/
|
620 |
function PPHttpPost($methodName_, $nvpStr_) {
|
621 |
global $gateway_environment;
|
622 |
+
$environment = $gateway_environment;
|
623 |
+
|
624 |
$API_UserName = pmpro_getOption("apiusername");
|
625 |
$API_Password = pmpro_getOption("apipassword");
|
626 |
$API_Signature = pmpro_getOption("apisignature");
|
627 |
$API_Endpoint = "https://api-3t.paypal.com/nvp";
|
628 |
if("sandbox" === $environment || "beta-sandbox" === $environment) {
|
629 |
$API_Endpoint = "https://api-3t.$environment.paypal.com/nvp";
|
630 |
+
}
|
631 |
+
|
632 |
$version = urlencode('72.0');
|
633 |
+
|
634 |
// setting the curl parameters.
|
635 |
$ch = curl_init();
|
636 |
curl_setopt($ch, CURLOPT_URL, $API_Endpoint);
|
637 |
curl_setopt($ch, CURLOPT_VERBOSE, 1);
|
638 |
+
|
639 |
// turning off the server and peer verification(TrustManager Concept).
|
640 |
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
|
641 |
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
|
642 |
+
|
643 |
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
|
644 |
curl_setopt($ch, CURLOPT_POST, 1);
|
645 |
+
|
646 |
// NVPRequest for submitting to server
|
647 |
$nvpreq = "METHOD=" . urlencode($methodName_) . "&VERSION=" . urlencode($version) . "&PWD=" . urlencode($API_Password) . "&USER=" . urlencode($API_UserName) . "&SIGNATURE=" . urlencode($API_Signature) . "&BUTTONSOURCE=" . urlencode(PAYPAL_BN_CODE) . $nvpStr_;
|
648 |
+
|
649 |
// setting the nvpreq as POST FIELD to curl
|
650 |
curl_setopt($ch, CURLOPT_POSTFIELDS, $nvpreq);
|
651 |
+
|
652 |
// getting response from server
|
653 |
$httpResponse = curl_exec($ch);
|
654 |
+
|
655 |
if(empty($httpResponse)) {
|
656 |
exit("$methodName_ failed: ".curl_error($ch).'('.curl_errno($ch).')');
|
657 |
}
|
658 |
+
|
659 |
// Extract the RefundTransaction response details
|
660 |
$httpResponseAr = explode("&", $httpResponse);
|
661 |
+
|
662 |
$httpParsedResponseAr = array();
|
663 |
foreach ($httpResponseAr as $i => $value) {
|
664 |
$tmpAr = explode("=", $value);
|
666 |
$httpParsedResponseAr[$tmpAr[0]] = $tmpAr[1];
|
667 |
}
|
668 |
}
|
669 |
+
|
670 |
if((0 == sizeof($httpParsedResponseAr)) || !array_key_exists('ACK', $httpParsedResponseAr)) {
|
671 |
exit("Invalid HTTP Response for POST request($nvpreq) to $API_Endpoint.");
|
672 |
}
|
673 |
+
|
674 |
return $httpParsedResponseAr;
|
675 |
}
|
676 |
}
|
classes/gateways/class.pmprogateway_paypalexpress.php
CHANGED
@@ -1,46 +1,46 @@
|
|
1 |
<?php
|
2 |
//include pmprogateway
|
3 |
require_once(dirname(__FILE__) . "/class.pmprogateway.php");
|
4 |
-
|
5 |
//load classes init method
|
6 |
add_action('init', array('PMProGateway_paypalexpress', 'init'));
|
7 |
-
|
8 |
class PMProGateway_paypalexpress extends PMProGateway
|
9 |
{
|
10 |
function PMProGateway_paypalexpress($gateway = NULL)
|
11 |
{
|
12 |
$this->gateway = $gateway;
|
13 |
return $this->gateway;
|
14 |
-
}
|
15 |
-
|
16 |
/**
|
17 |
* Run on WP init
|
18 |
-
*
|
19 |
* @since 1.8
|
20 |
*/
|
21 |
static function init()
|
22 |
-
{
|
23 |
//make sure PayPal Express is a gateway option
|
24 |
add_filter('pmpro_gateways', array('PMProGateway_paypalexpress', 'pmpro_gateways'));
|
25 |
-
|
26 |
//add fields to payment settings
|
27 |
add_filter('pmpro_payment_options', array('PMProGateway_paypalexpress', 'pmpro_payment_options'));
|
28 |
-
|
29 |
/*
|
30 |
This code is the same for PayPal Website Payments Pro, PayPal Express, and PayPal Standard
|
31 |
So we only load it if we haven't already.
|
32 |
*/
|
33 |
global $pmpro_payment_option_fields_for_paypal;
|
34 |
if(empty($pmpro_payment_option_fields_for_paypal))
|
35 |
-
{
|
36 |
-
add_filter('pmpro_payment_option_fields', array('PMProGateway_paypalexpress', 'pmpro_payment_option_fields'), 10, 2);
|
37 |
$pmpro_payment_option_fields_for_paypal = true;
|
38 |
}
|
39 |
-
|
40 |
//code to add at checkout
|
41 |
$gateway = pmpro_getGateway();
|
42 |
if($gateway == "paypalexpress")
|
43 |
-
{
|
44 |
add_filter('pmpro_include_billing_address_fields', '__return_false');
|
45 |
add_filter('pmpro_include_payment_information_fields', '__return_false');
|
46 |
add_filter('pmpro_required_billing_fields', array('PMProGateway_paypalexpress', 'pmpro_required_billing_fields'));
|
@@ -51,27 +51,27 @@
|
|
51 |
add_action('pmpro_checkout_after_form', array('PMProGateway_paypalexpress', 'pmpro_checkout_after_form'));
|
52 |
}
|
53 |
}
|
54 |
-
|
55 |
/**
|
56 |
* Make sure this gateway is in the gateways list
|
57 |
-
*
|
58 |
* @since 1.8
|
59 |
*/
|
60 |
static function pmpro_gateways($gateways)
|
61 |
{
|
62 |
if(empty($gateways['paypalexpress']))
|
63 |
$gateways['paypalexpress'] = __('PayPal Express', 'pmpro');
|
64 |
-
|
65 |
return $gateways;
|
66 |
}
|
67 |
-
|
68 |
/**
|
69 |
* Get a list of payment options that the this gateway needs/supports.
|
70 |
-
*
|
71 |
* @since 1.8
|
72 |
*/
|
73 |
static function getGatewayOptions()
|
74 |
-
{
|
75 |
$options = array(
|
76 |
'sslseal',
|
77 |
'nuclear_HTTPS',
|
@@ -85,29 +85,29 @@
|
|
85 |
'tax_state',
|
86 |
'tax_rate'
|
87 |
);
|
88 |
-
|
89 |
return $options;
|
90 |
}
|
91 |
-
|
92 |
/**
|
93 |
* Set payment options for payment settings page.
|
94 |
-
*
|
95 |
* @since 1.8
|
96 |
*/
|
97 |
static function pmpro_payment_options($options)
|
98 |
-
{
|
99 |
//get stripe options
|
100 |
$paypal_options = PMProGateway_paypalexpress::getGatewayOptions();
|
101 |
-
|
102 |
//merge with others.
|
103 |
$options = array_merge($paypal_options, $options);
|
104 |
-
|
105 |
return $options;
|
106 |
}
|
107 |
-
|
108 |
/**
|
109 |
* Display fields for this gateway's options.
|
110 |
-
*
|
111 |
* @since 1.8
|
112 |
*/
|
113 |
static function pmpro_payment_option_fields($values, $gateway)
|
@@ -117,20 +117,20 @@
|
|
117 |
<td colspan="2">
|
118 |
<?php _e('PayPal Settings', 'pmpro'); ?>
|
119 |
</td>
|
120 |
-
</tr>
|
121 |
<tr class="gateway gateway_paypalstandard" <?php if($gateway != "paypalstandard") { ?>style="display: none;"<?php } ?>>
|
122 |
<td colspan="2">
|
123 |
<strong><?php _e('Note', 'pmpro');?>:</strong> <?php _e('We do not recommend using PayPal Standard. We suggest using PayPal Express, Website Payments Pro (Legacy), or PayPal Pro (Payflow Pro). <a target="_blank" href="http://www.paidmembershipspro.com/2013/09/read-using-paypal-standard-paid-memberships-pro/">More information on why can be found here.</a>', 'pmpro');?>
|
124 |
-
</td>
|
125 |
-
</tr>
|
126 |
<tr class="gateway gateway_paypal gateway_paypalexpress gateway_paypalstandard" <?php if($gateway != "paypal" && $gateway != "paypalexpress" && $gateway != "paypalstandard") { ?>style="display: none;"<?php } ?>>
|
127 |
-
<th scope="row" valign="top">
|
128 |
<label for="gateway_email"><?php _e('Gateway Account Email', 'pmpro');?>:</label>
|
129 |
</th>
|
130 |
<td>
|
131 |
<input type="text" id="gateway_email" name="gateway_email" size="60" value="<?php echo esc_attr($values['gateway_email'])?>" />
|
132 |
</td>
|
133 |
-
</tr>
|
134 |
<tr class="gateway gateway_paypal gateway_paypalexpress" <?php if($gateway != "paypal" && $gateway != "paypalexpress") { ?>style="display: none;"<?php } ?>>
|
135 |
<th scope="row" valign="top">
|
136 |
<label for="apiusername"><?php _e('API Username', 'pmpro');?>:</label>
|
@@ -146,7 +146,7 @@
|
|
146 |
<td>
|
147 |
<input type="text" id="apipassword" name="apipassword" size="60" value="<?php echo esc_attr($values['apipassword'])?>" />
|
148 |
</td>
|
149 |
-
</tr>
|
150 |
<tr class="gateway gateway_paypal gateway_paypalexpress" <?php if($gateway != "paypal" && $gateway != "paypalexpress") { ?>style="display: none;"<?php } ?>>
|
151 |
<th scope="row" valign="top">
|
152 |
<label for="apisignature"><?php _e('API Signature', 'pmpro');?>:</label>
|
@@ -154,7 +154,7 @@
|
|
154 |
<td>
|
155 |
<input type="text" id="apisignature" name="apisignature" size="60" value="<?php echo esc_attr($values['apisignature'])?>" />
|
156 |
</td>
|
157 |
-
</tr>
|
158 |
<tr class="gateway gateway_paypal gateway_paypalexpress gateway_paypalstandard" <?php if($gateway != "paypal" && $gateway != "paypalexpress" && $gateway != "paypalstandard") { ?>style="display: none;"<?php } ?>>
|
159 |
<th scope="row" valign="top">
|
160 |
<label><?php _e('IPN Handler URL', 'pmpro');?>:</label>
|
@@ -165,10 +165,10 @@
|
|
165 |
</tr>
|
166 |
<?php
|
167 |
}
|
168 |
-
|
169 |
/**
|
170 |
* Remove required billing fields
|
171 |
-
*
|
172 |
* @since 1.8
|
173 |
*/
|
174 |
static function pmpro_required_billing_fields($fields)
|
@@ -187,10 +187,10 @@
|
|
187 |
unset($fields['ExpirationMonth']);
|
188 |
unset($fields['ExpirationYear']);
|
189 |
unset($fields['CVV']);
|
190 |
-
|
191 |
return $fields;
|
192 |
}
|
193 |
-
|
194 |
/**
|
195 |
* Save session vars before processing
|
196 |
*
|
@@ -199,8 +199,8 @@
|
|
199 |
static function pmpro_checkout_before_processing()
|
200 |
{
|
201 |
global $current_user, $gateway;
|
202 |
-
|
203 |
-
//save user fields for PayPal Express
|
204 |
if(!$current_user->ID)
|
205 |
{
|
206 |
//get values from post
|
@@ -213,32 +213,32 @@
|
|
213 |
else
|
214 |
$password = "";
|
215 |
if(isset($_REQUEST['bemail']))
|
216 |
-
$bemail = $_REQUEST['bemail'];
|
217 |
else
|
218 |
$bemail = "";
|
219 |
-
|
220 |
//save to session
|
221 |
$_SESSION['pmpro_signup_username'] = $username;
|
222 |
$_SESSION['pmpro_signup_password'] = $password;
|
223 |
-
$_SESSION['pmpro_signup_email'] = $bemail;
|
224 |
}
|
225 |
-
|
226 |
//can use this hook to save some other variables to the session
|
227 |
do_action("pmpro_paypalexpress_session_vars");
|
228 |
}
|
229 |
-
|
230 |
/**
|
231 |
* Review and Confirmation code.
|
232 |
*
|
233 |
-
* @since 1.8
|
234 |
*/
|
235 |
static function pmpro_checkout_confirmed($pmpro_confirmed)
|
236 |
{
|
237 |
global $pmpro_msg, $pmpro_msgt, $pmpro_level, $current_user, $pmpro_review, $pmpro_paypal_token, $discount_code, $bemail;
|
238 |
-
|
239 |
//PayPal Express Call Backs
|
240 |
if(!empty($_REQUEST['review']))
|
241 |
-
{
|
242 |
if(!empty($_REQUEST['PayerID']))
|
243 |
$_SESSION['payer_id'] = $_REQUEST['PayerID'];
|
244 |
if(!empty($_REQUEST['paymentAmount']))
|
@@ -247,10 +247,10 @@
|
|
247 |
$_SESSION['currCodeType'] = $_REQUEST['currencyCodeType'];
|
248 |
if(!empty($_REQUEST['paymentType']))
|
249 |
$_SESSION['paymentType'] = $_REQUEST['paymentType'];
|
250 |
-
|
251 |
$morder = new MemberOrder();
|
252 |
$morder->getMemberOrderByPayPalToken($_REQUEST['token']);
|
253 |
-
$morder->Token = $morder->paypal_token; $pmpro_paypal_token = $morder->paypal_token;
|
254 |
if($morder->Token)
|
255 |
{
|
256 |
if($morder->Gateway->getExpressCheckoutDetails($morder))
|
@@ -261,7 +261,7 @@
|
|
261 |
{
|
262 |
$pmpro_msg = $morder->error;
|
263 |
$pmpro_msgt = "pmpro_error";
|
264 |
-
}
|
265 |
}
|
266 |
else
|
267 |
{
|
@@ -270,12 +270,12 @@
|
|
270 |
}
|
271 |
}
|
272 |
elseif(!empty($_REQUEST['confirm']))
|
273 |
-
{
|
274 |
$morder = new MemberOrder();
|
275 |
$morder->getMemberOrderByPayPalToken($_REQUEST['token']);
|
276 |
-
$morder->Token = $morder->paypal_token; $pmpro_paypal_token = $morder->paypal_token;
|
277 |
if($morder->Token)
|
278 |
-
{
|
279 |
//setup values
|
280 |
$morder->membership_id = $pmpro_level->id;
|
281 |
$morder->membership_name = $pmpro_level->name;
|
@@ -286,17 +286,17 @@
|
|
286 |
$morder->BillingPeriod = $pmpro_level->cycle_period;
|
287 |
$morder->BillingFrequency = $pmpro_level->cycle_number;
|
288 |
$morder->Email = $bemail;
|
289 |
-
|
290 |
//setup level var
|
291 |
-
$morder->getMembershipLevel();
|
292 |
$morder->membership_level = apply_filters("pmpro_checkout_level", $morder->membership_level);
|
293 |
-
|
294 |
//tax
|
295 |
$morder->subtotal = $morder->InitialPayment;
|
296 |
-
$morder->getTax();
|
297 |
if($pmpro_level->billing_limit)
|
298 |
$morder->TotalBillingCycles = $pmpro_level->billing_limit;
|
299 |
-
|
300 |
if(pmpro_isLevelTrial($pmpro_level))
|
301 |
{
|
302 |
$morder->TrialBillingPeriod = $pmpro_level->cycle_period;
|
@@ -304,13 +304,13 @@
|
|
304 |
$morder->TrialBillingCycles = $pmpro_level->trial_limit;
|
305 |
$morder->TrialAmount = $pmpro_level->trial_amount;
|
306 |
}
|
307 |
-
|
308 |
if($morder->confirm())
|
309 |
-
{
|
310 |
-
$pmpro_confirmed = true;
|
311 |
}
|
312 |
else
|
313 |
-
{
|
314 |
$pmpro_msg = $morder->error;
|
315 |
$pmpro_msgt = "pmpro_error";
|
316 |
}
|
@@ -321,38 +321,38 @@
|
|
321 |
$pmpro_msgt = "pmpro_error";
|
322 |
}
|
323 |
}
|
324 |
-
|
325 |
if(!empty($morder))
|
326 |
return array("pmpro_confirmed"=>$pmpro_confirmed, "morder"=>$morder);
|
327 |
else
|
328 |
return $pmpro_confirmed;
|
329 |
}
|
330 |
-
|
331 |
/**
|
332 |
* Swap in user/pass/etc from session
|
333 |
*
|
334 |
-
* @since 1.8
|
335 |
*/
|
336 |
static function pmpro_checkout_new_user_array($new_user_array)
|
337 |
{
|
338 |
global $current_user;
|
339 |
-
|
340 |
if(!$current_user->ID)
|
341 |
{
|
342 |
-
//reload the user fields
|
343 |
$new_user_array['user_login'] = $_SESSION['pmpro_signup_username'];
|
344 |
-
$new_user_array['user_pass'] = $_SESSION['pmpro_signup_password'];
|
345 |
$new_user_array['user_email'] = $_SESSION['pmpro_signup_email'];
|
346 |
-
|
347 |
//unset the user fields in session
|
348 |
unset($_SESSION['pmpro_signup_username']);
|
349 |
unset($_SESSION['pmpro_signup_password']);
|
350 |
unset($_SESSION['pmpro_signup_email']);
|
351 |
}
|
352 |
-
|
353 |
return $new_user_array;
|
354 |
}
|
355 |
-
|
356 |
/**
|
357 |
* Process at checkout
|
358 |
*
|
@@ -363,28 +363,28 @@
|
|
363 |
$order->payment_type = "PayPal Express";
|
364 |
$order->cardtype = "";
|
365 |
$order->ProfileStartDate = date("Y-m-d", strtotime("+ " . $order->BillingFrequency . " " . $order->BillingPeriod)) . "T0:0:0";
|
366 |
-
$order->ProfileStartDate = apply_filters("pmpro_profile_start_date", $order->ProfileStartDate, $order);
|
367 |
-
|
368 |
return $this->setExpressCheckout($order);
|
369 |
}
|
370 |
-
|
371 |
/**
|
372 |
* Process charge or subscription after confirmation.
|
373 |
*
|
374 |
* @since 1.8
|
375 |
*/
|
376 |
function confirm(&$order)
|
377 |
-
{
|
378 |
if(pmpro_isLevelRecurring($order->membership_level))
|
379 |
{
|
380 |
$order->ProfileStartDate = date("Y-m-d", strtotime("+ " . $order->BillingFrequency . " " . $order->BillingPeriod, current_time("timestamp"))) . "T0:0:0";
|
381 |
$order->ProfileStartDate = apply_filters("pmpro_profile_start_date", $order->ProfileStartDate, $order);
|
382 |
-
return $this->subscribe($order);
|
383 |
}
|
384 |
else
|
385 |
-
return $this->charge($order);
|
386 |
}
|
387 |
-
|
388 |
/**
|
389 |
* Swap in our submit buttons.
|
390 |
*
|
@@ -393,26 +393,26 @@
|
|
393 |
static function pmpro_checkout_default_submit_button($show)
|
394 |
{
|
395 |
global $gateway, $pmpro_requirebilling;
|
396 |
-
|
397 |
//show our submit buttons
|
398 |
?>
|
399 |
<?php if($gateway == "paypal" || $gateway == "paypalexpress" || $gateway == "paypalstandard") { ?>
|
400 |
<span id="pmpro_paypalexpress_checkout" <?php if(($gateway != "paypalexpress" && $gateway != "paypalstandard") || !$pmpro_requirebilling) { ?>style="display: none;"<?php } ?>>
|
401 |
-
<input type="hidden" name="submit-checkout" value="1" />
|
402 |
<input type="image" value="<?php _e('Check Out with PayPal', 'pmpro');?> »" src="<?php echo apply_filters("pmpro_paypal_button_image", "https://www.paypal.com/en_US/i/btn/btn_xpressCheckout.gif");?>" />
|
403 |
</span>
|
404 |
<?php } ?>
|
405 |
-
|
406 |
<span id="pmpro_submit_span" <?php if(($gateway == "paypalexpress" || $gateway == "paypalstandard") && $pmpro_requirebilling) { ?>style="display: none;"<?php } ?>>
|
407 |
-
<input type="hidden" name="submit-checkout" value="1" />
|
408 |
-
<input type="submit" class="pmpro_btn pmpro_btn-submit-checkout" value="<?php if($pmpro_requirebilling) { _e('Submit and Check Out', 'pmpro'); } else { _e('Submit and Confirm', 'pmpro');}?> »" />
|
409 |
</span>
|
410 |
<?php
|
411 |
-
|
412 |
//don't show the default
|
413 |
return false;
|
414 |
}
|
415 |
-
|
416 |
/**
|
417 |
* Scripts for checkout page.
|
418 |
*
|
@@ -421,25 +421,25 @@
|
|
421 |
static function pmpro_checkout_after_form()
|
422 |
{
|
423 |
?>
|
424 |
-
<script>
|
425 |
//choosing payment method
|
426 |
-
jQuery('input[name=gateway]').click(function() {
|
427 |
if(jQuery(this).val() == 'paypal')
|
428 |
{
|
429 |
jQuery('#pmpro_paypalexpress_checkout').hide();
|
430 |
jQuery('#pmpro_billing_address_fields').show();
|
431 |
-
jQuery('#pmpro_payment_information_fields').show();
|
432 |
jQuery('#pmpro_submit_span').show();
|
433 |
}
|
434 |
else
|
435 |
-
{
|
436 |
jQuery('#pmpro_billing_address_fields').hide();
|
437 |
-
jQuery('#pmpro_payment_information_fields').hide();
|
438 |
jQuery('#pmpro_submit_span').hide();
|
439 |
jQuery('#pmpro_paypalexpress_checkout').show();
|
440 |
}
|
441 |
});
|
442 |
-
|
443 |
//select the radio button if the label is clicked on
|
444 |
jQuery('a.pmpro_radio').click(function() {
|
445 |
jQuery(this).prev().click();
|
@@ -447,106 +447,106 @@
|
|
447 |
</script>
|
448 |
<?php
|
449 |
}
|
450 |
-
|
451 |
//PayPal Express, this is run first to authorize from PayPal
|
452 |
function setExpressCheckout(&$order)
|
453 |
-
{
|
454 |
global $pmpro_currency;
|
455 |
-
|
456 |
if(empty($order->code))
|
457 |
-
$order->code = $order->getRandomCode();
|
458 |
-
|
459 |
//clean up a couple values
|
460 |
$order->payment_type = "PayPal Express";
|
461 |
$order->CardType = "";
|
462 |
$order->cardtype = "";
|
463 |
-
|
464 |
//taxes on initial amount
|
465 |
$initial_payment = $order->InitialPayment;
|
466 |
$initial_payment_tax = $order->getTaxForPrice($initial_payment);
|
467 |
$initial_payment = round((float)$initial_payment + (float)$initial_payment_tax, 2);
|
468 |
-
|
469 |
//taxes on the amount
|
470 |
$amount = $order->PaymentAmount;
|
471 |
-
$amount_tax = $order->getTaxForPrice($amount);
|
472 |
$amount = round((float)$amount + (float)$amount_tax, 2);
|
473 |
-
|
474 |
//paypal profile stuff
|
475 |
$nvpStr = "";
|
476 |
$nvpStr .="&AMT=" . $initial_payment . "&CURRENCYCODE=" . $pmpro_currency;
|
477 |
if(!empty($order->ProfileStartDate) && strtotime($order->ProfileStartDate, current_time("timestamp")) > 0)
|
478 |
-
$nvpStr .= "&PROFILESTARTDATE=" . $order->ProfileStartDate;
|
479 |
if(!empty($order->BillingFrequency))
|
480 |
$nvpStr .= "&BILLINGPERIOD=" . $order->BillingPeriod . "&BILLINGFREQUENCY=" . $order->BillingFrequency . "&AUTOBILLAMT=AddToNextBilling&L_BILLINGTYPE0=RecurringPayments";
|
481 |
$nvpStr .= "&DESC=" . urlencode(substr($order->membership_level->name . " at " . get_bloginfo("name"), 0, 127));
|
482 |
-
$nvpStr .= "&NOTIFYURL=" . urlencode(admin_url('admin-ajax.php') . "?action=ipnhandler");
|
483 |
$nvpStr .= "&NOSHIPPING=1&L_BILLINGAGREEMENTDESCRIPTION0=" . urlencode(substr($order->membership_level->name . " at " . get_bloginfo("name"), 0, 127)) . "&L_PAYMENTTYPE0=Any";
|
484 |
-
|
485 |
-
//if billing cycles are defined
|
486 |
if(!empty($order->TotalBillingCycles))
|
487 |
$nvpStr .= "&TOTALBILLINGCYCLES=" . $order->TotalBillingCycles;
|
488 |
-
|
489 |
//if a trial period is defined
|
490 |
if(!empty($order->TrialBillingPeriod))
|
491 |
{
|
492 |
$trial_amount = $order->TrialAmount;
|
493 |
$trial_tax = $order->getTaxForPrice($trial_amount);
|
494 |
$trial_amount = round((float)$trial_amount + (float)$trial_tax, 2);
|
495 |
-
|
496 |
$nvpStr .= "&TRIALBILLINGPERIOD=" . $order->TrialBillingPeriod . "&TRIALBILLINGFREQUENCY=" . $order->TrialBillingFrequency . "&TRIALAMT=" . $trial_amount;
|
497 |
}
|
498 |
if(!empty($order->TrialBillingCycles))
|
499 |
$nvpStr .= "&TRIALTOTALBILLINGCYCLES=" . $order->TrialBillingCycles;
|
500 |
-
|
501 |
if(!empty($order->discount_code))
|
502 |
{
|
503 |
-
$nvpStr .= "&ReturnUrl=" . urlencode(pmpro_url("checkout", "?level=" . $order->membership_level->id . "&discount_code=" . $order->discount_code . "&review=" . $order->code));
|
504 |
}
|
505 |
else
|
506 |
{
|
507 |
-
$nvpStr .= "&ReturnUrl=" . urlencode(pmpro_url("checkout", "?level=" . $order->membership_level->id . "&review=" . $order->code));
|
508 |
}
|
509 |
-
|
510 |
-
$additional_parameters = apply_filters("pmpro_paypal_express_return_url_parameters", array());
|
511 |
if(!empty($additional_parameters))
|
512 |
{
|
513 |
-
foreach($additional_parameters as $key => $value)
|
514 |
$nvpStr .= urlencode("&" . $key . "=" . $value);
|
515 |
-
}
|
516 |
-
|
517 |
-
$nvpStr .= "&CANCELURL=" . urlencode(pmpro_url("levels"));
|
518 |
-
|
519 |
$account_optional = apply_filters('pmpro_paypal_account_optional', true);
|
520 |
if ($account_optional)
|
521 |
$nvpStr .= '&SOLUTIONTYPE=Sole&LANDINGPAGE=Billing';
|
522 |
-
|
523 |
-
$nvpStr = apply_filters("pmpro_set_express_checkout_nvpstr", $nvpStr, $order);
|
524 |
-
|
525 |
///echo str_replace("&", "&<br />", $nvpStr);
|
526 |
///exit;
|
527 |
-
|
528 |
-
$this->httpParsedResponseAr = $this->PPHttpPost('SetExpressCheckout', $nvpStr);
|
529 |
-
|
530 |
if("SUCCESS" == strtoupper($this->httpParsedResponseAr["ACK"]) || "SUCCESSWITHWARNING" == strtoupper($this->httpParsedResponseAr["ACK"])) {
|
531 |
-
$order->status = "token";
|
532 |
-
$order->paypal_token = urldecode($this->httpParsedResponseAr['TOKEN']);
|
533 |
-
|
534 |
//update order
|
535 |
-
$order->saveOrder();
|
536 |
-
|
537 |
//redirect to paypal
|
538 |
$paypal_url = "https://www.paypal.com/webscr&cmd=_express-checkout&useraction=commit&token=" . $this->httpParsedResponseAr['TOKEN'];
|
539 |
-
$environment = pmpro_getOption("gateway_environment");
|
540 |
-
if("sandbox" === $environment || "beta-sandbox" === $environment)
|
541 |
{
|
542 |
$paypal_url = "https://www.sandbox.paypal.com/webscr&useraction=commit&cmd=_express-checkout&token=" . $this->httpParsedResponseAr['TOKEN'];
|
543 |
-
}
|
544 |
-
|
545 |
-
wp_redirect($paypal_url);
|
546 |
exit;
|
547 |
-
|
548 |
//exit('SetExpressCheckout Completed Successfully: '.print_r($this->httpParsedResponseAr, true));
|
549 |
-
} else {
|
550 |
$order->status = "error";
|
551 |
$order->errorcode = $this->httpParsedResponseAr['L_ERRORCODE0'];
|
552 |
$order->error = urldecode($this->httpParsedResponseAr['L_LONGMESSAGE0']);
|
@@ -554,32 +554,32 @@
|
|
554 |
return false;
|
555 |
//exit('SetExpressCheckout failed: ' . print_r($httpParsedResponseAr, true));
|
556 |
}
|
557 |
-
|
558 |
//write session?
|
559 |
-
|
560 |
//redirect to PayPal
|
561 |
}
|
562 |
-
|
563 |
function getExpressCheckoutDetails(&$order)
|
564 |
-
{
|
565 |
$nvpStr="&TOKEN=".$order->Token;
|
566 |
-
|
567 |
$nvpStr = apply_filters("pmpro_get_express_checkout_details_nvpstr", $nvpStr, $order);
|
568 |
-
|
569 |
/* Make the API call and store the results in an array. If the
|
570 |
call was a success, show the authorization details, and provide
|
571 |
an action to complete the payment. If failed, show the error
|
572 |
*/
|
573 |
$this->httpParsedResponseAr = $this->PPHttpPost('GetExpressCheckoutDetails', $nvpStr);
|
574 |
-
|
575 |
if("SUCCESS" == strtoupper($this->httpParsedResponseAr["ACK"]) || "SUCCESSWITHWARNING" == strtoupper($this->httpParsedResponseAr["ACK"])) {
|
576 |
-
$order->status = "review";
|
577 |
-
|
578 |
//update order
|
579 |
-
$order->saveOrder();
|
580 |
-
|
581 |
-
return true;
|
582 |
-
} else {
|
583 |
$order->status = "error";
|
584 |
$order->errorcode = $this->httpParsedResponseAr['L_ERRORCODE0'];
|
585 |
$order->error = urldecode($this->httpParsedResponseAr['L_LONGMESSAGE0']);
|
@@ -588,20 +588,20 @@
|
|
588 |
//exit('SetExpressCheckout failed: ' . print_r($httpParsedResponseAr, true));
|
589 |
}
|
590 |
}
|
591 |
-
|
592 |
function charge(&$order)
|
593 |
{
|
594 |
global $pmpro_currency;
|
595 |
-
|
596 |
if(empty($order->code))
|
597 |
-
$order->code = $order->getRandomCode();
|
598 |
-
|
599 |
//taxes on the amount
|
600 |
$amount = $order->InitialPayment;
|
601 |
-
$amount_tax = $order->getTaxForPrice($amount);
|
602 |
$order->subtotal = $amount;
|
603 |
$amount = round((float)$amount + (float)$amount_tax, 2);
|
604 |
-
|
605 |
//paypal profile stuff
|
606 |
$nvpStr = "";
|
607 |
if(!empty($order->Token))
|
@@ -612,28 +612,28 @@
|
|
612 |
$nvpStr .= "&TAXAMT=" . $amount_tax;
|
613 |
*/
|
614 |
if(!empty($order->BillingFrequency))
|
615 |
-
$nvpStr .= "&BILLINGPERIOD=" . $order->BillingPeriod . "&BILLINGFREQUENCY=" . $order->BillingFrequency . "&AUTOBILLAMT=AddToNextBilling";
|
616 |
$nvpStr .= "&DESC=" . urlencode(substr($order->membership_level->name . " at " . get_bloginfo("name"), 0, 127));
|
617 |
$nvpStr .= "&NOTIFYURL=" . urlencode(admin_url('admin-ajax.php') . "?action=ipnhandler");
|
618 |
$nvpStr .= "&NOSHIPPING=1";
|
619 |
-
|
620 |
-
$nvpStr .= "&PAYERID=" . $_SESSION['payer_id'] . "&PAYMENTACTION=sale";
|
621 |
-
|
622 |
$nvpStr = apply_filters("pmpro_do_express_checkout_payment_nvpstr", $nvpStr, $order);
|
623 |
-
|
624 |
$order->nvpStr = $nvpStr;
|
625 |
-
|
626 |
$this->httpParsedResponseAr = $this->PPHttpPost('DoExpressCheckoutPayment', $nvpStr);
|
627 |
-
|
628 |
-
if("SUCCESS" == strtoupper($this->httpParsedResponseAr["ACK"]) || "SUCCESSWITHWARNING" == strtoupper($this->httpParsedResponseAr["ACK"])) {
|
629 |
-
$order->payment_transaction_id = urldecode($this->httpParsedResponseAr['TRANSACTIONID']);
|
630 |
-
$order->status = "success";
|
631 |
|
632 |
//update order
|
633 |
-
$order->saveOrder();
|
634 |
-
|
635 |
-
return true;
|
636 |
-
} else {
|
637 |
$order->status = "error";
|
638 |
$order->errorcode = $this->httpParsedResponseAr['L_ERRORCODE0'];
|
639 |
$order->error = urldecode($this->httpParsedResponseAr['L_LONGMESSAGE0']);
|
@@ -642,136 +642,136 @@
|
|
642 |
//exit('SetExpressCheckout failed: ' . print_r($httpParsedResponseAr, true));
|
643 |
}
|
644 |
}
|
645 |
-
|
646 |
function subscribe(&$order)
|
647 |
-
{
|
648 |
global $pmpro_currency;
|
649 |
-
|
650 |
if(empty($order->code))
|
651 |
-
$order->code = $order->getRandomCode();
|
652 |
|
653 |
//filter order before subscription. use with care.
|
654 |
$order = apply_filters("pmpro_subscribe_order", $order, $this);
|
655 |
-
|
656 |
//taxes on initial amount
|
657 |
$initial_payment = $order->InitialPayment;
|
658 |
$initial_payment_tax = $order->getTaxForPrice($initial_payment);
|
659 |
$initial_payment = round((float)$initial_payment + (float)$initial_payment_tax, 2);
|
660 |
-
|
661 |
//taxes on the amount
|
662 |
$amount = $order->PaymentAmount;
|
663 |
-
$amount_tax = $order->getTaxForPrice($amount);
|
664 |
//$amount = round((float)$amount + (float)$amount_tax, 2);
|
665 |
-
|
666 |
//paypal profile stuff
|
667 |
$nvpStr = "";
|
668 |
if(!empty($order->Token))
|
669 |
-
$nvpStr .= "&TOKEN=" . $order->Token;
|
670 |
$nvpStr .="&INITAMT=" . $initial_payment . "&AMT=" . $amount . "&CURRENCYCODE=" . $pmpro_currency . "&PROFILESTARTDATE=" . $order->ProfileStartDate;
|
671 |
if(!empty($amount_tax))
|
672 |
$nvpStr .= "&TAXAMT=" . $amount_tax;
|
673 |
-
$nvpStr .= "&BILLINGPERIOD=" . $order->BillingPeriod . "&BILLINGFREQUENCY=" . $order->BillingFrequency . "&AUTOBILLAMT=AddToNextBilling";
|
674 |
$nvpStr .= "&NOTIFYURL=" . urlencode(admin_url('admin-ajax.php') . "?action=ipnhandler");
|
675 |
$nvpStr .= "&DESC=" . urlencode(substr($order->membership_level->name . " at " . get_bloginfo("name"), 0, 127));
|
676 |
-
|
677 |
-
//if billing cycles are defined
|
678 |
if(!empty($order->TotalBillingCycles))
|
679 |
$nvpStr .= "&TOTALBILLINGCYCLES=" . $order->TotalBillingCycles;
|
680 |
-
|
681 |
//if a trial period is defined
|
682 |
if(!empty($order->TrialBillingPeriod))
|
683 |
{
|
684 |
$trial_amount = $order->TrialAmount;
|
685 |
$trial_tax = $order->getTaxForPrice($trial_amount);
|
686 |
$trial_amount = round((float)$trial_amount + (float)$trial_tax, 2);
|
687 |
-
|
688 |
$nvpStr .= "&TRIALBILLINGPERIOD=" . $order->TrialBillingPeriod . "&TRIALBILLINGFREQUENCY=" . $order->TrialBillingFrequency . "&TRIALAMT=" . $trial_amount;
|
689 |
}
|
690 |
if(!empty($order->TrialBillingCycles))
|
691 |
$nvpStr .= "&TRIALTOTALBILLINGCYCLES=" . $order->TrialBillingCycles;
|
692 |
-
|
693 |
$nvpStr = apply_filters("pmpro_create_recurring_payments_profile_nvpstr", $nvpStr, $order);
|
694 |
-
|
695 |
-
$this->nvpStr = $nvpStr;
|
696 |
-
|
697 |
///echo str_replace("&", "&<br />", $nvpStr);
|
698 |
///exit;
|
699 |
-
|
700 |
$this->httpParsedResponseAr = $this->PPHttpPost('CreateRecurringPaymentsProfile', $nvpStr);
|
701 |
-
|
702 |
if("SUCCESS" == strtoupper($this->httpParsedResponseAr["ACK"]) || "SUCCESSWITHWARNING" == strtoupper($this->httpParsedResponseAr["ACK"])) {
|
703 |
-
$order->status = "success";
|
704 |
$order->payment_transaction_id = urldecode($this->httpParsedResponseAr['PROFILEID']);
|
705 |
$order->subscription_transaction_id = urldecode($this->httpParsedResponseAr['PROFILEID']);
|
706 |
-
|
707 |
//update order
|
708 |
-
$order->saveOrder();
|
709 |
-
|
710 |
-
return true;
|
711 |
-
} else {
|
712 |
$order->status = "error";
|
713 |
$order->errorcode = $this->httpParsedResponseAr['L_ERRORCODE0'];
|
714 |
$order->error = urldecode($this->httpParsedResponseAr['L_LONGMESSAGE0']);
|
715 |
$order->shorterror = urldecode($this->httpParsedResponseAr['L_SHORTMESSAGE0']);
|
716 |
-
|
717 |
-
return false;
|
718 |
}
|
719 |
}
|
720 |
-
|
721 |
function cancel(&$order)
|
722 |
-
{
|
723 |
//paypal profile stuff
|
724 |
-
$nvpStr = "";
|
725 |
-
$nvpStr .= "&PROFILEID=" . urlencode($order->subscription_transaction_id) . "&ACTION=Cancel&NOTE=" . urlencode("User requested cancel.");
|
726 |
-
|
727 |
$nvpStr = apply_filters("pmpro_manage_recurring_payments_profile_status_nvpstr", $nvpStr, $order);
|
728 |
-
|
729 |
-
$this->httpParsedResponseAr = $this->PPHttpPost('ManageRecurringPaymentsProfileStatus', $nvpStr);
|
730 |
-
|
731 |
-
if("SUCCESS" == strtoupper($this->httpParsedResponseAr["ACK"]) || "SUCCESSWITHWARNING" == strtoupper($this->httpParsedResponseAr["ACK"]))
|
732 |
-
{
|
733 |
-
$order->updateStatus("cancelled");
|
734 |
-
return true;
|
735 |
-
}
|
736 |
-
else
|
737 |
{
|
738 |
$order->status = "error";
|
739 |
$order->errorcode = $this->httpParsedResponseAr['L_ERRORCODE0'];
|
740 |
$order->error = urldecode($this->httpParsedResponseAr['L_LONGMESSAGE0']) . ". " . __("Please contact the site owner or cancel your subscription from within PayPal to make sure you are not charged going forward.", "pmpro");
|
741 |
$order->shorterror = urldecode($this->httpParsedResponseAr['L_SHORTMESSAGE0']);
|
742 |
-
|
743 |
-
return false;
|
744 |
}
|
745 |
}
|
746 |
|
747 |
function getSubscriptionStatus(&$order)
|
748 |
-
{
|
749 |
if(empty($order->subscription_transaction_id))
|
750 |
return false;
|
751 |
-
|
752 |
//paypal profile stuff
|
753 |
-
$nvpStr = "";
|
754 |
-
$nvpStr .= "&PROFILEID=" . urlencode($order->subscription_transaction_id);
|
755 |
-
|
756 |
$nvpStr = apply_filters("pmpro_get_recurring_payments_profile_details_nvpstr", $nvpStr, $order);
|
757 |
-
|
758 |
-
$this->httpParsedResponseAr = $this->PPHttpPost('GetRecurringPaymentsProfileDetails', $nvpStr);
|
759 |
-
|
760 |
-
if("SUCCESS" == strtoupper($this->httpParsedResponseAr["ACK"]) || "SUCCESSWITHWARNING" == strtoupper($this->httpParsedResponseAr["ACK"]))
|
761 |
-
{
|
762 |
-
return $this->httpParsedResponseAr;
|
763 |
-
}
|
764 |
-
else
|
765 |
{
|
766 |
$order->status = "error";
|
767 |
$order->errorcode = $this->httpParsedResponseAr['L_ERRORCODE0'];
|
768 |
$order->error = urldecode($this->httpParsedResponseAr['L_LONGMESSAGE0']);
|
769 |
$order->shorterror = urldecode($this->httpParsedResponseAr['L_SHORTMESSAGE0']);
|
770 |
-
|
771 |
-
return false;
|
772 |
}
|
773 |
-
}
|
774 |
-
|
775 |
/**
|
776 |
* PAYPAL Function
|
777 |
* Send HTTP POST Request
|
@@ -782,46 +782,46 @@
|
|
782 |
*/
|
783 |
function PPHttpPost($methodName_, $nvpStr_) {
|
784 |
global $gateway_environment;
|
785 |
-
$environment = $gateway_environment;
|
786 |
-
|
787 |
$API_UserName = pmpro_getOption("apiusername");
|
788 |
$API_Password = pmpro_getOption("apipassword");
|
789 |
$API_Signature = pmpro_getOption("apisignature");
|
790 |
$API_Endpoint = "https://api-3t.paypal.com/nvp";
|
791 |
if("sandbox" === $environment || "beta-sandbox" === $environment) {
|
792 |
$API_Endpoint = "https://api-3t.$environment.paypal.com/nvp";
|
793 |
-
}
|
794 |
-
|
795 |
$version = urlencode('72.0');
|
796 |
-
|
797 |
// setting the curl parameters.
|
798 |
$ch = curl_init();
|
799 |
curl_setopt($ch, CURLOPT_URL, $API_Endpoint);
|
800 |
curl_setopt($ch, CURLOPT_VERBOSE, 1);
|
801 |
-
|
802 |
// turning off the server and peer verification(TrustManager Concept).
|
803 |
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
|
804 |
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
|
805 |
-
|
806 |
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
|
807 |
curl_setopt($ch, CURLOPT_POST, 1);
|
808 |
-
|
809 |
// NVPRequest for submitting to server
|
810 |
$nvpreq = "METHOD=" . urlencode($methodName_) . "&VERSION=" . urlencode($version) . "&PWD=" . urlencode($API_Password) . "&USER=" . urlencode($API_UserName) . "&SIGNATURE=" . urlencode($API_Signature) . "&BUTTONSOURCE=" . urlencode(PAYPAL_BN_CODE) . $nvpStr_;
|
811 |
-
|
812 |
// setting the nvpreq as POST FIELD to curl
|
813 |
curl_setopt($ch, CURLOPT_POSTFIELDS, $nvpreq);
|
814 |
-
|
815 |
// getting response from server
|
816 |
$httpResponse = curl_exec($ch);
|
817 |
-
|
818 |
if(!$httpResponse) {
|
819 |
exit("$methodName_ failed: ".curl_error($ch).'('.curl_errno($ch).')');
|
820 |
}
|
821 |
-
|
822 |
// Extract the RefundTransaction response details
|
823 |
$httpResponseAr = explode("&", $httpResponse);
|
824 |
-
|
825 |
$httpParsedResponseAr = array();
|
826 |
foreach ($httpResponseAr as $i => $value) {
|
827 |
$tmpAr = explode("=", $value);
|
@@ -829,11 +829,11 @@
|
|
829 |
$httpParsedResponseAr[$tmpAr[0]] = $tmpAr[1];
|
830 |
}
|
831 |
}
|
832 |
-
|
833 |
if((0 == sizeof($httpParsedResponseAr)) || !array_key_exists('ACK', $httpParsedResponseAr)) {
|
834 |
exit("Invalid HTTP Response for POST request($nvpreq) to $API_Endpoint.");
|
835 |
}
|
836 |
-
|
837 |
return $httpParsedResponseAr;
|
838 |
}
|
839 |
}
|
1 |
<?php
|
2 |
//include pmprogateway
|
3 |
require_once(dirname(__FILE__) . "/class.pmprogateway.php");
|
4 |
+
|
5 |
//load classes init method
|
6 |
add_action('init', array('PMProGateway_paypalexpress', 'init'));
|
7 |
+
|
8 |
class PMProGateway_paypalexpress extends PMProGateway
|
9 |
{
|
10 |
function PMProGateway_paypalexpress($gateway = NULL)
|
11 |
{
|
12 |
$this->gateway = $gateway;
|
13 |
return $this->gateway;
|
14 |
+
}
|
15 |
+
|
16 |
/**
|
17 |
* Run on WP init
|
18 |
+
*
|
19 |
* @since 1.8
|
20 |
*/
|
21 |
static function init()
|
22 |
+
{
|
23 |
//make sure PayPal Express is a gateway option
|
24 |
add_filter('pmpro_gateways', array('PMProGateway_paypalexpress', 'pmpro_gateways'));
|
25 |
+
|
26 |
//add fields to payment settings
|
27 |
add_filter('pmpro_payment_options', array('PMProGateway_paypalexpress', 'pmpro_payment_options'));
|
28 |
+
|
29 |
/*
|
30 |
This code is the same for PayPal Website Payments Pro, PayPal Express, and PayPal Standard
|
31 |
So we only load it if we haven't already.
|
32 |
*/
|
33 |
global $pmpro_payment_option_fields_for_paypal;
|
34 |
if(empty($pmpro_payment_option_fields_for_paypal))
|
35 |
+
{
|
36 |
+
add_filter('pmpro_payment_option_fields', array('PMProGateway_paypalexpress', 'pmpro_payment_option_fields'), 10, 2);
|
37 |
$pmpro_payment_option_fields_for_paypal = true;
|
38 |
}
|
39 |
+
|
40 |
//code to add at checkout
|
41 |
$gateway = pmpro_getGateway();
|
42 |
if($gateway == "paypalexpress")
|
43 |
+
{
|
44 |
add_filter('pmpro_include_billing_address_fields', '__return_false');
|
45 |
add_filter('pmpro_include_payment_information_fields', '__return_false');
|
46 |
add_filter('pmpro_required_billing_fields', array('PMProGateway_paypalexpress', 'pmpro_required_billing_fields'));
|
51 |
add_action('pmpro_checkout_after_form', array('PMProGateway_paypalexpress', 'pmpro_checkout_after_form'));
|
52 |
}
|
53 |
}
|
54 |
+
|
55 |
/**
|
56 |
* Make sure this gateway is in the gateways list
|
57 |
+
*
|
58 |
* @since 1.8
|
59 |
*/
|
60 |
static function pmpro_gateways($gateways)
|
61 |
{
|
62 |
if(empty($gateways['paypalexpress']))
|
63 |
$gateways['paypalexpress'] = __('PayPal Express', 'pmpro');
|
64 |
+
|
65 |
return $gateways;
|
66 |
}
|
67 |
+
|
68 |
/**
|
69 |
* Get a list of payment options that the this gateway needs/supports.
|
70 |
+
*
|
71 |
* @since 1.8
|
72 |
*/
|
73 |
static function getGatewayOptions()
|
74 |
+
{
|
75 |
$options = array(
|
76 |
'sslseal',
|
77 |
'nuclear_HTTPS',
|
85 |
'tax_state',
|
86 |
'tax_rate'
|
87 |
);
|
88 |
+
|
89 |
return $options;
|
90 |
}
|
91 |
+
|
92 |
/**
|
93 |
* Set payment options for payment settings page.
|
94 |
+
*
|
95 |
* @since 1.8
|
96 |
*/
|
97 |
static function pmpro_payment_options($options)
|
98 |
+
{
|
99 |
//get stripe options
|
100 |
$paypal_options = PMProGateway_paypalexpress::getGatewayOptions();
|
101 |
+
|
102 |
//merge with others.
|
103 |
$options = array_merge($paypal_options, $options);
|
104 |
+
|
105 |
return $options;
|
106 |
}
|
107 |
+
|
108 |
/**
|
109 |
* Display fields for this gateway's options.
|
110 |
+
*
|
111 |
* @since 1.8
|
112 |
*/
|
113 |
static function pmpro_payment_option_fields($values, $gateway)
|
117 |
<td colspan="2">
|
118 |
<?php _e('PayPal Settings', 'pmpro'); ?>
|
119 |
</td>
|
120 |
+
</tr>
|
121 |
<tr class="gateway gateway_paypalstandard" <?php if($gateway != "paypalstandard") { ?>style="display: none;"<?php } ?>>
|
122 |
<td colspan="2">
|
123 |
<strong><?php _e('Note', 'pmpro');?>:</strong> <?php _e('We do not recommend using PayPal Standard. We suggest using PayPal Express, Website Payments Pro (Legacy), or PayPal Pro (Payflow Pro). <a target="_blank" href="http://www.paidmembershipspro.com/2013/09/read-using-paypal-standard-paid-memberships-pro/">More information on why can be found here.</a>', 'pmpro');?>
|
124 |
+
</td>
|
125 |
+
</tr>
|
126 |
<tr class="gateway gateway_paypal gateway_paypalexpress gateway_paypalstandard" <?php if($gateway != "paypal" && $gateway != "paypalexpress" && $gateway != "paypalstandard") { ?>style="display: none;"<?php } ?>>
|
127 |
+
<th scope="row" valign="top">
|
128 |
<label for="gateway_email"><?php _e('Gateway Account Email', 'pmpro');?>:</label>
|
129 |
</th>
|
130 |
<td>
|
131 |
<input type="text" id="gateway_email" name="gateway_email" size="60" value="<?php echo esc_attr($values['gateway_email'])?>" />
|
132 |
</td>
|
133 |
+
</tr>
|
134 |
<tr class="gateway gateway_paypal gateway_paypalexpress" <?php if($gateway != "paypal" && $gateway != "paypalexpress") { ?>style="display: none;"<?php } ?>>
|
135 |
<th scope="row" valign="top">
|
136 |
<label for="apiusername"><?php _e('API Username', 'pmpro');?>:</label>
|
146 |
<td>
|
147 |
<input type="text" id="apipassword" name="apipassword" size="60" value="<?php echo esc_attr($values['apipassword'])?>" />
|
148 |
</td>
|
149 |
+
</tr>
|
150 |
<tr class="gateway gateway_paypal gateway_paypalexpress" <?php if($gateway != "paypal" && $gateway != "paypalexpress") { ?>style="display: none;"<?php } ?>>
|
151 |
<th scope="row" valign="top">
|
152 |
<label for="apisignature"><?php _e('API Signature', 'pmpro');?>:</label>
|
154 |
<td>
|
155 |
<input type="text" id="apisignature" name="apisignature" size="60" value="<?php echo esc_attr($values['apisignature'])?>" />
|
156 |
</td>
|
157 |
+
</tr>
|
158 |
<tr class="gateway gateway_paypal gateway_paypalexpress gateway_paypalstandard" <?php if($gateway != "paypal" && $gateway != "paypalexpress" && $gateway != "paypalstandard") { ?>style="display: none;"<?php } ?>>
|
159 |
<th scope="row" valign="top">
|
160 |
<label><?php _e('IPN Handler URL', 'pmpro');?>:</label>
|
165 |
</tr>
|
166 |
<?php
|
167 |
}
|
168 |
+
|
169 |
/**
|
170 |
* Remove required billing fields
|
171 |
+
*
|
172 |
* @since 1.8
|
173 |
*/
|
174 |
static function pmpro_required_billing_fields($fields)
|
187 |
unset($fields['ExpirationMonth']);
|
188 |
unset($fields['ExpirationYear']);
|
189 |
unset($fields['CVV']);
|
190 |
+
|
191 |
return $fields;
|
192 |
}
|
193 |
+
|
194 |
/**
|
195 |
* Save session vars before processing
|
196 |
*
|
199 |
static function pmpro_checkout_before_processing()
|
200 |
{
|
201 |
global $current_user, $gateway;
|
202 |
+
|
203 |
+
//save user fields for PayPal Express
|
204 |
if(!$current_user->ID)
|
205 |
{
|
206 |
//get values from post
|
213 |
else
|
214 |
$password = "";
|
215 |
if(isset($_REQUEST['bemail']))
|
216 |
+
$bemail = $_REQUEST['bemail'];
|
217 |
else
|
218 |
$bemail = "";
|
219 |
+
|
220 |
//save to session
|
221 |
$_SESSION['pmpro_signup_username'] = $username;
|
222 |
$_SESSION['pmpro_signup_password'] = $password;
|
223 |
+
$_SESSION['pmpro_signup_email'] = $bemail;
|
224 |
}
|
225 |
+
|
226 |
//can use this hook to save some other variables to the session
|
227 |
do_action("pmpro_paypalexpress_session_vars");
|
228 |
}
|
229 |
+
|
230 |
/**
|
231 |
* Review and Confirmation code.
|
232 |
*
|
233 |
+
* @since 1.8
|
234 |
*/
|
235 |
static function pmpro_checkout_confirmed($pmpro_confirmed)
|
236 |
{
|
237 |
global $pmpro_msg, $pmpro_msgt, $pmpro_level, $current_user, $pmpro_review, $pmpro_paypal_token, $discount_code, $bemail;
|
238 |
+
|
239 |
//PayPal Express Call Backs
|
240 |
if(!empty($_REQUEST['review']))
|
241 |
+
{
|
242 |
if(!empty($_REQUEST['PayerID']))
|
243 |
$_SESSION['payer_id'] = $_REQUEST['PayerID'];
|
244 |
if(!empty($_REQUEST['paymentAmount']))
|
247 |
$_SESSION['currCodeType'] = $_REQUEST['currencyCodeType'];
|
248 |
if(!empty($_REQUEST['paymentType']))
|
249 |
$_SESSION['paymentType'] = $_REQUEST['paymentType'];
|
250 |
+
|
251 |
$morder = new MemberOrder();
|
252 |
$morder->getMemberOrderByPayPalToken($_REQUEST['token']);
|
253 |
+
$morder->Token = $morder->paypal_token; $pmpro_paypal_token = $morder->paypal_token;
|
254 |
if($morder->Token)
|
255 |
{
|
256 |
if($morder->Gateway->getExpressCheckoutDetails($morder))
|
261 |
{
|
262 |
$pmpro_msg = $morder->error;
|
263 |
$pmpro_msgt = "pmpro_error";
|
264 |
+
}
|
265 |
}
|
266 |
else
|
267 |
{
|
270 |
}
|
271 |
}
|
272 |
elseif(!empty($_REQUEST['confirm']))
|
273 |
+
{
|
274 |
$morder = new MemberOrder();
|
275 |
$morder->getMemberOrderByPayPalToken($_REQUEST['token']);
|
276 |
+
$morder->Token = $morder->paypal_token; $pmpro_paypal_token = $morder->paypal_token;
|
277 |
if($morder->Token)
|
278 |
+
{
|
279 |
//setup values
|
280 |
$morder->membership_id = $pmpro_level->id;
|
281 |
$morder->membership_name = $pmpro_level->name;
|
286 |
$morder->BillingPeriod = $pmpro_level->cycle_period;
|
287 |
$morder->BillingFrequency = $pmpro_level->cycle_number;
|
288 |
$morder->Email = $bemail;
|
289 |
+
|
290 |
//setup level var
|
291 |
+
$morder->getMembershipLevel();
|
292 |
$morder->membership_level = apply_filters("pmpro_checkout_level", $morder->membership_level);
|
293 |
+
|
294 |
//tax
|
295 |
$morder->subtotal = $morder->InitialPayment;
|
296 |
+
$morder->getTax();
|
297 |
if($pmpro_level->billing_limit)
|
298 |
$morder->TotalBillingCycles = $pmpro_level->billing_limit;
|
299 |
+
|
300 |
if(pmpro_isLevelTrial($pmpro_level))
|
301 |
{
|
302 |
$morder->TrialBillingPeriod = $pmpro_level->cycle_period;
|
304 |
$morder->TrialBillingCycles = $pmpro_level->trial_limit;
|
305 |
$morder->TrialAmount = $pmpro_level->trial_amount;
|
306 |
}
|
307 |
+
|
308 |
if($morder->confirm())
|
309 |
+
{
|
310 |
+
$pmpro_confirmed = true;
|
311 |
}
|
312 |
else
|
313 |
+
{
|
314 |
$pmpro_msg = $morder->error;
|
315 |
$pmpro_msgt = "pmpro_error";
|
316 |
}
|
321 |
$pmpro_msgt = "pmpro_error";
|
322 |
}
|
323 |
}
|
324 |
+
|
325 |
if(!empty($morder))
|
326 |
return array("pmpro_confirmed"=>$pmpro_confirmed, "morder"=>$morder);
|
327 |
else
|
328 |
return $pmpro_confirmed;
|
329 |
}
|
330 |
+
|
331 |
/**
|
332 |
* Swap in user/pass/etc from session
|
333 |
*
|
334 |
+
* @since 1.8
|
335 |
*/
|
336 |
static function pmpro_checkout_new_user_array($new_user_array)
|
337 |
{
|
338 |
global $current_user;
|
339 |
+
|
340 |
if(!$current_user->ID)
|
341 |
{
|
342 |
+
//reload the user fields
|
343 |
$new_user_array['user_login'] = $_SESSION['pmpro_signup_username'];
|
344 |
+
$new_user_array['user_pass'] = $_SESSION['pmpro_signup_password'];
|
345 |
$new_user_array['user_email'] = $_SESSION['pmpro_signup_email'];
|
346 |
+
|
347 |
//unset the user fields in session
|
348 |
unset($_SESSION['pmpro_signup_username']);
|
349 |
unset($_SESSION['pmpro_signup_password']);
|
350 |
unset($_SESSION['pmpro_signup_email']);
|
351 |
}
|
352 |
+
|
353 |
return $new_user_array;
|
354 |
}
|
355 |
+
|
356 |
/**
|
357 |
* Process at checkout
|
358 |
*
|
363 |
$order->payment_type = "PayPal Express";
|
364 |
$order->cardtype = "";
|
365 |
$order->ProfileStartDate = date("Y-m-d", strtotime("+ " . $order->BillingFrequency . " " . $order->BillingPeriod)) . "T0:0:0";
|
366 |
+
$order->ProfileStartDate = apply_filters("pmpro_profile_start_date", $order->ProfileStartDate, $order);
|
367 |
+
|
368 |
return $this->setExpressCheckout($order);
|
369 |
}
|
370 |
+
|
371 |
/**
|
372 |
* Process charge or subscription after confirmation.
|
373 |
*
|
374 |
* @since 1.8
|
375 |
*/
|
376 |
function confirm(&$order)
|
377 |
+
{
|
378 |
if(pmpro_isLevelRecurring($order->membership_level))
|
379 |
{
|
380 |
$order->ProfileStartDate = date("Y-m-d", strtotime("+ " . $order->BillingFrequency . " " . $order->BillingPeriod, current_time("timestamp"))) . "T0:0:0";
|
381 |
$order->ProfileStartDate = apply_filters("pmpro_profile_start_date", $order->ProfileStartDate, $order);
|
382 |
+
return $this->subscribe($order);
|
383 |
}
|
384 |
else
|
385 |
+
return $this->charge($order);
|
386 |
}
|
387 |
+
|
388 |
/**
|
389 |
* Swap in our submit buttons.
|
390 |
*
|
393 |
static function pmpro_checkout_default_submit_button($show)
|
394 |
{
|
395 |
global $gateway, $pmpro_requirebilling;
|
396 |
+
|
397 |
//show our submit buttons
|
398 |
?>
|
399 |
<?php if($gateway == "paypal" || $gateway == "paypalexpress" || $gateway == "paypalstandard") { ?>
|
400 |
<span id="pmpro_paypalexpress_checkout" <?php if(($gateway != "paypalexpress" && $gateway != "paypalstandard") || !$pmpro_requirebilling) { ?>style="display: none;"<?php } ?>>
|
401 |
+
<input type="hidden" name="submit-checkout" value="1" />
|
402 |
<input type="image" value="<?php _e('Check Out with PayPal', 'pmpro');?> »" src="<?php echo apply_filters("pmpro_paypal_button_image", "https://www.paypal.com/en_US/i/btn/btn_xpressCheckout.gif");?>" />
|
403 |
</span>
|
404 |
<?php } ?>
|
405 |
+
|
406 |
<span id="pmpro_submit_span" <?php if(($gateway == "paypalexpress" || $gateway == "paypalstandard") && $pmpro_requirebilling) { ?>style="display: none;"<?php } ?>>
|
407 |
+
<input type="hidden" name="submit-checkout" value="1" />
|
408 |
+
<input type="submit" class="pmpro_btn pmpro_btn-submit-checkout" value="<?php if($pmpro_requirebilling) { _e('Submit and Check Out', 'pmpro'); } else { _e('Submit and Confirm', 'pmpro');}?> »" />
|
409 |
</span>
|
410 |
<?php
|
411 |
+
|
412 |
//don't show the default
|
413 |
return false;
|
414 |
}
|
415 |
+
|
416 |
/**
|
417 |
* Scripts for checkout page.
|
418 |
*
|
421 |
static function pmpro_checkout_after_form()
|
422 |
{
|
423 |
?>
|
424 |
+
<script>
|
425 |
//choosing payment method
|
426 |
+
jQuery('input[name=gateway]').click(function() {
|
427 |
if(jQuery(this).val() == 'paypal')
|
428 |
{
|
429 |
jQuery('#pmpro_paypalexpress_checkout').hide();
|
430 |
jQuery('#pmpro_billing_address_fields').show();
|
431 |
+
jQuery('#pmpro_payment_information_fields').show();
|
432 |
jQuery('#pmpro_submit_span').show();
|
433 |
}
|
434 |
else
|
435 |
+
{
|
436 |
jQuery('#pmpro_billing_address_fields').hide();
|
437 |
+
jQuery('#pmpro_payment_information_fields').hide();
|
438 |
jQuery('#pmpro_submit_span').hide();
|
439 |
jQuery('#pmpro_paypalexpress_checkout').show();
|
440 |
}
|
441 |
});
|
442 |
+
|
443 |
//select the radio button if the label is clicked on
|
444 |
jQuery('a.pmpro_radio').click(function() {
|
445 |
jQuery(this).prev().click();
|
447 |
</script>
|
448 |
<?php
|
449 |
}
|
450 |
+
|
451 |
//PayPal Express, this is run first to authorize from PayPal
|
452 |
function setExpressCheckout(&$order)
|
453 |
+
{
|
454 |
global $pmpro_currency;
|
455 |
+
|
456 |
if(empty($order->code))
|
457 |
+
$order->code = $order->getRandomCode();
|
458 |
+
|
459 |
//clean up a couple values
|
460 |
$order->payment_type = "PayPal Express";
|
461 |
$order->CardType = "";
|
462 |
$order->cardtype = "";
|
463 |
+
|
464 |
//taxes on initial amount
|
465 |
$initial_payment = $order->InitialPayment;
|
466 |
$initial_payment_tax = $order->getTaxForPrice($initial_payment);
|
467 |
$initial_payment = round((float)$initial_payment + (float)$initial_payment_tax, 2);
|
468 |
+
|
469 |
//taxes on the amount
|
470 |
$amount = $order->PaymentAmount;
|
471 |
+
$amount_tax = $order->getTaxForPrice($amount);
|
472 |
$amount = round((float)$amount + (float)$amount_tax, 2);
|
473 |
+
|
474 |
//paypal profile stuff
|
475 |
$nvpStr = "";
|
476 |
$nvpStr .="&AMT=" . $initial_payment . "&CURRENCYCODE=" . $pmpro_currency;
|
477 |
if(!empty($order->ProfileStartDate) && strtotime($order->ProfileStartDate, current_time("timestamp")) > 0)
|
478 |
+
$nvpStr .= "&PROFILESTARTDATE=" . $order->ProfileStartDate;
|
479 |
if(!empty($order->BillingFrequency))
|
480 |
$nvpStr .= "&BILLINGPERIOD=" . $order->BillingPeriod . "&BILLINGFREQUENCY=" . $order->BillingFrequency . "&AUTOBILLAMT=AddToNextBilling&L_BILLINGTYPE0=RecurringPayments";
|
481 |
$nvpStr .= "&DESC=" . urlencode(substr($order->membership_level->name . " at " . get_bloginfo("name"), 0, 127));
|
482 |
+
$nvpStr .= "&NOTIFYURL=" . urlencode(admin_url('admin-ajax.php') . "?action=ipnhandler");
|
483 |
$nvpStr .= "&NOSHIPPING=1&L_BILLINGAGREEMENTDESCRIPTION0=" . urlencode(substr($order->membership_level->name . " at " . get_bloginfo("name"), 0, 127)) . "&L_PAYMENTTYPE0=Any";
|
484 |
+
|
485 |
+
//if billing cycles are defined
|
486 |
if(!empty($order->TotalBillingCycles))
|
487 |
$nvpStr .= "&TOTALBILLINGCYCLES=" . $order->TotalBillingCycles;
|
488 |
+
|
489 |
//if a trial period is defined
|
490 |
if(!empty($order->TrialBillingPeriod))
|
491 |
{
|
492 |
$trial_amount = $order->TrialAmount;
|
493 |
$trial_tax = $order->getTaxForPrice($trial_amount);
|
494 |
$trial_amount = round((float)$trial_amount + (float)$trial_tax, 2);
|
495 |
+
|
496 |
$nvpStr .= "&TRIALBILLINGPERIOD=" . $order->TrialBillingPeriod . "&TRIALBILLINGFREQUENCY=" . $order->TrialBillingFrequency . "&TRIALAMT=" . $trial_amount;
|
497 |
}
|
498 |
if(!empty($order->TrialBillingCycles))
|
499 |
$nvpStr .= "&TRIALTOTALBILLINGCYCLES=" . $order->TrialBillingCycles;
|
500 |
+
|
501 |
if(!empty($order->discount_code))
|
502 |
{
|
503 |
+
$nvpStr .= "&ReturnUrl=" . urlencode(pmpro_url("checkout", "?level=" . $order->membership_level->id . "&discount_code=" . $order->discount_code . "&review=" . $order->code));
|
504 |
}
|
505 |
else
|
506 |
{
|
507 |
+
$nvpStr .= "&ReturnUrl=" . urlencode(pmpro_url("checkout", "?level=" . $order->membership_level->id . "&review=" . $order->code));
|
508 |
}
|
509 |
+
|
510 |
+
$additional_parameters = apply_filters("pmpro_paypal_express_return_url_parameters", array());
|
511 |
if(!empty($additional_parameters))
|
512 |
{
|
513 |
+
foreach($additional_parameters as $key => $value)
|
514 |
$nvpStr .= urlencode("&" . $key . "=" . $value);
|
515 |
+
}
|
516 |
+
|
517 |
+
$nvpStr .= "&CANCELURL=" . urlencode(pmpro_url("levels"));
|
518 |
+
|
519 |
$account_optional = apply_filters('pmpro_paypal_account_optional', true);
|
520 |
if ($account_optional)
|
521 |
$nvpStr .= '&SOLUTIONTYPE=Sole&LANDINGPAGE=Billing';
|
522 |
+
|
523 |
+
$nvpStr = apply_filters("pmpro_set_express_checkout_nvpstr", $nvpStr, $order);
|
524 |
+
|
525 |
///echo str_replace("&", "&<br />", $nvpStr);
|
526 |
///exit;
|
527 |
+
|
528 |
+
$this->httpParsedResponseAr = $this->PPHttpPost('SetExpressCheckout', $nvpStr);
|
529 |
+
|
530 |
if("SUCCESS" == strtoupper($this->httpParsedResponseAr["ACK"]) || "SUCCESSWITHWARNING" == strtoupper($this->httpParsedResponseAr["ACK"])) {
|
531 |
+
$order->status = "token";
|
532 |
+
$order->paypal_token = urldecode($this->httpParsedResponseAr['TOKEN']);
|
533 |
+
|
534 |
//update order
|
535 |
+
$order->saveOrder();
|
536 |
+
|
537 |
//redirect to paypal
|
538 |
$paypal_url = "https://www.paypal.com/webscr&cmd=_express-checkout&useraction=commit&token=" . $this->httpParsedResponseAr['TOKEN'];
|
539 |
+
$environment = pmpro_getOption("gateway_environment");
|
540 |
+
if("sandbox" === $environment || "beta-sandbox" === $environment)
|
541 |
{
|
542 |
$paypal_url = "https://www.sandbox.paypal.com/webscr&useraction=commit&cmd=_express-checkout&token=" . $this->httpParsedResponseAr['TOKEN'];
|
543 |
+
}
|
544 |
+
|
545 |
+
wp_redirect($paypal_url);
|
546 |
exit;
|
547 |
+
|
548 |
//exit('SetExpressCheckout Completed Successfully: '.print_r($this->httpParsedResponseAr, true));
|
549 |
+
} else {
|
550 |
$order->status = "error";
|
551 |
$order->errorcode = $this->httpParsedResponseAr['L_ERRORCODE0'];
|
552 |
$order->error = urldecode($this->httpParsedResponseAr['L_LONGMESSAGE0']);
|
554 |
return false;
|
555 |
//exit('SetExpressCheckout failed: ' . print_r($httpParsedResponseAr, true));
|
556 |
}
|
557 |
+
|
558 |
//write session?
|
559 |
+
|
560 |
//redirect to PayPal
|
561 |
}
|
562 |
+
|
563 |
function getExpressCheckoutDetails(&$order)
|
564 |
+
{
|
565 |
$nvpStr="&TOKEN=".$order->Token;
|
566 |
+
|
567 |
$nvpStr = apply_filters("pmpro_get_express_checkout_details_nvpstr", $nvpStr, $order);
|
568 |
+
|
569 |
/* Make the API call and store the results in an array. If the
|
570 |
call was a success, show the authorization details, and provide
|
571 |
an action to complete the payment. If failed, show the error
|
572 |
*/
|
573 |
$this->httpParsedResponseAr = $this->PPHttpPost('GetExpressCheckoutDetails', $nvpStr);
|
574 |
+
|
575 |
if("SUCCESS" == strtoupper($this->httpParsedResponseAr["ACK"]) || "SUCCESSWITHWARNING" == strtoupper($this->httpParsedResponseAr["ACK"])) {
|
576 |
+
$order->status = "review";
|
577 |
+
|
578 |
//update order
|
579 |
+
$order->saveOrder();
|
580 |
+
|
581 |
+
return true;
|
582 |
+
} else {
|
583 |
$order->status = "error";
|
584 |
$order->errorcode = $this->httpParsedResponseAr['L_ERRORCODE0'];
|
585 |
$order->error = urldecode($this->httpParsedResponseAr['L_LONGMESSAGE0']);
|
588 |
//exit('SetExpressCheckout failed: ' . print_r($httpParsedResponseAr, true));
|
589 |
}
|
590 |
}
|
591 |
+
|
592 |
function charge(&$order)
|
593 |
{
|
594 |
global $pmpro_currency;
|
595 |
+
|
596 |
if(empty($order->code))
|
597 |
+
$order->code = $order->getRandomCode();
|
598 |
+
|
599 |
//taxes on the amount
|
600 |
$amount = $order->InitialPayment;
|
601 |
+
$amount_tax = $order->getTaxForPrice($amount);
|
602 |
$order->subtotal = $amount;
|
603 |
$amount = round((float)$amount + (float)$amount_tax, 2);
|
604 |
+
|
605 |
//paypal profile stuff
|
606 |
$nvpStr = "";
|
607 |
if(!empty($order->Token))
|
612 |
$nvpStr .= "&TAXAMT=" . $amount_tax;
|
613 |
*/
|
614 |
if(!empty($order->BillingFrequency))
|
615 |
+
$nvpStr .= "&BILLINGPERIOD=" . $order->BillingPeriod . "&BILLINGFREQUENCY=" . $order->BillingFrequency . "&AUTOBILLAMT=AddToNextBilling";
|
616 |
$nvpStr .= "&DESC=" . urlencode(substr($order->membership_level->name . " at " . get_bloginfo("name"), 0, 127));
|
617 |
$nvpStr .= "&NOTIFYURL=" . urlencode(admin_url('admin-ajax.php') . "?action=ipnhandler");
|
618 |
$nvpStr .= "&NOSHIPPING=1";
|
619 |
+
|
620 |
+
$nvpStr .= "&PAYERID=" . $_SESSION['payer_id'] . "&PAYMENTACTION=sale";
|
621 |
+
|
622 |
$nvpStr = apply_filters("pmpro_do_express_checkout_payment_nvpstr", $nvpStr, $order);
|
623 |
+
|
624 |
$order->nvpStr = $nvpStr;
|
625 |
+
|
626 |
$this->httpParsedResponseAr = $this->PPHttpPost('DoExpressCheckoutPayment', $nvpStr);
|
627 |
+
|
628 |
+
if("SUCCESS" == strtoupper($this->httpParsedResponseAr["ACK"]) || "SUCCESSWITHWARNING" == strtoupper($this->httpParsedResponseAr["ACK"])) {
|
629 |
+
$order->payment_transaction_id = urldecode($this->httpParsedResponseAr['TRANSACTIONID']);
|
630 |
+
$order->status = "success";
|
631 |
|
632 |
//update order
|
633 |
+
$order->saveOrder();
|
634 |
+
|
635 |
+
return true;
|
636 |
+
} else {
|
637 |
$order->status = "error";
|
638 |
$order->errorcode = $this->httpParsedResponseAr['L_ERRORCODE0'];
|
639 |
$order->error = urldecode($this->httpParsedResponseAr['L_LONGMESSAGE0']);
|
642 |
//exit('SetExpressCheckout failed: ' . print_r($httpParsedResponseAr, true));
|
643 |
}
|
644 |
}
|
645 |
+
|
646 |
function subscribe(&$order)
|
647 |
+
{
|
648 |
global $pmpro_currency;
|
649 |
+
|
650 |
if(empty($order->code))
|
651 |
+
$order->code = $order->getRandomCode();
|
652 |
|
653 |
//filter order before subscription. use with care.
|
654 |
$order = apply_filters("pmpro_subscribe_order", $order, $this);
|
655 |
+
|
656 |
//taxes on initial amount
|
657 |
$initial_payment = $order->InitialPayment;
|
658 |
$initial_payment_tax = $order->getTaxForPrice($initial_payment);
|
659 |
$initial_payment = round((float)$initial_payment + (float)$initial_payment_tax, 2);
|
660 |
+
|
661 |
//taxes on the amount
|
662 |
$amount = $order->PaymentAmount;
|
663 |
+
$amount_tax = $order->getTaxForPrice($amount);
|
664 |
//$amount = round((float)$amount + (float)$amount_tax, 2);
|
665 |
+
|
666 |
//paypal profile stuff
|
667 |
$nvpStr = "";
|
668 |
if(!empty($order->Token))
|
669 |
+
$nvpStr .= "&TOKEN=" . $order->Token;
|
670 |
$nvpStr .="&INITAMT=" . $initial_payment . "&AMT=" . $amount . "&CURRENCYCODE=" . $pmpro_currency . "&PROFILESTARTDATE=" . $order->ProfileStartDate;
|
671 |
if(!empty($amount_tax))
|
672 |
$nvpStr .= "&TAXAMT=" . $amount_tax;
|
673 |
+
$nvpStr .= "&BILLINGPERIOD=" . $order->BillingPeriod . "&BILLINGFREQUENCY=" . $order->BillingFrequency . "&AUTOBILLAMT=AddToNextBilling";
|
674 |
$nvpStr .= "&NOTIFYURL=" . urlencode(admin_url('admin-ajax.php') . "?action=ipnhandler");
|
675 |
$nvpStr .= "&DESC=" . urlencode(substr($order->membership_level->name . " at " . get_bloginfo("name"), 0, 127));
|
676 |
+
|
677 |
+
//if billing cycles are defined
|
678 |
if(!empty($order->TotalBillingCycles))
|
679 |
$nvpStr .= "&TOTALBILLINGCYCLES=" . $order->TotalBillingCycles;
|
680 |
+
|
681 |
//if a trial period is defined
|
682 |
if(!empty($order->TrialBillingPeriod))
|
683 |
{
|
684 |
$trial_amount = $order->TrialAmount;
|
685 |
$trial_tax = $order->getTaxForPrice($trial_amount);
|
686 |
$trial_amount = round((float)$trial_amount + (float)$trial_tax, 2);
|
687 |
+
|
688 |
$nvpStr .= "&TRIALBILLINGPERIOD=" . $order->TrialBillingPeriod . "&TRIALBILLINGFREQUENCY=" . $order->TrialBillingFrequency . "&TRIALAMT=" . $trial_amount;
|
689 |
}
|
690 |
if(!empty($order->TrialBillingCycles))
|
691 |
$nvpStr .= "&TRIALTOTALBILLINGCYCLES=" . $order->TrialBillingCycles;
|
692 |
+
|
693 |
$nvpStr = apply_filters("pmpro_create_recurring_payments_profile_nvpstr", $nvpStr, $order);
|
694 |
+
|
695 |
+
$this->nvpStr = $nvpStr;
|
696 |
+
|
697 |
///echo str_replace("&", "&<br />", $nvpStr);
|
698 |
///exit;
|
699 |
+
|
700 |
$this->httpParsedResponseAr = $this->PPHttpPost('CreateRecurringPaymentsProfile', $nvpStr);
|
701 |
+
|
702 |
if("SUCCESS" == strtoupper($this->httpParsedResponseAr["ACK"]) || "SUCCESSWITHWARNING" == strtoupper($this->httpParsedResponseAr["ACK"])) {
|
703 |
+
$order->status = "success";
|
704 |
$order->payment_transaction_id = urldecode($this->httpParsedResponseAr['PROFILEID']);
|
705 |
$order->subscription_transaction_id = urldecode($this->httpParsedResponseAr['PROFILEID']);
|
706 |
+
|
707 |
//update order
|
708 |
+
$order->saveOrder();
|
709 |
+
|
710 |
+
return true;
|
711 |
+
} else {
|
712 |
$order->status = "error";
|
713 |
$order->errorcode = $this->httpParsedResponseAr['L_ERRORCODE0'];
|
714 |
$order->error = urldecode($this->httpParsedResponseAr['L_LONGMESSAGE0']);
|
715 |
$order->shorterror = urldecode($this->httpParsedResponseAr['L_SHORTMESSAGE0']);
|
716 |
+
|
717 |
+
return false;
|
718 |
}
|
719 |
}
|
720 |
+
|
721 |
function cancel(&$order)
|
722 |
+
{
|
723 |
//paypal profile stuff
|
724 |
+
$nvpStr = "";
|
725 |
+
$nvpStr .= "&PROFILEID=" . urlencode($order->subscription_transaction_id) . "&ACTION=Cancel&NOTE=" . urlencode("User requested cancel.");
|
726 |
+
|
727 |
$nvpStr = apply_filters("pmpro_manage_recurring_payments_profile_status_nvpstr", $nvpStr, $order);
|
728 |
+
|
729 |
+
$this->httpParsedResponseAr = $this->PPHttpPost('ManageRecurringPaymentsProfileStatus', $nvpStr);
|
730 |
+
|
731 |
+
if("SUCCESS" == strtoupper($this->httpParsedResponseAr["ACK"]) || "SUCCESSWITHWARNING" == strtoupper($this->httpParsedResponseAr["ACK"]))
|
732 |
+
{
|
733 |
+
$order->updateStatus("cancelled");
|
734 |
+
return true;
|
735 |
+
}
|
736 |
+
else
|
737 |
{
|
738 |
$order->status = "error";
|
739 |
$order->errorcode = $this->httpParsedResponseAr['L_ERRORCODE0'];
|
740 |
$order->error = urldecode($this->httpParsedResponseAr['L_LONGMESSAGE0']) . ". " . __("Please contact the site owner or cancel your subscription from within PayPal to make sure you are not charged going forward.", "pmpro");
|
741 |
$order->shorterror = urldecode($this->httpParsedResponseAr['L_SHORTMESSAGE0']);
|
742 |
+
|
743 |
+
return false;
|
744 |
}
|
745 |
}
|
746 |
|
747 |
function getSubscriptionStatus(&$order)
|
748 |
+
{
|
749 |
if(empty($order->subscription_transaction_id))
|
750 |
return false;
|
751 |
+
|
752 |
//paypal profile stuff
|
753 |
+
$nvpStr = "";
|
754 |
+
$nvpStr .= "&PROFILEID=" . urlencode($order->subscription_transaction_id);
|
755 |
+
|
756 |
$nvpStr = apply_filters("pmpro_get_recurring_payments_profile_details_nvpstr", $nvpStr, $order);
|
757 |
+
|
758 |
+
$this->httpParsedResponseAr = $this->PPHttpPost('GetRecurringPaymentsProfileDetails', $nvpStr);
|
759 |
+
|
760 |
+
if("SUCCESS" == strtoupper($this->httpParsedResponseAr["ACK"]) || "SUCCESSWITHWARNING" == strtoupper($this->httpParsedResponseAr["ACK"]))
|
761 |
+
{
|
762 |
+
return $this->httpParsedResponseAr;
|
763 |
+
}
|
764 |
+
else
|
765 |
{
|
766 |
$order->status = "error";
|
767 |
$order->errorcode = $this->httpParsedResponseAr['L_ERRORCODE0'];
|
768 |
$order->error = urldecode($this->httpParsedResponseAr['L_LONGMESSAGE0']);
|
769 |
$order->shorterror = urldecode($this->httpParsedResponseAr['L_SHORTMESSAGE0']);
|
770 |
+
|
771 |
+
return false;
|
772 |
}
|
773 |
+
}
|
774 |
+
|
775 |
/**
|
776 |
* PAYPAL Function
|
777 |
* Send HTTP POST Request
|
782 |
*/
|
783 |
function PPHttpPost($methodName_, $nvpStr_) {
|
784 |
global $gateway_environment;
|
785 |
+
$environment = $gateway_environment;
|
786 |
+
|
787 |
$API_UserName = pmpro_getOption("apiusername");
|
788 |
$API_Password = pmpro_getOption("apipassword");
|
789 |
$API_Signature = pmpro_getOption("apisignature");
|
790 |
$API_Endpoint = "https://api-3t.paypal.com/nvp";
|
791 |
if("sandbox" === $environment || "beta-sandbox" === $environment) {
|
792 |
$API_Endpoint = "https://api-3t.$environment.paypal.com/nvp";
|
793 |
+
}
|
794 |
+
|
795 |
$version = urlencode('72.0');
|
796 |
+
|
797 |
// setting the curl parameters.
|
798 |
$ch = curl_init();
|
799 |
curl_setopt($ch, CURLOPT_URL, $API_Endpoint);
|
800 |
curl_setopt($ch, CURLOPT_VERBOSE, 1);
|
801 |
+
|
802 |
// turning off the server and peer verification(TrustManager Concept).
|
803 |
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
|
804 |
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
|
805 |
+
|
806 |
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
|
807 |
curl_setopt($ch, CURLOPT_POST, 1);
|
808 |
+
|
809 |
// NVPRequest for submitting to server
|
810 |
$nvpreq = "METHOD=" . urlencode($methodName_) . "&VERSION=" . urlencode($version) . "&PWD=" . urlencode($API_Password) . "&USER=" . urlencode($API_UserName) . "&SIGNATURE=" . urlencode($API_Signature) . "&BUTTONSOURCE=" . urlencode(PAYPAL_BN_CODE) . $nvpStr_;
|
811 |
+
|
812 |
// setting the nvpreq as POST FIELD to curl
|
813 |
curl_setopt($ch, CURLOPT_POSTFIELDS, $nvpreq);
|
814 |
+
|
815 |
// getting response from server
|
816 |
$httpResponse = curl_exec($ch);
|
817 |
+
|
818 |
if(!$httpResponse) {
|
819 |
exit("$methodName_ failed: ".curl_error($ch).'('.curl_errno($ch).')');
|
820 |
}
|
821 |
+
|
822 |
// Extract the RefundTransaction response details
|
823 |
$httpResponseAr = explode("&", $httpResponse);
|
824 |
+
|
825 |
$httpParsedResponseAr = array();
|
826 |
foreach ($httpResponseAr as $i => $value) {
|
827 |
$tmpAr = explode("=", $value);
|
829 |
$httpParsedResponseAr[$tmpAr[0]] = $tmpAr[1];
|
830 |
}
|
831 |
}
|
832 |
+
|
833 |
if((0 == sizeof($httpParsedResponseAr)) || !array_key_exists('ACK', $httpParsedResponseAr)) {
|
834 |
exit("Invalid HTTP Response for POST request($nvpreq) to $API_Endpoint.");
|
835 |
}
|
836 |
+
|
837 |
return $httpParsedResponseAr;
|
838 |
}
|
839 |
}
|
classes/gateways/class.pmprogateway_paypalstandard.php
CHANGED
@@ -1,537 +1,537 @@
|
|
1 |
-
<?php
|
2 |
-
//include pmprogateway
|
3 |
-
require_once(dirname(__FILE__) . "/class.pmprogateway.php");
|
4 |
-
|
5 |
-
//load classes init method
|
6 |
-
add_action('init', array('PMProGateway_paypalstandard', 'init'));
|
7 |
-
|
8 |
-
class PMProGateway_paypalstandard extends PMProGateway
|
9 |
-
{
|
10 |
-
function PMProGateway_paypalstandard($gateway = NULL)
|
11 |
-
{
|
12 |
-
$this->gateway = $gateway;
|
13 |
-
return $this->gateway;
|
14 |
-
}
|
15 |
-
|
16 |
-
/**
|
17 |
-
* Run on WP init
|
18 |
-
*
|
19 |
-
* @since 1.8
|
20 |
-
*/
|
21 |
-
static function init()
|
22 |
-
{
|
23 |
-
//make sure PayPal Express is a gateway option
|
24 |
-
add_filter('pmpro_gateways', array('PMProGateway_paypalstandard', 'pmpro_gateways'));
|
25 |
-
|
26 |
-
//add fields to payment settings
|
27 |
-
add_filter('pmpro_payment_options', array('PMProGateway_paypalstandard', 'pmpro_payment_options'));
|
28 |
-
|
29 |
-
/*
|
30 |
-
This code is the same for PayPal Website Payments Pro, PayPal Express, and PayPal Standard
|
31 |
-
So we only load it if we haven't already.
|
32 |
-
*/
|
33 |
-
global $pmpro_payment_option_fields_for_paypal;
|
34 |
-
if(empty($pmpro_payment_option_fields_for_paypal))
|
35 |
-
{
|
36 |
-
add_filter('pmpro_payment_option_fields', array('PMProGateway_paypalstandard', 'pmpro_payment_option_fields'), 10, 2);
|
37 |
-
$pmpro_payment_option_fields_for_paypal = true;
|
38 |
-
}
|
39 |
-
|
40 |
-
//code to add at checkout
|
41 |
-
$gateway = pmpro_getGateway();
|
42 |
-
if($gateway == "paypalstandard")
|
43 |
-
{
|
44 |
-
add_filter('pmpro_include_billing_address_fields', '__return_false');
|
45 |
-
add_filter('pmpro_include_payment_information_fields', '__return_false');
|
46 |
-
add_filter('pmpro_required_billing_fields', array('PMProGateway_paypalstandard', 'pmpro_required_billing_fields'));
|
47 |
-
add_filter('pmpro_checkout_default_submit_button', array('PMProGateway_paypalstandard', 'pmpro_checkout_default_submit_button'));
|
48 |
-
add_filter('pmpro_checkout_before_change_membership_level', array('PMProGateway_paypalstandard', 'pmpro_checkout_before_change_membership_level'), 10, 2);
|
49 |
-
}
|
50 |
-
}
|
51 |
-
|
52 |
-
/**
|
53 |
-
* Make sure this gateway is in the gateways list
|
54 |
-
*
|
55 |
-
* @since 1.8
|
56 |
-
*/
|
57 |
-
static function pmpro_gateways($gateways)
|
58 |
-
{
|
59 |
-
if(empty($gateways['paypalstandard']))
|
60 |
-
$gateways['paypalstandard'] = __('PayPal Standard', 'pmpro');
|
61 |
-
|
62 |
-
return $gateways;
|
63 |
-
}
|
64 |
-
|
65 |
-
/**
|
66 |
-
* Get a list of payment options that the this gateway needs/supports.
|
67 |
-
*
|
68 |
-
* @since 1.8
|
69 |
-
*/
|
70 |
-
static function getGatewayOptions()
|
71 |
-
{
|
72 |
-
$options = array(
|
73 |
-
'sslseal',
|
74 |
-
'nuclear_HTTPS',
|
75 |
-
'gateway_environment',
|
76 |
-
'gateway_email',
|
77 |
-
'currency',
|
78 |
-
'use_ssl',
|
79 |
-
'tax_state',
|
80 |
-
'tax_rate'
|
81 |
-
);
|
82 |
-
|
83 |
-
return $options;
|
84 |
-
}
|
85 |
-
|
86 |
-
/**
|
87 |
-
* Set payment options for payment settings page.
|
88 |
-
*
|
89 |
-
* @since 1.8
|
90 |
-
*/
|
91 |
-
static function pmpro_payment_options($options)
|
92 |
-
{
|
93 |
-
//get stripe options
|
94 |
-
$paypal_options = PMProGateway_paypalexpress::getGatewayOptions();
|
95 |
-
|
96 |
-
//merge with others.
|
97 |
-
$options = array_merge($paypal_options, $options);
|
98 |
-
|
99 |
-
return $options;
|
100 |
-
}
|
101 |
-
|
102 |
-
/**
|
103 |
-
* Display fields for this gateway's options.
|
104 |
-
*
|
105 |
-
* @since 1.8
|
106 |
-
*/
|
107 |
-
static function pmpro_payment_option_fields($values, $gateway)
|
108 |
-
{
|
109 |
-
?>
|
110 |
-
<tr class="pmpro_settings_divider gateway gateway_paypal gateway_paypalexpress gateway_paypalstandard" <?php if($gateway != "paypal" && $gateway != "paypalexpress" && $gateway != "paypalstandard") { ?>style="display: none;"<?php } ?>>
|
111 |
-
<td colspan="2">
|
112 |
-
<?php _e('PayPal Settings', 'pmpro'); ?>
|
113 |
-
</td>
|
114 |
-
</tr>
|
115 |
-
<tr class="gateway gateway_paypalstandard" <?php if($gateway != "paypalstandard") { ?>style="display: none;"<?php } ?>>
|
116 |
-
<td colspan="2">
|
117 |
-
<strong><?php _e('Note', 'pmpro');?>:</strong> <?php _e('We do not recommend using PayPal Standard. We suggest using PayPal Express, Website Payments Pro (Legacy), or PayPal Pro (Payflow Pro). <a target="_blank" href="http://www.paidmembershipspro.com/2013/09/read-using-paypal-standard-paid-memberships-pro/">More information on why can be found here.</a>', 'pmpro');?>
|
118 |
-
</td>
|
119 |
-
</tr>
|
120 |
-
<tr class="gateway gateway_paypal gateway_paypalexpress gateway_paypalstandard" <?php if($gateway != "paypal" && $gateway != "paypalexpress" && $gateway != "paypalstandard") { ?>style="display: none;"<?php } ?>>
|
121 |
-
<th scope="row" valign="top">
|
122 |
-
<label for="gateway_email"><?php _e('Gateway Account Email', 'pmpro');?>:</label>
|
123 |
-
</th>
|
124 |
-
<td>
|
125 |
-
<input type="text" id="gateway_email" name="gateway_email" size="60" value="<?php echo esc_attr($values['gateway_email'])?>" />
|
126 |
-
</td>
|
127 |
-
</tr>
|
128 |
-
<tr class="gateway gateway_paypal gateway_paypalexpress" <?php if($gateway != "paypal" && $gateway != "paypalexpress") { ?>style="display: none;"<?php } ?>>
|
129 |
-
<th scope="row" valign="top">
|
130 |
-
<label for="apiusername"><?php _e('API Username', 'pmpro');?>:</label>
|
131 |
-
</th>
|
132 |
-
<td>
|
133 |
-
<input type="text" id="apiusername" name="apiusername" size="60" value="<?php echo esc_attr($values['apiusername'])?>" />
|
134 |
-
</td>
|
135 |
-
</tr>
|
136 |
-
<tr class="gateway gateway_paypal gateway_paypalexpress" <?php if($gateway != "paypal" && $gateway != "paypalexpress") { ?>style="display: none;"<?php } ?>>
|
137 |
-
<th scope="row" valign="top">
|
138 |
-
<label for="apipassword"><?php _e('API Password', 'pmpro');?>:</label>
|
139 |
-
</th>
|
140 |
-
<td>
|
141 |
-
<input type="text" id="apipassword" name="apipassword" size="60" value="<?php echo esc_attr($values['apipassword'])?>" />
|
142 |
-
</td>
|
143 |
-
</tr>
|
144 |
-
<tr class="gateway gateway_paypal gateway_paypalexpress" <?php if($gateway != "paypal" && $gateway != "paypalexpress") { ?>style="display: none;"<?php } ?>>
|
145 |
-
<th scope="row" valign="top">
|
146 |
-
<label for="apisignature"><?php _e('API Signature', 'pmpro');?>:</label>
|
147 |
-
</th>
|
148 |
-
<td>
|
149 |
-
<input type="text" id="apisignature" name="apisignature" size="60" value="<?php echo esc_attr($values['apisignature'])?>" />
|
150 |
-
</td>
|
151 |
-
</tr>
|
152 |
-
<tr class="gateway gateway_paypal gateway_paypalexpress gateway_paypalstandard" <?php if($gateway != "paypal" && $gateway != "paypalexpress" && $gateway != "paypalstandard") { ?>style="display: none;"<?php } ?>>
|
153 |
-
<th scope="row" valign="top">
|
154 |
-
<label><?php _e('IPN Handler URL', 'pmpro');?>:</label>
|
155 |
-
</th>
|
156 |
-
<td>
|
157 |
-
<p><?php _e('Here is your IPN URL for reference. You SHOULD NOT set this in your PayPal settings.', 'pmpro');?> <pre><?php echo admin_url("admin-ajax.php") . "?action=ipnhandler";?></pre></p>
|
158 |
-
</td>
|
159 |
-
</tr>
|
160 |
-
<?php
|
161 |
-
}
|
162 |
-
|
163 |
-
/**
|
164 |
-
* Remove required billing fields
|
165 |
-
*
|
166 |
-
* @since 1.8
|
167 |
-
*/
|
168 |
-
static function pmpro_required_billing_fields($fields)
|
169 |
-
{
|
170 |
-
unset($fields['bfirstname']);
|
171 |
-
unset($fields['blastname']);
|
172 |
-
unset($fields['baddress1']);
|
173 |
-
unset($fields['bcity']);
|
174 |
-
unset($fields['bstate']);
|
175 |
-
unset($fields['bzipcode']);
|
176 |
-
unset($fields['bphone']);
|
177 |
-
unset($fields['bemail']);
|
178 |
-
unset($fields['bcountry']);
|
179 |
-
unset($fields['CardType']);
|
180 |
-
unset($fields['AccountNumber']);
|
181 |
-
unset($fields['ExpirationMonth']);
|
182 |
-
unset($fields['ExpirationYear']);
|
183 |
-
unset($fields['CVV']);
|
184 |
-
|
185 |
-
return $fields;
|
186 |
-
}
|
187 |
-
|
188 |
-
/**
|
189 |
-
* Swap in our submit buttons.
|
190 |
-
*
|
191 |
-
* @since 1.8
|
192 |
-
*/
|
193 |
-
static function pmpro_checkout_default_submit_button($show)
|
194 |
-
{
|
195 |
-
global $gateway, $pmpro_requirebilling;
|
196 |
-
|
197 |
-
//show our submit buttons
|
198 |
-
?>
|
199 |
-
<?php if($gateway == "paypal" || $gateway == "paypalexpress" || $gateway == "paypalstandard") { ?>
|
200 |
-
<span id="pmpro_paypalexpress_checkout" <?php if(($gateway != "paypalexpress" && $gateway != "paypalstandard") || !$pmpro_requirebilling) { ?>style="display: none;"<?php } ?>>
|
201 |
-
<input type="hidden" name="submit-checkout" value="1" />
|
202 |
-
<input type="image" value="<?php _e('Check Out with PayPal', 'pmpro');?> »" src="<?php echo apply_filters("pmpro_paypal_button_image", "https://www.paypal.com/en_US/i/btn/btn_xpressCheckout.gif");?>" />
|
203 |
-
</span>
|
204 |
-
<?php } ?>
|
205 |
-
|
206 |
-
<span id="pmpro_submit_span" <?php if(($gateway == "paypalexpress" || $gateway == "paypalstandard") && $pmpro_requirebilling) { ?>style="display: none;"<?php } ?>>
|
207 |
-
<input type="hidden" name="submit-checkout" value="1" />
|
208 |
-
<input type="submit" class="pmpro_btn pmpro_btn-submit-checkout" value="<?php if($pmpro_requirebilling) { _e('Submit and Check Out', 'pmpro'); } else { _e('Submit and Confirm', 'pmpro');}?> »" />
|
209 |
-
</span>
|
210 |
-
<?php
|
211 |
-
|
212 |
-
//don't show the default
|
213 |
-
return false;
|
214 |
-
}
|
215 |
-
|
216 |
-
/**
|
217 |
-
* Instead of change membership levels, send users to PayPal to pay.
|
218 |
-
*
|
219 |
-
* @since 1.8
|
220 |
-
*/
|
221 |
-
static function pmpro_checkout_before_change_membership_level($user_id, $morder)
|
222 |
-
{
|
223 |
-
global $discount_code_id, $wpdb;
|
224 |
-
|
225 |
-
//if no order, no need to pay
|
226 |
-
if(empty($morder))
|
227 |
-
return;
|
228 |
-
|
229 |
-
$morder->user_id = $user_id;
|
230 |
-
$morder->saveOrder();
|
231 |
-
|
232 |
-
//save discount code use
|
233 |
-
if(!empty($discount_code_id))
|
234 |
-
$wpdb->query("INSERT INTO $wpdb->pmpro_discount_codes_uses (code_id, user_id, order_id, timestamp) VALUES('" . $discount_code_id . "', '" . $user_id . "', '" . $morder->id . "', now())");
|
235 |
-
|
236 |
-
do_action("pmpro_before_send_to_paypal_standard", $user_id, $morder);
|
237 |
-
|
238 |
-
$morder->Gateway->sendToPayPal($morder);
|
239 |
-
}
|
240 |
-
|
241 |
-
/**
|
242 |
-
* Process checkout.
|
243 |
-
*
|
244 |
-
*/
|
245 |
-
function process(&$order)
|
246 |
-
{
|
247 |
-
if(empty($order->code))
|
248 |
-
$order->code = $order->getRandomCode();
|
249 |
-
|
250 |
-
//clean up a couple values
|
251 |
-
$order->payment_type = "PayPal Standard";
|
252 |
-
$order->CardType = "";
|
253 |
-
$order->cardtype = "";
|
254 |
-
|
255 |
-
//just save, the user will go to PayPal to pay
|
256 |
-
$order->status = "review";
|
257 |
-
$order->saveOrder();
|
258 |
-
|
259 |
-
return true;
|
260 |
-
}
|
261 |
-
|
262 |
-
function sendToPayPal(&$order)
|
263 |
-
{
|
264 |
-
global $pmpro_currency;
|
265 |
-
|
266 |
-
//taxes on initial amount
|
267 |
-
$initial_payment = $order->InitialPayment;
|
268 |
-
$initial_payment_tax = $order->getTaxForPrice($initial_payment);
|
269 |
-
$initial_payment = round((float)$initial_payment + (float)$initial_payment_tax, 2);
|
270 |
-
|
271 |
-
//taxes on the amount
|
272 |
-
$amount = $order->PaymentAmount;
|
273 |
-
$amount_tax = $order->getTaxForPrice($amount);
|
274 |
-
$amount = round((float)$amount + (float)$amount_tax, 2);
|
275 |
-
|
276 |
-
//build PayPal Redirect
|
277 |
-
$environment = pmpro_getOption("gateway_environment");
|
278 |
-
if("sandbox" === $environment || "beta-sandbox" === $environment)
|
279 |
-
$paypal_url ="https://www.sandbox.paypal.com/cgi-bin/webscr?business=" . urlencode(pmpro_getOption("gateway_email"));
|
280 |
-
else
|
281 |
-
$paypal_url = "https://www.paypal.com/cgi-bin/webscr?business=" . urlencode(pmpro_getOption("gateway_email"));
|
282 |
-
|
283 |
-
if(pmpro_isLevelRecurring($order->membership_level))
|
284 |
-
{
|
285 |
-
//convert billing period
|
286 |
-
if($order->BillingPeriod == "Day")
|
287 |
-
$period = "D";
|
288 |
-
elseif($order->BillingPeriod == "Week")
|
289 |
-
$period = "W";
|
290 |
-
elseif($order->BillingPeriod == "Month")
|
291 |
-
$period = "M";
|
292 |
-
elseif($order->BillingPeriod == "Year")
|
293 |
-
$period = "Y";
|
294 |
-
else
|
295 |
-
{
|
296 |
-
$order->error = "Invalid billing period: " . $order->BillingPeriod;
|
297 |
-
$order->shorterror = "Invalid billing period: " . $order->BillingPeriod;
|
298 |
-
return false;
|
299 |
-
}
|
300 |
-
|
301 |
-
//other args
|
302 |
-
$paypal_args = array(
|
303 |
-
'cmd' => '_xclick-subscriptions',
|
304 |
-
'a1' => number_format($initial_payment, 2),
|
305 |
-
'p1' => $order->BillingFrequency,
|
306 |
-
't1' => $period,
|
307 |
-
'a3' => number_format($amount, 2),
|
308 |
-
'p3' => $order->BillingFrequency,
|
309 |
-
't3' => $period,
|
310 |
-
'item_name' => substr($order->membership_level->name . " at " . get_bloginfo("name"), 0, 127),
|
311 |
-
'email' => $order->Email,
|
312 |
-
'no_shipping' => '1',
|
313 |
-
'shipping' => '0',
|
314 |
-
'no_note' => '1',
|
315 |
-
'currency_code' => $pmpro_currency,
|
316 |
-
'item_number' => $order->code,
|
317 |
-
'charset' => get_bloginfo( 'charset' ),
|
318 |
-
'rm' => '2',
|
319 |
-
'return' => pmpro_url("confirmation", "?level=" . $order->membership_level->id),
|
320 |
-
'notify_url' => admin_url("admin-ajax.php") . "?action=ipnhandler",
|
321 |
-
'src' => '1',
|
322 |
-
'sra' => '1',
|
323 |
-
'bn' => PAYPAL_BN_CODE
|
324 |
-
);
|
325 |
-
|
326 |
-
//trial?
|
327 |
-
/*
|
328 |
-
Note here that the TrialBillingCycles value is being ignored. PayPal Standard only offers 1 payment during each trial period.
|
329 |
-
*/
|
330 |
-
if(!empty($order->TrialBillingPeriod))
|
331 |
-
{
|
332 |
-
//if a1 and a2 are 0, let's just combine them. PayPal doesn't like a2 = 0.
|
333 |
-
if($paypal_args['a1'] == 0 && $order->TrialAmount == 0)
|
334 |
-
{
|
335 |
-
$paypal_args['p1'] = $paypal_args['p1'] + $order->TrialBillingFrequency;
|
336 |
-
}
|
337 |
-
else
|
338 |
-
{
|
339 |
-
$trial_amount = $order->TrialAmount;
|
340 |
-
$trial_tax = $order->getTaxForPrice($trial_amount);
|
341 |
-
$trial_amount = round((float)$trial_amount + (float)$trial_tax, 2);
|
342 |
-
|
343 |
-
$paypal_args['a2'] = $trial_amount;
|
344 |
-
$paypal_args['p2'] = $order->TrialBillingFrequency;
|
345 |
-
$paypal_args['t2'] = $period;
|
346 |
-
}
|
347 |
-
}
|
348 |
-
else
|
349 |
-
{
|
350 |
-
//we can try to work in any change in ProfileStartDate
|
351 |
-
$psd = date("Y-m-d", strtotime("+ " . $order->BillingFrequency . " " . $order->BillingPeriod, current_time("timestamp"))) . "T0:0:0";
|
352 |
-
$adjusted_psd = apply_filters("pmpro_profile_start_date", $psd, $order);
|
353 |
-
if($psd != $adjusted_psd)
|
354 |
-
{
|
355 |
-
//someone is trying to push the start date back
|
356 |
-
$adjusted_psd_time = strtotime($adjusted_psd, current_time("timestamp"));
|
357 |
-
$seconds_til_psd = $adjusted_psd_time - current_time('timestamp');
|
358 |
-
$days_til_psd = floor($seconds_til_psd/(60*60*24));
|
359 |
-
|
360 |
-
//push back trial one by days_til_psd
|
361 |
-
if($days_til_psd > 90)
|
362 |
-
{
|
363 |
-
//we need to convert to weeks, because PayPal limits t1 to 90 days
|
364 |
-
$weeks_til_psd = round($days_til_psd / 7);
|
365 |
-
$paypal_args['p1'] = $weeks_til_psd;
|
366 |
-
$paypal_args['t1'] = "W";
|
367 |
-
}
|
368 |
-
elseif($days_til_psd > 0)
|
369 |
-
{
|
370 |
-
//use days
|
371 |
-
$paypal_args['p1'] = $days_til_psd;
|
372 |
-
$paypal_args['t1'] = "D";
|
373 |
-
}
|
374 |
-
}
|
375 |
-
}
|
376 |
-
|
377 |
-
//billing limit?
|
378 |
-
if(!empty($order->TotalBillingCycles))
|
379 |
-
{
|
380 |
-
if(!empty($trial_amount))
|
381 |
-
{
|
382 |
-
|
383 |
-
$srt = intval($order->TotalBillingCycles) - 1; //subtract one for the trial period
|
384 |
-
}
|
385 |
-
else
|
386 |
-
{
|
387 |
-
$srt = intval($order->TotalBillingCycles);
|
388 |
-
}
|
389 |
-
|
390 |
-
//srt must be at least 2 or the subscription is not "recurring" according to paypal
|
391 |
-
if($srt > 1)
|
392 |
-
$paypal_args['srt'] = $srt;
|
393 |
-
else
|
394 |
-
$paypal_args['src'] = '0';
|
395 |
-
}
|
396 |
-
else
|
397 |
-
$paypal_args['srt'] = '0'; //indefinite subscription
|
398 |
-
}
|
399 |
-
else
|
400 |
-
{
|
401 |
-
//other args
|
402 |
-
$paypal_args = array(
|
403 |
-
'cmd' => '_xclick',
|
404 |
-
'amount' => number_format($initial_payment, 2),
|
405 |
-
'item_name' => substr($order->membership_level->name . " at " . get_bloginfo("name"), 0, 127),
|
406 |
-
'email' => $order->Email,
|
407 |
-
'no_shipping' => '1',
|
408 |
-
'shipping' => '0',
|
409 |
-
'no_note' => '1',
|
410 |
-
'currency_code' => $pmpro_currency,
|
411 |
-
'item_number' => $order->code,
|
412 |
-
'charset' => get_bloginfo( 'charset' ),
|
413 |
-
'rm' => '2',
|
414 |
-
'return' => pmpro_url("confirmation", "?level=" . $order->membership_level->id),
|
415 |
-
'notify_url' => admin_url("admin-ajax.php") . "?action=ipnhandler",
|
416 |
-
'bn' => PAYPAL_BN_CODE
|
417 |
-
);
|
418 |
-
}
|
419 |
-
|
420 |
-
$nvpStr = "";
|
421 |
-
foreach($paypal_args as $key => $value)
|
422 |
-
{
|
423 |
-
$nvpStr .= "&" . $key . "=" . urlencode($value);
|
424 |
-
}
|
425 |
-
|
426 |
-
//anything modders might add
|
427 |
-
$additional_parameters = apply_filters("pmpro_paypal_express_return_url_parameters", array());
|
428 |
-
if(!empty($additional_parameters))
|
429 |
-
{
|
430 |
-
foreach($additional_parameters as $key => $value)
|
431 |
-
$nvpStr .= urlencode("&" . $key . "=" . $value);
|
432 |
-
}
|
433 |
-
|
434 |
-
$account_optional = apply_filters('pmpro_paypal_account_optional', true);
|
435 |
-
if ($account_optional)
|
436 |
-
$nvpStr .= '&SOLUTIONTYPE=Sole&LANDINGPAGE=Billing';
|
437 |
-
|
438 |
-
$nvpStr = apply_filters("pmpro_paypal_standard_nvpstr", $nvpStr, $order);
|
439 |
-
|
440 |
-
//redirect to paypal
|
441 |
-
$paypal_url .= $nvpStr;
|
442 |
-
|
443 |
-
//wp_die(str_replace("&", "<br />", $paypal_url));
|
444 |
-
|
445 |
-
wp_redirect($paypal_url);
|
446 |
-
exit;
|
447 |
-
}
|
448 |
-
|
449 |
-
function cancel(&$order)
|
450 |
-
{
|
451 |
-
//paypal profile stuff
|
452 |
-
$nvpStr = "";
|
453 |
-
$nvpStr .= "&PROFILEID=" . urlencode($order->subscription_transaction_id) . "&ACTION=Cancel&NOTE=" . urlencode("User requested cancel.");
|
454 |
-
|
455 |
-
$this->httpParsedResponseAr = $this->PPHttpPost('ManageRecurringPaymentsProfileStatus', $nvpStr);
|
456 |
-
|
457 |
-
if("SUCCESS" == strtoupper($this->httpParsedResponseAr["ACK"]) || "SUCCESSWITHWARNING" == strtoupper($this->httpParsedResponseAr["ACK"]))
|
458 |
-
{
|
459 |
-
$order->updateStatus("cancelled");
|
460 |
-
return true;
|
461 |
-
}
|
462 |
-
else
|
463 |
-
{
|
464 |
-
$order->status = "error";
|
465 |
-
$order->errorcode = $this->httpParsedResponseAr['L_ERRORCODE0'];
|
466 |
-
$order->error = urldecode($this->httpParsedResponseAr['L_LONGMESSAGE0']) . ". " . __("Please contact the site owner or cancel your subscription from within PayPal to make sure you are not charged going forward.", "pmpro");
|
467 |
-
$order->shorterror = urldecode($this->httpParsedResponseAr['L_SHORTMESSAGE0']);
|
468 |
-
|
469 |
-
return false;
|
470 |
-
}
|
471 |
-
}
|
472 |
-
|
473 |
-
/**
|
474 |
-
* PAYPAL Function
|
475 |
-
* Send HTTP POST Request
|
476 |
-
*
|
477 |
-
* @param string The API method name
|
478 |
-
* @param string The POST Message fields in &name=value pair format
|
479 |
-
* @return array Parsed HTTP Response body
|
480 |
-
*/
|
481 |
-
function PPHttpPost($methodName_, $nvpStr_) {
|
482 |
-
global $gateway_environment;
|
483 |
-
$environment = $gateway_environment;
|
484 |
-
|
485 |
-
$API_UserName = pmpro_getOption("apiusername");
|
486 |
-
$API_Password = pmpro_getOption("apipassword");
|
487 |
-
$API_Signature = pmpro_getOption("apisignature");
|
488 |
-
$API_Endpoint = "https://api-3t.paypal.com/nvp";
|
489 |
-
if("sandbox" === $environment || "beta-sandbox" === $environment) {
|
490 |
-
$API_Endpoint = "https://api-3t.$environment.paypal.com/nvp";
|
491 |
-
}
|
492 |
-
|
493 |
-
$version = urlencode('72.0');
|
494 |
-
|
495 |
-
// setting the curl parameters.
|
496 |
-
$ch = curl_init();
|
497 |
-
curl_setopt($ch, CURLOPT_URL, $API_Endpoint);
|
498 |
-
curl_setopt($ch, CURLOPT_VERBOSE, 1);
|
499 |
-
|
500 |
-
// turning off the server and peer verification(TrustManager Concept).
|
501 |
-
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
|
502 |
-
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
|
503 |
-
|
504 |
-
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
|
505 |
-
curl_setopt($ch, CURLOPT_POST, 1);
|
506 |
-
|
507 |
-
// NVPRequest for submitting to server
|
508 |
-
$nvpreq = "METHOD=" . urlencode($methodName_) . "&VERSION=" . urlencode($version) . "&PWD=" . urlencode($API_Password) . "&USER=" . urlencode($API_UserName) . "&SIGNATURE=" . urlencode($API_Signature) . "&bn=" . urlencode(PAYPAL_BN_CODE) . $nvpStr_;
|
509 |
-
|
510 |
-
// setting the nvpreq as POST FIELD to curl
|
511 |
-
curl_setopt($ch, CURLOPT_POSTFIELDS, $nvpreq);
|
512 |
-
|
513 |
-
// getting response from server
|
514 |
-
$httpResponse = curl_exec($ch);
|
515 |
-
|
516 |
-
if(!$httpResponse) {
|
517 |
-
exit("$methodName_ failed: ".curl_error($ch).'('.curl_errno($ch).')');
|
518 |
-
}
|
519 |
-
|
520 |
-
// Extract the RefundTransaction response details
|
521 |
-
$httpResponseAr = explode("&", $httpResponse);
|
522 |
-
|
523 |
-
$httpParsedResponseAr = array();
|
524 |
-
foreach ($httpResponseAr as $i => $value) {
|
525 |
-
$tmpAr = explode("=", $value);
|
526 |
-
if(sizeof($tmpAr) > 1) {
|
527 |
-
$httpParsedResponseAr[$tmpAr[0]] = $tmpAr[1];
|
528 |
-
}
|
529 |
-
}
|
530 |
-
|
531 |
-
if((0 == sizeof($httpParsedResponseAr)) || !array_key_exists('ACK', $httpParsedResponseAr)) {
|
532 |
-
exit("Invalid HTTP Response for POST request($nvpreq) to $API_Endpoint.");
|
533 |
-
}
|
534 |
-
|
535 |
-
return $httpParsedResponseAr;
|
536 |
-
}
|
537 |
-
}
|
1 |
+
<?php
|
2 |
+
//include pmprogateway
|
3 |
+
require_once(dirname(__FILE__) . "/class.pmprogateway.php");
|
4 |
+
|
5 |
+
//load classes init method
|
6 |
+
add_action('init', array('PMProGateway_paypalstandard', 'init'));
|
7 |
+
|
8 |
+
class PMProGateway_paypalstandard extends PMProGateway
|
9 |
+
{
|
10 |
+
function PMProGateway_paypalstandard($gateway = NULL)
|
11 |
+
{
|
12 |
+
$this->gateway = $gateway;
|
13 |
+
return $this->gateway;
|
14 |
+
}
|
15 |
+
|
16 |
+
/**
|
17 |
+
* Run on WP init
|
18 |
+
*
|
19 |
+
* @since 1.8
|
20 |
+
*/
|
21 |
+
static function init()
|
22 |
+
{
|
23 |
+
//make sure PayPal Express is a gateway option
|
24 |
+
add_filter('pmpro_gateways', array('PMProGateway_paypalstandard', 'pmpro_gateways'));
|
25 |
+
|
26 |
+
//add fields to payment settings
|
27 |
+
add_filter('pmpro_payment_options', array('PMProGateway_paypalstandard', 'pmpro_payment_options'));
|
28 |
+
|
29 |
+
/*
|
30 |
+
This code is the same for PayPal Website Payments Pro, PayPal Express, and PayPal Standard
|
31 |
+
So we only load it if we haven't already.
|
32 |
+
*/
|
33 |
+
global $pmpro_payment_option_fields_for_paypal;
|
34 |
+
if(empty($pmpro_payment_option_fields_for_paypal))
|
35 |
+
{
|
36 |
+
add_filter('pmpro_payment_option_fields', array('PMProGateway_paypalstandard', 'pmpro_payment_option_fields'), 10, 2);
|
37 |
+
$pmpro_payment_option_fields_for_paypal = true;
|
38 |
+
}
|
39 |
+
|
40 |
+
//code to add at checkout
|
41 |
+
$gateway = pmpro_getGateway();
|
42 |
+
if($gateway == "paypalstandard")
|
43 |
+
{
|
44 |
+
add_filter('pmpro_include_billing_address_fields', '__return_false');
|
45 |
+
add_filter('pmpro_include_payment_information_fields', '__return_false');
|
46 |
+
add_filter('pmpro_required_billing_fields', array('PMProGateway_paypalstandard', 'pmpro_required_billing_fields'));
|
47 |
+
add_filter('pmpro_checkout_default_submit_button', array('PMProGateway_paypalstandard', 'pmpro_checkout_default_submit_button'));
|
48 |
+
add_filter('pmpro_checkout_before_change_membership_level', array('PMProGateway_paypalstandard', 'pmpro_checkout_before_change_membership_level'), 10, 2);
|
49 |
+
}
|
50 |
+
}
|
51 |
+
|
52 |
+
/**
|
53 |
+
* Make sure this gateway is in the gateways list
|
54 |
+
*
|
55 |
+
* @since 1.8
|
56 |
+
*/
|
57 |
+
static function pmpro_gateways($gateways)
|
58 |
+
{
|
59 |
+
if(empty($gateways['paypalstandard']))
|
60 |
+
$gateways['paypalstandard'] = __('PayPal Standard', 'pmpro');
|
61 |
+
|
62 |
+
return $gateways;
|
63 |
+
}
|
64 |
+
|
65 |
+
/**
|
66 |
+
* Get a list of payment options that the this gateway needs/supports.
|
67 |
+
*
|
68 |
+
* @since 1.8
|
69 |
+
*/
|
70 |
+
static function getGatewayOptions()
|
71 |
+
{
|
72 |
+
$options = array(
|
73 |
+
'sslseal',
|
74 |
+
'nuclear_HTTPS',
|
75 |
+
'gateway_environment',
|
76 |
+
'gateway_email',
|
77 |
+
'currency',
|
78 |
+
'use_ssl',
|
79 |
+
'tax_state',
|
80 |
+
'tax_rate'
|
81 |
+
);
|
82 |
+
|
83 |
+
return $options;
|
84 |
+
}
|
85 |
+
|
86 |
+
/**
|
87 |
+
* Set payment options for payment settings page.
|
88 |
+
*
|
89 |
+
* @since 1.8
|
90 |
+
*/
|
91 |
+
static function pmpro_payment_options($options)
|
92 |
+
{
|
93 |
+
//get stripe options
|
94 |
+
$paypal_options = PMProGateway_paypalexpress::getGatewayOptions();
|
95 |
+
|
96 |
+
//merge with others.
|
97 |
+
$options = array_merge($paypal_options, $options);
|
98 |
+
|
99 |
+
return $options;
|
100 |
+
}
|
101 |
+
|
102 |
+
/**
|
103 |
+
* Display fields for this gateway's options.
|
104 |
+
*
|
105 |
+
* @since 1.8
|
106 |
+
*/
|
107 |
+
static function pmpro_payment_option_fields($values, $gateway)
|
108 |
+
{
|
109 |
+
?>
|
110 |
+
<tr class="pmpro_settings_divider gateway gateway_paypal gateway_paypalexpress gateway_paypalstandard" <?php if($gateway != "paypal" && $gateway != "paypalexpress" && $gateway != "paypalstandard") { ?>style="display: none;"<?php } ?>>
|
111 |
+
<td colspan="2">
|
112 |
+
<?php _e('PayPal Settings', 'pmpro'); ?>
|
113 |
+
</td>
|
114 |
+
</tr>
|
115 |
+
<tr class="gateway gateway_paypalstandard" <?php if($gateway != "paypalstandard") { ?>style="display: none;"<?php } ?>>
|
116 |
+
<td colspan="2">
|
117 |
+
<strong><?php _e('Note', 'pmpro');?>:</strong> <?php _e('We do not recommend using PayPal Standard. We suggest using PayPal Express, Website Payments Pro (Legacy), or PayPal Pro (Payflow Pro). <a target="_blank" href="http://www.paidmembershipspro.com/2013/09/read-using-paypal-standard-paid-memberships-pro/">More information on why can be found here.</a>', 'pmpro');?>
|
118 |
+
</td>
|
119 |
+
</tr>
|
120 |
+
<tr class="gateway gateway_paypal gateway_paypalexpress gateway_paypalstandard" <?php if($gateway != "paypal" && $gateway != "paypalexpress" && $gateway != "paypalstandard") { ?>style="display: none;"<?php } ?>>
|
121 |
+
<th scope="row" valign="top">
|
122 |
+
<label for="gateway_email"><?php _e('Gateway Account Email', 'pmpro');?>:</label>
|
123 |
+
</th>
|
124 |
+
<td>
|
125 |
+
<input type="text" id="gateway_email" name="gateway_email" size="60" value="<?php echo esc_attr($values['gateway_email'])?>" />
|
126 |
+
</td>
|
127 |
+
</tr>
|
128 |
+
<tr class="gateway gateway_paypal gateway_paypalexpress" <?php if($gateway != "paypal" && $gateway != "paypalexpress") { ?>style="display: none;"<?php } ?>>
|
129 |
+
<th scope="row" valign="top">
|
130 |
+
<label for="apiusername"><?php _e('API Username', 'pmpro');?>:</label>
|
131 |
+
</th>
|
132 |
+
<td>
|
133 |
+
<input type="text" id="apiusername" name="apiusername" size="60" value="<?php echo esc_attr($values['apiusername'])?>" />
|
134 |
+
</td>
|
135 |
+
</tr>
|
136 |
+
<tr class="gateway gateway_paypal gateway_paypalexpress" <?php if($gateway != "paypal" && $gateway != "paypalexpress") { ?>style="display: none;"<?php } ?>>
|
137 |
+
<th scope="row" valign="top">
|
138 |
+
<label for="apipassword"><?php _e('API Password', 'pmpro');?>:</label>
|
139 |
+
</th>
|
140 |
+
<td>
|
141 |
+
<input type="text" id="apipassword" name="apipassword" size="60" value="<?php echo esc_attr($values['apipassword'])?>" />
|
142 |
+
</td>
|
143 |
+
</tr>
|
144 |
+
<tr class="gateway gateway_paypal gateway_paypalexpress" <?php if($gateway != "paypal" && $gateway != "paypalexpress") { ?>style="display: none;"<?php } ?>>
|
145 |
+
<th scope="row" valign="top">
|
146 |
+
<label for="apisignature"><?php _e('API Signature', 'pmpro');?>:</label>
|
147 |
+
</th>
|
148 |
+
<td>
|
149 |
+
<input type="text" id="apisignature" name="apisignature" size="60" value="<?php echo esc_attr($values['apisignature'])?>" />
|
150 |
+
</td>
|
151 |
+
</tr>
|
152 |
+
<tr class="gateway gateway_paypal gateway_paypalexpress gateway_paypalstandard" <?php if($gateway != "paypal" && $gateway != "paypalexpress" && $gateway != "paypalstandard") { ?>style="display: none;"<?php } ?>>
|
153 |
+
<th scope="row" valign="top">
|
154 |
+
<label><?php _e('IPN Handler URL', 'pmpro');?>:</label>
|
155 |
+
</th>
|
156 |
+
<td>
|
157 |
+
<p><?php _e('Here is your IPN URL for reference. You SHOULD NOT set this in your PayPal settings.', 'pmpro');?> <pre><?php echo admin_url("admin-ajax.php") . "?action=ipnhandler";?></pre></p>
|
158 |
+
</td>
|
159 |
+
</tr>
|
160 |
+
<?php
|
161 |
+
}
|
162 |
+
|
163 |
+
/**
|
164 |
+
* Remove required billing fields
|
165 |
+
*
|
166 |
+
* @since 1.8
|
167 |
+
*/
|
168 |
+
static function pmpro_required_billing_fields($fields)
|
169 |
+
{
|
170 |
+
unset($fields['bfirstname']);
|
171 |
+
unset($fields['blastname']);
|
172 |
+
unset($fields['baddress1']);
|
173 |
+
unset($fields['bcity']);
|
174 |
+
unset($fields['bstate']);
|
175 |
+
unset($fields['bzipcode']);
|
176 |
+
unset($fields['bphone']);
|
177 |
+
unset($fields['bemail']);
|
178 |
+
unset($fields['bcountry']);
|
179 |
+
unset($fields['CardType']);
|
180 |
+
unset($fields['AccountNumber']);
|
181 |
+
unset($fields['ExpirationMonth']);
|
182 |
+
unset($fields['ExpirationYear']);
|
183 |
+
unset($fields['CVV']);
|
184 |
+
|
185 |
+
return $fields;
|
186 |
+
}
|
187 |
+
|
188 |
+
/**
|
189 |
+
* Swap in our submit buttons.
|
190 |
+
*
|
191 |
+
* @since 1.8
|
192 |
+
*/
|
193 |
+
static function pmpro_checkout_default_submit_button($show)
|
194 |
+
{
|
195 |
+
global $gateway, $pmpro_requirebilling;
|
196 |
+
|
197 |
+
//show our submit buttons
|
198 |
+
?>
|
199 |
+
<?php if($gateway == "paypal" || $gateway == "paypalexpress" || $gateway == "paypalstandard") { ?>
|
200 |
+
<span id="pmpro_paypalexpress_checkout" <?php if(($gateway != "paypalexpress" && $gateway != "paypalstandard") || !$pmpro_requirebilling) { ?>style="display: none;"<?php } ?>>
|
201 |
+
<input type="hidden" name="submit-checkout" value="1" />
|
202 |
+
<input type="image" value="<?php _e('Check Out with PayPal', 'pmpro');?> »" src="<?php echo apply_filters("pmpro_paypal_button_image", "https://www.paypal.com/en_US/i/btn/btn_xpressCheckout.gif");?>" />
|
203 |
+
</span>
|
204 |
+
<?php } ?>
|
205 |
+
|
206 |
+
<span id="pmpro_submit_span" <?php if(($gateway == "paypalexpress" || $gateway == "paypalstandard") && $pmpro_requirebilling) { ?>style="display: none;"<?php } ?>>
|
207 |
+
<input type="hidden" name="submit-checkout" value="1" />
|
208 |
+
<input type="submit" class="pmpro_btn pmpro_btn-submit-checkout" value="<?php if($pmpro_requirebilling) { _e('Submit and Check Out', 'pmpro'); } else { _e('Submit and Confirm', 'pmpro');}?> »" />
|
209 |
+
</span>
|
210 |
+
<?php
|
211 |
+
|
212 |
+
//don't show the default
|
213 |
+
return false;
|
214 |
+
}
|
215 |
+
|
216 |
+
/**
|
217 |
+
* Instead of change membership levels, send users to PayPal to pay.
|
218 |
+
*
|
219 |
+
* @since 1.8
|
220 |
+
*/
|
221 |
+
static function pmpro_checkout_before_change_membership_level($user_id, $morder)
|
222 |
+
{
|
223 |
+
global $discount_code_id, $wpdb;
|
224 |
+
|
225 |
+
//if no order, no need to pay
|
226 |
+
if(empty($morder))
|
227 |
+
return;
|
228 |
+
|
229 |
+
$morder->user_id = $user_id;
|
230 |
+
$morder->saveOrder();
|
231 |
+
|
232 |
+
//save discount code use
|
233 |
+
if(!empty($discount_code_id))
|
234 |
+
$wpdb->query("INSERT INTO $wpdb->pmpro_discount_codes_uses (code_id, user_id, order_id, timestamp) VALUES('" . $discount_code_id . "', '" . $user_id . "', '" . $morder->id . "', now())");
|
235 |
+
|
236 |
+
do_action("pmpro_before_send_to_paypal_standard", $user_id, $morder);
|
237 |
+
|
238 |
+
$morder->Gateway->sendToPayPal($morder);
|
239 |
+
}
|
240 |
+
|
241 |
+
/**
|
242 |
+
* Process checkout.
|
243 |
+
*
|
244 |
+
*/
|
245 |
+
function process(&$order)
|
246 |
+
{
|
247 |
+
if(empty($order->code))
|
248 |
+
$order->code = $order->getRandomCode();
|
249 |
+
|
250 |
+
//clean up a couple values
|
251 |
+
$order->payment_type = "PayPal Standard";
|
252 |
+
$order->CardType = "";
|
253 |
+
$order->cardtype = "";
|
254 |
+
|
255 |
+
//just save, the user will go to PayPal to pay
|
256 |
+
$order->status = "review";
|
257 |
+
$order->saveOrder();
|
258 |
+
|
259 |
+
return true;
|
260 |
+
}
|
261 |
+
|
262 |
+
function sendToPayPal(&$order)
|
263 |
+
{
|
264 |
+
global $pmpro_currency;
|
265 |
+
|
266 |
+
//taxes on initial amount
|
267 |
+
$initial_payment = $order->InitialPayment;
|
268 |
+
$initial_payment_tax = $order->getTaxForPrice($initial_payment);
|
269 |
+
$initial_payment = round((float)$initial_payment + (float)$initial_payment_tax, 2);
|
270 |
+
|
271 |
+
//taxes on the amount
|
272 |
+
$amount = $order->PaymentAmount;
|
273 |
+
$amount_tax = $order->getTaxForPrice($amount);
|
274 |
+
$amount = round((float)$amount + (float)$amount_tax, 2);
|
275 |
+
|
276 |
+
//build PayPal Redirect
|
277 |
+
$environment = pmpro_getOption("gateway_environment");
|
278 |
+
if("sandbox" === $environment || "beta-sandbox" === $environment)
|
279 |
+
$paypal_url ="https://www.sandbox.paypal.com/cgi-bin/webscr?business=" . urlencode(pmpro_getOption("gateway_email"));
|
280 |
+
else
|
281 |
+
$paypal_url = "https://www.paypal.com/cgi-bin/webscr?business=" . urlencode(pmpro_getOption("gateway_email"));
|
282 |
+
|
283 |
+
if(pmpro_isLevelRecurring($order->membership_level))
|
284 |
+
{
|
285 |
+
//convert billing period
|
286 |
+
if($order->BillingPeriod == "Day")
|
287 |
+
$period = "D";
|
288 |
+
elseif($order->BillingPeriod == "Week")
|
289 |
+
$period = "W";
|
290 |
+
elseif($order->BillingPeriod == "Month")
|
291 |
+
$period = "M";
|
292 |
+
elseif($order->BillingPeriod == "Year")
|
293 |
+
$period = "Y";
|
294 |
+
else
|
295 |
+
{
|
296 |
+
$order->error = "Invalid billing period: " . $order->BillingPeriod;
|
297 |
+
$order->shorterror = "Invalid billing period: " . $order->BillingPeriod;
|
298 |
+
return false;
|
299 |
+
}
|
300 |
+
|
301 |
+
//other args
|
302 |
+
$paypal_args = array(
|
303 |
+
'cmd' => '_xclick-subscriptions',
|
304 |
+
'a1' => number_format($initial_payment, 2),
|
305 |
+
'p1' => $order->BillingFrequency,
|
306 |
+
't1' => $period,
|
307 |
+
'a3' => number_format($amount, 2),
|
308 |
+
'p3' => $order->BillingFrequency,
|
309 |
+
't3' => $period,
|
310 |
+
'item_name' => substr($order->membership_level->name . " at " . get_bloginfo("name"), 0, 127),
|
311 |
+
'email' => $order->Email,
|
312 |
+
'no_shipping' => '1',
|
313 |
+
'shipping' => '0',
|
314 |
+
'no_note' => '1',
|
315 |
+
'currency_code' => $pmpro_currency,
|
316 |
+
'item_number' => $order->code,
|
317 |
+
'charset' => get_bloginfo( 'charset' ),
|
318 |
+
'rm' => '2',
|
319 |
+
'return' => pmpro_url("confirmation", "?level=" . $order->membership_level->id),
|
320 |
+
'notify_url' => admin_url("admin-ajax.php") . "?action=ipnhandler",
|
321 |
+
'src' => '1',
|
322 |
+
'sra' => '1',
|
323 |
+
'bn' => PAYPAL_BN_CODE
|
324 |
+
);
|
325 |
+
|
326 |
+
//trial?
|
327 |
+
/*
|
328 |
+
Note here that the TrialBillingCycles value is being ignored. PayPal Standard only offers 1 payment during each trial period.
|
329 |
+
*/
|
330 |
+
if(!empty($order->TrialBillingPeriod))
|
331 |
+
{
|
332 |
+
//if a1 and a2 are 0, let's just combine them. PayPal doesn't like a2 = 0.
|
333 |
+
if($paypal_args['a1'] == 0 && $order->TrialAmount == 0)
|
334 |
+
{
|
335 |
+
$paypal_args['p1'] = $paypal_args['p1'] + $order->TrialBillingFrequency;
|
336 |
+
}
|
337 |
+
else
|
338 |
+
{
|
339 |
+
$trial_amount = $order->TrialAmount;
|
340 |
+
$trial_tax = $order->getTaxForPrice($trial_amount);
|
341 |
+
$trial_amount = round((float)$trial_amount + (float)$trial_tax, 2);
|
342 |
+
|
343 |
+
$paypal_args['a2'] = $trial_amount;
|
344 |
+
$paypal_args['p2'] = $order->TrialBillingFrequency;
|
345 |
+
$paypal_args['t2'] = $period;
|
346 |
+
}
|
347 |
+
}
|
348 |
+
else
|
349 |
+
{
|
350 |
+
//we can try to work in any change in ProfileStartDate
|
351 |
+
$psd = date("Y-m-d", strtotime("+ " . $order->BillingFrequency . " " . $order->BillingPeriod, current_time("timestamp"))) . "T0:0:0";
|
352 |
+
$adjusted_psd = apply_filters("pmpro_profile_start_date", $psd, $order);
|
353 |
+
if($psd != $adjusted_psd)
|
354 |
+
{
|
355 |
+
//someone is trying to push the start date back
|
356 |
+
$adjusted_psd_time = strtotime($adjusted_psd, current_time("timestamp"));
|
357 |
+
$seconds_til_psd = $adjusted_psd_time - current_time('timestamp');
|
358 |
+
$days_til_psd = floor($seconds_til_psd/(60*60*24));
|
359 |
+
|
360 |
+
//push back trial one by days_til_psd
|
361 |
+
if($days_til_psd > 90)
|
362 |
+
{
|
363 |
+
//we need to convert to weeks, because PayPal limits t1 to 90 days
|
364 |
+
$weeks_til_psd = round($days_til_psd / 7);
|
365 |
+
$paypal_args['p1'] = $weeks_til_psd;
|
366 |
+
$paypal_args['t1'] = "W";
|
367 |
+
}
|
368 |
+
elseif($days_til_psd > 0)
|
369 |
+
{
|
370 |
+
//use days
|
371 |
+
$paypal_args['p1'] = $days_til_psd;
|
372 |
+
$paypal_args['t1'] = "D";
|
373 |
+
}
|
374 |
+
}
|
375 |
+
}
|
376 |
+
|
377 |
+
//billing limit?
|
378 |
+
if(!empty($order->TotalBillingCycles))
|
379 |
+
{
|
380 |
+
if(!empty($trial_amount))
|
381 |
+
{
|
382 |
+
|
383 |
+
$srt = intval($order->TotalBillingCycles) - 1; //subtract one for the trial period
|
384 |
+
}
|
385 |
+
else
|
386 |
+
{
|
387 |
+
$srt = intval($order->TotalBillingCycles);
|
388 |
+
}
|
389 |
+
|
390 |
+
//srt must be at least 2 or the subscription is not "recurring" according to paypal
|
391 |
+
if($srt > 1)
|
392 |
+
$paypal_args['srt'] = $srt;
|
393 |
+
else
|
394 |
+
$paypal_args['src'] = '0';
|
395 |
+
}
|
396 |
+
else
|
397 |
+
$paypal_args['srt'] = '0'; //indefinite subscription
|
398 |
+
}
|
399 |
+
else
|
400 |
+
{
|
401 |
+
//other args
|
402 |
+
$paypal_args = array(
|
403 |
+
'cmd' => '_xclick',
|
404 |
+
'amount' => number_format($initial_payment, 2),
|
405 |
+
'item_name' => substr($order->membership_level->name . " at " . get_bloginfo("name"), 0, 127),
|
406 |
+
'email' => $order->Email,
|
407 |
+
'no_shipping' => '1',
|
408 |
+
'shipping' => '0',
|
409 |
+
'no_note' => '1',
|
410 |
+
'currency_code' => $pmpro_currency,
|
411 |
+
'item_number' => $order->code,
|
412 |
+
'charset' => get_bloginfo( 'charset' ),
|
413 |
+
'rm' => '2',
|
414 |
+
'return' => pmpro_url("confirmation", "?level=" . $order->membership_level->id),
|
415 |
+
'notify_url' => admin_url("admin-ajax.php") . "?action=ipnhandler",
|
416 |
+
'bn' => PAYPAL_BN_CODE
|
417 |
+
);
|
418 |
+
}
|
419 |
+
|
420 |
+
$nvpStr = "";
|
421 |
+
foreach($paypal_args as $key => $value)
|
422 |
+
{
|
423 |
+
$nvpStr .= "&" . $key . "=" . urlencode($value);
|
424 |
+
}
|
425 |
+
|
426 |
+
//anything modders might add
|
427 |
+
$additional_parameters = apply_filters("pmpro_paypal_express_return_url_parameters", array());
|
428 |
+
if(!empty($additional_parameters))
|
429 |
+
{
|
430 |
+
foreach($additional_parameters as $key => $value)
|
431 |
+
$nvpStr .= urlencode("&" . $key . "=" . $value);
|
432 |
+
}
|
433 |
+
|
434 |
+
$account_optional = apply_filters('pmpro_paypal_account_optional', true);
|
435 |
+
if ($account_optional)
|
436 |
+
$nvpStr .= '&SOLUTIONTYPE=Sole&LANDINGPAGE=Billing';
|
437 |
+
|
438 |
+
$nvpStr = apply_filters("pmpro_paypal_standard_nvpstr", $nvpStr, $order);
|
439 |
+
|
440 |
+
//redirect to paypal
|
441 |
+
$paypal_url .= $nvpStr;
|
442 |
+
|
443 |
+
//wp_die(str_replace("&", "<br />", $paypal_url));
|
444 |
+
|
445 |
+
wp_redirect($paypal_url);
|
446 |
+
exit;
|
447 |
+
}
|
448 |
+
|
449 |
+
function cancel(&$order)
|
450 |
+
{
|
451 |
+
//paypal profile stuff
|
452 |
+
$nvpStr = "";
|
453 |
+
$nvpStr .= "&PROFILEID=" . urlencode($order->subscription_transaction_id) . "&ACTION=Cancel&NOTE=" . urlencode("User requested cancel.");
|
454 |
+
|
455 |
+
$this->httpParsedResponseAr = $this->PPHttpPost('ManageRecurringPaymentsProfileStatus', $nvpStr);
|
456 |
+
|
457 |
+
if("SUCCESS" == strtoupper($this->httpParsedResponseAr["ACK"]) || "SUCCESSWITHWARNING" == strtoupper($this->httpParsedResponseAr["ACK"]))
|
458 |
+
{
|
459 |
+
$order->updateStatus("cancelled");
|
460 |
+
return true;
|
461 |
+
}
|
462 |
+
else
|
463 |
+
{
|
464 |
+
$order->status = "error";
|
465 |
+
$order->errorcode = $this->httpParsedResponseAr['L_ERRORCODE0'];
|
466 |
+
$order->error = urldecode($this->httpParsedResponseAr['L_LONGMESSAGE0']) . ". " . __("Please contact the site owner or cancel your subscription from within PayPal to make sure you are not charged going forward.", "pmpro");
|
467 |
+
$order->shorterror = urldecode($this->httpParsedResponseAr['L_SHORTMESSAGE0']);
|
468 |
+
|
469 |
+
return false;
|
470 |
+
}
|
471 |
+
}
|
472 |
+
|
473 |
+
/**
|
474 |
+
* PAYPAL Function
|
475 |
+
* Send HTTP POST Request
|
476 |
+
*
|
477 |
+
* @param string The API method name
|
478 |
+
* @param string The POST Message fields in &name=value pair format
|
479 |
+
* @return array Parsed HTTP Response body
|
480 |
+
*/
|
481 |
+
function PPHttpPost($methodName_, $nvpStr_) {
|
482 |
+
global $gateway_environment;
|
483 |
+
$environment = $gateway_environment;
|
484 |
+
|
485 |
+
$API_UserName = pmpro_getOption("apiusername");
|
486 |
+
$API_Password = pmpro_getOption("apipassword");
|
487 |
+
$API_Signature = pmpro_getOption("apisignature");
|
488 |
+
$API_Endpoint = "https://api-3t.paypal.com/nvp";
|
489 |
+
if("sandbox" === $environment || "beta-sandbox" === $environment) {
|
490 |
+
$API_Endpoint = "https://api-3t.$environment.paypal.com/nvp";
|
491 |
+
}
|
492 |
+
|
493 |
+
$version = urlencode('72.0');
|
494 |
+
|
495 |
+
// setting the curl parameters.
|
496 |
+
$ch = curl_init();
|
497 |
+
curl_setopt($ch, CURLOPT_URL, $API_Endpoint);
|
498 |
+
curl_setopt($ch, CURLOPT_VERBOSE, 1);
|
499 |
+
|
500 |
+
// turning off the server and peer verification(TrustManager Concept).
|
501 |
+
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
|
502 |
+
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
|
503 |
+
|
504 |
+
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
|
505 |
+
curl_setopt($ch, CURLOPT_POST, 1);
|
506 |
+
|
507 |
+
// NVPRequest for submitting to server
|
508 |
+
$nvpreq = "METHOD=" . urlencode($methodName_) . "&VERSION=" . urlencode($version) . "&PWD=" . urlencode($API_Password) . "&USER=" . urlencode($API_UserName) . "&SIGNATURE=" . urlencode($API_Signature) . "&bn=" . urlencode(PAYPAL_BN_CODE) . $nvpStr_;
|
509 |
+
|
510 |
+
// setting the nvpreq as POST FIELD to curl
|
511 |
+
curl_setopt($ch, CURLOPT_POSTFIELDS, $nvpreq);
|
512 |
+
|
513 |
+
// getting response from server
|
514 |
+
$httpResponse = curl_exec($ch);
|
515 |
+
|
516 |
+
if(!$httpResponse) {
|
517 |
+
exit("$methodName_ failed: ".curl_error($ch).'('.curl_errno($ch).')');
|
518 |
+
}
|
519 |
+
|
520 |
+
// Extract the RefundTransaction response details
|
521 |
+
$httpResponseAr = explode("&", $httpResponse);
|
522 |
+
|
523 |
+
$httpParsedResponseAr = array();
|
524 |
+
foreach ($httpResponseAr as $i => $value) {
|
525 |
+
$tmpAr = explode("=", $value);
|
526 |
+
if(sizeof($tmpAr) > 1) {
|
527 |
+
$httpParsedResponseAr[$tmpAr[0]] = $tmpAr[1];
|
528 |
+
}
|
529 |
+
}
|
530 |
+
|
531 |
+
if((0 == sizeof($httpParsedResponseAr)) || !array_key_exists('ACK', $httpParsedResponseAr)) {
|
532 |
+
exit("Invalid HTTP Response for POST request($nvpreq) to $API_Endpoint.");
|
533 |
+
}
|
534 |
+
|
535 |
+
return $httpParsedResponseAr;
|
536 |
+
}
|
537 |
+
}
|
classes/gateways/class.pmprogateway_stripe.php
CHANGED
@@ -1,1617 +1,1617 @@
|
|
1 |
-
<?php
|
2 |
-
//include pmprogateway
|
3 |
-
require_once(dirname(__FILE__) . "/class.pmprogateway.php");
|
4 |
-
|
5 |
-
//load classes init method
|
6 |
-
add_action('init', array('PMProGateway_stripe', 'init'));
|
7 |
-
|
8 |
-
/**
|
9 |
-
* PMProGateway_stripe Class
|
10 |
-
*
|
11 |
-
* Handles Stripe integration.
|
12 |
-
*
|
13 |
-
* @since 1.4
|
14 |
-
*/
|
15 |
-
class PMProGateway_stripe extends PMProGateway
|
16 |
-
{
|
17 |
-
/**
|
18 |
-
* Stripe Class Constructor
|
19 |
-
*
|
20 |
-
* @since 1.4
|
21 |
-
*/
|
22 |
-
function PMProGateway_stripe($gateway = NULL)
|
23 |
-
{
|
24 |
-
$this->gateway = $gateway;
|
25 |
-
$this->gateway_environment = pmpro_getOption("gateway_environment");
|
26 |
-
|
27 |
-
$this->loadStripeLibrary();
|
28 |
-
Stripe::setApiKey(pmpro_getOption("stripe_secretkey"));
|
29 |
-
|
30 |
-
return $this->gateway;
|
31 |
-
}
|
32 |
-
|
33 |
-
/**
|
34 |
-
* Load the Stripe API library.
|
35 |
-
*
|
36 |
-
* @since 1.8
|
37 |
-
* Moved into a method in version 1.8 so we only load it when needed.
|
38 |
-
*/
|
39 |
-
function loadStripeLibrary()
|
40 |
-
{
|
41 |
-
//load Stripe library if it hasn't been loaded already (usually by another plugin using Stripe)
|
42 |
-
if(!class_exists("Stripe"))
|
43 |
-
require_once(dirname(__FILE__) . "/../../includes/lib/Stripe/Stripe.php");
|
44 |
-
}
|
45 |
-
|
46 |
-
/**
|
47 |
-
* Run on WP init
|
48 |
-
*
|
49 |
-
* @since 1.8
|
50 |
-
*/
|
51 |
-
static function init()
|
52 |
-
{
|
53 |
-
//make sure Stripe is a gateway option
|
54 |
-
add_filter('pmpro_gateways', array('PMProGateway_stripe', 'pmpro_gateways'));
|
55 |
-
|
56 |
-
//add fields to payment settings
|
57 |
-
add_filter('pmpro_payment_options', array('PMProGateway_stripe', 'pmpro_payment_options'));
|
58 |
-
add_filter('pmpro_payment_option_fields', array('PMProGateway_stripe', 'pmpro_payment_option_fields'), 10, 2);
|
59 |
-
|
60 |
-
//add some fields to edit user page (Updates)
|
61 |
-
add_action('pmpro_after_membership_level_profile_fields', array('PMProGateway_stripe', 'user_profile_fields'));
|
62 |
-
add_action('profile_update', array('PMProGateway_stripe', 'user_profile_fields_save'));
|
63 |
-
|
64 |
-
//old global RE showing billing address or not
|
65 |
-
global $pmpro_stripe_lite;
|
66 |
-
$pmpro_stripe_lite = apply_filters("pmpro_stripe_lite", !pmpro_getOption("stripe_billingaddress")); //default is oposite of the stripe_billingaddress setting
|
67 |
-
|
68 |
-
//updates cron
|
69 |
-
add_action('pmpro_activation', array('PMProGateway_stripe', 'pmpro_activation'));
|
70 |
-
add_action('pmpro_deactivation', array('PMProGateway_stripe', 'pmpro_deactivation'));
|
71 |
-
add_action('pmpro_cron_stripe_subscription_updates', array('PMProGateway_stripe', 'pmpro_cron_stripe_subscription_updates'));
|
72 |
-
|
73 |
-
//code to add at checkout if Stripe is the current gateway
|
74 |
-
$gateway = pmpro_getOption("gateway");
|
75 |
-
if($gateway == "stripe")
|
76 |
-
{
|
77 |
-
add_action('pmpro_checkout_preheader', array('PMProGateway_stripe', 'pmpro_checkout_preheader'));
|
78 |
-
add_filter('pmpro_checkout_order', array('PMProGateway_stripe', 'pmpro_checkout_order'));
|
79 |
-
add_filter('pmpro_include_billing_address_fields', array('PMProGateway_stripe', 'pmpro_include_billing_address_fields'));
|
80 |
-
add_filter('pmpro_include_cardtype_field', array('PMProGateway_stripe', 'pmpro_include_billing_address_fields'));
|
81 |
-
add_filter('pmpro_include_payment_information_fields', array('PMProGateway_stripe', 'pmpro_include_payment_information_fields'));
|
82 |
-
}
|
83 |
-
}
|
84 |
-
|
85 |
-
/**
|
86 |
-
* Make sure Stripe is in the gateways list
|
87 |
-
*
|
88 |
-
* @since 1.8
|
89 |
-
*/
|
90 |
-
static function pmpro_gateways($gateways)
|
91 |
-
{
|
92 |
-
if(empty($gateways['stripe']))
|
93 |
-
$gateways['stripe'] = __('Stripe', 'pmpro');
|
94 |
-
|
95 |
-
return $gateways;
|
96 |
-
}
|
97 |
-
|
98 |
-
/**
|
99 |
-
* Get a list of payment options that the Stripe gateway needs/supports.
|
100 |
-
*
|
101 |
-
* @since 1.8
|
102 |
-
*/
|
103 |
-
static function getGatewayOptions()
|
104 |
-
{
|
105 |
-
$options = array(
|
106 |
-
'sslseal',
|
107 |
-
'nuclear_HTTPS',
|
108 |
-
'gateway_environment',
|
109 |
-
'stripe_secretkey',
|
110 |
-
'stripe_publishablekey',
|
111 |
-
'stripe_billingaddress',
|
112 |
-
'currency',
|
113 |
-
'use_ssl',
|
114 |
-
'tax_state',
|
115 |
-
'tax_rate',
|
116 |
-
'accepted_credit_cards'
|
117 |
-
);
|
118 |
-
|
119 |
-
return $options;
|
120 |
-
}
|
121 |
-
|
122 |
-
/**
|
123 |
-
* Set payment options for payment settings page.
|
124 |
-
*
|
125 |
-
* @since 1.8
|
126 |
-
*/
|
127 |
-
static function pmpro_payment_options($options)
|
128 |
-
{
|
129 |
-
//get stripe options
|
130 |
-
$stripe_options = PMProGateway_stripe::getGatewayOptions();
|
131 |
-
|
132 |
-
//merge with others.
|
133 |
-
$options = array_merge($stripe_options, $options);
|
134 |
-
|
135 |
-
return $options;
|
136 |
-
}
|
137 |
-
|
138 |
-
/**
|
139 |
-
* Display fields for Stripe options.
|
140 |
-
*
|
141 |
-
* @since 1.8
|
142 |
-
*/
|
143 |
-
static function pmpro_payment_option_fields($values, $gateway)
|
144 |
-
{
|
145 |
-
?>
|
146 |
-
<tr class="pmpro_settings_divider gateway gateway_stripe" <?php if($gateway != "stripe") { ?>style="display: none;"<?php } ?>>
|
147 |
-
<td colspan="2">
|
148 |
-
<?php _e('Stripe Settings', 'pmpro'); ?>
|
149 |
-
</td>
|
150 |
-
</tr>
|
151 |
-
<tr class="gateway gateway_stripe" <?php if($gateway != "stripe") { ?>style="display: none;"<?php } ?>>
|
152 |
-
<th scope="row" valign="top">
|
153 |
-
<label for="stripe_secretkey"><?php _e('Secret Key', 'pmpro');?>:</label>
|
154 |
-
</th>
|
155 |
-
<td>
|
156 |
-
<input type="text" id="stripe_secretkey" name="stripe_secretkey" size="60" value="<?php echo esc_attr($values['stripe_secretkey'])?>" />
|
157 |
-
</td>
|
158 |
-
</tr>
|
159 |
-
<tr class="gateway gateway_stripe" <?php if($gateway != "stripe") { ?>style="display: none;"<?php } ?>>
|
160 |
-
<th scope="row" valign="top">
|
161 |
-
<label for="stripe_publishablekey"><?php _e('Publishable Key', 'pmpro');?>:</label>
|
162 |
-
</th>
|
163 |
-
<td>
|
164 |
-
<input type="text" id="stripe_publishablekey" name="stripe_publishablekey" size="60" value="<?php echo esc_attr($values['stripe_publishablekey'])?>" />
|
165 |
-
</td>
|
166 |
-
</tr>
|
167 |
-
<tr class="gateway gateway_stripe" <?php if($gateway != "stripe") { ?>style="display: none;"<?php } ?>>
|
168 |
-
<th scope="row" valign="top">
|
169 |
-
<label for="stripe_billingaddress"><?php _e('Show Billing Address Fields', 'pmpro');?>:</label>
|
170 |
-
</th>
|
171 |
-
<td>
|
172 |
-
<select id="stripe_billingaddress" name="stripe_billingaddress">
|
173 |
-
<option value="0" <?php if(empty($values['stripe_billingaddress'])) { ?>selected="selected"<?php } ?>><?php _e('No', 'pmpro');?></option>
|
174 |
-
<option value="1" <?php if(!empty($values['stripe_billingaddress'])) { ?>selected="selected"<?php } ?>><?php _e('Yes', 'pmpro');?></option>
|
175 |
-
</select>
|
176 |
-
<small><?php _e("Stripe doesn't require billing address fields. Choose 'No' to hide them on the checkout page.<br /><strong>If No, make sure you disable address verification in the Stripe dashboard settings.</strong>", 'pmpro');?></small>
|
177 |
-
</td>
|
178 |
-
</tr>
|
179 |
-
<tr class="gateway gateway_stripe" <?php if($gateway != "stripe") { ?>style="display: none;"<?php } ?>>
|
180 |
-
<th scope="row" valign="top">
|
181 |
-
<label><?php _e('Web Hook URL', 'pmpro');?>:</label>
|
182 |
-
</th>
|
183 |
-
<td>
|
184 |
-
<p><?php _e('To fully integrate with Stripe, be sure to set your Web Hook URL to', 'pmpro');?> <pre><?php echo admin_url("admin-ajax.php") . "?action=stripe_webhook";?></pre></p>
|
185 |
-
</td>
|
186 |
-
</tr>
|
187 |
-
<?php
|
188 |
-
}
|
189 |
-
|
190 |
-
/**
|
191 |
-
* Code added to checkout preheader.
|
192 |
-
*
|
193 |
-
* @since 1.8
|
194 |
-
*/
|
195 |
-
static function pmpro_checkout_preheader()
|
196 |
-
{
|
197 |
-
global $gateway, $pmpro_level;
|
198 |
-
|
199 |
-
if($gateway == "stripe" && !pmpro_isLevelFree($pmpro_level))
|
200 |
-
{
|
201 |
-
//stripe js library
|
202 |
-
wp_enqueue_script("stripe", "https://js.stripe.com/v2/", array(), NULL);
|
203 |
-
|
204 |
-
//stripe js code for checkout
|
205 |
-
function pmpro_stripe_javascript()
|
206 |
-
{
|
207 |
-
global $pmpro_gateway, $pmpro_level, $pmpro_stripe_lite;
|
208 |
-
?>
|
209 |
-
<script type="text/javascript">
|
210 |
-
// this identifies your website in the createToken call below
|
211 |
-
Stripe.setPublishableKey('<?php echo pmpro_getOption("stripe_publishablekey"); ?>');
|
212 |
-
|
213 |
-
var pmpro_require_billing = true;
|
214 |
-
|
215 |
-
jQuery(document).ready(function() {
|
216 |
-
jQuery("#pmpro_form, .pmpro_form").submit(function(event) {
|
217 |
-
|
218 |
-
//double check in case a discount code made the level free
|
219 |
-
if(pmpro_require_billing)
|
220 |
-
{
|
221 |
-
//build array for creating token
|
222 |
-
var args = {
|
223 |
-
number: jQuery('#AccountNumber').val(),
|
224 |
-
cvc: jQuery('#CVV').val(),
|
225 |
-
exp_month: jQuery('#ExpirationMonth').val(),
|
226 |
-
exp_year: jQuery('#ExpirationYear').val()
|
227 |
-
<?php
|
228 |
-
$pmpro_stripe_verify_address = apply_filters("pmpro_stripe_verify_address", pmpro_getOption('stripe_billingaddress'));
|
229 |
-
if(!empty($pmpro_stripe_verify_address))
|
230 |
-
{
|
231 |
-
?>
|
232 |
-
,address_line1: jQuery('#baddress1').val(),
|
233 |
-
address_line2: jQuery('#baddress2').val(),
|
234 |
-
address_city: jQuery('#bcity').val(),
|
235 |
-
address_state: jQuery('#bstate').val(),
|
236 |
-
address_zip: jQuery('#bzipcode').val(),
|
237 |
-
address_country: jQuery('#bcountry').val()
|
238 |
-
<?php
|
239 |
-
}
|
240 |
-
?>
|
241 |
-
};
|
242 |
-
|
243 |
-
if (jQuery('#bfirstname').length && jQuery('#blastname').length)
|
244 |
-
args['name'] = jQuery.trim(jQuery('#bfirstname').val() + ' ' + jQuery('#blastname').val());
|
245 |
-
|
246 |
-
//create token
|
247 |
-
Stripe.createToken(args, stripeResponseHandler);
|
248 |
-
|
249 |
-
// prevent the form from submitting with the default action
|
250 |
-
return false;
|
251 |
-
}
|
252 |
-
else
|
253 |
-
return true; //not using Stripe anymore
|
254 |
-
});
|
255 |
-
});
|
256 |
-
|
257 |
-
function stripeResponseHandler(status, response) {
|
258 |
-
if (response.error) {
|
259 |
-
// re-enable the submit button
|
260 |
-
jQuery('.pmpro_btn-submit-checkout').removeAttr("disabled");
|
261 |
-
|
262 |
-
//hide processing message
|
263 |
-
jQuery('#pmpro_processing_message').css('visibility', 'hidden');
|
264 |
-
|
265 |
-
// show the errors on the form
|
266 |
-
alert(response.error.message);
|
267 |
-
jQuery(".payment-errors").text(response.error.message);
|
268 |
-
} else {
|
269 |
-
var form$ = jQuery("#pmpro_form, .pmpro_form");
|
270 |
-
// token contains id, last4, and card type
|
271 |
-
var token = response['id'];
|
272 |
-
// insert the token into the form so it gets submitted to the server
|
273 |
-
form$.append("<input type='hidden' name='stripeToken' value='" + token + "'/>");
|
274 |
-
|
275 |
-
console.log(response);
|
276 |
-
|
277 |
-
//insert fields for other card fields
|
278 |
-
if(jQuery('#CardType[name=CardType]').length)
|
279 |
-
jQuery('#CardType').val(response['card']['brand']);
|
280 |
-
else
|
281 |
-
form$.append("<input type='hidden' name='CardType' value='" + response['card']['brand'] + "'/>");
|
282 |
-
form$.append("<input type='hidden' name='AccountNumber' value='XXXXXXXXXXXXX" + response['card']['last4'] + "'/>");
|
283 |
-
form$.append("<input type='hidden' name='ExpirationMonth' value='" + ("0" + response['card']['exp_month']).slice(-2) + "'/>");
|
284 |
-
form$.append("<input type='hidden' name='ExpirationYear' value='" + response['card']['exp_year'] + "'/>");
|
285 |
-
|
286 |
-
// and submit
|
287 |
-
form$.get(0).submit();
|
288 |
-
}
|
289 |
-
}
|
290 |
-
</script>
|
291 |
-
<?php
|
292 |
-
}
|
293 |
-
add_action("wp_head", "pmpro_stripe_javascript");
|
294 |
-
|
295 |
-
//don't require the CVV
|
296 |
-
function pmpro_stripe_dont_require_CVV($fields)
|
297 |
-
{
|
298 |
-
unset($fields['CVV']);
|
299 |
-
return $fields;
|
300 |
-
}
|
301 |
-
add_filter("pmpro_required_billing_fields", "pmpro_stripe_dont_require_CVV");
|
302 |
-
}
|
303 |
-
}
|
304 |
-
|
305 |
-
/**
|
306 |
-
* Filtering orders at checkout.
|
307 |
-
*
|
308 |
-
* @since 1.8
|
309 |
-
*/
|
310 |
-
static function pmpro_checkout_order($morder)
|
311 |
-
{
|
312 |
-
//load up token values
|
313 |
-
if(isset($_REQUEST['stripeToken']))
|
314 |
-
{
|
315 |
-
$morder->stripeToken = $_REQUEST['stripeToken'];
|
316 |
-
}
|
317 |
-
|
318 |
-
//stripe lite code to get name from other sources if available
|
319 |
-
global $pmpro_stripe_lite, $current_user;
|
320 |
-
if(!empty($pmpro_stripe_lite) && empty($morder->FirstName) && empty($morder->LastName))
|
321 |
-
{
|
322 |
-
if(!empty($current_user->ID))
|
323 |
-
{
|
324 |
-
$morder->FirstName = get_user_meta($current_user->ID, "first_name", true);
|
325 |
-
$morder->LastName = get_user_meta($current_user->ID, "last_name", true);
|
326 |
-
}
|
327 |
-
elseif(!empty($_REQUEST['first_name']) && !empty($_REQUEST['last_name']))
|
328 |
-
{
|
329 |
-
$morder->FirstName = $_REQUEST['first_name'];
|
330 |
-
$morder->LastName = $_REQUEST['last_name'];
|
331 |
-
}
|
332 |
-
}
|
333 |
-
|
334 |
-
return $morder;
|
335 |
-
}
|
336 |
-
|
337 |
-
/**
|
338 |
-
* Code to run after checkout
|
339 |
-
*
|
340 |
-
* @since 1.8
|
341 |
-
*/
|
342 |
-
static function pmpro_after_checkout($user_id, $morder)
|
343 |
-
{
|
344 |
-
global $gateway;
|
345 |
-
|
346 |
-
if($gateway == "stripe")
|
347 |
-
{
|
348 |
-
if(!empty($morder) && !empty($morer->Gateway) && !empty($morder->Gateway->customer) && !empty($morder->Gateway->customer->id))
|
349 |
-
{
|
350 |
-
update_user_meta($user_id, "pmpro_stripe_customerid", $morder->Gateway->customer->id);
|
351 |
-
}
|
352 |
-
}
|
353 |
-
}
|
354 |
-
|
355 |
-
/**
|
356 |
-
* Check settings if billing address should be shown.
|
357 |
-
* @since 1.8
|
358 |
-
*/
|
359 |
-
static function pmpro_include_billing_address_fields($include)
|
360 |
-
{
|
361 |
-
//check settings RE showing billing address
|
362 |
-
if(!pmpro_getOption("stripe_billingaddress"))
|
363 |
-
$include = false;
|
364 |
-
|
365 |
-
return $include;
|
366 |
-
}
|
367 |
-
|
368 |
-
/**
|
369 |
-
* Use our own payment fields at checkout. (Remove the name attributes.)
|
370 |
-
* @since 1.8
|
371 |
-
*/
|
372 |
-
static function pmpro_include_payment_information_fields($include)
|
373 |
-
{
|
374 |
-
//global vars
|
375 |
-
global $pmpro_requirebilling, $pmpro_show_discount_code, $discount_code, $CardType, $AccountNumber, $ExpirationMonth, $ExpirationYear;
|
376 |
-
|
377 |
-
//get accepted credit cards
|
378 |
-
$pmpro_accepted_credit_cards = pmpro_getOption("accepted_credit_cards");
|
379 |
-
$pmpro_accepted_credit_cards = explode(",", $pmpro_accepted_credit_cards);
|
380 |
-
$pmpro_accepted_credit_cards_string = pmpro_implodeToEnglish($pmpro_accepted_credit_cards);
|
381 |
-
|
382 |
-
//include ours
|
383 |
-
?>
|
384 |
-
<table id="pmpro_payment_information_fields" class="pmpro_checkout top1em" width="100%" cellpadding="0" cellspacing="0" border="0" <?php if(!$pmpro_requirebilling || apply_filters("pmpro_hide_payment_information_fields", false) ) { ?>style="display: none;"<?php } ?>>
|
385 |
-
<thead>
|
386 |
-
<tr>
|
387 |
-
<th><span class="pmpro_thead-msg"><?php printf(__('We Accept %s', 'pmpro'), $pmpro_accepted_credit_cards_string);?></span><?php _e('Payment Information', 'pmpro');?></th>
|
388 |
-
</tr>
|
389 |
-
</thead>
|
390 |
-
<tbody>
|
391 |
-
<tr valign="top">
|
392 |
-
<td>
|
393 |
-
<?php
|
394 |
-
$sslseal = pmpro_getOption("sslseal");
|
395 |
-
if($sslseal)
|
396 |
-
{
|
397 |
-
?>
|
398 |
-
<div class="pmpro_sslseal"><?php echo stripslashes($sslseal)?></div>
|
399 |
-
<?php
|
400 |
-
}
|
401 |
-
?>
|
402 |
-
<?php
|
403 |
-
$pmpro_include_cardtype_field = apply_filters('pmpro_include_cardtype_field', false);
|
404 |
-
if($pmpro_include_cardtype_field)
|
405 |
-
{
|
406 |
-
?>
|
407 |
-
<div class="pmpro_payment-card-type">
|
408 |
-
<label for="CardType"><?php _e('Card Type', 'pmpro');?></label>
|
409 |
-
<select id="CardType" class=" <?php echo pmpro_getClassForField("CardType");?>">
|
410 |
-
<?php foreach($pmpro_accepted_credit_cards as $cc) { ?>
|
411 |
-
<option value="<?php echo $cc?>" <?php if($CardType == $cc) { ?>selected="selected"<?php } ?>><?php echo $cc?></option>
|
412 |
-
<?php } ?>
|
413 |
-
</select>
|
414 |
-
</div>
|
415 |
-
<?php
|
416 |
-
}
|
417 |
-
else
|
418 |
-
{
|
419 |
-
?>
|
420 |
-
<input type="hidden" id="CardType" name="CardType" value="<?php echo esc_attr($CardType);?>" />
|
421 |
-
<script>
|
422 |
-
jQuery(document).ready(function() {
|
423 |
-
jQuery('#AccountNumber').validateCreditCard(function(result) {
|
424 |
-
var cardtypenames = {
|
425 |
-
"amex":"American Express",
|
426 |
-
"diners_club_carte_blanche":"Diners Club Carte Blanche",
|
427 |
-
"diners_club_international":"Diners Club International",
|
428 |
-
"discover":"Discover",
|
429 |
-
"jcb":"JCB",
|
430 |
-
"laser":"Laser",
|
431 |
-
"maestro":"Maestro",
|
432 |
-
"mastercard":"Mastercard",
|
433 |
-
"visa":"Visa",
|
434 |
-
"visa_electron":"Visa Electron"
|
435 |
-
}
|
436 |
-
|
437 |
-
if(result.card_type)
|
438 |
-
jQuery('#CardType').val(cardtypenames[result.card_type.name]);
|
439 |
-
else
|
440 |
-
jQuery('#CardType').val('Unknown Card Type');
|
441 |
-
});
|
442 |
-
});
|
443 |
-
</script>
|
444 |
-
<?php
|
445 |
-
}
|
446 |
-
?>
|
447 |
-
|
448 |
-
<div class="pmpro_payment-account-number">
|
449 |
-
<label for="AccountNumber"><?php _e('Card Number', 'pmpro');?></label>
|
450 |
-
<input id="AccountNumber" class="input <?php echo pmpro_getClassForField("AccountNumber");?>" type="text" size="25" value="<?php echo esc_attr($AccountNumber)?>" autocomplete="off" />
|
451 |
-
</div>
|
452 |
-
|
453 |
-
<div class="pmpro_payment-expiration">
|
454 |
-
<label for="ExpirationMonth"><?php _e('Expiration Date', 'pmpro');?></label>
|
455 |
-
<select id="ExpirationMonth" class=" <?php echo pmpro_getClassForField("ExpirationMonth");?>">
|
456 |
-
<option value="01" <?php if($ExpirationMonth == "01") { ?>selected="selected"<?php } ?>>01</option>
|
457 |
-
<option value="02" <?php if($ExpirationMonth == "02") { ?>selected="selected"<?php } ?>>02</option>
|
458 |
-
<option value="03" <?php if($ExpirationMonth == "03") { ?>selected="selected"<?php } ?>>03</option>
|
459 |
-
<option value="04" <?php if($ExpirationMonth == "04") { ?>selected="selected"<?php } ?>>04</option>
|
460 |
-
<option value="05" <?php if($ExpirationMonth == "05") { ?>selected="selected"<?php } ?>>05</option>
|
461 |
-
<option value="06" <?php if($ExpirationMonth == "06") { ?>selected="selected"<?php } ?>>06</option>
|
462 |
-
<option value="07" <?php if($ExpirationMonth == "07") { ?>selected="selected"<?php } ?>>07</option>
|
463 |
-
<option value="08" <?php if($ExpirationMonth == "08") { ?>selected="selected"<?php } ?>>08</option>
|
464 |
-
<option value="09" <?php if($ExpirationMonth == "09") { ?>selected="selected"<?php } ?>>09</option>
|
465 |
-
<option value="10" <?php if($ExpirationMonth == "10") { ?>selected="selected"<?php } ?>>10</option>
|
466 |
-
<option value="11" <?php if($ExpirationMonth == "11") { ?>selected="selected"<?php } ?>>11</option>
|
467 |
-
<option value="12" <?php if($ExpirationMonth == "12") { ?>selected="selected"<?php } ?>>12</option>
|
468 |
-
</select>/<select id="ExpirationYear" class=" <?php echo pmpro_getClassForField("ExpirationYear");?>">
|
469 |
-
<?php
|
470 |
-
for($i = date("Y"); $i < date("Y") + 10; $i++)
|
471 |
-
{
|
472 |
-
?>
|
473 |
-
<option value="<?php echo $i?>" <?php if($ExpirationYear == $i) { ?>selected="selected"<?php } ?>><?php echo $i?></option>
|
474 |
-
<?php
|
475 |
-
}
|
476 |
-
?>
|
477 |
-
</select>
|
478 |
-
</div>
|
479 |
-
|
480 |
-
<?php
|
481 |
-
$pmpro_show_cvv = apply_filters("pmpro_show_cvv", true);
|
482 |
-
if($pmpro_show_cvv)
|
483 |
-
{
|
484 |
-
?>
|
485 |
-
<div class="pmpro_payment-cvv">
|
486 |
-
<label for="CVV"><?php _ex('CVV', 'Credit card security code, CVV/CCV/CVV2', 'pmpro');?></label>
|
487 |
-
<input class="input" id="CVV" type="text" size="4" value="<?php if(!empty($_REQUEST['CVV'])) { echo esc_attr($_REQUEST['CVV']); }?>" class=" <?php echo pmpro_getClassForField("CVV");?>" /> <small>(<a href="javascript:void(0);" onclick="javascript:window.open('<?php echo pmpro_https_filter(PMPRO_URL)?>/pages/popup-cvv.html','cvv','toolbar=no, location=no, directories=no, status=no, menubar=no, scrollbars=yes, resizable=yes, width=600, height=475');"><?php _ex("what's this?", 'link to CVV help', 'pmpro');?></a>)</small>
|
488 |
-
</div>
|
489 |
-
<?php
|
490 |
-
}
|
491 |
-
?>
|
492 |
-
|
493 |
-
<?php if($pmpro_show_discount_code) { ?>
|
494 |
-
<div class="pmpro_payment-discount-code">
|
495 |
-
<label for="discount_code"><?php _e('Discount Code', 'pmpro');?></label>
|
496 |
-
<input class="input <?php echo pmpro_getClassForField("discount_code");?>" id="discount_code" name="discount_code" type="text" size="20" value="<?php echo esc_attr($discount_code)?>" />
|
497 |
-
<input type="button" id="discount_code_button" name="discount_code_button" value="<?php _e('Apply', 'pmpro');?>" />
|
498 |
-
<p id="discount_code_message" class="pmpro_message" style="display: none;"></p>
|
499 |
-
</div>
|
500 |
-
<?php } ?>
|
501 |
-
|
502 |
-
</td>
|
503 |
-
</tr>
|
504 |
-
</tbody>
|
505 |
-
</table>
|
506 |
-
<?php
|
507 |
-
|
508 |
-
//don't include the default
|
509 |
-
return false;
|
510 |
-
}
|
511 |
-
|
512 |
-
/**
|
513 |
-
* Fields shown on edit user page
|
514 |
-
*
|
515 |
-
* @since 1.8
|
516 |
-
*/
|
517 |
-
static function user_profile_fields($user)
|
518 |
-
{
|
519 |
-
global $wpdb, $current_user, $pmpro_currency_symbol;
|
520 |
-
|
521 |
-
$cycles = array( __('Day(s)', 'pmpro') => 'Day', __('Week(s)', 'pmpro') => 'Week', __('Month(s)', 'pmpro') => 'Month', __('Year(s)', 'pmpro') => 'Year' );
|
522 |
-
$current_year = date("Y");
|
523 |
-
$current_month = date("m");
|
524 |
-
|
525 |
-
//make sure the current user has privileges
|
526 |
-
$membership_level_capability = apply_filters("pmpro_edit_member_capability", "manage_options");
|
527 |
-
if(!current_user_can($membership_level_capability))
|
528 |
-
return false;
|
529 |
-
|
530 |
-
//more privelges they should have
|
531 |
-
$show_membership_level = apply_filters("pmpro_profile_show_membership_level", true, $user);
|
532 |
-
if(!$show_membership_level)
|
533 |
-
return false;
|
534 |
-
|
535 |
-
//check that user has a current subscription at Stripe
|
536 |
-
$last_order = new MemberOrder();
|
537 |
-
$last_order->getLastMemberOrder($user->ID);
|
538 |
-
|
539 |
-
//assume no sub to start
|
540 |
-
$sub = false;
|
541 |
-
|
542 |
-
//check that gateway is Stripe
|
543 |
-
if($last_order->gateway == "stripe")
|
544 |
-
{
|
545 |
-
//is there a customer?
|
546 |
-
$sub = $last_order->Gateway->getSubscription($last_order);
|
547 |
-
}
|
548 |
-
|
549 |
-
$customer_id = $user->pmpro_stripe_customerid;
|
550 |
-
|
551 |
-
if(empty($sub))
|
552 |
-
{
|
553 |
-
//make sure we delete stripe updates
|
554 |
-
update_user_meta($user->ID, "pmpro_stripe_updates", array());
|
555 |
-
|
556 |
-
//if the last order has a sub id, let the admin know there is no sub at Stripe
|
557 |
-
if(!empty($last_order) && $last_order->gateway == "stripe" && !empty($last_order->subscription_transaction_id) && strpos($last_order->subscription_transaction_id, "sub_") !== false)
|
558 |
-
{
|
559 |
-
?>
|
560 |
-
<p><strong>Note:</strong> Subscription <strong><?php echo $last_order->subscription_transaction_id;?></strong> could not be found at Stripe. It might have been deleted.</p>
|
561 |
-
<?php
|
562 |
-
}
|
563 |
-
}
|
564 |
-
else
|
565 |
-
{
|
566 |
-
?>
|
567 |
-
<h3><?php _e("Subscription Updates", "pmpro"); ?></h3>
|
568 |
-
<p>
|
569 |
-
<?php
|
570 |
-
if(empty($_REQUEST['user_id']))
|
571 |
-
_e("Subscription updates, allow you to change the member's subscription values at predefined times. Be sure to click Update Profile after making changes.", 'pmpro');
|
572 |
-
else
|
573 |
-
_e("Subscription updates, allow you to change the member's subscription values at predefined times. Be sure to click Update User after making changes.", 'pmpro');
|
574 |
-
?>
|
575 |
-
</p>
|
576 |
-
<table class="form-table">
|
577 |
-
<tr>
|
578 |
-
<th><label for="membership_level"><?php _e("Update", "pmpro"); ?></label></th>
|
579 |
-
<td id="updates_td">
|
580 |
-
<?php
|
581 |
-
$old_updates = $user->pmpro_stripe_updates;
|
582 |
-
if(is_array($old_updates))
|
583 |
-
{
|
584 |
-
$updates = array_merge(
|
585 |
-
array(array('template'=>true, 'when'=>'now', 'date_month'=>'', 'date_day'=>'', 'date_year'=>'', 'billing_amount'=>'', 'cycle_number'=>'', 'cycle_period'=>'Month')),
|
586 |
-
$old_updates
|
587 |
-
);
|
588 |
-
}
|
589 |
-
else
|
590 |
-
$updates = array(array('template'=>true, 'when'=>'now', 'date_month'=>'', 'date_day'=>'', 'date_year'=>'', 'billing_amount'=>'', 'cycle_number'=>'', 'cycle_period'=>'Month'));
|
591 |
-
|
592 |
-
foreach($updates as $update)
|
593 |
-
{
|
594 |
-
?>
|
595 |
-
<div class="updates_update" <?php if(!empty($update['template'])) { ?>style="display: none;"<?php } ?>>
|
596 |
-
<select class="updates_when" name="updates_when[]">
|
597 |
-
<option value="now" <?php selected($update['when'], "now");?>>Now</option>
|
598 |
-
<option value="payment" <?php selected($update['when'], "payment");?>>After Next Payment</option>
|
599 |
-
<option value="date" <?php selected($update['when'], "date");?>>On Date</option>
|
600 |
-
</select>
|
601 |
-
<span class="updates_date" <?php if($uwhen != "date") { ?>style="display: none;"<?php } ?>>
|
602 |
-
<select name="updates_date_month[]">
|
603 |
-
<?php
|
604 |
-
for($i = 1; $i < 13; $i++)
|
605 |
-
{
|
606 |
-
?>
|
607 |
-
<option value="<?php echo str_pad($i, 2, "0", STR_PAD_LEFT);?>" <?php if(!empty($update['date_month']) && $update['date_month'] == $i) { ?>selected="selected"<?php } ?>>
|
608 |
-
<?php echo date("M", strtotime($i . "/1/" . $current_year));?>
|
609 |
-
</option>
|
610 |
-
<?php
|
611 |
-
}
|
612 |
-
?>
|
613 |
-
</select>
|
614 |
-
<input name="updates_date_day[]" type="text" size="2" value="<?php if(!empty($update['date_day'])) echo esc_attr($update['date_day']);?>" />
|
615 |
-
<input name="updates_date_year[]" type="text" size="4" value="<?php if(!empty($update['date_year'])) echo esc_attr($update['date_year']);?>" />
|
616 |
-
</span>
|
617 |
-
<span class="updates_billing" <?php if($uwhen == "no") { ?>style="display: none;"<?php } ?>>
|
618 |
-
<?php echo $pmpro_currency_symbol?><input name="updates_billing_amount[]" type="text" size="10" value="<?php echo esc_attr($update['billing_amount']);?>" />
|
619 |
-
<small><?php _e('per', 'pmpro');?></small>
|
620 |
-
<input name="updates_cycle_number[]" type="text" size="5" value="<?php echo esc_attr($update['cycle_number']);?>" />
|
621 |
-
<select name="updates_cycle_period[]">
|
622 |
-
<?php
|
623 |
-
foreach ( $cycles as $name => $value ) {
|
624 |
-
echo "<option value='$value'";
|
625 |
-
if(!empty($update['cycle_period']) && $update['cycle_period'] == $value) echo " selected='selected'";
|
626 |
-
echo ">$name</option>";
|
627 |
-
}
|
628 |
-
?>
|
629 |
-
</select>
|
630 |
-
</span>
|
631 |
-
<span>
|
632 |
-
<a class="updates_remove" href="javascript:void(0);">Remove</a>
|
633 |
-
</span>
|
634 |
-
</div>
|
635 |
-
<?php
|
636 |
-
}
|
637 |
-
?>
|
638 |
-
<p><a id="updates_new_update" href="javascript:void(0);">+ New Update</a></p>
|
639 |
-
</td>
|
640 |
-
</tr>
|
641 |
-
</table>
|
642 |
-
<script>
|
643 |
-
jQuery(document).ready(function() {
|
644 |
-
//function to update dropdowns/etc based on when field
|
645 |
-
function updateSubscriptionUpdateFields(when)
|
646 |
-
{
|
647 |
-
if(jQuery(when).val() == 'date')
|
648 |
-
jQuery(when).parent().children('.updates_date').show();
|
649 |
-
else
|
650 |
-
jQuery(when).parent().children('.updates_date').hide();
|
651 |
-
|
652 |
-
if(jQuery(when).val() == 'no')
|
653 |
-
jQuery(when).parent().children('.updates_billing').hide();
|
654 |
-
else
|
655 |
-
jQuery(when).parent().children('.updates_billing').show();
|
656 |
-
}
|
657 |
-
|
658 |
-
//and update on page load
|
659 |
-
jQuery('.updates_when').each(function() { if(jQuery(this).parent().css('display') != 'none') updateSubscriptionUpdateFields(this); });
|
660 |
-
|
661 |
-
//add a new update when clicking to
|
662 |
-
var num_updates_divs = <?php echo count($updates);?>;
|
663 |
-
jQuery('#updates_new_update').click(function() {
|
664 |
-
//get updates
|
665 |
-
updates = jQuery('.updates_update').toArray();
|
666 |
-
|
667 |
-
//clone the first one
|
668 |
-
new_div = jQuery(updates[0]).clone();
|
669 |
-
|
670 |
-
//append
|
671 |
-
new_div.insertBefore('#updates_new_update');
|
672 |
-
|
673 |
-
//update events
|
674 |
-
addUpdateEvents()
|
675 |
-
|
676 |
-
//unhide it
|
677 |
-
new_div.show();
|
678 |
-
updateSubscriptionUpdateFields(new_div.children('.updates_when'));
|
679 |
-
});
|
680 |
-
|
681 |
-
function addUpdateEvents()
|
682 |
-
{
|
683 |
-
//update when when changes
|
684 |
-
jQuery('.updates_when').change(function() {
|
685 |
-
updateSubscriptionUpdateFields(this);
|
686 |
-
});
|
687 |
-
|
688 |
-
//remove updates when clicking
|
689 |
-
jQuery('.updates_remove').click(function() {
|
690 |
-
jQuery(this).parent().parent().remove();
|
691 |
-
});
|
692 |
-
}
|
693 |
-
addUpdateEvents();
|
694 |
-
});
|
695 |
-
</script>
|
696 |
-
<?php
|
697 |
-
}
|
698 |
-
}
|
699 |
-
|
700 |
-
/**
|
701 |
-
* Process fields from the edit user page
|
702 |
-
*
|
703 |
-
* @since 1.8
|
704 |
-
*/
|
705 |
-
static function user_profile_fields_save($user_id)
|
706 |
-
{
|
707 |
-
global $wpdb;
|
708 |
-
|
709 |
-
//check capabilities
|
710 |
-
$membership_level_capability = apply_filters("pmpro_edit_member_capability", "manage_options");
|
711 |
-
if(!current_user_can($membership_level_capability))
|
712 |
-
return false;
|
713 |
-
|
714 |
-
//make sure some value was passed
|
715 |
-
if(!isset($_POST['updates_when']) || !is_array($_POST['updates_when']))
|
716 |
-
return;
|
717 |
-
|
718 |
-
//vars
|
719 |
-
$updates = array();
|
720 |
-
$next_on_date_update = "";
|
721 |
-
|
722 |
-
//build array of updates (we skip the first because it's the template field for the JavaScript
|
723 |
-
for($i = 1; $i < count($_POST['updates_when']); $i++)
|
724 |
-
{
|
725 |
-
$update = array();
|
726 |
-
|
727 |
-
//all updates have these values
|
728 |
-
$update['when'] = $_POST['updates_when'][$i];
|
729 |
-
$update['billing_amount'] = $_POST['updates_billing_amount'][$i];
|
730 |
-
$update['cycle_number'] = $_POST['updates_cycle_number'][$i];
|
731 |
-
$update['cycle_period'] = $_POST['updates_cycle_period'][$i];
|
732 |
-
|
733 |
-
//these values only for on date updates
|
734 |
-
if($_POST['updates_when'][$i] == "date")
|
735 |
-
{
|
736 |
-
$update['date_month'] = str_pad($_POST['updates_date_month'][$i], 2, "0", STR_PAD_LEFT);
|
737 |
-
$update['date_day'] = str_pad($_POST['updates_date_day'][$i], 2, "0", STR_PAD_LEFT);
|
738 |
-
$update['date_year'] = $_POST['updates_date_year'][$i];
|
739 |
-
}
|
740 |
-
|
741 |
-
//make sure the update is valid
|
742 |
-
if(empty($update['cycle_number']))
|
743 |
-
continue;
|
744 |
-
|
745 |
-
//if when is now, update the subscription
|
746 |
-
if($update['when'] == "now")
|
747 |
-
{
|
748 |
-
//get level for user
|
749 |
-
$user_level = pmpro_getMembershipLevelForUser($user_id);
|
750 |
-
|
751 |
-
//get current plan at Stripe to get payment date
|
752 |
-
$last_order = new MemberOrder();
|
753 |
-
$last_order->getLastMemberOrder($user_id);
|
754 |
-
$last_order->setGateway('stripe');
|
755 |
-
$last_order->Gateway->getCustomer($last_order);
|
756 |
-
|
757 |
-
$subscription = $last_order->Gateway->getSubscription($last_order);
|
758 |
-
|
759 |
-
if(!empty($subscription))
|
760 |
-
{
|
761 |
-
$end_timestamp = $subscription->current_period_end;
|
762 |
-
|
763 |
-
//cancel the old subscription
|
764 |
-
if(!$last_order->Gateway->cancelSubscriptionAtGateway($subscription))
|
765 |
-
{
|
766 |
-
//throw error and halt save
|
767 |
-
function pmpro_stripe_user_profile_fields_save_error($errors, $update, $user)
|
768 |
-
{
|
769 |
-
$errors->add('pmpro_stripe_updates',__('Could not cancel the old subscription. Updates have not been processed.', 'pmpro'));
|
770 |
-
}
|
771 |
-
add_filter('user_profile_update_errors', 'pmpro_stripe_user_profile_fields_save_error', 10, 3);
|
772 |
-
|
773 |
-
//stop processing updates
|
774 |
-
return;
|
775 |
-
}
|
776 |
-
}
|
777 |
-
|
778 |
-
//if we didn't get an end date, let's set one one cycle out
|
779 |
-
if(empty($end_timestamp))
|
780 |
-
$end_timestamp = strtotime("+" . $update['cycle_number'] . " " . $update['cycle_period'], current_time('timestamp'));
|
781 |
-
|
782 |
-
//build order object
|
783 |
-
$update_order = new MemberOrder();
|
784 |
-
$update_order->setGateway('stripe');
|
785 |
-
$update_order->user_id = $user_id;
|
786 |
-
$update_order->membership_id = $user_level->id;
|
787 |
-
$update_order->membership_name = $user_level->name;
|
788 |
-
$update_order->InitialPayment = 0;
|
789 |
-
$update_order->PaymentAmount = $update['billing_amount'];
|
790 |
-
$update_order->ProfileStartDate = date("Y-m-d", $end_timestamp);
|
791 |
-
$update_order->BillingPeriod = $update['cycle_period'];
|
792 |
-
$update_order->BillingFrequency = $update['cycle_number'];
|
793 |
-
|
794 |
-
//need filter to reset ProfileStartDate
|
795 |
-
add_filter('pmpro_profile_start_date', create_function('$startdate, $order', 'return "' . $update_order->ProfileStartDate . 'T0:0:0";'), 10, 2);
|
796 |
-
|
797 |
-
//update subscription
|
798 |
-
$update_order->Gateway->subscribe($update_order, false);
|
799 |
-
|
800 |
-
//update membership
|
801 |
-
$sqlQuery = "UPDATE $wpdb->pmpro_memberships_users
|
802 |
-
SET billing_amount = '" . esc_sql($update['billing_amount']) . "',
|
803 |
-
cycle_number = '" . esc_sql($update['cycle_number']) . "',
|
804 |
-
cycle_period = '" . esc_sql($update['cycle_period']) . "',
|
805 |
-
trial_amount = '',
|
806 |
-
trial_limit = ''
|
807 |
-
WHERE user_id = '" . esc_sql($user_id) . "'
|
808 |
-
AND membership_id = '" . esc_sql($last_order->membership_id) . "'
|
809 |
-
AND status = 'active'
|
810 |
-
LIMIT 1";
|
811 |
-
|
812 |
-
$wpdb->query($sqlQuery);
|
813 |
-
|
814 |
-
//save order so we know which plan to look for at stripe (order code = plan id)
|
815 |
-
$update_order->status = "success";
|
816 |
-
$update_order->saveOrder();
|
817 |
-
|
818 |
-
continue;
|
819 |
-
}
|
820 |
-
elseif($update['when'] == 'date')
|
821 |
-
{
|
822 |
-
if(!empty($next_on_date_update))
|
823 |
-
$next_on_date_update = min($next_on_date_update, $update['date_year'] . "-" . $update['date_month'] . "-" . $update['date_day']);
|
824 |
-
else
|
825 |
-
$next_on_date_update = $update['date_year'] . "-" . $update['date_month'] . "-" . $update['date_day'];
|
826 |
-
}
|
827 |
-
|
828 |
-
//add to array
|
829 |
-
$updates[] = $update;
|
830 |
-
}
|
831 |
-
|
832 |
-
//save in user meta
|
833 |
-
update_user_meta($user_id, "pmpro_stripe_updates", $updates);
|
834 |
-
|
835 |
-
//save date of next on-date update to make it easier to query for these in cron job
|
836 |
-
update_user_meta($user_id, "pmpro_stripe_next_on_date_update", $next_on_date_update);
|
837 |
-
}
|
838 |
-
|
839 |
-
/**
|
840 |
-
* Cron activation for subscription updates.
|
841 |
-
*
|
842 |
-
* @since 1.8
|
843 |
-
*/
|
844 |
-
static function pmpro_activation()
|
845 |
-
{
|
846 |
-
wp_schedule_event(time(), 'daily', 'pmpro_cron_stripe_subscription_updates');
|
847 |
-
}
|
848 |
-
|
849 |
-
/**
|
850 |
-
* Cron deactivation for subscription updates.
|
851 |
-
*
|
852 |
-
* @since 1.8
|
853 |
-
*/
|
854 |
-
static function pmpro_deactivation()
|
855 |
-
{
|
856 |
-
wp_clear_scheduled_hook('pmpro_cron_stripe_subscription_updates');
|
857 |
-
}
|
858 |
-
|
859 |
-
/**
|
860 |
-
* Cron job for subscription updates.
|
861 |
-
*
|
862 |
-
* @since 1.8
|
863 |
-
*/
|
864 |
-
static function pmpro_cron_stripe_subscription_updates()
|
865 |
-
{
|
866 |
-
global $wpdb;
|
867 |
-
|
868 |
-
//get all updates for today (or before today)
|
869 |
-
$sqlQuery = "SELECT *
|
870 |
-
FROM $wpdb->usermeta
|
871 |
-
WHERE meta_key = 'pmpro_stripe_next_on_date_update'
|
872 |
-
AND meta_value IS NOT NULL
|
873 |
-
AND meta_value <> ''
|
874 |
-
AND meta_value < '" . date("Y-m-d", strtotime("+1 day")) . "'";
|
875 |
-
$updates = $wpdb->get_results($sqlQuery);
|
876 |
-
|
877 |
-
if(!empty($updates))
|
878 |
-
{
|
879 |
-
//loop through
|
880 |
-
foreach($updates as $update)
|
881 |
-
{
|
882 |
-
//pull values from update
|
883 |
-
$user_id = $update->user_id;
|
884 |
-
|
885 |
-
$user = get_userdata($user_id);
|
886 |
-
|
887 |
-
//if user is missing, delete the update info and continue
|
888 |
-
if(empty($user) || empty($user->ID))
|
889 |
-
{
|
890 |
-
delete_user_meta($user_id, "pmpro_stripe_updates");
|
891 |
-
delete_user_meta($user_id, "pmpro_stripe_next_on_date_update");
|
892 |
-
|
893 |
-
continue;
|
894 |
-
}
|
895 |
-
|
896 |
-
$user_updates = $user->pmpro_stripe_updates;
|
897 |
-
$next_on_date_update = "";
|
898 |
-
|
899 |
-
//loop through updates looking for updates happening today or earlier
|
900 |
-
if(!empty($user_updates))
|
901 |
-
{
|
902 |
-
foreach($user_updates as $key => $update)
|
903 |
-
{
|
904 |
-
if($update['when'] == 'date' &&
|
905 |
-
$update['date_year'] . "-" . $update['date_month'] . "-" . $update['date_day'] <= date("Y-m-d")
|
906 |
-
)
|
907 |
-
{
|
908 |
-
//get level for user
|
909 |
-
$user_level = pmpro_getMembershipLevelForUser($user_id);
|
910 |
-
|
911 |
-
//get current plan at Stripe to get payment date
|
912 |
-
$last_order = new MemberOrder();
|
913 |
-
$last_order->getLastMemberOrder($user_id);
|
914 |
-
$last_order->setGateway('stripe');
|
915 |
-
$last_order->Gateway->getCustomer($last_order);
|
916 |
-
|
917 |
-
if(!empty($last_order->Gateway->customer))
|
918 |
-
{
|
919 |
-
//find the first subscription
|
920 |
-
if(!empty($last_order->Gateway->customer->subscriptions['data'][0]))
|
921 |
-
{
|
922 |
-
$first_sub = $last_order->Gateway->customer->subscriptions['data'][0]->__toArray();
|
923 |
-
$end_timestamp = $first_sub['current_period_end'];
|
924 |
-
}
|
925 |
-
}
|
926 |
-
|
927 |
-
//if we didn't get an end date, let's set one one cycle out
|
928 |
-
$end_timestamp = strtotime("+" . $update['cycle_number'] . " " . $update['cycle_period']);
|
929 |
-
|
930 |
-
//build order object
|
931 |
-
$update_order = new MemberOrder();
|
932 |
-
$update_order->setGateway('stripe');
|
933 |
-
$update_order->user_id = $user_id;
|
934 |
-
$update_order->membership_id = $user_level->id;
|
935 |
-
$update_order->membership_name = $user_level->name;
|
936 |
-
$update_order->InitialPayment = 0;
|
937 |
-
$update_order->PaymentAmount = $update['billing_amount'];
|
938 |
-
$update_order->ProfileStartDate = date("Y-m-d", $end_timestamp);
|
939 |
-
$update_order->BillingPeriod = $update['cycle_period'];
|
940 |
-
$update_order->BillingFrequency = $update['cycle_number'];
|
941 |
-
|
942 |
-
//update subscription
|
943 |
-
$update_order->Gateway->subscribe($update_order, false);
|
944 |
-
|
945 |
-
//update membership
|
946 |
-
$sqlQuery = "UPDATE $wpdb->pmpro_memberships_users
|
947 |
-
SET billing_amount = '" . esc_sql($update['billing_amount']) . "',
|
948 |
-
cycle_number = '" . esc_sql($update['cycle_number']) . "',
|
949 |
-
cycle_period = '" . esc_sql($update['cycle_period']) . "'
|
950 |
-
WHERE user_id = '" . esc_sql($user_id) . "'
|
951 |
-
AND membership_id = '" . esc_sql($last_order->membership_id) . "'
|
952 |
-
AND status = 'active'
|
953 |
-
LIMIT 1";
|
954 |
-
|
955 |
-
$wpdb->query($sqlQuery);
|
956 |
-
|
957 |
-
//save order
|
958 |
-
$update_order->status = "success";
|
959 |
-
$update_order->save();
|
960 |
-
|
961 |
-
//remove update from list
|
962 |
-
unset($user_updates[$key]);
|
963 |
-
}
|
964 |
-
elseif($update['when'] == 'date')
|
965 |
-
{
|
966 |
-
//this is an on date update for the future, update the next on date update
|
967 |
-
if(!empty($next_on_date_update))
|
968 |
-
$next_on_date_update = min($next_on_date_update, $update['date_year'] . "-" . $update['date_month'] . "-" . $update['date_day']);
|
969 |
-
else
|
970 |
-
$next_on_date_update = $update['date_year'] . "-" . $update['date_month'] . "-" . $update['date_day'];
|
971 |
-
}
|
972 |
-
}
|
973 |
-
}
|
974 |
-
|
975 |
-
//save updates in case we removed some
|
976 |
-
update_user_meta($user_id, "pmpro_stripe_updates", $user_updates);
|
977 |
-
|
978 |
-
//save date of next on-date update to make it easier to query for these in cron job
|
979 |
-
update_user_meta($user_id, "pmpro_stripe_next_on_date_update", $next_on_date_update);
|
980 |
-
}
|
981 |
-
}
|
982 |
-
}
|
983 |
-
|
984 |
-
/**
|
985 |
-
* Process checkout and decide if a charge and or subscribe is needed
|
986 |
-
*
|
987 |
-
* @since 1.4
|
988 |
-
*/
|
989 |
-
function process(&$order)
|
990 |
-
{
|
991 |
-
//check for initial payment
|
992 |
-
if(floatval($order->InitialPayment) == 0)
|
993 |
-
{
|
994 |
-
//just subscribe
|
995 |
-
return $this->subscribe($order);
|
996 |
-
}
|
997 |
-
else
|
998 |
-
{
|
999 |
-
//charge then subscribe
|
1000 |
-
if($this->charge($order))
|
1001 |
-
{
|
1002 |
-
if(pmpro_isLevelRecurring($order->membership_level))
|
1003 |
-
{
|
1004 |
-
if($this->subscribe($order))
|
1005 |
-
{
|
1006 |
-
//yay!
|
1007 |
-
return true;
|
1008 |
-
}
|
1009 |
-
else
|
1010 |
-
{
|
1011 |
-
//try to refund initial charge
|
1012 |
-
return false;
|
1013 |
-
}
|
1014 |
-
}
|
1015 |
-
else
|
1016 |
-
{
|
1017 |
-
//only a one time charge
|
1018 |
-
$order->status = "success"; //saved on checkout page
|
1019 |
-
return true;
|
1020 |
-
}
|
1021 |
-
}
|
1022 |
-
else
|
1023 |
-
{
|
1024 |
-
if(empty($order->error))
|
1025 |
-
$order->error = __("Unknown error: Initial payment failed.", "pmpro");
|
1026 |
-
return false;
|
1027 |
-
}
|
1028 |
-
}
|
1029 |
-
}
|
1030 |
-
|
1031 |
-
/**
|
1032 |
-
* Make a one-time charge with Stripe
|
1033 |
-
*
|
1034 |
-
* @since 1.4
|
1035 |
-
*/
|
1036 |
-
function charge(&$order)
|
1037 |
-
{
|
1038 |
-
global $pmpro_currency;
|
1039 |
-
|
1040 |
-
//create a code for the order
|
1041 |
-
if(empty($order->code))
|
1042 |
-
$order->code = $order->getRandomCode();
|
1043 |
-
|
1044 |
-
//what amount to charge?
|
1045 |
-
$amount = $order->InitialPayment;
|
1046 |
-
|
1047 |
-
//tax
|
1048 |
-
$order->subtotal = $amount;
|
1049 |
-
$tax = $order->getTax(true);
|
1050 |
-
$amount = round((float)$order->subtotal + (float)$tax, 2);
|
1051 |
-
|
1052 |
-
//create a customer
|
1053 |
-
$result = $this->getCustomer($order);
|
1054 |
-
|
1055 |
-
if(empty($result))
|
1056 |
-
{
|
1057 |
-
//failed to create customer
|
1058 |
-
return false;
|
1059 |
-
}
|
1060 |
-
|
1061 |
-
//charge
|
1062 |
-
try
|
1063 |
-
{
|
1064 |
-
$response = Stripe_Charge::create(array(
|
1065 |
-
"amount" => $amount * 100, # amount in cents, again
|
1066 |
-
"currency" => strtolower($pmpro_currency),
|
1067 |
-
"customer" => $this->customer->id,
|
1068 |
-
"description" => "Order #" . $order->code . ", " . trim($order->FirstName . " " . $order->LastName) . " (" . $order->Email . ")"
|
1069 |
-
)
|
1070 |
-
);
|
1071 |
-
}
|
1072 |
-
catch (Exception $e)
|
1073 |
-
{
|
1074 |
-
//$order->status = "error";
|
1075 |
-
$order->errorcode = true;
|
1076 |
-
$order->error = "Error: " . $e->getMessage();
|
1077 |
-
$order->shorterror = $order->error;
|
1078 |
-
return false;
|
1079 |
-
}
|
1080 |
-
|
1081 |
-
if(empty($response["failure_message"]))
|
1082 |
-
{
|
1083 |
-
//successful charge
|
1084 |
-
$order->payment_transaction_id = $response["id"];
|
1085 |
-
$order->updateStatus("success");
|
1086 |
-
$order->saveOrder();
|
1087 |
-
return true;
|
1088 |
-
}
|
1089 |
-
else
|
1090 |
-
{
|
1091 |
-
//$order->status = "error";
|
1092 |
-
$order->errorcode = true;
|
1093 |
-
$order->error = $response['failure_message'];
|
1094 |
-
$order->shorterror = $response['failure_message'];
|
1095 |
-
return false;
|
1096 |
-
}
|
1097 |
-
}
|
1098 |
-
|
1099 |
-
/**
|
1100 |
-
* Get a Stripe customer object.
|
1101 |
-
*
|
1102 |
-
* If $this->customer is set, it returns it.
|
1103 |
-
* It first checks if the order has a subscription_transaction_id. If so, that's the customer id.
|
1104 |
-
* If not, it checks for a user_id on the order and searches for a customer id in the user meta.
|
1105 |
-
* If a customer id is found, it checks for a customer through the Stripe API.
|
1106 |
-
* If a customer is found and there is a stripeToken on the order passed, it will update the customer.
|
1107 |
-
* If no customer is found and there is a stripeToken on the order passed, it will create a customer.
|
1108 |
-
*
|
1109 |
-
* @since 1.4
|
1110 |
-
* @return Stripe_Customer|false
|
1111 |
-
*/
|
1112 |
-
function getCustomer(&$order = false, $force = false)
|
1113 |
-
{
|
1114 |
-
global $current_user;
|
1115 |
-
|
1116 |
-
//already have it?
|
1117 |
-
if(!empty($this->customer) && !$force)
|
1118 |
-
return $this->customer;
|
1119 |
-
|
1120 |
-
//figure out user_id and user
|
1121 |
-
if(!empty($order->user_id))
|
1122 |
-
$user_id = $order->user_id;
|
1123 |
-
|
1124 |
-
//if no id passed, check the current user
|
1125 |
-
if(empty($user_id) && !empty($current_user->ID))
|
1126 |
-
$user_id = $current_user->ID;
|
1127 |
-
|
1128 |
-
if(!empty($user_id))
|
1129 |
-
$user = get_userdata($user_id);
|
1130 |
-
else
|
1131 |
-
$user = NULL;
|
1132 |
-
|
1133 |
-
//transaction id?
|
1134 |
-
if(!empty($order->subscription_transaction_id) && strpos($order->subscription_transaction_id, "cus_") !== false)
|
1135 |
-
$customer_id = $order->subscription_transaction_id;
|
1136 |
-
else
|
1137 |
-
{
|
1138 |
-
//try based on user id
|
1139 |
-
if(!empty($user_id))
|
1140 |
-
{
|
1141 |
-
$customer_id = get_user_meta($user_id, "pmpro_stripe_customerid", true);
|
1142 |
-
}
|
1143 |
-
}
|
1144 |
-
|
1145 |
-
//get name and email values from order in case we update
|
1146 |
-
$name = trim($order->FirstName . " " . $order->LastName);
|
1147 |
-
if(empty($name) && !empty($user->ID))
|
1148 |
-
{
|
1149 |
-
$name = trim($user->first_name . " " . $user->last_name);
|
1150 |
-
|
1151 |
-
//still empty?
|
1152 |
-
if(empty($name))
|
1153 |
-
$name = $user->user_login;
|
1154 |
-
}
|
1155 |
-
elseif(empty($name))
|
1156 |
-
$name = "No Name";
|
1157 |
-
|
1158 |
-
$email = $order->Email;
|
1159 |
-
if(empty($email) && !empty($user->ID))
|
1160 |
-
{
|
1161 |
-
$email = $user->user_email;
|
1162 |
-
}
|
1163 |
-
elseif(empty($email))
|
1164 |
-
$email = "No Email";
|
1165 |
-
|
1166 |
-
//check for an existing stripe customer
|
1167 |
-
if(!empty($customer_id))
|
1168 |
-
{
|
1169 |
-
try
|
1170 |
-
{
|
1171 |
-
$this->customer = Stripe_Customer::retrieve($customer_id);
|
1172 |
-
|
1173 |
-
//update the customer description and card
|
1174 |
-
if(!empty($order->stripeToken))
|
1175 |
-
{
|
1176 |
-
$this->customer->description = $name . " (" . $email . ")";
|
1177 |
-
$this->customer->email = $email;
|
1178 |
-
$this->customer->card = $order->stripeToken;
|
1179 |
-
$this->customer->save();
|
1180 |
-
}
|
1181 |
-
|
1182 |
-
return $this->customer;
|
1183 |
-
}
|
1184 |
-
catch (Exception $e)
|
1185 |
-
{
|
1186 |
-
//assume no customer found
|
1187 |
-
}
|
1188 |
-
}
|
1189 |
-
|
1190 |
-
//no customer id, create one
|
1191 |
-
if(!empty($order->stripeToken))
|
1192 |
-
{
|
1193 |
-
try
|
1194 |
-
{
|
1195 |
-
$this->customer = Stripe_Customer::create(array(
|
1196 |
-
"description" =>
|
1197 |
-
"email" => $order->Email,
|
1198 |
-
"card" => $order->stripeToken
|
1199 |
-
));
|
1200 |
-
}
|
1201 |
-
catch (Exception $e)
|
1202 |
-
{
|
1203 |
-
$order->error = __("Error creating customer record with Stripe:", "pmpro") . " " . $e->getMessage();
|
1204 |
-
$order->shorterror = $order->error;
|
1205 |
-
return false;
|
1206 |
-
}
|
1207 |
-
|
1208 |
-
if(!empty($user_id))
|
1209 |
-
{
|
1210 |
-
//user logged in/etc
|
1211 |
-
update_user_meta($user_id, "pmpro_stripe_customerid", $this->customer->id);
|
1212 |
-
}
|
1213 |
-
else
|
1214 |
-
{
|
1215 |
-
//user not registered yet, queue it up
|
1216 |
-
global $pmpro_stripe_customer_id;
|
1217 |
-
$pmpro_stripe_customer_id = $this->customer->id;
|
1218 |
-
function pmpro_user_register_stripe_customerid($user_id)
|
1219 |
-
{
|
1220 |
-
global $pmpro_stripe_customer_id;
|
1221 |
-
update_user_meta($user_id, "pmpro_stripe_customerid", $pmpro_stripe_customer_id);
|
1222 |
-
}
|
1223 |
-
add_action("user_register", "pmpro_user_register_stripe_customerid");
|
1224 |
-
}
|
1225 |
-
|
1226 |
-
return apply_filters('pmpro_stripe_create_customer', $this->customer);
|
1227 |
-
}
|
1228 |
-
|
1229 |
-
return false;
|
1230 |
-
}
|
1231 |
-
|
1232 |
-
/**
|
1233 |
-
* Get a Stripe subscription from a PMPro order
|
1234 |
-
*
|
1235 |
-
* @since 1.8
|
1236 |
-
*/
|
1237 |
-
function getSubscription(&$order)
|
1238 |
-
{
|
1239 |
-
global $wpdb;
|
1240 |
-
|
1241 |
-
//no order?
|
1242 |
-
if(empty($order) || empty($order->code))
|
1243 |
-
return false;
|
1244 |
-
|
1245 |
-
$result = $this->getCustomer($order, true); //force so we don't get a cached sub for someone else
|
1246 |
-
|
1247 |
-
//no customer?
|
1248 |
-
if(empty($result))
|
1249 |
-
return false;
|
1250 |
-
|
1251 |
-
//is there a subscription transaction id pointing to a sub?
|
1252 |
-
if(!empty($order->subscription_transaction_id) && strpos($order->subscription_transaction_id, "sub_") !== false)
|
1253 |
-
{
|
1254 |
-
try
|
1255 |
-
{
|
1256 |
-
$sub = $this->customer->subscriptions->retrieve($order->subscription_transaction_id);
|
1257 |
-
}
|
1258 |
-
catch (Exception $e)
|
1259 |
-
{
|
1260 |
-
$order->error = __("Error creating plan with Stripe:", "pmpro") . $e->getMessage();
|
1261 |
-
$order->shorterror = $order->error;
|
1262 |
-
return false;
|
1263 |
-
}
|
1264 |
-
|
1265 |
-
return $sub;
|
1266 |
-
}
|
1267 |
-
|
1268 |
-
//no subscriptions object in customer
|
1269 |
-
if(empty($this->customer->subscriptions))
|
1270 |
-
return false;
|
1271 |
-
|
1272 |
-
//find subscription based on customer id and order/plan id
|
1273 |
-
$subscriptions = $this->customer->subscriptions->all();
|
1274 |
-
|
1275 |
-
//no subscriptions
|
1276 |
-
if(empty($subscriptions) || empty($subscriptions->data))
|
1277 |
-
return false;
|
1278 |
-
|
1279 |
-
//we really want to test against the order codes of all orders with the same subscription_transaction_id (customer id)
|
1280 |
-
$codes = $wpdb->get_col("SELECT code FROM $wpdb->pmpro_membership_orders WHERE user_id = '" . $order->user_id . "' AND subscription_transaction_id = '" . $order->subscription_transaction_id . "' AND status NOT IN('refunded', 'review', 'token', 'error')");
|
1281 |
-
|
1282 |
-
//find the one for this order
|
1283 |
-
foreach($subscriptions->data as $sub)
|
1284 |
-
{
|
1285 |
-
if(in_array($sub->plan->id, $codes))
|
1286 |
-
{
|
1287 |
-
return $sub;
|
1288 |
-
}
|
1289 |
-
}
|
1290 |
-
|
1291 |
-
//didn't find anything yet
|
1292 |
-
return false;
|
1293 |
-
}
|
1294 |
-
|
1295 |
-
/**
|
1296 |
-
* Create a new subscription with Stripe
|
1297 |
-
*
|
1298 |
-
* @since 1.4
|
1299 |
-
*/
|
1300 |
-
function subscribe(&$order, $checkout = true)
|
1301 |
-
{
|
1302 |
-
global $pmpro_currency;
|
1303 |
-
|
1304 |
-
//create a code for the order
|
1305 |
-
if(empty($order->code))
|
1306 |
-
$order->code = $order->getRandomCode();
|
1307 |
-
|
1308 |
-
//filter order before subscription. use with care.
|
1309 |
-
$order = apply_filters("pmpro_subscribe_order", $order, $this);
|
1310 |
-
|
1311 |
-
//figure out the user
|
1312 |
-
if(!empty($order->user_id))
|
1313 |
-
$user_id = $order->user_id;
|
1314 |
-
else
|
1315 |
-
{
|
1316 |
-
global $current_user;
|
1317 |
-
$user_id = $current_user->ID;
|
1318 |
-
}
|
1319 |
-
|
1320 |
-
//setup customer
|
1321 |
-
$result = $this->getCustomer($order);
|
1322 |
-
if(empty($result))
|
1323 |
-
return false; //error retrieving customer
|
1324 |
-
|
1325 |
-
//set subscription id to custom id
|
1326 |
-
$order->subscription_transaction_id = $this->customer['id']; //transaction id is the customer id, we save it in user meta later too
|
1327 |
-
|
1328 |
-
//figure out the amounts
|
1329 |
-
$amount = $order->PaymentAmount;
|
1330 |
-
$amount_tax = $order->getTaxForPrice($amount);
|
1331 |
-
$amount = round((float)$amount + (float)$amount_tax, 2);
|
1332 |
-
|
1333 |
-
/*
|
1334 |
-
There are two parts to the trial. Part 1 is simply the delay until the first payment
|
1335 |
-
since we are doing the first payment as a separate transaction.
|
1336 |
-
The second part is the actual "trial" set by the admin.
|
1337 |
-
|
1338 |
-
Stripe only supports Year or Month for billing periods, but we account for Days and Weeks just in case.
|
1339 |
-
*/
|
1340 |
-
//figure out the trial length (first payment handled by initial charge)
|
1341 |
-
if($order->BillingPeriod == "Year")
|
1342 |
-
$trial_period_days = $order->BillingFrequency * 365; //annual
|
1343 |
-
elseif($order->BillingPeriod == "Day")
|
1344 |
-
$trial_period_days = $order->BillingFrequency * 1; //daily
|
1345 |
-
elseif($order->BillingPeriod == "Week")
|
1346 |
-
$trial_period_days = $order->BillingFrequency * 7; //weekly
|
1347 |
-
else
|
1348 |
-
$trial_period_days = $order->BillingFrequency * 30; //assume monthly
|
1349 |
-
|
1350 |
-
//convert to a profile start date
|
1351 |
-
$order->ProfileStartDate = date("Y-m-d", strtotime("+ " . $trial_period_days . " Day", current_time("timestamp"))) . "T0:0:0";
|
1352 |
-
|
1353 |
-
//filter the start date
|
1354 |
-
$order->ProfileStartDate = apply_filters("pmpro_profile_start_date", $order->ProfileStartDate, $order);
|
1355 |
-
|
1356 |
-
//convert back to days
|
1357 |
-
$trial_period_days = ceil(abs(strtotime(date("Y-m-d"), current_time("timestamp")) - strtotime($order->ProfileStartDate, current_time("timestamp"))) / 86400);
|
1358 |
-
|
1359 |
-
//for free trials, just push the start date of the subscription back
|
1360 |
-
if(!empty($order->TrialBillingCycles) && $order->TrialAmount == 0)
|
1361 |
-
{
|
1362 |
-
$trialOccurrences = (int)$order->TrialBillingCycles;
|
1363 |
-
if($order->BillingPeriod == "Year")
|
1364 |
-
$trial_period_days = $trial_period_days + (365 * $order->BillingFrequency * $trialOccurrences); //annual
|
1365 |
-
elseif($order->BillingPeriod == "Day")
|
1366 |
-
$trial_period_days = $trial_period_days + (1 * $order->BillingFrequency * $trialOccurrences); //daily
|
1367 |
-
elseif($order->BillingPeriod == "Week")
|
1368 |
-
$trial_period_days = $trial_period_days + (7 * $order->BillingFrequency * $trialOccurrences); //weekly
|
1369 |
-
else
|
1370 |
-
$trial_period_days = $trial_period_days + (30 * $order->BillingFrequency * $trialOccurrences); //assume monthly
|
1371 |
-
}
|
1372 |
-
elseif(!empty($order->TrialBillingCycles))
|
1373 |
-
{
|
1374 |
-
/*
|
1375 |
-
Let's set the subscription to the trial and give the user an "update" to change the sub later to full price (since v2.0)
|
1376 |
-
|
1377 |
-
This will force TrialBillingCycles > 1 to act as if they were 1
|
1378 |
-
*/
|
1379 |
-
$new_user_updates = array();
|
1380 |
-
$new_user_updates[] = array(
|
1381 |
-
'when' => 'payment',
|
1382 |
-
'billing_amount' => $order->PaymentAmount,
|
1383 |
-
'cycle_period' => $order->BillingPeriod,
|
1384 |
-
'cycle_number' => $order->BillingFrequency
|
1385 |
-
);
|
1386 |
-
|
1387 |
-
//now amount to equal the trial #s
|
1388 |
-
$amount = $order->TrialAmount;
|
1389 |
-
$amount_tax = $order->getTaxForPrice($amount);
|
1390 |
-
$amount = round((float)$amount + (float)$amount_tax, 2);
|
1391 |
-
}
|
1392 |
-
|
1393 |
-
//create a plan
|
1394 |
-
try
|
1395 |
-
{
|
1396 |
-
$plan = array(
|
1397 |
-
"amount" => $amount * 100,
|
1398 |
-
"interval_count" => $order->BillingFrequency,
|
1399 |
-
"interval" => strtolower($order->BillingPeriod),
|
1400 |
-
"trial_period_days" => $trial_period_days,
|
1401 |
-
"name" => $order->membership_name . " for order " . $order->code,
|
1402 |
-
"currency" => strtolower($pmpro_currency),
|
1403 |
-
"id" => $order->code
|
1404 |
-
);
|
1405 |
-
|
1406 |
-
$plan = Stripe_Plan::create(apply_filters('pmpro_stripe_create_plan_array', $plan));
|
1407 |
-
}
|
1408 |
-
catch (Exception $e)
|
1409 |
-
{
|
1410 |
-
$order->error = __("Error creating plan with Stripe:", "pmpro") . $e->getMessage();
|
1411 |
-
$order->shorterror = $order->error;
|
1412 |
-
return false;
|
1413 |
-
}
|
1414 |
-
|
1415 |
-
//before subscribing, let's clear out the updates so we don't trigger any during sub
|
1416 |
-
if(!empty($user_id))
|
1417 |
-
{
|
1418 |
-
$old_user_updates = get_user_meta($user_id, "pmpro_stripe_updates", true);
|
1419 |
-
update_user_meta($user_id, "pmpro_stripe_updates", array());
|
1420 |
-
}
|
1421 |
-
|
1422 |
-
if(empty($order->subscription_transaction_id) && !empty($this->customer['id']))
|
1423 |
-
$order->subscription_transaction_id = $this->customer['id'];
|
1424 |
-
|
1425 |
-
//subscribe to the plan
|
1426 |
-
try
|
1427 |
-
{
|
1428 |
-
$subscription = array("plan" => $order->code);
|
1429 |
-
$result = $this->customer->subscriptions->create(apply_filters('pmpro_stripe_create_subscription_array', $subscription));
|
1430 |
-
}
|
1431 |
-
catch (Exception $e)
|
1432 |
-
{
|
1433 |
-
//try to delete the plan
|
1434 |
-
$plan->delete();
|
1435 |
-
|
1436 |
-
//give the user any old updates back
|
1437 |
-
if(!empty($user_id))
|
1438 |
-
update_user_meta($user_id, "pmpro_stripe_updates", $old_user_updates);
|
1439 |
-
|
1440 |
-
//return error
|
1441 |
-
$order->error = __("Error subscribing customer to plan with Stripe:", "pmpro") . $e->getMessage();
|
1442 |
-
$order->shorterror = $order->error;
|
1443 |
-
return false;
|
1444 |
-
}
|
1445 |
-
|
1446 |
-
//delete the plan
|
1447 |
-
$plan = Stripe_Plan::retrieve($order->code);
|
1448 |
-
$plan->delete();
|
1449 |
-
|
1450 |
-
//if we got this far, we're all good
|
1451 |
-
$order->status = "success";
|
1452 |
-
$order->subscription_transaction_id = $result['id'];
|
1453 |
-
|
1454 |
-
//save new updates if this is at checkout
|
1455 |
-
if($checkout)
|
1456 |
-
{
|
1457 |
-
//empty out updates unless set above
|
1458 |
-
if(empty($new_user_updates))
|
1459 |
-
$new_user_updates = array();
|
1460 |
-
|
1461 |
-
//update user meta
|
1462 |
-
if(!empty($user_id))
|
1463 |
-
update_user_meta($user_id, "pmpro_stripe_updates", $new_user_updates);
|
1464 |
-
else
|
1465 |
-
{
|
1466 |
-
//need to remember the user updates to save later
|
1467 |
-
global $pmpro_stripe_updates;
|
1468 |
-
$pmpro_stripe_updates = $new_user_updates;
|
1469 |
-
function pmpro_user_register_stripe_updates($user_id)
|
1470 |
-
{
|
1471 |
-
global $pmpro_stripe_updates;
|
1472 |
-
update_user_meta($user_id, "pmpro_stripe_updates", $pmpro_stripe_updates);
|
1473 |
-
}
|
1474 |
-
add_action("user_register", "pmpro_user_register_stripe_updates");
|
1475 |
-
}
|
1476 |
-
}
|
1477 |
-
else
|
1478 |
-
{
|
1479 |
-
//give them their old updates back
|
1480 |
-
update_user_meta($user_id, "pmpro_stripe_updates", $old_user_updates);
|
1481 |
-
}
|
1482 |
-
|
1483 |
-
return true;
|
1484 |
-
}
|
1485 |
-
|
1486 |
-
/**
|
1487 |
-
* Helper method to update the customer info via getCustomer
|
1488 |
-
*
|
1489 |
-
* @since 1.4
|
1490 |
-
*/
|
1491 |
-
function update(&$order)
|
1492 |
-
{
|
1493 |
-
//we just have to run getCustomer which will look for the customer and update it with the new token
|
1494 |
-
$result = $this->getCustomer($order);
|
1495 |
-
|
1496 |
-
if(!empty($result))
|
1497 |
-
{
|
1498 |
-
return true;
|
1499 |
-
}
|
1500 |
-
else
|
1501 |
-
{
|
1502 |
-
return false; //couldn't find the customer
|
1503 |
-
}
|
1504 |
-
}
|
1505 |
-
|
1506 |
-
/**
|
1507 |
-
* Cancel a subscription at Stripe
|
1508 |
-
*
|
1509 |
-
* @since 1.4
|
1510 |
-
*/
|
1511 |
-
function cancel(&$order, $update_status = true)
|
1512 |
-
{
|
1513 |
-
//no matter what happens below, we're going to cancel the order in our system
|
1514 |
-
if($update_status)
|
1515 |
-
$order->updateStatus("cancelled");
|
1516 |
-
|
1517 |
-
//require a subscription id
|
1518 |
-
if(empty($order->subscription_transaction_id))
|
1519 |
-
return false;
|
1520 |
-
|
1521 |
-
//find the customer
|
1522 |
-
$result = $this->getCustomer($order);
|
1523 |
-
|
1524 |
-
if(!empty($result))
|
1525 |
-
{
|
1526 |
-
//find subscription with this order code
|
1527 |
-
$subscription = $this->getSubscription($order);
|
1528 |
-
|
1529 |
-
if(!empty($subscription))
|
1530 |
-
{
|
1531 |
-
if($this->cancelSubscriptionAtGateway($subscription))
|
1532 |
-
{
|
1533 |
-
//we're okay, going to return true later
|
1534 |
-
}
|
1535 |
-
else
|
1536 |
-
{
|
1537 |
-
$order->error = __("Could not cancel old subscription.", "pmpro");
|
1538 |
-
$order->shorterror = $order->error;
|
1539 |
-
|
1540 |
-
return false;
|
1541 |
-
}
|
1542 |
-
}
|
1543 |
-
|
1544 |
-
/*
|
1545 |
-
Clear updates for this user. (But not if checking out, we would have already done that.)
|
1546 |
-
*/
|
1547 |
-
if(empty($_REQUEST['submit-checkout']))
|
1548 |
-
update_user_meta($order->user_id, "pmpro_stripe_updates", array());
|
1549 |
-
|
1550 |
-
return true;
|
1551 |
-
}
|
1552 |
-
else
|
1553 |
-
{
|
1554 |
-
$order->error = __("Could not find the customer.", "pmpro");
|
1555 |
-
$order->shorterror = $order->error;
|
1556 |
-
return false; //no customer found
|
1557 |
-
}
|
1558 |
-
}
|
1559 |
-
|
1560 |
-
/**
|
1561 |
-
* Helper method to cancel a subscription at Stripe and also clear up any upaid invoices.
|
1562 |
-
*
|
1563 |
-
* @since 1.8
|
1564 |
-
*/
|
1565 |
-
function cancelSubscriptionAtGateway($subscription)
|
1566 |
-
{
|
1567 |
-
//need a valid sub
|
1568 |
-
if(empty($subscription->id))
|
1569 |
-
return false;
|
1570 |
-
|
1571 |
-
//make sure we get the customer for this subscription
|
1572 |
-
$order = new MemberOrder();
|
1573 |
-
$order->getLastMemberOrderBySubscriptionTransactionID($subscription->id);
|
1574 |
-
|
1575 |
-
//no order?
|
1576 |
-
if(empty($order))
|
1577 |
-
{
|
1578 |
-
//lets cancel anyway, but this is suspicious
|
1579 |
-
$r = $subscription->cancel();
|
1580 |
-
|
1581 |
-
return true;
|
1582 |
-
}
|
1583 |
-
|
1584 |
-
//okay have an order, so get customer so we can cancel invoices too
|
1585 |
-
$this->getCustomer($order);
|
1586 |
-
|
1587 |
-
//get open invoices
|
1588 |
-
$invoices = $this->customer->invoices();
|
1589 |
-
$invoices = $invoices->all();
|
1590 |
-
|
1591 |
-
//found it, cancel it
|
1592 |
-
try
|
1593 |
-
{
|
1594 |
-
//find any open invoices for this subscription and forgive them
|
1595 |
-
if(!empty($invoices))
|
1596 |
-
{
|
1597 |
-
foreach($invoices->data as $invoice)
|
1598 |
-
{
|
1599 |
-
if(!$invoice->closed && $invoice->subscription == $subscription->id)
|
1600 |
-
{
|
1601 |
-
$invoice->closed = true;
|
1602 |
-
$invoice->save();
|
1603 |
-
}
|
1604 |
-
}
|
1605 |
-
}
|
1606 |
-
|
1607 |
-
//cancel
|
1608 |
-
$r = $subscription->cancel();
|
1609 |
-
|
1610 |
-
return true;
|
1611 |
-
}
|
1612 |
-
catch(Exception $e)
|
1613 |
-
{
|
1614 |
-
return false;
|
1615 |
-
}
|
1616 |
-
}
|
1617 |
}
|
1 |
+
<?php
|
2 |
+
//include pmprogateway
|
3 |
+
require_once(dirname(__FILE__) . "/class.pmprogateway.php");
|
4 |
+
|
5 |
+
//load classes init method
|
6 |
+
add_action('init', array('PMProGateway_stripe', 'init'));
|
7 |
+
|
8 |
+
/**
|
9 |
+
* PMProGateway_stripe Class
|
10 |
+
*
|
11 |
+
* Handles Stripe integration.
|
12 |
+
*
|
13 |
+
* @since 1.4
|
14 |
+
*/
|
15 |
+
class PMProGateway_stripe extends PMProGateway
|
16 |
+
{
|
17 |
+
/**
|
18 |
+
* Stripe Class Constructor
|
19 |
+
*
|
20 |
+
* @since 1.4
|
21 |
+
*/
|
22 |
+
function PMProGateway_stripe($gateway = NULL)
|
23 |
+
{
|
24 |
+
$this->gateway = $gateway;
|
25 |
+
$this->gateway_environment = pmpro_getOption("gateway_environment");
|
26 |
+
|
27 |
+
$this->loadStripeLibrary();
|
28 |
+
Stripe::setApiKey(pmpro_getOption("stripe_secretkey"));
|
29 |
+
|
30 |
+
return $this->gateway;
|
31 |
+
}
|
32 |
+
|
33 |
+
/**
|
34 |
+
* Load the Stripe API library.
|
35 |
+
*
|
36 |
+
* @since 1.8
|
37 |
+
* Moved into a method in version 1.8 so we only load it when needed.
|
38 |
+
*/
|
39 |
+
function loadStripeLibrary()
|
40 |
+
{
|
41 |
+
//load Stripe library if it hasn't been loaded already (usually by another plugin using Stripe)
|
42 |
+
if(!class_exists("Stripe"))
|
43 |
+
require_once(dirname(__FILE__) . "/../../includes/lib/Stripe/Stripe.php");
|
44 |
+
}
|
45 |
+
|
46 |
+
/**
|
47 |
+
* Run on WP init
|
48 |
+
*
|
49 |
+
* @since 1.8
|
50 |
+
*/
|
51 |
+
static function init()
|
52 |
+
{
|
53 |
+
//make sure Stripe is a gateway option
|
54 |
+
add_filter('pmpro_gateways', array('PMProGateway_stripe', 'pmpro_gateways'));
|
55 |
+
|
56 |
+
//add fields to payment settings
|
57 |
+
add_filter('pmpro_payment_options', array('PMProGateway_stripe', 'pmpro_payment_options'));
|
58 |
+
add_filter('pmpro_payment_option_fields', array('PMProGateway_stripe', 'pmpro_payment_option_fields'), 10, 2);
|
59 |
+
|
60 |
+
//add some fields to edit user page (Updates)
|
61 |
+
add_action('pmpro_after_membership_level_profile_fields', array('PMProGateway_stripe', 'user_profile_fields'));
|
62 |
+
add_action('profile_update', array('PMProGateway_stripe', 'user_profile_fields_save'));
|
63 |
+
|
64 |
+
//old global RE showing billing address or not
|
65 |
+
global $pmpro_stripe_lite;
|
66 |
+
$pmpro_stripe_lite = apply_filters("pmpro_stripe_lite", !pmpro_getOption("stripe_billingaddress")); //default is oposite of the stripe_billingaddress setting
|
67 |
+
|
68 |
+
//updates cron
|
69 |
+
add_action('pmpro_activation', array('PMProGateway_stripe', 'pmpro_activation'));
|
70 |
+
add_action('pmpro_deactivation', array('PMProGateway_stripe', 'pmpro_deactivation'));
|
71 |
+
add_action('pmpro_cron_stripe_subscription_updates', array('PMProGateway_stripe', 'pmpro_cron_stripe_subscription_updates'));
|
72 |
+
|
73 |
+
//code to add at checkout if Stripe is the current gateway
|
74 |
+
$gateway = pmpro_getOption("gateway");
|
75 |
+
if($gateway == "stripe")
|
76 |
+
{
|
77 |
+
add_action('pmpro_checkout_preheader', array('PMProGateway_stripe', 'pmpro_checkout_preheader'));
|
78 |
+
add_filter('pmpro_checkout_order', array('PMProGateway_stripe', 'pmpro_checkout_order'));
|
79 |
+
add_filter('pmpro_include_billing_address_fields', array('PMProGateway_stripe', 'pmpro_include_billing_address_fields'));
|
80 |
+
add_filter('pmpro_include_cardtype_field', array('PMProGateway_stripe', 'pmpro_include_billing_address_fields'));
|
81 |
+
add_filter('pmpro_include_payment_information_fields', array('PMProGateway_stripe', 'pmpro_include_payment_information_fields'));
|
82 |
+
}
|
83 |
+
}
|
84 |
+
|
85 |
+
/**
|
86 |
+
* Make sure Stripe is in the gateways list
|
87 |
+
*
|
88 |
+
* @since 1.8
|
89 |
+
*/
|
90 |
+
static function pmpro_gateways($gateways)
|
91 |
+
{
|
92 |
+
if(empty($gateways['stripe']))
|
93 |
+
$gateways['stripe'] = __('Stripe', 'pmpro');
|
94 |
+
|
95 |
+
return $gateways;
|
96 |
+
}
|
97 |
+
|
98 |
+
/**
|
99 |
+
* Get a list of payment options that the Stripe gateway needs/supports.
|
100 |
+
*
|
101 |
+
* @since 1.8
|
102 |
+
*/
|
103 |
+
static function getGatewayOptions()
|
104 |
+
{
|
105 |
+
$options = array(
|
106 |
+
'sslseal',
|
107 |
+
'nuclear_HTTPS',
|
108 |
+
'gateway_environment',
|
109 |
+
'stripe_secretkey',
|
110 |
+
'stripe_publishablekey',
|
111 |
+
'stripe_billingaddress',
|
112 |
+
'currency',
|
113 |
+
'use_ssl',
|
114 |
+
'tax_state',
|
115 |
+
'tax_rate',
|
116 |
+
'accepted_credit_cards'
|
117 |
+
);
|
118 |
+
|
119 |
+
return $options;
|
120 |
+
}
|
121 |
+
|
122 |
+
/**
|
123 |
+
* Set payment options for payment settings page.
|
124 |
+
*
|
125 |
+
* @since 1.8
|
126 |
+
*/
|
127 |
+
static function pmpro_payment_options($options)
|
128 |
+
{
|
129 |
+
//get stripe options
|
130 |
+
$stripe_options = PMProGateway_stripe::getGatewayOptions();
|
131 |
+
|
132 |
+
//merge with others.
|
133 |
+
$options = array_merge($stripe_options, $options);
|
134 |
+
|
135 |
+
return $options;
|
136 |
+
}
|
137 |
+
|
138 |
+
/**
|
139 |
+
* Display fields for Stripe options.
|
140 |
+
*
|
141 |
+
* @since 1.8
|
142 |
+
*/
|
143 |
+
static function pmpro_payment_option_fields($values, $gateway)
|
144 |
+
{
|
145 |
+
?>
|
146 |
+
<tr class="pmpro_settings_divider gateway gateway_stripe" <?php if($gateway != "stripe") { ?>style="display: none;"<?php } ?>>
|
147 |
+
<td colspan="2">
|
148 |
+
<?php _e('Stripe Settings', 'pmpro'); ?>
|
149 |
+
</td>
|
150 |
+
</tr>
|
151 |
+
<tr class="gateway gateway_stripe" <?php if($gateway != "stripe") { ?>style="display: none;"<?php } ?>>
|
152 |
+
<th scope="row" valign="top">
|
153 |
+
<label for="stripe_secretkey"><?php _e('Secret Key', 'pmpro');?>:</label>
|
154 |
+
</th>
|
155 |
+
<td>
|
156 |
+
<input type="text" id="stripe_secretkey" name="stripe_secretkey" size="60" value="<?php echo esc_attr($values['stripe_secretkey'])?>" />
|
157 |
+
</td>
|
158 |
+
</tr>
|
159 |
+
<tr class="gateway gateway_stripe" <?php if($gateway != "stripe") { ?>style="display: none;"<?php } ?>>
|
160 |
+
<th scope="row" valign="top">
|
161 |
+
<label for="stripe_publishablekey"><?php _e('Publishable Key', 'pmpro');?>:</label>
|
162 |
+
</th>
|
163 |
+
<td>
|
164 |
+
<input type="text" id="stripe_publishablekey" name="stripe_publishablekey" size="60" value="<?php echo esc_attr($values['stripe_publishablekey'])?>" />
|
165 |
+
</td>
|
166 |
+
</tr>
|
167 |
+
<tr class="gateway gateway_stripe" <?php if($gateway != "stripe") { ?>style="display: none;"<?php } ?>>
|
168 |
+
<th scope="row" valign="top">
|
169 |
+
<label for="stripe_billingaddress"><?php _e('Show Billing Address Fields', 'pmpro');?>:</label>
|
170 |
+
</th>
|
171 |
+
<td>
|
172 |
+
<select id="stripe_billingaddress" name="stripe_billingaddress">
|
173 |
+
<option value="0" <?php if(empty($values['stripe_billingaddress'])) { ?>selected="selected"<?php } ?>><?php _e('No', 'pmpro');?></option>
|
174 |
+
<option value="1" <?php if(!empty($values['stripe_billingaddress'])) { ?>selected="selected"<?php } ?>><?php _e('Yes', 'pmpro');?></option>
|
175 |
+
</select>
|
176 |
+
<small><?php _e("Stripe doesn't require billing address fields. Choose 'No' to hide them on the checkout page.<br /><strong>If No, make sure you disable address verification in the Stripe dashboard settings.</strong>", 'pmpro');?></small>
|
177 |
+
</td>
|
178 |
+
</tr>
|
179 |
+
<tr class="gateway gateway_stripe" <?php if($gateway != "stripe") { ?>style="display: none;"<?php } ?>>
|
180 |
+
<th scope="row" valign="top">
|
181 |
+
<label><?php _e('Web Hook URL', 'pmpro');?>:</label>
|
182 |
+
</th>
|
183 |
+
<td>
|
184 |
+
<p><?php _e('To fully integrate with Stripe, be sure to set your Web Hook URL to', 'pmpro');?> <pre><?php echo admin_url("admin-ajax.php") . "?action=stripe_webhook";?></pre></p>
|
185 |
+
</td>
|
186 |
+
</tr>
|
187 |
+
<?php
|
188 |
+
}
|
189 |
+
|
190 |
+
/**
|
191 |
+
* Code added to checkout preheader.
|
192 |
+
*
|
193 |
+
* @since 1.8
|
194 |
+
*/
|
195 |
+
static function pmpro_checkout_preheader()
|
196 |
+
{
|
197 |
+
global $gateway, $pmpro_level;
|
198 |
+
|
199 |
+
if($gateway == "stripe" && !pmpro_isLevelFree($pmpro_level))
|
200 |
+
{
|
201 |
+
//stripe js library
|
202 |
+
wp_enqueue_script("stripe", "https://js.stripe.com/v2/", array(), NULL);
|
203 |
+
|
204 |
+
//stripe js code for checkout
|
205 |
+
function pmpro_stripe_javascript()
|
206 |
+
{
|
207 |
+
global $pmpro_gateway, $pmpro_level, $pmpro_stripe_lite;
|
208 |
+
?>
|
209 |
+
<script type="text/javascript">
|
210 |
+
// this identifies your website in the createToken call below
|
211 |
+
Stripe.setPublishableKey('<?php echo pmpro_getOption("stripe_publishablekey"); ?>');
|
212 |
+
|
213 |
+
var pmpro_require_billing = true;
|
214 |
+
|
215 |
+
jQuery(document).ready(function() {
|
216 |
+
jQuery("#pmpro_form, .pmpro_form").submit(function(event) {
|
217 |
+
|
218 |
+
//double check in case a discount code made the level free
|
219 |
+
if(pmpro_require_billing)
|
220 |
+
{
|
221 |
+
//build array for creating token
|
222 |
+
var args = {
|
223 |
+
number: jQuery('#AccountNumber').val(),
|
224 |
+
cvc: jQuery('#CVV').val(),
|
225 |
+
exp_month: jQuery('#ExpirationMonth').val(),
|
226 |
+
exp_year: jQuery('#ExpirationYear').val()
|
227 |
+
<?php
|
228 |
+
$pmpro_stripe_verify_address = apply_filters("pmpro_stripe_verify_address", pmpro_getOption('stripe_billingaddress'));
|
229 |
+
if(!empty($pmpro_stripe_verify_address))
|
230 |
+
{
|
231 |
+
?>
|
232 |
+
,address_line1: jQuery('#baddress1').val(),
|
233 |
+
address_line2: jQuery('#baddress2').val(),
|
234 |
+
address_city: jQuery('#bcity').val(),
|
235 |
+
address_state: jQuery('#bstate').val(),
|
236 |
+
address_zip: jQuery('#bzipcode').val(),
|
237 |
+
address_country: jQuery('#bcountry').val()
|
238 |
+
<?php
|
239 |
+
}
|
240 |
+
?>
|
241 |
+
};
|
242 |
+
|
243 |
+
if (jQuery('#bfirstname').length && jQuery('#blastname').length)
|
244 |
+
args['name'] = jQuery.trim(jQuery('#bfirstname').val() + ' ' + jQuery('#blastname').val());
|
245 |
+
|
246 |
+
//create token
|
247 |
+
Stripe.createToken(args, stripeResponseHandler);
|
248 |
+
|
249 |
+
// prevent the form from submitting with the default action
|
250 |
+
return false;
|
251 |
+
}
|
252 |
+
else
|
253 |
+
return true; //not using Stripe anymore
|
254 |
+
});
|
255 |
+
});
|
256 |
+
|
257 |
+
function stripeResponseHandler(status, response) {
|
258 |
+
if (response.error) {
|
259 |
+
// re-enable the submit button
|
260 |
+
jQuery('.pmpro_btn-submit-checkout').removeAttr("disabled");
|
261 |
+
|
262 |
+
//hide processing message
|
263 |
+
jQuery('#pmpro_processing_message').css('visibility', 'hidden');
|
264 |
+
|
265 |
+
// show the errors on the form
|
266 |
+
alert(response.error.message);
|
267 |
+
jQuery(".payment-errors").text(response.error.message);
|
268 |
+
} else {
|
269 |
+
var form$ = jQuery("#pmpro_form, .pmpro_form");
|
270 |
+
// token contains id, last4, and card type
|
271 |
+
var token = response['id'];
|
272 |
+
// insert the token into the form so it gets submitted to the server
|
273 |
+
form$.append("<input type='hidden' name='stripeToken' value='" + token + "'/>");
|
274 |
+
|
275 |
+
console.log(response);
|
276 |
+
|
277 |
+
//insert fields for other card fields
|
278 |
+
if(jQuery('#CardType[name=CardType]').length)
|
279 |
+
jQuery('#CardType').val(response['card']['brand']);
|
280 |
+
else
|
281 |
+
form$.append("<input type='hidden' name='CardType' value='" + response['card']['brand'] + "'/>");
|
282 |
+
form$.append("<input type='hidden' name='AccountNumber' value='XXXXXXXXXXXXX" + response['card']['last4'] + "'/>");
|
283 |
+
form$.append("<input type='hidden' name='ExpirationMonth' value='" + ("0" + response['card']['exp_month']).slice(-2) + "'/>");
|
284 |
+
form$.append("<input type='hidden' name='ExpirationYear' value='" + response['card']['exp_year'] + "'/>");
|
285 |
+
|
286 |
+
// and submit
|
287 |
+
form$.get(0).submit();
|
288 |
+
}
|
289 |
+
}
|
290 |
+
</script>
|
291 |
+
<?php
|
292 |
+
}
|
293 |
+
add_action("wp_head", "pmpro_stripe_javascript");
|
294 |
+
|
295 |
+
//don't require the CVV
|
296 |
+
function pmpro_stripe_dont_require_CVV($fields)
|
297 |
+
{
|
298 |
+
unset($fields['CVV']);
|
299 |
+
return $fields;
|
300 |
+
}
|
301 |
+
add_filter("pmpro_required_billing_fields", "pmpro_stripe_dont_require_CVV");
|
302 |
+
}
|
303 |
+
}
|
304 |
+
|
305 |
+
/**
|
306 |
+
* Filtering orders at checkout.
|
307 |
+
*
|
308 |
+
* @since 1.8
|
309 |
+
*/
|
310 |
+
static function pmpro_checkout_order($morder)
|
311 |
+
{
|
312 |
+
//load up token values
|
313 |
+
if(isset($_REQUEST['stripeToken']))
|
314 |
+
{
|
315 |
+
$morder->stripeToken = $_REQUEST['stripeToken'];
|
316 |
+
}
|
317 |
+
|
318 |
+
//stripe lite code to get name from other sources if available
|
319 |
+
global $pmpro_stripe_lite, $current_user;
|
320 |
+
if(!empty($pmpro_stripe_lite) && empty($morder->FirstName) && empty($morder->LastName))
|
321 |
+
{
|
322 |
+
if(!empty($current_user->ID))
|
323 |
+
{
|
324 |
+
$morder->FirstName = get_user_meta($current_user->ID, "first_name", true);
|
325 |
+
$morder->LastName = get_user_meta($current_user->ID, "last_name", true);
|
326 |
+
}
|
327 |
+
elseif(!empty($_REQUEST['first_name']) && !empty($_REQUEST['last_name']))
|
328 |
+
{
|
329 |
+
$morder->FirstName = $_REQUEST['first_name'];
|
330 |
+
$morder->LastName = $_REQUEST['last_name'];
|
331 |
+
}
|
332 |
+
}
|
333 |
+
|
334 |
+
return $morder;
|
335 |
+
}
|
336 |
+
|
337 |
+
/**
|
338 |
+
* Code to run after checkout
|
339 |
+
*
|
340 |
+
* @since 1.8
|
341 |
+
*/
|
342 |
+
static function pmpro_after_checkout($user_id, $morder)
|
343 |
+
{
|
344 |
+
global $gateway;
|
345 |
+
|
346 |
+
if($gateway == "stripe")
|
347 |
+
{
|
348 |
+
if(!empty($morder) && !empty($morer->Gateway) && !empty($morder->Gateway->customer) && !empty($morder->Gateway->customer->id))
|
349 |
+
{
|
350 |
+
update_user_meta($user_id, "pmpro_stripe_customerid", $morder->Gateway->customer->id);
|
351 |
+
}
|
352 |
+
}
|
353 |
+
}
|
354 |
+
|
355 |
+
/**
|
356 |
+
* Check settings if billing address should be shown.
|
357 |
+
* @since 1.8
|
358 |
+
*/
|
359 |
+
static function pmpro_include_billing_address_fields($include)
|
360 |
+
{
|
361 |
+
//check settings RE showing billing address
|
362 |
+
if(!pmpro_getOption("stripe_billingaddress"))
|
363 |
+
$include = false;
|
364 |
+
|
365 |
+
return $include;
|
366 |
+
}
|
367 |
+
|
368 |
+
/**
|
369 |
+
* Use our own payment fields at checkout. (Remove the name attributes.)
|
370 |
+
* @since 1.8
|
371 |
+
*/
|
372 |
+
static function pmpro_include_payment_information_fields($include)
|
373 |
+
{
|
374 |
+
//global vars
|
375 |
+
global $pmpro_requirebilling, $pmpro_show_discount_code, $discount_code, $CardType, $AccountNumber, $ExpirationMonth, $ExpirationYear;
|
376 |
+
|
377 |
+
//get accepted credit cards
|
378 |
+
$pmpro_accepted_credit_cards = pmpro_getOption("accepted_credit_cards");
|
379 |
+
$pmpro_accepted_credit_cards = explode(",", $pmpro_accepted_credit_cards);
|
380 |
+
$pmpro_accepted_credit_cards_string = pmpro_implodeToEnglish($pmpro_accepted_credit_cards);
|
381 |
+
|
382 |
+
//include ours
|
383 |
+
?>
|
384 |
+
<table id="pmpro_payment_information_fields" class="pmpro_checkout top1em" width="100%" cellpadding="0" cellspacing="0" border="0" <?php if(!$pmpro_requirebilling || apply_filters("pmpro_hide_payment_information_fields", false) ) { ?>style="display: none;"<?php } ?>>
|
385 |
+
<thead>
|
386 |
+
<tr>
|
387 |
+
<th><span class="pmpro_thead-msg"><?php printf(__('We Accept %s', 'pmpro'), $pmpro_accepted_credit_cards_string);?></span><?php _e('Payment Information', 'pmpro');?></th>
|
388 |
+
</tr>
|
389 |
+
</thead>
|
390 |
+
<tbody>
|
391 |
+
<tr valign="top">
|
392 |
+
<td>
|
393 |
+
<?php
|
394 |
+
$sslseal = pmpro_getOption("sslseal");
|
395 |
+
if($sslseal)
|
396 |
+
{
|
397 |
+
?>
|
398 |
+
<div class="pmpro_sslseal"><?php echo stripslashes($sslseal)?></div>
|
399 |
+
<?php
|
400 |
+
}
|
401 |
+
?>
|
402 |
+
<?php
|
403 |
+
$pmpro_include_cardtype_field = apply_filters('pmpro_include_cardtype_field', false);
|
404 |
+
if($pmpro_include_cardtype_field)
|
405 |
+
{
|
406 |
+
?>
|
407 |
+
<div class="pmpro_payment-card-type">
|
408 |
+
<label for="CardType"><?php _e('Card Type', 'pmpro');?></label>
|
409 |
+
<select id="CardType" class=" <?php echo pmpro_getClassForField("CardType");?>">
|
410 |
+
<?php foreach($pmpro_accepted_credit_cards as $cc) { ?>
|
411 |
+
<option value="<?php echo $cc?>" <?php if($CardType == $cc) { ?>selected="selected"<?php } ?>><?php echo $cc?></option>
|
412 |
+
<?php } ?>
|
413 |
+
</select>
|
414 |
+
</div>
|
415 |
+
<?php
|
416 |
+
}
|
417 |
+
else
|
418 |
+
{
|
419 |
+
?>
|
420 |
+
<input type="hidden" id="CardType" name="CardType" value="<?php echo esc_attr($CardType);?>" />
|
421 |
+
<script>
|
422 |
+
jQuery(document).ready(function() {
|
423 |
+
jQuery('#AccountNumber').validateCreditCard(function(result) {
|
424 |
+
var cardtypenames = {
|
425 |
+
"amex":"American Express",
|
426 |
+
"diners_club_carte_blanche":"Diners Club Carte Blanche",
|
427 |
+
"diners_club_international":"Diners Club International",
|
428 |
+
"discover":"Discover",
|
429 |
+
"jcb":"JCB",
|
430 |
+
"laser":"Laser",
|
431 |
+
"maestro":"Maestro",
|
432 |
+
"mastercard":"Mastercard",
|
433 |
+
"visa":"Visa",
|
434 |
+
"visa_electron":"Visa Electron"
|
435 |
+
}
|
436 |
+
|
437 |
+
if(result.card_type)
|
438 |
+
jQuery('#CardType').val(cardtypenames[result.card_type.name]);
|
439 |
+
else
|
440 |
+
jQuery('#CardType').val('Unknown Card Type');
|
441 |
+
});
|
442 |
+
});
|
443 |
+
</script>
|
444 |
+
<?php
|
445 |
+
}
|
446 |
+
?>
|
447 |
+
|
448 |
+
<div class="pmpro_payment-account-number">
|
449 |
+
<label for="AccountNumber"><?php _e('Card Number', 'pmpro');?></label>
|
450 |
+
<input id="AccountNumber" class="input <?php echo pmpro_getClassForField("AccountNumber");?>" type="text" size="25" value="<?php echo esc_attr($AccountNumber)?>" autocomplete="off" />
|
451 |
+
</div>
|
452 |
+
|
453 |
+
<div class="pmpro_payment-expiration">
|
454 |
+
<label for="ExpirationMonth"><?php _e('Expiration Date', 'pmpro');?></label>
|
455 |
+
<select id="ExpirationMonth" class=" <?php echo pmpro_getClassForField("ExpirationMonth");?>">
|
456 |
+
<option value="01" <?php if($ExpirationMonth == "01") { ?>selected="selected"<?php } ?>>01</option>
|
457 |
+
<option value="02" <?php if($ExpirationMonth == "02") { ?>selected="selected"<?php } ?>>02</option>
|
458 |
+
<option value="03" <?php if($ExpirationMonth == "03") { ?>selected="selected"<?php } ?>>03</option>
|
459 |
+
<option value="04" <?php if($ExpirationMonth == "04") { ?>selected="selected"<?php } ?>>04</option>
|
460 |
+
<option value="05" <?php if($ExpirationMonth == "05") { ?>selected="selected"<?php } ?>>05</option>
|
461 |
+
<option value="06" <?php if($ExpirationMonth == "06") { ?>selected="selected"<?php } ?>>06</option>
|
462 |
+
<option value="07" <?php if($ExpirationMonth == "07") { ?>selected="selected"<?php } ?>>07</option>
|
463 |
+
<option value="08" <?php if($ExpirationMonth == "08") { ?>selected="selected"<?php } ?>>08</option>
|
464 |
+
<option value="09" <?php if($ExpirationMonth == "09") { ?>selected="selected"<?php } ?>>09</option>
|
465 |
+
<option value="10" <?php if($ExpirationMonth == "10") { ?>selected="selected"<?php } ?>>10</option>
|
466 |
+
<option value="11" <?php if($ExpirationMonth == "11") { ?>selected="selected"<?php } ?>>11</option>
|
467 |
+
<option value="12" <?php if($ExpirationMonth == "12") { ?>selected="selected"<?php } ?>>12</option>
|
468 |
+
</select>/<select id="ExpirationYear" class=" <?php echo pmpro_getClassForField("ExpirationYear");?>">
|
469 |
+
<?php
|
470 |
+
for($i = date("Y"); $i < date("Y") + 10; $i++)
|
471 |
+
{
|
472 |
+
?>
|
473 |
+
<option value="<?php echo $i?>" <?php if($ExpirationYear == $i) { ?>selected="selected"<?php } ?>><?php echo $i?></option>
|
474 |
+
<?php
|
475 |
+
}
|
476 |
+
?>
|
477 |
+
</select>
|
478 |
+
</div>
|
479 |
+
|
480 |
+
<?php
|
481 |
+
$pmpro_show_cvv = apply_filters("pmpro_show_cvv", true);
|
482 |
+
if($pmpro_show_cvv)
|
483 |
+
{
|
484 |
+
?>
|
485 |
+
<div class="pmpro_payment-cvv">
|
486 |
+
<label for="CVV"><?php _ex('CVV', 'Credit card security code, CVV/CCV/CVV2', 'pmpro');?></label>
|
487 |
+
<input class="input" id="CVV" type="text" size="4" value="<?php if(!empty($_REQUEST['CVV'])) { echo esc_attr($_REQUEST['CVV']); }?>" class=" <?php echo pmpro_getClassForField("CVV");?>" /> <small>(<a href="javascript:void(0);" onclick="javascript:window.open('<?php echo pmpro_https_filter(PMPRO_URL)?>/pages/popup-cvv.html','cvv','toolbar=no, location=no, directories=no, status=no, menubar=no, scrollbars=yes, resizable=yes, width=600, height=475');"><?php _ex("what's this?", 'link to CVV help', 'pmpro');?></a>)</small>
|
488 |
+
</div>
|
489 |
+
<?php
|
490 |
+
}
|
491 |
+
?>
|
492 |
+
|
493 |
+
<?php if($pmpro_show_discount_code) { ?>
|
494 |
+
<div class="pmpro_payment-discount-code">
|
495 |
+
<label for="discount_code"><?php _e('Discount Code', 'pmpro');?></label>
|
496 |
+
<input class="input <?php echo pmpro_getClassForField("discount_code");?>" id="discount_code" name="discount_code" type="text" size="20" value="<?php echo esc_attr($discount_code)?>" />
|
497 |
+
<input type="button" id="discount_code_button" name="discount_code_button" value="<?php _e('Apply', 'pmpro');?>" />
|
498 |
+
<p id="discount_code_message" class="pmpro_message" style="display: none;"></p>
|
499 |
+
</div>
|
500 |
+
<?php } ?>
|
501 |
+
|
502 |
+
</td>
|
503 |
+
</tr>
|
504 |
+
</tbody>
|
505 |
+
</table>
|
506 |
+
<?php
|
507 |
+
|
508 |
+
//don't include the default
|
509 |
+
return false;
|
510 |
+
}
|
511 |
+
|
512 |
+
/**
|
513 |
+
* Fields shown on edit user page
|
514 |
+
*
|
515 |
+
* @since 1.8
|
516 |
+
*/
|
517 |
+
static function user_profile_fields($user)
|
518 |
+
{
|
519 |
+
global $wpdb, $current_user, $pmpro_currency_symbol;
|
520 |
+
|
521 |
+
$cycles = array( __('Day(s)', 'pmpro') => 'Day', __('Week(s)', 'pmpro') => 'Week', __('Month(s)', 'pmpro') => 'Month', __('Year(s)', 'pmpro') => 'Year' );
|
522 |
+
$current_year = date("Y");
|
523 |
+
$current_month = date("m");
|
524 |
+
|
525 |
+
//make sure the current user has privileges
|
526 |
+
$membership_level_capability = apply_filters("pmpro_edit_member_capability", "manage_options");
|
527 |
+
if(!current_user_can($membership_level_capability))
|
528 |
+
return false;
|
529 |
+
|
530 |
+
//more privelges they should have
|
531 |
+
$show_membership_level = apply_filters("pmpro_profile_show_membership_level", true, $user);
|
532 |
+
if(!$show_membership_level)
|
533 |
+
return false;
|
534 |
+
|
535 |
+
//check that user has a current subscription at Stripe
|
536 |
+
$last_order = new MemberOrder();
|
537 |
+
$last_order->getLastMemberOrder($user->ID);
|
538 |
+
|
539 |
+
//assume no sub to start
|
540 |
+
$sub = false;
|
541 |
+
|
542 |
+
//check that gateway is Stripe
|
543 |
+
if($last_order->gateway == "stripe")
|
544 |
+
{
|
545 |
+
//is there a customer?
|
546 |
+
$sub = $last_order->Gateway->getSubscription($last_order);
|
547 |
+
}
|
548 |
+
|
549 |
+
$customer_id = $user->pmpro_stripe_customerid;
|
550 |
+
|
551 |
+
if(empty($sub))
|
552 |
+
{
|
553 |
+
//make sure we delete stripe updates
|
554 |
+
update_user_meta($user->ID, "pmpro_stripe_updates", array());
|
555 |
+
|
556 |
+
//if the last order has a sub id, let the admin know there is no sub at Stripe
|
557 |
+
if(!empty($last_order) && $last_order->gateway == "stripe" && !empty($last_order->subscription_transaction_id) && strpos($last_order->subscription_transaction_id, "sub_") !== false)
|
558 |
+
{
|
559 |
+
?>
|
560 |
+
<p><strong>Note:</strong> Subscription <strong><?php echo $last_order->subscription_transaction_id;?></strong> could not be found at Stripe. It might have been deleted.</p>
|
561 |
+
<?php
|
562 |
+
}
|
563 |
+
}
|
564 |
+
else
|
565 |
+
{
|
566 |
+
?>
|
567 |
+
<h3><?php _e("Subscription Updates", "pmpro"); ?></h3>
|
568 |
+
<p>
|
569 |
+
<?php
|
570 |
+
if(empty($_REQUEST['user_id']))
|
571 |
+
_e("Subscription updates, allow you to change the member's subscription values at predefined times. Be sure to click Update Profile after making changes.", 'pmpro');
|
572 |
+
else
|
573 |
+
_e("Subscription updates, allow you to change the member's subscription values at predefined times. Be sure to click Update User after making changes.", 'pmpro');
|
574 |
+
?>
|
575 |
+
</p>
|
576 |
+
<table class="form-table">
|
577 |
+
<tr>
|
578 |
+
<th><label for="membership_level"><?php _e("Update", "pmpro"); ?></label></th>
|
579 |
+
<td id="updates_td">
|
580 |
+
<?php
|
581 |
+
$old_updates = $user->pmpro_stripe_updates;
|
582 |
+
if(is_array($old_updates))
|
583 |
+
{
|
584 |
+
$updates = array_merge(
|
585 |
+
array(array('template'=>true, 'when'=>'now', 'date_month'=>'', 'date_day'=>'', 'date_year'=>'', 'billing_amount'=>'', 'cycle_number'=>'', 'cycle_period'=>'Month')),
|
586 |
+
$old_updates
|
587 |
+
);
|
588 |
+
}
|
589 |
+
else
|
590 |
+
$updates = array(array('template'=>true, 'when'=>'now', 'date_month'=>'', 'date_day'=>'', 'date_year'=>'', 'billing_amount'=>'', 'cycle_number'=>'', 'cycle_period'=>'Month'));
|
591 |
+
|
592 |
+
foreach($updates as $update)
|
593 |
+
{
|
594 |
+
?>
|
595 |
+
<div class="updates_update" <?php if(!empty($update['template'])) { ?>style="display: none;"<?php } ?>>
|
596 |
+
<select class="updates_when" name="updates_when[]">
|
597 |
+
<option value="now" <?php selected($update['when'], "now");?>>Now</option>
|
598 |
+
<option value="payment" <?php selected($update['when'], "payment");?>>After Next Payment</option>
|
599 |
+
<option value="date" <?php selected($update['when'], "date");?>>On Date</option>
|
600 |
+
</select>
|
601 |
+
<span class="updates_date" <?php if($uwhen != "date") { ?>style="display: none;"<?php } ?>>
|
602 |
+
<select name="updates_date_month[]">
|
603 |
+
<?php
|
604 |
+
for($i = 1; $i < 13; $i++)
|
605 |
+
{
|
606 |
+
?>
|
607 |
+
<option value="<?php echo str_pad($i, 2, "0", STR_PAD_LEFT);?>" <?php if(!empty($update['date_month']) && $update['date_month'] == $i) { ?>selected="selected"<?php } ?>>
|
608 |
+
<?php echo date("M", strtotime($i . "/1/" . $current_year));?>
|
609 |
+
</option>
|
610 |
+
<?php
|
611 |
+
}
|
612 |
+
?>
|
613 |
+
</select>
|
614 |
+
<input name="updates_date_day[]" type="text" size="2" value="<?php if(!empty($update['date_day'])) echo esc_attr($update['date_day']);?>" />
|
615 |
+
<input name="updates_date_year[]" type="text" size="4" value="<?php if(!empty($update['date_year'])) echo esc_attr($update['date_year']);?>" />
|
616 |
+
</span>
|
617 |
+
<span class="updates_billing" <?php if($uwhen == "no") { ?>style="display: none;"<?php } ?>>
|
618 |
+
<?php echo $pmpro_currency_symbol?><input name="updates_billing_amount[]" type="text" size="10" value="<?php echo esc_attr($update['billing_amount']);?>" />
|
619 |
+
<small><?php _e('per', 'pmpro');?></small>
|
620 |
+
<input name="updates_cycle_number[]" type="text" size="5" value="<?php echo esc_attr($update['cycle_number']);?>" />
|
621 |
+
<select name="updates_cycle_period[]">
|
622 |
+
<?php
|
623 |
+
foreach ( $cycles as $name => $value ) {
|
624 |
+
echo "<option value='$value'";
|
625 |
+
if(!empty($update['cycle_period']) && $update['cycle_period'] == $value) echo " selected='selected'";
|
626 |
+
echo ">$name</option>";
|
627 |
+
}
|
628 |
+
?>
|
629 |
+
</select>
|
630 |
+
</span>
|
631 |
+
<span>
|
632 |
+
<a class="updates_remove" href="javascript:void(0);">Remove</a>
|
633 |
+
</span>
|
634 |
+
</div>
|
635 |
+
<?php
|
636 |
+
}
|
637 |
+
?>
|
638 |
+
<p><a id="updates_new_update" href="javascript:void(0);">+ New Update</a></p>
|
639 |
+
</td>
|
640 |
+
</tr>
|
641 |
+
</table>
|
642 |
+
<script>
|
643 |
+
jQuery(document).ready(function() {
|
644 |
+
//function to update dropdowns/etc based on when field
|
645 |
+
function updateSubscriptionUpdateFields(when)
|
646 |
+
{
|
647 |
+
if(jQuery(when).val() == 'date')
|
648 |
+
jQuery(when).parent().children('.updates_date').show();
|
649 |
+
else
|
650 |
+
jQuery(when).parent().children('.updates_date').hide();
|
651 |
+
|
652 |
+
if(jQuery(when).val() == 'no')
|
653 |
+
jQuery(when).parent().children('.updates_billing').hide();
|
654 |
+
else
|
655 |
+
jQuery(when).parent().children('.updates_billing').show();
|
656 |
+
}
|
657 |
+
|
658 |
+
//and update on page load
|
659 |
+
jQuery('.updates_when').each(function() { if(jQuery(this).parent().css('display') != 'none') updateSubscriptionUpdateFields(this); });
|
660 |
+
|
661 |
+
//add a new update when clicking to
|
662 |
+
var num_updates_divs = <?php echo count($updates);?>;
|
663 |
+
jQuery('#updates_new_update').click(function() {
|
664 |
+
//get updates
|
665 |
+
updates = jQuery('.updates_update').toArray();
|
666 |
+
|
667 |
+
//clone the first one
|
668 |
+
new_div = jQuery(updates[0]).clone();
|
669 |
+
|
670 |
+
//append
|
671 |
+
new_div.insertBefore('#updates_new_update');
|
672 |
+
|
673 |
+
//update events
|
674 |
+
addUpdateEvents()
|
675 |
+
|
676 |
+
//unhide it
|
677 |
+
new_div.show();
|
678 |
+
updateSubscriptionUpdateFields(new_div.children('.updates_when'));
|
679 |
+
});
|
680 |
+
|
681 |
+
function addUpdateEvents()
|
682 |
+
{
|
683 |
+
//update when when changes
|
684 |
+
jQuery('.updates_when').change(function() {
|
685 |
+
updateSubscriptionUpdateFields(this);
|
686 |
+
});
|
687 |
+
|
688 |
+
//remove updates when clicking
|
689 |
+
jQuery('.updates_remove').click(function() {
|
690 |
+
jQuery(this).parent().parent().remove();
|
691 |
+
});
|
692 |
+
}
|
693 |
+
addUpdateEvents();
|
694 |
+
});
|
695 |
+
</script>
|
696 |
+
<?php
|
697 |
+
}
|
698 |
+
}
|
699 |
+
|
700 |
+
/**
|
701 |
+
* Process fields from the edit user page
|
702 |
+
*
|
703 |
+
* @since 1.8
|
704 |
+
*/
|
705 |
+
static function user_profile_fields_save($user_id)
|
706 |
+
{
|
707 |
+
global $wpdb;
|
708 |
+
|
709 |
+
//check capabilities
|
710 |
+
$membership_level_capability = apply_filters("pmpro_edit_member_capability", "manage_options");
|
711 |
+
if(!current_user_can($membership_level_capability))
|
712 |
+
return false;
|
713 |
+
|
714 |
+
//make sure some value was passed
|
715 |
+
if(!isset($_POST['updates_when']) || !is_array($_POST['updates_when']))
|
716 |
+
return;
|
717 |
+
|
718 |
+
//vars
|
719 |
+
$updates = array();
|
720 |
+
$next_on_date_update = "";
|
721 |
+
|
722 |
+
//build array of updates (we skip the first because it's the template field for the JavaScript
|
723 |
+
for($i = 1; $i < count($_POST['updates_when']); $i++)
|
724 |
+
{
|
725 |
+
$update = array();
|
726 |
+
|
727 |
+
//all updates have these values
|
728 |
+
$update['when'] = $_POST['updates_when'][$i];
|
729 |
+
$update['billing_amount'] = $_POST['updates_billing_amount'][$i];
|
730 |
+
$update['cycle_number'] = $_POST['updates_cycle_number'][$i];
|
731 |
+
$update['cycle_period'] = $_POST['updates_cycle_period'][$i];
|
732 |
+
|
733 |
+
//these values only for on date updates
|
734 |
+
if($_POST['updates_when'][$i] == "date")
|
735 |
+
{
|
736 |
+
$update['date_month'] = str_pad($_POST['updates_date_month'][$i], 2, "0", STR_PAD_LEFT);
|
737 |
+
$update['date_day'] = str_pad($_POST['updates_date_day'][$i], 2, "0", STR_PAD_LEFT);
|
738 |
+
$update['date_year'] = $_POST['updates_date_year'][$i];
|
739 |
+
}
|
740 |
+
|
741 |
+
//make sure the update is valid
|
742 |
+
if(empty($update['cycle_number']))
|
743 |
+
continue;
|
744 |
+
|
745 |
+
//if when is now, update the subscription
|
746 |
+
if($update['when'] == "now")
|
747 |
+
{
|
748 |
+
//get level for user
|
749 |
+
$user_level = pmpro_getMembershipLevelForUser($user_id);
|
750 |
+
|
751 |
+
//get current plan at Stripe to get payment date
|
752 |
+
$last_order = new MemberOrder();
|
753 |
+
$last_order->getLastMemberOrder($user_id);
|
754 |
+
$last_order->setGateway('stripe');
|
755 |
+
$last_order->Gateway->getCustomer($last_order);
|
756 |
+
|
757 |
+
$subscription = $last_order->Gateway->getSubscription($last_order);
|
758 |
+
|
759 |
+
if(!empty($subscription))
|
760 |
+
{
|
761 |
+
$end_timestamp = $subscription->current_period_end;
|
762 |
+
|
763 |
+
//cancel the old subscription
|
764 |
+
if(!$last_order->Gateway->cancelSubscriptionAtGateway($subscription))
|
765 |
+
{
|
766 |
+
//throw error and halt save
|
767 |
+
function pmpro_stripe_user_profile_fields_save_error($errors, $update, $user)
|
768 |
+
{
|
769 |
+
$errors->add('pmpro_stripe_updates',__('Could not cancel the old subscription. Updates have not been processed.', 'pmpro'));
|
770 |
+
}
|
771 |
+
add_filter('user_profile_update_errors', 'pmpro_stripe_user_profile_fields_save_error', 10, 3);
|
772 |
+
|
773 |
+
//stop processing updates
|
774 |
+
return;
|
775 |
+
}
|
776 |
+
}
|
777 |
+
|
778 |
+
//if we didn't get an end date, let's set one one cycle out
|
779 |
+
if(empty($end_timestamp))
|
780 |
+
$end_timestamp = strtotime("+" . $update['cycle_number'] . " " . $update['cycle_period'], current_time('timestamp'));
|
781 |
+
|
782 |
+
//build order object
|
783 |
+
$update_order = new MemberOrder();
|
784 |
+
$update_order->setGateway('stripe');
|
785 |
+
$update_order->user_id = $user_id;
|
786 |
+
$update_order->membership_id = $user_level->id;
|
787 |
+
$update_order->membership_name = $user_level->name;
|
788 |
+
$update_order->InitialPayment = 0;
|
789 |
+
$update_order->PaymentAmount = $update['billing_amount'];
|
790 |
+
$update_order->ProfileStartDate = date("Y-m-d", $end_timestamp);
|
791 |
+
$update_order->BillingPeriod = $update['cycle_period'];
|
792 |
+
$update_order->BillingFrequency = $update['cycle_number'];
|
793 |
+
|
794 |
+
//need filter to reset ProfileStartDate
|
795 |
+
add_filter('pmpro_profile_start_date', create_function('$startdate, $order', 'return "' . $update_order->ProfileStartDate . 'T0:0:0";'), 10, 2);
|
796 |
+
|
797 |
+
//update subscription
|
798 |
+
$update_order->Gateway->subscribe($update_order, false);
|
799 |
+
|
800 |
+
//update membership
|
801 |
+
$sqlQuery = "UPDATE $wpdb->pmpro_memberships_users
|
802 |
+
SET billing_amount = '" . esc_sql($update['billing_amount']) . "',
|
803 |
+
cycle_number = '" . esc_sql($update['cycle_number']) . "',
|
804 |
+
cycle_period = '" . esc_sql($update['cycle_period']) . "',
|
805 |
+
trial_amount = '',
|
806 |
+
trial_limit = ''
|
807 |
+
WHERE user_id = '" . esc_sql($user_id) . "'
|
808 |
+
AND membership_id = '" . esc_sql($last_order->membership_id) . "'
|
809 |
+
AND status = 'active'
|
810 |
+
LIMIT 1";
|
811 |
+
|
812 |
+
$wpdb->query($sqlQuery);
|
813 |
+
|
814 |
+
//save order so we know which plan to look for at stripe (order code = plan id)
|
815 |
+
$update_order->status = "success";
|
816 |
+
$update_order->saveOrder();
|
817 |
+
|
818 |
+
continue;
|
819 |
+
}
|
820 |
+
elseif($update['when'] == 'date')
|
821 |
+
{
|
822 |
+
if(!empty($next_on_date_update))
|
823 |
+
$next_on_date_update = min($next_on_date_update, $update['date_year'] . "-" . $update['date_month'] . "-" . $update['date_day']);
|
824 |
+
else
|
825 |
+
$next_on_date_update = $update['date_year'] . "-" . $update['date_month'] . "-" . $update['date_day'];
|
826 |
+
}
|
827 |
+
|
828 |
+
//add to array
|
829 |
+
$updates[] = $update;
|
830 |
+
}
|
831 |
+
|
832 |
+
//save in user meta
|
833 |
+
update_user_meta($user_id, "pmpro_stripe_updates", $updates);
|
834 |
+
|
835 |
+
//save date of next on-date update to make it easier to query for these in cron job
|
836 |
+
update_user_meta($user_id, "pmpro_stripe_next_on_date_update", $next_on_date_update);
|
837 |
+
}
|
838 |
+
|
839 |
+
/**
|
840 |
+
* Cron activation for subscription updates.
|
841 |
+
*
|
842 |
+
* @since 1.8
|
843 |
+
*/
|
844 |
+
static function pmpro_activation()
|
845 |
+
{
|
846 |
+
wp_schedule_event(time(), 'daily', 'pmpro_cron_stripe_subscription_updates');
|
847 |
+
}
|
848 |
+
|
849 |
+
/**
|
850 |
+
* Cron deactivation for subscription updates.
|
851 |
+
*
|
852 |
+
* @since 1.8
|
853 |
+
*/
|
854 |
+
static function pmpro_deactivation()
|
855 |
+
{
|
856 |
+
wp_clear_scheduled_hook('pmpro_cron_stripe_subscription_updates');
|
857 |
+
}
|
858 |
+
|
859 |
+
/**
|
860 |
+
* Cron job for subscription updates.
|
861 |
+
*
|
862 |
+
* @since 1.8
|
863 |
+
*/
|
864 |
+
static function pmpro_cron_stripe_subscription_updates()
|
865 |
+
{
|
866 |
+
global $wpdb;
|
867 |
+
|
868 |
+
//get all updates for today (or before today)
|
869 |
+
$sqlQuery = "SELECT *
|
870 |
+
FROM $wpdb->usermeta
|
871 |
+
WHERE meta_key = 'pmpro_stripe_next_on_date_update'
|
872 |
+
AND meta_value IS NOT NULL
|
873 |
+
AND meta_value <> ''
|
874 |
+
AND meta_value < '" . date("Y-m-d", strtotime("+1 day")) . "'";
|
875 |
+
$updates = $wpdb->get_results($sqlQuery);
|
876 |
+
|
877 |
+
if(!empty($updates))
|
878 |
+
{
|
879 |
+
//loop through
|
880 |
+
foreach($updates as $update)
|
881 |
+
{
|
882 |
+
//pull values from update
|
883 |
+
$user_id = $update->user_id;
|
884 |
+
|
885 |
+
$user = get_userdata($user_id);
|
886 |
+
|
887 |
+
//if user is missing, delete the update info and continue
|
888 |
+
if(empty($user) || empty($user->ID))
|
889 |
+
{
|
890 |
+
delete_user_meta($user_id, "pmpro_stripe_updates");
|
891 |
+
delete_user_meta($user_id, "pmpro_stripe_next_on_date_update");
|
892 |
+
|
893 |
+
continue;
|
894 |
+
}
|
895 |
+
|
896 |
+
$user_updates = $user->pmpro_stripe_updates;
|
897 |
+
$next_on_date_update = "";
|
898 |
+
|
899 |
+
//loop through updates looking for updates happening today or earlier
|
900 |
+
if(!empty($user_updates))
|
901 |
+
{
|
902 |
+
foreach($user_updates as $key => $update)
|
903 |
+
{
|
904 |
+
if($update['when'] == 'date' &&
|
905 |
+
$update['date_year'] . "-" . $update['date_month'] . "-" . $update['date_day'] <= date("Y-m-d")
|
906 |
+
)
|
907 |
+
{
|
908 |
+
//get level for user
|
909 |
+
$user_level = pmpro_getMembershipLevelForUser($user_id);
|
910 |
+
|
911 |
+
//get current plan at Stripe to get payment date
|
912 |
+
$last_order = new MemberOrder();
|
913 |
+
$last_order->getLastMemberOrder($user_id);
|
914 |
+
$last_order->setGateway('stripe');
|
915 |
+
$last_order->Gateway->getCustomer($last_order);
|
916 |
+
|
917 |
+
if(!empty($last_order->Gateway->customer))
|
918 |
+
{
|
919 |
+
//find the first subscription
|
920 |
+
if(!empty($last_order->Gateway->customer->subscriptions['data'][0]))
|
921 |
+
{
|
922 |
+
$first_sub = $last_order->Gateway->customer->subscriptions['data'][0]->__toArray();
|
923 |
+
$end_timestamp = $first_sub['current_period_end'];
|
924 |
+
}
|
925 |
+
}
|
926 |
+
|
927 |
+
//if we didn't get an end date, let's set one one cycle out
|
928 |
+
$end_timestamp = strtotime("+" . $update['cycle_number'] . " " . $update['cycle_period']);
|
929 |
+
|
930 |
+
//build order object
|
931 |
+
$update_order = new MemberOrder();
|
932 |
+
$update_order->setGateway('stripe');
|
933 |
+
$update_order->user_id = $user_id;
|
934 |
+
$update_order->membership_id = $user_level->id;
|
935 |
+
$update_order->membership_name = $user_level->name;
|
936 |
+
$update_order->InitialPayment = 0;
|
937 |
+
$update_order->PaymentAmount = $update['billing_amount'];
|
938 |
+
$update_order->ProfileStartDate = date("Y-m-d", $end_timestamp);
|
939 |
+
$update_order->BillingPeriod = $update['cycle_period'];
|
940 |
+
$update_order->BillingFrequency = $update['cycle_number'];
|
941 |
+
|
942 |
+
//update subscription
|
943 |
+
$update_order->Gateway->subscribe($update_order, false);
|
944 |
+
|
945 |
+
//update membership
|
946 |
+
$sqlQuery = "UPDATE $wpdb->pmpro_memberships_users
|
947 |
+
SET billing_amount = '" . esc_sql($update['billing_amount']) . "',
|
948 |
+
cycle_number = '" . esc_sql($update['cycle_number']) . "',
|
949 |
+
cycle_period = '" . esc_sql($update['cycle_period']) . "'
|
950 |
+
WHERE user_id = '" . esc_sql($user_id) . "'
|
951 |
+
AND membership_id = '" . esc_sql($last_order->membership_id) . "'
|
952 |
+
AND status = 'active'
|
953 |
+
LIMIT 1";
|
954 |
+
|
955 |
+
$wpdb->query($sqlQuery);
|
956 |
+
|
957 |
+
//save order
|
958 |
+
$update_order->status = "success";
|
959 |
+
$update_order->save();
|
960 |
+
|
961 |
+
//remove update from list
|
962 |
+
unset($user_updates[$key]);
|
963 |
+
}
|
964 |
+
elseif($update['when'] == 'date')
|
965 |
+
{
|
966 |
+
//this is an on date update for the future, update the next on date update
|
967 |
+
if(!empty($next_on_date_update))
|
968 |
+
$next_on_date_update = min($next_on_date_update, $update['date_year'] . "-" . $update['date_month'] . "-" . $update['date_day']);
|
969 |
+
else
|
970 |
+
$next_on_date_update = $update['date_year'] . "-" . $update['date_month'] . "-" . $update['date_day'];
|
971 |
+
}
|
972 |
+
}
|
973 |
+
}
|
974 |
+
|
975 |
+
//save updates in case we removed some
|
976 |
+
update_user_meta($user_id, "pmpro_stripe_updates", $user_updates);
|
977 |
+
|
978 |
+
//save date of next on-date update to make it easier to query for these in cron job
|
979 |
+
update_user_meta($user_id, "pmpro_stripe_next_on_date_update", $next_on_date_update);
|
980 |
+
}
|
981 |
+
}
|
982 |
+
}
|
983 |
+
|
984 |
+
/**
|
985 |
+
* Process checkout and decide if a charge and or subscribe is needed
|
986 |
+
*
|
987 |
+
* @since 1.4
|
988 |
+
*/
|
989 |
+
function process(&$order)
|
990 |
+
{
|
991 |
+
//check for initial payment
|
992 |
+
if(floatval($order->InitialPayment) == 0)
|
993 |
+
{
|
994 |
+
//just subscribe
|
995 |
+
return $this->subscribe($order);
|
996 |
+
}
|
997 |
+
else
|
998 |
+
{
|
999 |
+
//charge then subscribe
|
1000 |
+
if($this->charge($order))
|
1001 |
+
{
|
1002 |
+
if(pmpro_isLevelRecurring($order->membership_level))
|
1003 |
+
{
|
1004 |
+
if($this->subscribe($order))
|
1005 |
+
{
|
1006 |
+
//yay!
|
1007 |
+
return true;
|
1008 |
+
}
|
1009 |
+
else
|
1010 |
+
{
|
1011 |
+
//try to refund initial charge
|
1012 |
+
return false;
|
1013 |
+
}
|
1014 |
+
}
|
1015 |
+
else
|
1016 |
+
{
|
1017 |
+
//only a one time charge
|
1018 |
+
$order->status = "success"; //saved on checkout page
|
1019 |
+
return true;
|
1020 |
+
}
|
1021 |
+
}
|
1022 |
+
else
|
1023 |
+
{
|
1024 |
+
if(empty($order->error))
|
1025 |
+
$order->error = __("Unknown error: Initial payment failed.", "pmpro");
|
1026 |
+
return false;
|
1027 |
+
}
|
1028 |
+
}
|
1029 |
+
}
|
1030 |
+
|
1031 |
+
/**
|
1032 |
+
* Make a one-time charge with Stripe
|
1033 |
+
*
|
1034 |
+
* @since 1.4
|
1035 |
+
*/
|
1036 |
+
function charge(&$order)
|
1037 |
+
{
|
1038 |
+
global $pmpro_currency;
|
1039 |
+
|
1040 |
+
//create a code for the order
|
1041 |
+
if(empty($order->code))
|
1042 |
+
$order->code = $order->getRandomCode();
|
1043 |
+
|
1044 |
+
//what amount to charge?
|
1045 |
+
$amount = $order->InitialPayment;
|
1046 |
+
|
1047 |
+
//tax
|
1048 |
+
$order->subtotal = $amount;
|
1049 |
+
$tax = $order->getTax(true);
|
1050 |
+
$amount = round((float)$order->subtotal + (float)$tax, 2);
|
1051 |
+
|
1052 |
+
//create a customer
|
1053 |
+
$result = $this->getCustomer($order);
|
1054 |
+
|
1055 |
+
if(empty($result))
|
1056 |
+
{
|
1057 |
+
//failed to create customer
|
1058 |
+
return false;
|
1059 |
+
}
|
1060 |
+
|
1061 |
+
//charge
|
1062 |
+
try
|
1063 |
+
{
|
1064 |
+
$response = Stripe_Charge::create(array(
|
1065 |
+
"amount" => $amount * 100, # amount in cents, again
|
1066 |
+
"currency" => strtolower($pmpro_currency),
|
1067 |
+
"customer" => $this->customer->id,
|
1068 |
+
"description" => "Order #" . $order->code . ", " . trim($order->FirstName . " " . $order->LastName) . " (" . $order->Email . ")"
|
1069 |
+
)
|
1070 |
+
);
|
1071 |
+
}
|
1072 |
+
catch (Exception $e)
|
1073 |
+
{
|
1074 |
+
//$order->status = "error";
|
1075 |
+
$order->errorcode = true;
|
1076 |
+
$order->error = "Error: " . $e->getMessage();
|
1077 |
+
$order->shorterror = $order->error;
|
1078 |
+
return false;
|
1079 |
+
}
|
1080 |
+
|
1081 |
+
if(empty($response["failure_message"]))
|
1082 |
+
{
|
1083 |
+
//successful charge
|
1084 |
+
$order->payment_transaction_id = $response["id"];
|
1085 |
+
$order->updateStatus("success");
|
1086 |
+
$order->saveOrder();
|
1087 |
+
return true;
|
1088 |
+
}
|
1089 |
+
else
|
1090 |
+
{
|
1091 |
+
//$order->status = "error";
|
1092 |
+
$order->errorcode = true;
|
1093 |
+
$order->error = $response['failure_message'];
|
1094 |
+
$order->shorterror = $response['failure_message'];
|
1095 |
+
return false;
|
1096 |
+
}
|
1097 |
+
}
|
1098 |
+
|
1099 |
+
/**
|
1100 |
+
* Get a Stripe customer object.
|
1101 |
+
*
|
1102 |
+
* If $this->customer is set, it returns it.
|
1103 |
+
* It first checks if the order has a subscription_transaction_id. If so, that's the customer id.
|
1104 |
+
* If not, it checks for a user_id on the order and searches for a customer id in the user meta.
|
1105 |
+
* If a customer id is found, it checks for a customer through the Stripe API.
|
1106 |
+
* If a customer is found and there is a stripeToken on the order passed, it will update the customer.
|
1107 |
+
* If no customer is found and there is a stripeToken on the order passed, it will create a customer.
|
1108 |
+
*
|
1109 |
+
* @since 1.4
|
1110 |
+
* @return Stripe_Customer|false
|
1111 |
+
*/
|
1112 |
+
function getCustomer(&$order = false, $force = false)
|
1113 |
+
{
|
1114 |
+
global $current_user;
|
1115 |
+
|
1116 |
+
//already have it?
|
1117 |
+
if(!empty($this->customer) && !$force)
|
1118 |
+
return $this->customer;
|
1119 |
+
|
1120 |
+
//figure out user_id and user
|
1121 |
+
if(!empty($order->user_id))
|
1122 |
+
$user_id = $order->user_id;
|
1123 |
+
|
1124 |
+
//if no id passed, check the current user
|
1125 |
+
if(empty($user_id) && !empty($current_user->ID))
|
1126 |
+
$user_id = $current_user->ID;
|
1127 |
+
|
1128 |
+
if(!empty($user_id))
|
1129 |
+
$user = get_userdata($user_id);
|
1130 |
+
else
|
1131 |
+
$user = NULL;
|
1132 |
+
|
1133 |
+
//transaction id?
|
1134 |
+
if(!empty($order->subscription_transaction_id) && strpos($order->subscription_transaction_id, "cus_") !== false)
|
1135 |
+
$customer_id = $order->subscription_transaction_id;
|
1136 |
+
else
|
1137 |
+
{
|
1138 |
+
//try based on user id
|
1139 |
+
if(!empty($user_id))
|
1140 |
+
{
|
1141 |
+
$customer_id = get_user_meta($user_id, "pmpro_stripe_customerid", true);
|
1142 |
+
}
|
1143 |
+
}
|
1144 |
+
|
1145 |
+
//get name and email values from order in case we update
|
1146 |
+
$name = trim($order->FirstName . " " . $order->LastName);
|
1147 |
+
if(empty($name) && !empty($user->ID))
|
1148 |
+
{
|
1149 |
+
$name = trim($user->first_name . " " . $user->last_name);
|
1150 |
+
|
1151 |
+
//still empty?
|
1152 |
+
if(empty($name))
|
1153 |
+
$name = $user->user_login;
|
1154 |
+
}
|
1155 |
+
elseif(empty($name))
|
1156 |
+
$name = "No Name";
|
1157 |
+
|
1158 |
+
$email = $order->Email;
|
1159 |
+
if(empty($email) && !empty($user->ID))
|
1160 |
+
{
|
1161 |
+
$email = $user->user_email;
|
1162 |
+
}
|
1163 |
+
elseif(empty($email))
|
1164 |
+
$email = "No Email";
|
1165 |
+
|
1166 |
+
//check for an existing stripe customer
|
1167 |
+
if(!empty($customer_id))
|
1168 |
+
{
|
1169 |
+
try
|
1170 |
+
{
|
1171 |
+
$this->customer = Stripe_Customer::retrieve($customer_id);
|
1172 |
+
|
1173 |
+
//update the customer description and card
|
1174 |
+
if(!empty($order->stripeToken))
|
1175 |
+
{
|
1176 |
+
$this->customer->description = $name . " (" . $email . ")";
|
1177 |
+
$this->customer->email = $email;
|
1178 |
+
$this->customer->card = $order->stripeToken;
|
1179 |
+
$this->customer->save();
|
1180 |
+
}
|
1181 |
+
|
1182 |
+
return $this->customer;
|
1183 |
+
}
|
1184 |
+
catch (Exception $e)
|
1185 |
+
{
|
1186 |
+
//assume no customer found
|
1187 |
+
}
|
1188 |
+
}
|
1189 |
+
|
1190 |
+
//no customer id, create one
|
1191 |
+
if(!empty($order->stripeToken))
|
1192 |
+
{
|
1193 |
+
try
|
1194 |
+
{
|
1195 |
+
$this->customer = Stripe_Customer::create(array(
|
1196 |
+
"description" => $name . " (" . $email . ")",
|
1197 |
+
"email" => $order->Email,
|
1198 |
+
"card" => $order->stripeToken
|
1199 |
+
));
|
1200 |
+
}
|
1201 |
+
catch (Exception $e)
|
1202 |
+
{
|
1203 |
+
$order->error = __("Error creating customer record with Stripe:", "pmpro") . " " . $e->getMessage();
|
1204 |
+
$order->shorterror = $order->error;
|
1205 |
+
return false;
|
1206 |
+
}
|
1207 |
+
|
1208 |
+
if(!empty($user_id))
|
1209 |
+
{
|
1210 |
+
//user logged in/etc
|
1211 |
+
update_user_meta($user_id, "pmpro_stripe_customerid", $this->customer->id);
|
1212 |
+
}
|
1213 |
+
else
|
1214 |
+
{
|
1215 |
+
//user not registered yet, queue it up
|
1216 |
+
global $pmpro_stripe_customer_id;
|
1217 |
+
$pmpro_stripe_customer_id = $this->customer->id;
|
1218 |
+
function pmpro_user_register_stripe_customerid($user_id)
|
1219 |
+
{
|
1220 |
+
global $pmpro_stripe_customer_id;
|
1221 |
+
update_user_meta($user_id, "pmpro_stripe_customerid", $pmpro_stripe_customer_id);
|
1222 |
+
}
|
1223 |
+
add_action("user_register", "pmpro_user_register_stripe_customerid");
|
1224 |
+
}
|
1225 |
+
|
1226 |
+
return apply_filters('pmpro_stripe_create_customer', $this->customer);
|
1227 |
+
}
|
1228 |
+
|
1229 |
+
return false;
|
1230 |
+
}
|
1231 |
+
|
1232 |
+
/**
|
1233 |
+
* Get a Stripe subscription from a PMPro order
|
1234 |
+
*
|
1235 |
+
* @since 1.8
|
1236 |
+
*/
|
1237 |
+
function getSubscription(&$order)
|
1238 |
+
{
|
1239 |
+
global $wpdb;
|
1240 |
+
|
1241 |
+
//no order?
|
1242 |
+
if(empty($order) || empty($order->code))
|
1243 |
+
return false;
|
1244 |
+
|
1245 |
+
$result = $this->getCustomer($order, true); //force so we don't get a cached sub for someone else
|
1246 |
+
|
1247 |
+
//no customer?
|
1248 |
+
if(empty($result))
|
1249 |
+
return false;
|
1250 |
+
|
1251 |
+
//is there a subscription transaction id pointing to a sub?
|
1252 |
+
if(!empty($order->subscription_transaction_id) && strpos($order->subscription_transaction_id, "sub_") !== false)
|
1253 |
+
{
|
1254 |
+
try
|
1255 |
+
{
|
1256 |
+
$sub = $this->customer->subscriptions->retrieve($order->subscription_transaction_id);
|
1257 |
+
}
|
1258 |
+
catch (Exception $e)
|
1259 |
+
{
|
1260 |
+
$order->error = __("Error creating plan with Stripe:", "pmpro") . $e->getMessage();
|
1261 |
+
$order->shorterror = $order->error;
|
1262 |
+
return false;
|
1263 |
+
}
|
1264 |
+
|
1265 |
+
return $sub;
|
1266 |
+
}
|
1267 |
+
|
1268 |
+
//no subscriptions object in customer
|
1269 |
+
if(empty($this->customer->subscriptions))
|
1270 |
+
return false;
|
1271 |
+
|
1272 |
+
//find subscription based on customer id and order/plan id
|
1273 |
+
$subscriptions = $this->customer->subscriptions->all();
|
1274 |
+
|
1275 |
+
//no subscriptions
|
1276 |
+
if(empty($subscriptions) || empty($subscriptions->data))
|
1277 |
+
return false;
|
1278 |
+
|
1279 |
+
//we really want to test against the order codes of all orders with the same subscription_transaction_id (customer id)
|
1280 |
+
$codes = $wpdb->get_col("SELECT code FROM $wpdb->pmpro_membership_orders WHERE user_id = '" . $order->user_id . "' AND subscription_transaction_id = '" . $order->subscription_transaction_id . "' AND status NOT IN('refunded', 'review', 'token', 'error')");
|
1281 |
+
|
1282 |
+
//find the one for this order
|
1283 |
+
foreach($subscriptions->data as $sub)
|
1284 |
+
{
|
1285 |
+
if(in_array($sub->plan->id, $codes))
|
1286 |
+
{
|
1287 |
+
return $sub;
|
1288 |
+
}
|
1289 |
+
}
|
1290 |
+
|
1291 |
+
//didn't find anything yet
|
1292 |
+
return false;
|
1293 |
+
}
|
1294 |
+
|
1295 |
+
/**
|
1296 |
+
* Create a new subscription with Stripe
|
1297 |
+
*
|
1298 |
+
* @since 1.4
|
1299 |
+
*/
|
1300 |
+
function subscribe(&$order, $checkout = true)
|
1301 |
+
{
|
1302 |
+
global $pmpro_currency;
|
1303 |
+
|
1304 |
+
//create a code for the order
|
1305 |
+
if(empty($order->code))
|
1306 |
+
$order->code = $order->getRandomCode();
|
1307 |
+
|
1308 |
+
//filter order before subscription. use with care.
|
1309 |
+
$order = apply_filters("pmpro_subscribe_order", $order, $this);
|
1310 |
+
|
1311 |
+
//figure out the user
|
1312 |
+
if(!empty($order->user_id))
|
1313 |
+
$user_id = $order->user_id;
|
1314 |
+
else
|
1315 |
+
{
|
1316 |
+
global $current_user;
|
1317 |
+
$user_id = $current_user->ID;
|
1318 |
+
}
|
1319 |
+
|
1320 |
+
//setup customer
|
1321 |
+
$result = $this->getCustomer($order);
|
1322 |
+
if(empty($result))
|
1323 |
+
return false; //error retrieving customer
|
1324 |
+
|
1325 |
+
//set subscription id to custom id
|
1326 |
+
$order->subscription_transaction_id = $this->customer['id']; //transaction id is the customer id, we save it in user meta later too
|
1327 |
+
|
1328 |
+
//figure out the amounts
|
1329 |
+
$amount = $order->PaymentAmount;
|
1330 |
+
$amount_tax = $order->getTaxForPrice($amount);
|
1331 |
+
$amount = round((float)$amount + (float)$amount_tax, 2);
|
1332 |
+
|
1333 |
+
/*
|
1334 |
+
There are two parts to the trial. Part 1 is simply the delay until the first payment
|
1335 |
+
since we are doing the first payment as a separate transaction.
|
1336 |
+
The second part is the actual "trial" set by the admin.
|
1337 |
+
|
1338 |
+
Stripe only supports Year or Month for billing periods, but we account for Days and Weeks just in case.
|
1339 |
+
*/
|
1340 |
+
//figure out the trial length (first payment handled by initial charge)
|
1341 |
+
if($order->BillingPeriod == "Year")
|
1342 |
+
$trial_period_days = $order->BillingFrequency * 365; //annual
|
1343 |
+
elseif($order->BillingPeriod == "Day")
|
1344 |
+
$trial_period_days = $order->BillingFrequency * 1; //daily
|
1345 |
+
elseif($order->BillingPeriod == "Week")
|
1346 |
+
$trial_period_days = $order->BillingFrequency * 7; //weekly
|
1347 |
+
else
|
1348 |
+
$trial_period_days = $order->BillingFrequency * 30; //assume monthly
|
1349 |
+
|
1350 |
+
//convert to a profile start date
|
1351 |
+
$order->ProfileStartDate = date("Y-m-d", strtotime("+ " . $trial_period_days . " Day", current_time("timestamp"))) . "T0:0:0";
|
1352 |
+
|
1353 |
+
//filter the start date
|
1354 |
+
$order->ProfileStartDate = apply_filters("pmpro_profile_start_date", $order->ProfileStartDate, $order);
|
1355 |
+
|
1356 |
+
//convert back to days
|
1357 |
+
$trial_period_days = ceil(abs(strtotime(date("Y-m-d"), current_time("timestamp")) - strtotime($order->ProfileStartDate, current_time("timestamp"))) / 86400);
|
1358 |
+
|
1359 |
+
//for free trials, just push the start date of the subscription back
|
1360 |
+
if(!empty($order->TrialBillingCycles) && $order->TrialAmount == 0)
|
1361 |
+
{
|
1362 |
+
$trialOccurrences = (int)$order->TrialBillingCycles;
|
1363 |
+
if($order->BillingPeriod == "Year")
|
1364 |
+
$trial_period_days = $trial_period_days + (365 * $order->BillingFrequency * $trialOccurrences); //annual
|
1365 |
+
elseif($order->BillingPeriod == "Day")
|
1366 |
+
$trial_period_days = $trial_period_days + (1 * $order->BillingFrequency * $trialOccurrences); //daily
|
1367 |
+
elseif($order->BillingPeriod == "Week")
|
1368 |
+
$trial_period_days = $trial_period_days + (7 * $order->BillingFrequency * $trialOccurrences); //weekly
|
1369 |
+
else
|
1370 |
+
$trial_period_days = $trial_period_days + (30 * $order->BillingFrequency * $trialOccurrences); //assume monthly
|
1371 |
+
}
|
1372 |
+
elseif(!empty($order->TrialBillingCycles))
|
1373 |
+
{
|
1374 |
+
/*
|
1375 |
+
Let's set the subscription to the trial and give the user an "update" to change the sub later to full price (since v2.0)
|
1376 |
+
|
1377 |
+
This will force TrialBillingCycles > 1 to act as if they were 1
|
1378 |
+
*/
|
1379 |
+
$new_user_updates = array();
|
1380 |
+
$new_user_updates[] = array(
|
1381 |
+
'when' => 'payment',
|
1382 |
+
'billing_amount' => $order->PaymentAmount,
|
1383 |
+
'cycle_period' => $order->BillingPeriod,
|
1384 |
+
'cycle_number' => $order->BillingFrequency
|
1385 |
+
);
|
1386 |
+
|
1387 |
+
//now amount to equal the trial #s
|
1388 |
+
$amount = $order->TrialAmount;
|
1389 |
+
$amount_tax = $order->getTaxForPrice($amount);
|
1390 |
+
$amount = round((float)$amount + (float)$amount_tax, 2);
|
1391 |
+
}
|
1392 |
+
|
1393 |
+
//create a plan
|
1394 |
+
try
|
1395 |
+
{
|
1396 |
+
$plan = array(
|
1397 |
+
"amount" => $amount * 100,
|
1398 |
+
"interval_count" => $order->BillingFrequency,
|
1399 |
+
"interval" => strtolower($order->BillingPeriod),
|
1400 |
+
"trial_period_days" => $trial_period_days,
|
1401 |
+
"name" => $order->membership_name . " for order " . $order->code,
|
1402 |
+
"currency" => strtolower($pmpro_currency),
|
1403 |
+
"id" => $order->code
|
1404 |
+
);
|
1405 |
+
|
1406 |
+
$plan = Stripe_Plan::create(apply_filters('pmpro_stripe_create_plan_array', $plan));
|
1407 |
+
}
|
1408 |
+
catch (Exception $e)
|
1409 |
+
{
|
1410 |
+
$order->error = __("Error creating plan with Stripe:", "pmpro") . $e->getMessage();
|
1411 |
+
$order->shorterror = $order->error;
|
1412 |
+
return false;
|
1413 |
+
}
|
1414 |
+
|
1415 |
+
//before subscribing, let's clear out the updates so we don't trigger any during sub
|
1416 |
+
if(!empty($user_id))
|
1417 |
+
{
|
1418 |
+
$old_user_updates = get_user_meta($user_id, "pmpro_stripe_updates", true);
|
1419 |
+
update_user_meta($user_id, "pmpro_stripe_updates", array());
|
1420 |
+
}
|
1421 |
+
|
1422 |
+
if(empty($order->subscription_transaction_id) && !empty($this->customer['id']))
|
1423 |
+
$order->subscription_transaction_id = $this->customer['id'];
|
1424 |
+
|
1425 |
+
//subscribe to the plan
|
1426 |
+
try
|
1427 |
+
{
|
1428 |
+
$subscription = array("plan" => $order->code);
|
1429 |
+
$result = $this->customer->subscriptions->create(apply_filters('pmpro_stripe_create_subscription_array', $subscription));
|
1430 |
+
}
|
1431 |
+
catch (Exception $e)
|
1432 |
+
{
|
1433 |
+
//try to delete the plan
|
1434 |
+
$plan->delete();
|
1435 |
+
|
1436 |
+
//give the user any old updates back
|
1437 |
+
if(!empty($user_id))
|
1438 |
+
update_user_meta($user_id, "pmpro_stripe_updates", $old_user_updates);
|
1439 |
+
|
1440 |
+
//return error
|
1441 |
+
$order->error = __("Error subscribing customer to plan with Stripe:", "pmpro") . $e->getMessage();
|
1442 |
+
$order->shorterror = $order->error;
|
1443 |
+
return false;
|
1444 |
+
}
|
1445 |
+
|
1446 |
+
//delete the plan
|
1447 |
+
$plan = Stripe_Plan::retrieve($order->code);
|
1448 |
+
$plan->delete();
|
1449 |
+
|
1450 |
+
//if we got this far, we're all good
|
1451 |
+
$order->status = "success";
|
1452 |
+
$order->subscription_transaction_id = $result['id'];
|
1453 |
+
|
1454 |
+
//save new updates if this is at checkout
|
1455 |
+
if($checkout)
|
1456 |
+
{
|
1457 |
+
//empty out updates unless set above
|
1458 |
+
if(empty($new_user_updates))
|
1459 |
+
$new_user_updates = array();
|
1460 |
+
|
1461 |
+
//update user meta
|
1462 |
+
if(!empty($user_id))
|
1463 |
+
update_user_meta($user_id, "pmpro_stripe_updates", $new_user_updates);
|
1464 |
+
else
|
1465 |
+
{
|
1466 |
+
//need to remember the user updates to save later
|
1467 |
+
global $pmpro_stripe_updates;
|
1468 |
+
$pmpro_stripe_updates = $new_user_updates;
|
1469 |
+
function pmpro_user_register_stripe_updates($user_id)
|
1470 |
+
{
|
1471 |
+
global $pmpro_stripe_updates;
|
1472 |
+
update_user_meta($user_id, "pmpro_stripe_updates", $pmpro_stripe_updates);
|
1473 |
+
}
|
1474 |
+
add_action("user_register", "pmpro_user_register_stripe_updates");
|
1475 |
+
}
|
1476 |
+
}
|
1477 |
+
else
|
1478 |
+
{
|
1479 |
+
//give them their old updates back
|
1480 |
+
update_user_meta($user_id, "pmpro_stripe_updates", $old_user_updates);
|
1481 |
+
}
|
1482 |
+
|
1483 |
+
return true;
|
1484 |
+
}
|
1485 |
+
|
1486 |
+
/**
|
1487 |
+
* Helper method to update the customer info via getCustomer
|
1488 |
+
*
|
1489 |
+
* @since 1.4
|
1490 |
+
*/
|
1491 |
+
function update(&$order)
|
1492 |
+
{
|
1493 |
+
//we just have to run getCustomer which will look for the customer and update it with the new token
|
1494 |
+
$result = $this->getCustomer($order);
|
1495 |
+
|
1496 |
+
if(!empty($result))
|
1497 |
+
{
|
1498 |
+
return true;
|
1499 |
+
}
|
1500 |
+
else
|
1501 |
+
{
|
1502 |
+
return false; //couldn't find the customer
|
1503 |
+
}
|
1504 |
+
}
|
1505 |
+
|
1506 |
+
/**
|
1507 |
+
* Cancel a subscription at Stripe
|
1508 |
+
*
|
1509 |
+
* @since 1.4
|
1510 |
+
*/
|
1511 |
+
function cancel(&$order, $update_status = true)
|
1512 |
+
{
|
1513 |
+
//no matter what happens below, we're going to cancel the order in our system
|
1514 |
+
if($update_status)
|
1515 |
+
$order->updateStatus("cancelled");
|
1516 |
+
|
1517 |
+
//require a subscription id
|
1518 |
+
if(empty($order->subscription_transaction_id))
|
1519 |
+
return false;
|
1520 |
+
|
1521 |
+
//find the customer
|
1522 |
+
$result = $this->getCustomer($order);
|
1523 |
+
|
1524 |
+
if(!empty($result))
|
1525 |
+
{
|
1526 |
+
//find subscription with this order code
|
1527 |
+
$subscription = $this->getSubscription($order);
|
1528 |
+
|
1529 |
+
if(!empty($subscription))
|
1530 |
+
{
|
1531 |
+
if($this->cancelSubscriptionAtGateway($subscription))
|
1532 |
+
{
|
1533 |
+
//we're okay, going to return true later
|
1534 |
+
}
|
1535 |
+
else
|
1536 |
+
{
|
1537 |
+
$order->error = __("Could not cancel old subscription.", "pmpro");
|
1538 |
+
$order->shorterror = $order->error;
|
1539 |
+
|
1540 |
+
return false;
|
1541 |
+
}
|
1542 |
+
}
|
1543 |
+
|
1544 |
+
/*
|
1545 |
+
Clear updates for this user. (But not if checking out, we would have already done that.)
|
1546 |
+
*/
|
1547 |
+
if(empty($_REQUEST['submit-checkout']))
|
1548 |
+
update_user_meta($order->user_id, "pmpro_stripe_updates", array());
|
1549 |
+
|
1550 |
+
return true;
|
1551 |
+
}
|
1552 |
+
else
|
1553 |
+
{
|
1554 |
+
$order->error = __("Could not find the customer.", "pmpro");
|
1555 |
+
$order->shorterror = $order->error;
|
1556 |
+
return false; //no customer found
|
1557 |
+
}
|
1558 |
+
}
|
1559 |
+
|
1560 |
+
/**
|
1561 |
+
* Helper method to cancel a subscription at Stripe and also clear up any upaid invoices.
|
1562 |
+
*
|
1563 |
+
* @since 1.8
|
1564 |
+
*/
|
1565 |
+
function cancelSubscriptionAtGateway($subscription)
|
1566 |
+
{
|
1567 |
+
//need a valid sub
|
1568 |
+
if(empty($subscription->id))
|
1569 |
+
return false;
|
1570 |
+
|
1571 |
+
//make sure we get the customer for this subscription
|
1572 |
+
$order = new MemberOrder();
|
1573 |
+
$order->getLastMemberOrderBySubscriptionTransactionID($subscription->id);
|
1574 |
+
|
1575 |
+
//no order?
|
1576 |
+
if(empty($order))
|
1577 |
+
{
|
1578 |
+
//lets cancel anyway, but this is suspicious
|
1579 |
+
$r = $subscription->cancel();
|
1580 |
+
|
1581 |
+
return true;
|
1582 |
+
}
|
1583 |
+
|
1584 |
+
//okay have an order, so get customer so we can cancel invoices too
|
1585 |
+
$this->getCustomer($order);
|
1586 |
+
|
1587 |
+
//get open invoices
|
1588 |
+
$invoices = $this->customer->invoices();
|
1589 |
+
$invoices = $invoices->all();
|
1590 |
+
|
1591 |
+
//found it, cancel it
|
1592 |
+
try
|
1593 |
+
{
|
1594 |
+
//find any open invoices for this subscription and forgive them
|
1595 |
+
if(!empty($invoices))
|
1596 |
+
{
|
1597 |
+
foreach($invoices->data as $invoice)
|
1598 |
+
{
|
1599 |
+
if(!$invoice->closed && $invoice->subscription == $subscription->id)
|
1600 |
+
{
|
1601 |
+
$invoice->closed = true;
|
1602 |
+
$invoice->save();
|
1603 |
+
}
|
1604 |
+
}
|
1605 |
+
}
|
1606 |
+
|
1607 |
+
//cancel
|
1608 |
+
$r = $subscription->cancel();
|
1609 |
+
|
1610 |
+
return true;
|
1611 |
+
}
|
1612 |
+
catch(Exception $e)
|
1613 |
+
{
|
1614 |
+
return false;
|
1615 |
+
}
|
1616 |
+
}
|
1617 |
}
|
classes/gateways/class.pmprogateway_twocheckout.php
CHANGED
@@ -12,6 +12,13 @@
|
|
12 |
if(!class_exists("Twocheckout"))
|
13 |
require_once(dirname(__FILE__) . "/../../includes/lib/Twocheckout/Twocheckout.php");
|
14 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
15 |
$this->gateway = $gateway;
|
16 |
return $this->gateway;
|
17 |
}
|
@@ -68,6 +75,7 @@
|
|
68 |
'gateway_environment',
|
69 |
'twocheckout_apiusername',
|
70 |
'twocheckout_apipassword',
|
|
|
71 |
'twocheckout_accountnumber',
|
72 |
'twocheckout_secretword',
|
73 |
'currency',
|
@@ -114,6 +122,7 @@
|
|
114 |
</th>
|
115 |
<td>
|
116 |
<input type="text" id="twocheckout_apiusername" name="twocheckout_apiusername" size="60" value="<?php echo esc_attr($values['twocheckout_apiusername'])?>" />
|
|
|
117 |
</td>
|
118 |
</tr>
|
119 |
<tr class="gateway gateway_twocheckout" <?php if($gateway != "twocheckout") { ?>style="display: none;"<?php } ?>>
|
@@ -122,6 +131,16 @@
|
|
122 |
</th>
|
123 |
<td>
|
124 |
<input type="text" id="twocheckout_apipassword" name="twocheckout_apipassword" size="60" value="<?php echo esc_attr($values['twocheckout_apipassword'])?>" />
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
125 |
</td>
|
126 |
</tr>
|
127 |
<tr class="gateway gateway_twocheckout" <?php if($gateway != "twocheckout") { ?>style="display: none;"<?php } ?>>
|
@@ -130,6 +149,7 @@
|
|
130 |
</th>
|
131 |
<td>
|
132 |
<input type="text" name="twocheckout_accountnumber" size="60" value="<?php echo $values['twocheckout_accountnumber']?>" />
|
|
|
133 |
</td>
|
134 |
</tr>
|
135 |
<tr class="gateway gateway_twocheckout" <?php if($gateway != "twocheckout") { ?>style="display: none;"<?php } ?>>
|
@@ -138,6 +158,7 @@
|
|
138 |
</th>
|
139 |
<td>
|
140 |
<input type="text" name="twocheckout_secretword" size="60" value="<?php echo $values['twocheckout_secretword']?>" />
|
|
|
141 |
</td>
|
142 |
</tr>
|
143 |
<tr class="gateway gateway_twocheckout" <?php if($gateway != "twocheckout") { ?>style="display: none;"<?php } ?>>
|
@@ -145,7 +166,8 @@
|
|
145 |
<label><?php _e('TwoCheckout INS URL', 'pmpro');?>:</label>
|
146 |
</th>
|
147 |
<td>
|
148 |
-
<p><?php _e('To fully integrate with 2Checkout, be sure to
|
|
|
149 |
</td>
|
150 |
</tr>
|
151 |
<?php
|
@@ -204,7 +226,7 @@
|
|
204 |
*/
|
205 |
static function pmpro_checkout_before_change_membership_level($user_id, $morder)
|
206 |
{
|
207 |
-
global $discount_code_id;
|
208 |
|
209 |
//if no order, no need to pay
|
210 |
if(empty($morder))
|
@@ -246,9 +268,7 @@
|
|
246 |
function sendToTwocheckout(&$order)
|
247 |
{
|
248 |
global $pmpro_currency;
|
249 |
-
|
250 |
-
Twocheckout::setCredentials( pmpro_getOption("twocheckout_apiusername"), pmpro_getOption("twocheckout_apipassword") );
|
251 |
-
|
252 |
$tco_args = array(
|
253 |
'sid' => pmpro_getOption("twocheckout_accountnumber"),
|
254 |
'mode' => '2CO', // will always be 2CO according to docs (@see https://www.2checkout.com/documentation/checkout/parameter-sets/pass-through-products/)
|
@@ -295,9 +315,17 @@
|
|
295 |
}
|
296 |
|
297 |
// Demo mode?
|
298 |
-
$
|
299 |
-
|
|
|
|
|
|
|
|
|
|
|
300 |
$tco_args['demo'] = 'Y';
|
|
|
|
|
|
|
301 |
|
302 |
// Trial?
|
303 |
//li_#_startup_fee Any start up fees for the product or service. Can be negative to provide discounted first installment pricing, but cannot equal or surpass the product price.
|
@@ -322,39 +350,64 @@
|
|
322 |
|
323 |
$ptpStr = apply_filters( 'pmpro_twocheckout_ptpstr', $ptpStr, $order );
|
324 |
|
325 |
-
|
326 |
-
|
|
|
327 |
|
328 |
-
//
|
329 |
-
$
|
|
|
|
|
|
|
|
|
330 |
|
331 |
-
//
|
332 |
-
//die();
|
333 |
wp_redirect( $tco_url );
|
334 |
exit;
|
335 |
}
|
336 |
|
337 |
function cancel(&$order) {
|
338 |
-
//
|
339 |
-
|
340 |
-
|
341 |
-
|
|
|
|
|
342 |
|
343 |
-
|
344 |
-
|
345 |
-
|
346 |
-
|
347 |
-
|
348 |
-
|
349 |
-
|
350 |
-
|
351 |
-
|
352 |
-
|
353 |
-
|
354 |
-
|
355 |
-
|
|
|
356 |
}
|
|
|
|
|
357 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
358 |
return $order;
|
359 |
}
|
360 |
}
|
12 |
if(!class_exists("Twocheckout"))
|
13 |
require_once(dirname(__FILE__) . "/../../includes/lib/Twocheckout/Twocheckout.php");
|
14 |
|
15 |
+
//set API connection vars
|
16 |
+
Twocheckout::sellerId(pmpro_getOption('twocheckout_accountnumber'));
|
17 |
+
Twocheckout::privateKey(pmpro_getOption('twocheckout_privatekey'));
|
18 |
+
Twocheckout::username(pmpro_getOption('twocheckout_apiusername'));
|
19 |
+
Twocheckout::password(pmpro_getOption('twocheckout_apipassword'));
|
20 |
+
Twocheckout::$verifySSL = false;
|
21 |
+
|
22 |
$this->gateway = $gateway;
|
23 |
return $this->gateway;
|
24 |
}
|
75 |
'gateway_environment',
|
76 |
'twocheckout_apiusername',
|
77 |
'twocheckout_apipassword',
|
78 |
+
'twocheckout_privatekey',
|
79 |
'twocheckout_accountnumber',
|
80 |
'twocheckout_secretword',
|
81 |
'currency',
|
122 |
</th>
|
123 |
<td>
|
124 |
<input type="text" id="twocheckout_apiusername" name="twocheckout_apiusername" size="60" value="<?php echo esc_attr($values['twocheckout_apiusername'])?>" />
|
125 |
+
<br /><small><?php _e('Go to Account » User Management in 2Checkout and create a user with API Access and API Updating.');?></small>
|
126 |
</td>
|
127 |
</tr>
|
128 |
<tr class="gateway gateway_twocheckout" <?php if($gateway != "twocheckout") { ?>style="display: none;"<?php } ?>>
|
131 |
</th>
|
132 |
<td>
|
133 |
<input type="text" id="twocheckout_apipassword" name="twocheckout_apipassword" size="60" value="<?php echo esc_attr($values['twocheckout_apipassword'])?>" />
|
134 |
+
<br /><small><?php _e('Password for the API user created.');?></small>
|
135 |
+
</td>
|
136 |
+
</tr>
|
137 |
+
<tr class="gateway gateway_twocheckout" <?php if($gateway != "twocheckout") { ?>style="display: none;"<?php } ?>>
|
138 |
+
<th scope="row" valign="top">
|
139 |
+
<label for="twocheckout_privatekey"><?php _e('API Private Key', 'pmpro');?>:</label>
|
140 |
+
</th>
|
141 |
+
<td>
|
142 |
+
<input type="text" name="twocheckout_privatekey" size="60" value="<?php echo $values['twocheckout_privatekey']?>" />
|
143 |
+
<br /><small><?php _e('Go to API in 2Checkout and generate a new key pair. Paste the Private Key here.');?></small>
|
144 |
</td>
|
145 |
</tr>
|
146 |
<tr class="gateway gateway_twocheckout" <?php if($gateway != "twocheckout") { ?>style="display: none;"<?php } ?>>
|
149 |
</th>
|
150 |
<td>
|
151 |
<input type="text" name="twocheckout_accountnumber" size="60" value="<?php echo $values['twocheckout_accountnumber']?>" />
|
152 |
+
<br /><small><?php _e('Click on the profile icon in 2Checkout to find your Account Number.');?></small>
|
153 |
</td>
|
154 |
</tr>
|
155 |
<tr class="gateway gateway_twocheckout" <?php if($gateway != "twocheckout") { ?>style="display: none;"<?php } ?>>
|
158 |
</th>
|
159 |
<td>
|
160 |
<input type="text" name="twocheckout_secretword" size="60" value="<?php echo $values['twocheckout_secretword']?>" />
|
161 |
+
<br /><small><?php _e('Go to Account » Site Management. Look under Checkout Options to find the Secret Word.');?></small>
|
162 |
</td>
|
163 |
</tr>
|
164 |
<tr class="gateway gateway_twocheckout" <?php if($gateway != "twocheckout") { ?>style="display: none;"<?php } ?>>
|
166 |
<label><?php _e('TwoCheckout INS URL', 'pmpro');?>:</label>
|
167 |
</th>
|
168 |
<td>
|
169 |
+
<p><?php _e('To fully integrate with 2Checkout, be sure to use the following for your INS URL and Approved URL', 'pmpro');?> <pre><?php echo admin_url("admin-ajax.php") . "?action=twocheckout-ins";?></pre></p>
|
170 |
+
|
171 |
</td>
|
172 |
</tr>
|
173 |
<?php
|
226 |
*/
|
227 |
static function pmpro_checkout_before_change_membership_level($user_id, $morder)
|
228 |
{
|
229 |
+
global $wpdb, $discount_code_id;
|
230 |
|
231 |
//if no order, no need to pay
|
232 |
if(empty($morder))
|
268 |
function sendToTwocheckout(&$order)
|
269 |
{
|
270 |
global $pmpro_currency;
|
271 |
+
|
|
|
|
|
272 |
$tco_args = array(
|
273 |
'sid' => pmpro_getOption("twocheckout_accountnumber"),
|
274 |
'mode' => '2CO', // will always be 2CO according to docs (@see https://www.2checkout.com/documentation/checkout/parameter-sets/pass-through-products/)
|
315 |
}
|
316 |
|
317 |
// Demo mode?
|
318 |
+
if(empty($order->gateway_environment))
|
319 |
+
$gateway_environment = pmpro_getOption("gateway_environment");
|
320 |
+
else
|
321 |
+
$gateway_environment = $order->gateway_environment;
|
322 |
+
if("sandbox" === $gateway_environment || "beta-sandbox" === $gateway_environment)
|
323 |
+
{
|
324 |
+
Twocheckout::sandbox(true);
|
325 |
$tco_args['demo'] = 'Y';
|
326 |
+
}
|
327 |
+
else
|
328 |
+
Twocheckout::sandbox(false);
|
329 |
|
330 |
// Trial?
|
331 |
//li_#_startup_fee Any start up fees for the product or service. Can be negative to provide discounted first installment pricing, but cannot equal or surpass the product price.
|
350 |
|
351 |
$ptpStr = apply_filters( 'pmpro_twocheckout_ptpstr', $ptpStr, $order );
|
352 |
|
353 |
+
///useful for debugging
|
354 |
+
///echo str_replace("&", "&<br />", $ptpStr);
|
355 |
+
///exit;
|
356 |
|
357 |
+
//figure out gateway environment and URL to use
|
358 |
+
if($gateway_environment == "live")
|
359 |
+
$host = "www.2checkout.com";
|
360 |
+
else
|
361 |
+
$host = "sandbox.2checkout.com";
|
362 |
+
$tco_url = 'https://' . $host . '/checkout/purchase' . $ptpStr;
|
363 |
|
364 |
+
//redirect to 2checkout
|
|
|
365 |
wp_redirect( $tco_url );
|
366 |
exit;
|
367 |
}
|
368 |
|
369 |
function cancel(&$order) {
|
370 |
+
//no matter what happens below, we're going to cancel the order in our system
|
371 |
+
$order->updateStatus("cancelled");
|
372 |
+
|
373 |
+
//require a subscription id
|
374 |
+
if(empty($order->subscription_transaction_id))
|
375 |
+
return false;
|
376 |
|
377 |
+
//build api params
|
378 |
+
$params = array();
|
379 |
+
$params['sale_id'] = $order->subscription_transaction_id;
|
380 |
+
|
381 |
+
// Demo mode?
|
382 |
+
if(empty($order->gateway_environment))
|
383 |
+
$gateway_environment = pmpro_getOption("gateway_environment");
|
384 |
+
else
|
385 |
+
$gateway_environment = $order->gateway_environment;
|
386 |
+
|
387 |
+
if("sandbox" === $gateway_environment || "beta-sandbox" === $gateway_environment)
|
388 |
+
{
|
389 |
+
Twocheckout::sandbox(true);
|
390 |
+
$params['demo'] = 'Y';
|
391 |
}
|
392 |
+
else
|
393 |
+
Twocheckout::sandbox(false);
|
394 |
|
395 |
+
$result = Twocheckout_Sale::stop( $params ); // Stop the recurring billing
|
396 |
+
|
397 |
+
// Successfully cancelled
|
398 |
+
if (isset($result['response_code']) && $result['response_code'] === 'OK') {
|
399 |
+
$order->updateStatus("cancelled");
|
400 |
+
return true;
|
401 |
+
}
|
402 |
+
// Failed
|
403 |
+
else {
|
404 |
+
$order->status = "error";
|
405 |
+
$order->errorcode = $result->getCode();
|
406 |
+
$order->error = $result->getMessage();
|
407 |
+
|
408 |
+
return false;
|
409 |
+
}
|
410 |
+
|
411 |
return $order;
|
412 |
}
|
413 |
}
|
css/admin.css
CHANGED
@@ -1,114 +1,118 @@
|
|
1 |
-
/* icon */
|
2 |
-
#wp-admin-bar-paid-memberships-pro .ab-item .ab-icon:before {
|
3 |
-
font-family: "dashicons";
|
4 |
-
content: "\f307";
|
5 |
-
}
|
6 |
-
.pmpro_admin tr td .dashicons {padding-top: 5px; }
|
7 |
-
|
8 |
-
/* header/etc */
|
9 |
-
.pmpro_admin {background: url(../images/Paid-Memberships-Pro_watermark.png) bottom right no-repeat !important; padding: 1em 0 70px 0; }
|
10 |
-
|
11 |
-
.pmpro_admin .pmpro_banner h2 {float: left; }
|
12 |
-
.pmpro_admin .pmpro_banner .pmpro_meta {float: left; margin: 26px 0 0 0; font-size: 12px; }
|
13 |
-
.pmpro_admin .pmpro_banner .pmpro_meta .pmpro_tag-blue {margin: 0 0 0 5px; }
|
14 |
-
.pmpro_admin .pmpro_banner .pmpro_logo {float: left; margin: 0 1em 0 0; width: 350px; height: 75px; }
|
15 |
-
.pmpro_admin .pmpro_banner ul.pmpro_menu {clear: both; border: 1px solid #CCC; border-radius: 5px; -moz-border-radius: 5px; background: #FFF; }
|
16 |
-
.pmpro_admin .pmpro_banner ul.pmpro_menu li {display: inline-block; margin: 10px 0; padding: 0px 10px; border-right: 1px solid #CCC; }
|
17 |
-
.pmpro_admin .pmpro_banner ul.pmpro_menu li a, .pmpro_admin .pmpro_banner ul.pmpro_menu li a:link {color: #1e0741; text-decoration: none; }
|
18 |
-
.pmpro_admin .pmpro_banner ul.pmpro_menu li a:hover {text-decoration: underline; color: #412f5b; }
|
19 |
-
|
20 |
-
.pmpro_admin .pmpro_tag-grey {display: inline-block; font-size: 11px; font-weight: bold; position: relative; padding: 2px 5px; border: 1px solid #CCC; background: whiteSmoke; border-radius: 10px; -moz-border-radius: 10px; -webkit-border-radius: 10px; }
|
21 |
-
.pmpro_admin .pmpro_tag-blue {display: inline-block; font-size: 11px; font-weight: bold; position: relative; padding: 2px 5px; border: 1px solid #2997c8; border-radius: 10px; -moz-border-radius: 10px; -webkit-border-radius: 10px; background: #2997c8; color: #FFF; text-decoration: none; }
|
22 |
-
.pmpro_admin a.pmpro_tag-blue:hover {background: #77a02e; border: 1px solid #77a02e; }
|
23 |
-
|
24 |
-
.pmpro_admin .topborder {border-top: 1px solid #CCC; margin-top: 1em; padding-top: 1em; }
|
25 |
-
.pmpro_admin #editorcontainer #description {width: 100%; height: 180px; }
|
26 |
-
.pmpro_admin .widefat {margin-top: 1em; }
|
27 |
-
|
28 |
-
/* checkboxes */
|
29 |
-
.checkbox_box {width: 300px; background: #FFFFFF; border: 1px solid #CCC;}
|
30 |
-
.checkbox_box div {border-bottom: 1px solid #CCC; padding: 3px;}
|
31 |
-
.checkbox_box .clickable {cursor: pointer;}
|
32 |
-
.checkbox_box .clickable:hover {background: #FFC;}
|
33 |
-
|
34 |
-
/* levels */
|
35 |
-
tr.pmpro_gray td {color: #AAA;}
|
36 |
-
tr td.level_name a {font-size: 115%; font-weight: bold; }
|
37 |
-
|
38 |
-
|
39 |
-
tr.
|
40 |
-
tr.
|
41 |
-
|
42 |
-
|
43 |
-
|
44 |
-
.
|
45 |
-
|
46 |
-
|
47 |
-
|
48 |
-
.
|
49 |
-
|
50 |
-
.
|
51 |
-
.
|
52 |
-
.
|
53 |
-
|
54 |
-
|
55 |
-
|
56 |
-
|
57 |
-
|
58 |
-
|
59 |
-
|
60 |
-
|
61 |
-
|
62 |
-
.
|
63 |
-
.
|
64 |
-
|
65 |
-
|
66 |
-
|
67 |
-
|
68 |
-
|
69 |
-
|
70 |
-
|
71 |
-
div.pmpro_pagination
|
72 |
-
|
73 |
-
|
74 |
-
|
75 |
-
|
76 |
-
|
77 |
-
.
|
78 |
-
|
79 |
-
|
80 |
-
.pmpro_admin .widgets-holder-wrap
|
81 |
-
.pmpro_admin .widgets-holder-wrap .widget
|
82 |
-
.pmpro_admin
|
83 |
-
.pmpro_admin .widgets-holder-wrap .widget-
|
84 |
-
.pmpro_admin .widgets-holder-wrap .widget-
|
85 |
-
.pmpro_admin .widgets-holder-wrap .widget-
|
86 |
-
|
87 |
-
.pmpro_admin .widgets-holder-wrap .
|
88 |
-
.pmpro_admin .widgets-holder-wrap .
|
89 |
-
|
90 |
-
|
91 |
-
.pmpro_admin .widgets-holder-wrap .widget-
|
92 |
-
|
93 |
-
|
94 |
-
|
95 |
-
}
|
96 |
-
|
97 |
-
|
98 |
-
.auto-fold .pmpro_admin .widgets-holder-wrap .widget {
|
99 |
-
|
100 |
-
|
101 |
-
|
102 |
-
|
103 |
-
.
|
104 |
-
|
105 |
-
|
106 |
-
|
107 |
-
.
|
108 |
-
.
|
109 |
-
|
110 |
-
|
111 |
-
|
112 |
-
.
|
113 |
-
.
|
|
|
|
|
|
|
|
|
114 |
.js .postbox.pmpro_clickable h3 {cursor: pointer;}
|
1 |
+
/* icon */
|
2 |
+
#wp-admin-bar-paid-memberships-pro .ab-item .ab-icon:before {
|
3 |
+
font-family: "dashicons";
|
4 |
+
content: "\f307";
|
5 |
+
}
|
6 |
+
.pmpro_admin tr td .dashicons {padding-top: 5px; }
|
7 |
+
|
8 |
+
/* header/etc */
|
9 |
+
.pmpro_admin {background: url(../images/Paid-Memberships-Pro_watermark.png) bottom right no-repeat !important; padding: 1em 0 70px 0; }
|
10 |
+
|
11 |
+
.pmpro_admin .pmpro_banner h2 {float: left; }
|
12 |
+
.pmpro_admin .pmpro_banner .pmpro_meta {float: left; margin: 26px 0 0 0; font-size: 12px; }
|
13 |
+
.pmpro_admin .pmpro_banner .pmpro_meta .pmpro_tag-blue {margin: 0 0 0 5px; }
|
14 |
+
.pmpro_admin .pmpro_banner .pmpro_logo {float: left; margin: 0 1em 0 0; width: 350px; height: 75px; }
|
15 |
+
.pmpro_admin .pmpro_banner ul.pmpro_menu {clear: both; border: 1px solid #CCC; border-radius: 5px; -moz-border-radius: 5px; background: #FFF; }
|
16 |
+
.pmpro_admin .pmpro_banner ul.pmpro_menu li {display: inline-block; margin: 10px 0; padding: 0px 10px; border-right: 1px solid #CCC; }
|
17 |
+
.pmpro_admin .pmpro_banner ul.pmpro_menu li a, .pmpro_admin .pmpro_banner ul.pmpro_menu li a:link {color: #1e0741; text-decoration: none; }
|
18 |
+
.pmpro_admin .pmpro_banner ul.pmpro_menu li a:hover {text-decoration: underline; color: #412f5b; }
|
19 |
+
|
20 |
+
.pmpro_admin .pmpro_tag-grey {display: inline-block; font-size: 11px; font-weight: bold; position: relative; padding: 2px 5px; border: 1px solid #CCC; background: whiteSmoke; border-radius: 10px; -moz-border-radius: 10px; -webkit-border-radius: 10px; }
|
21 |
+
.pmpro_admin .pmpro_tag-blue {display: inline-block; font-size: 11px; font-weight: bold; position: relative; padding: 2px 5px; border: 1px solid #2997c8; border-radius: 10px; -moz-border-radius: 10px; -webkit-border-radius: 10px; background: #2997c8; color: #FFF; text-decoration: none; }
|
22 |
+
.pmpro_admin a.pmpro_tag-blue:hover {background: #77a02e; border: 1px solid #77a02e; }
|
23 |
+
|
24 |
+
.pmpro_admin .topborder {border-top: 1px solid #CCC; margin-top: 1em; padding-top: 1em; }
|
25 |
+
.pmpro_admin #editorcontainer #description {width: 100%; height: 180px; }
|
26 |
+
.pmpro_admin .widefat {margin-top: 1em; }
|
27 |
+
|
28 |
+
/* checkboxes */
|
29 |
+
.checkbox_box {width: 300px; background: #FFFFFF; border: 1px solid #CCC;}
|
30 |
+
.checkbox_box div {border-bottom: 1px solid #CCC; padding: 3px;}
|
31 |
+
.checkbox_box .clickable {cursor: pointer;}
|
32 |
+
.checkbox_box .clickable:hover {background: #FFC;}
|
33 |
+
|
34 |
+
/* levels */
|
35 |
+
tr.pmpro_gray td {color: #AAA;}
|
36 |
+
tr td.level_name a {font-size: 115%; font-weight: bold; }
|
37 |
+
.membership-levels tr {background: #fff;}
|
38 |
+
.membership-levels tr.alternate {background: #f9f9f9;}
|
39 |
+
.membership-levels tr.ui-sortable-helper {border: 1px solid #2997C8;}
|
40 |
+
tr.testclass {border: 3px solid #2997C8; background: #2997C8;}
|
41 |
+
|
42 |
+
/* settings */
|
43 |
+
tr.pmpro_settings_divider td {padding: 5px; margin: 0; color: #555; border-top: 1px solid #CCC; border-bottom: 1px solid #CCC;}
|
44 |
+
tr.pmpro_settings_divider td:before {content: "- ";}
|
45 |
+
tr.pmpro_settings_divider td:after {content: " -";}
|
46 |
+
|
47 |
+
/* messages */
|
48 |
+
.pmpro_message {background-color: #D5E4F7; background-image: url(../images/icon_information.gif); background-position: 3px 5px; background-repeat: no-repeat; margin: .5em 0; padding: 6px 6px 6px 25px; color: #345395; font-size: 11px; font-weight: bold; line-height: 1.3em; }
|
49 |
+
|
50 |
+
.pmpro_success {background-color: #CFEECA; background-image: url(../images/icon_success.gif); color: #208A1B; }
|
51 |
+
.pmpro_error {background-color: #F9D6CB; background-image: url(../images/icon_error.gif); color: #E36154; }
|
52 |
+
.pmpro_alert {background-color: #FFF6CC; background-image: url(../images/icon_alert.gif); color: #CF8516; }
|
53 |
+
|
54 |
+
.pmpro_message a {color: #345395; }
|
55 |
+
.pmpro_success a {color: #208A1B; }
|
56 |
+
.pmpro_error a {color: #E36154; }
|
57 |
+
.pmpro_alert a {color: #CF8516; }
|
58 |
+
|
59 |
+
/* highlighted trs */
|
60 |
+
tr.pmpro_message {background-image: none;}
|
61 |
+
tr.pmpro_success {background-image: none;}
|
62 |
+
tr.pmpro_error {background-image: none;}
|
63 |
+
tr.pmpro_alert {background-image: none;}
|
64 |
+
|
65 |
+
/* discount levels */
|
66 |
+
.pmpro_discount_levels {border: 1px solid #CCC;}
|
67 |
+
.pmpro_discount_levels div {padding: 5px; border: 1px solid #CCC;}
|
68 |
+
.pmpro_discount_levels div div {margin-top: 5px; background: #F5F5F5;}
|
69 |
+
|
70 |
+
/* pagination */
|
71 |
+
div.pmpro_pagination {padding: 3px; margin: 5px 0px 5px 0px; font-size: 10px; float: right; }
|
72 |
+
div.pmpro_pagination a {padding: 2px 5px 2px 5px; margin: 1px; border: 1px solid #666; text-decoration: none; /* no underline */ color: #666; background: #EEE; }
|
73 |
+
div.pmpro_pagination a:hover, div.pmpro_pagination a:active {background: #FFF; }
|
74 |
+
div.pmpro_pagination span.current {border: 1px solid #FFF; color: #FFF; background: #666; padding: 2px 5px 2px 5px; margin: 1px; font-weight: bold; }
|
75 |
+
div.pmpro_pagination span.disabled {padding: 2px 5px 2px 5px; margin: 2px; border: 1px solid #BBB; color: #BBB; background: #EFEFEF;}
|
76 |
+
|
77 |
+
p.pmpro_meta_notice {font-size: .8em; padding-top: 5px; border-top: 1px solid #CCC;}
|
78 |
+
|
79 |
+
/* add ons */
|
80 |
+
.pmpro_admin .widgets-holder-wrap {clear: both; margin-top: 20px; padding: 0 8px; }
|
81 |
+
.pmpro_admin .widgets-holder-wrap .widget {float: left; width: 32%; margin: 0 1% 1% 0; position: relative; }
|
82 |
+
.pmpro_admin .widgets-holder-wrap p.description {padding: 0; }
|
83 |
+
.pmpro_admin .widgets-holder-wrap .widget-top {height: auto; cursor: default; }
|
84 |
+
.pmpro_admin .widgets-holder-wrap .widget-inside {display: block; height: 130px; overflow: hidden; }
|
85 |
+
.pmpro_admin .widgets-holder-wrap .widget-inside p {height: 80px; overflow: hidden; }
|
86 |
+
.pmpro_admin #pmpro-gists.widgets-holder-wrap .widget-inside, .pmpro_admin #pmpro-gists.widgets-holder-wrap .widget-inside p {height: auto; }
|
87 |
+
.pmpro_admin .widgets-holder-wrap .widget-title { }
|
88 |
+
.pmpro_admin .widgets-holder-wrap .widget-title h4 { }
|
89 |
+
.pmpro_admin .widgets-holder-wrap .widget-title .status-label {display: block; float: left; margin: 0 5px 0 0; width: 10px;
|
90 |
+
height: 10px; overflow: hidden; border-radius: 10px; -moz-border-radius: 10px; -webkit-border-radius: 10px; border: 1px solid #DFDFDF; text-indent: -9999em; }
|
91 |
+
.pmpro_admin .widgets-holder-wrap .disabled .widget-title .status-label {background: #F00; }
|
92 |
+
.pmpro_admin .widgets-holder-wrap .enabled .widget-title .status-label {background: #0C0; }
|
93 |
+
|
94 |
+
.pmpro_admin .widgets-holder-wrap .widget-title .version {position: absolute; top: 13px; right: 10px; }
|
95 |
+
.pmpro_admin .widgets-holder-wrap .widget-inside .addon-thumb {width: 100px; height: 100px; float: right; margin: 10px 0 0 10px; border: 1px solid #DFDFDF; background: #FFF; padding: 2px;}
|
96 |
+
|
97 |
+
/*@media (min-width: 1200px) {
|
98 |
+
.auto-fold .pmpro_admin .widgets-holder-wrap .widget-inside, .auto-fold .pmpro_admin .widgets-holder-wrap .widget-inside p {height: auto; }
|
99 |
+
}
|
100 |
+
*/
|
101 |
+
@media (max-width:900px) {
|
102 |
+
.auto-fold .pmpro_admin .widgets-holder-wrap .widget {float: none; width: 100%; }
|
103 |
+
.auto-fold .pmpro_admin .widgets-holder-wrap .widget-inside, .auto-fold .pmpro_admin .widgets-holder-wrap .widget-inside p {height: auto; }
|
104 |
+
}
|
105 |
+
|
106 |
+
/* misc */
|
107 |
+
.pmpro_lite {color: #AAA;}
|
108 |
+
.pmpro_pad20 {padding: 20px !important;}
|
109 |
+
.pmpro_red {color: #CC0000;}
|
110 |
+
.pmpro_green {color: #00AA00;}
|
111 |
+
.ssp_description #description {width: 100%;}
|
112 |
+
.top0em {margin-top: 0;}
|
113 |
+
h2.nav-tab-wrapper {margin-bottom: 1em; }
|
114 |
+
|
115 |
+
/* reports */
|
116 |
+
.pmpro_reports-holder { }
|
117 |
+
.pmpro_clickable {cursor: pointer;}
|
118 |
.js .postbox.pmpro_clickable h3 {cursor: pointer;}
|
css/frontend.css
CHANGED
@@ -1,177 +1,177 @@
|
|
1 |
-
/*---------------------------------------
|
2 |
-
Buttons
|
3 |
-
---------------------------------------*/
|
4 |
-
.pmpro_btn, .pmpro_btn:link, .pmpro_content_message a, .pmpro_content_message a:link {
|
5 |
-
display: inline-block;
|
6 |
-
background-color: #EFEFEF;
|
7 |
-
background-image: none;
|
8 |
-
border: 1px solid #D6D6D6;
|
9 |
-
-webkit-border-radius: 4px;
|
10 |
-
-moz-border-radius: 4px;
|
11 |
-
border-radius: 4px;
|
12 |
-
padding: 6px 12px;
|
13 |
-
margin: 0;
|
14 |
-
color: #444;
|
15 |
-
font-size: 12px;
|
16 |
-
font-weight: 700;
|
17 |
-
text-transform: none;
|
18 |
-
text-decoration: none;
|
19 |
-
text-align: center;
|
20 |
-
white-space: nowrap;
|
21 |
-
vertical-align: middle;
|
22 |
-
cursor: pointer;
|
23 |
-
-webkit-user-select: none;
|
24 |
-
-moz-user-select: none;
|
25 |
-
-ms-user-select: none;
|
26 |
-
-o-user-select: none;
|
27 |
-
user-select: none;
|
28 |
-
}
|
29 |
-
|
30 |
-
.pmpro_btn:focus, .pmpro_content_message a:focus {
|
31 |
-
outline: thin dotted;
|
32 |
-
outline: 5px auto -webkit-focus-ring-color;
|
33 |
-
outline-offset: -2px;
|
34 |
-
}
|
35 |
-
|
36 |
-
.pmpro_btn:hover, .pmpro_btn:focus, .pmpro_content_message a:focus, .pmpro_content_message a:hover {
|
37 |
-
color: #000;
|
38 |
-
background-color: #FAFAFA;
|
39 |
-
text-decoration: none;
|
40 |
-
}
|
41 |
-
|
42 |
-
.pmpro_btn:active,
|
43 |
-
.pmpro_btn.active {
|
44 |
-
background-image: none;
|
45 |
-
outline: 0;
|
46 |
-
-webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
|
47 |
-
box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
|
48 |
-
}
|
49 |
-
|
50 |
-
.pmpro_btn.disabled,
|
51 |
-
.pmpro_btn[disabled],
|
52 |
-
fieldset[disabled] .pmpro_btn {
|
53 |
-
pointer-events: none;
|
54 |
-
cursor: not-allowed;
|
55 |
-
opacity: 0.65;
|
56 |
-
filter: alpha(opacity=65);
|
57 |
-
-webkit-box-shadow: none;
|
58 |
-
box-shadow: none;
|
59 |
-
}
|
60 |
-
|
61 |
-
.pmpro_btn.pmpro_cancel, .pmpro_btn.pmpro_cancel:link {background: none; border: none; margin: 0 0 0 10px; }
|
62 |
-
/*---------------------------------------
|
63 |
-
Forms
|
64 |
-
---------------------------------------*/
|
65 |
-
form.pmpro_form div {clear: left; margin: .5em 0 1em 0; }
|
66 |
-
form.pmpro_form label {float: left; margin: 3px 10px 0 0; width: 120px; font-weight: bold; text-align: right; }
|
67 |
-
form.pmpro_form label.pmpro_normal {float: none; margin: 0 0 0 0; width: auto; font-weight: normal; text-align: auto;}
|
68 |
-
.pmpro_clickable {cursor: pointer;}
|
69 |
-
form.pmpro_form .likelabel {font-weight: bold; }
|
70 |
-
form.pmpro_form .input, form.pmpro_form textarea, .input, form.pmpro_form select {padding: 3px; border: 1px solid #AAA; margin: 0 3px 0 0; }
|
71 |
-
form.pmpro_form textarea {font-family: Arial, Helvetica, sans-serif; font-size: 12px; }
|
72 |
-
form.pmpro_form select {margin: 2px 0 0 0 ; font-size: 12px;}
|
73 |
-
form.pmpro_form .lite {color: #666; }
|
74 |
-
form.pmpro_form .leftmar {margin: 8px 0 0 130px; }
|
75 |
-
|
76 |
-
form.pmpro_form .pmpro_captcha {margin: 0 0 0 130px !important; }
|
77 |
-
form.pmpro_form .pmpro_captcha div {clear: none; margin: 0; }
|
78 |
-
form.pmpro_form .pmpro_submit {margin-left: 130px; }
|
79 |
-
form.pmpro_form .pmpro_submit span {float: left; }
|
80 |
-
form.pmpro_form #pmpro_processing_message {margin: 5px 0 0 10px; font-style: italic; color: #999; }
|
81 |
-
|
82 |
-
/*--------------------------------------------------
|
83 |
-
Messages - Success, Error, Alert
|
84 |
-
----------------------------------------------------*/
|
85 |
-
.pmpro_message {background-color: #d9edf7; margin: .5em 0; padding: 10px 15px; color: #31708f; font-size: 14px; font-weight: 400; line-height: 1.5em; -webkit-border-radius: 4px; -moz-border-radius: 4px; border-radius: 4px; border: 1px solid #bce8f1; }
|
86 |
-
|
87 |
-
.pmpro_success {background-color: #dff0d8; color: #3c763d; border-color: #d6e9c6; }
|
88 |
-
.pmpro_error {background-color: #f2dede; color: #a94442; border-color: #ebccd1; }
|
89 |
-
.pmpro_alert {background-color: #fcf8e3; color: #8a6d3b; border-color: #faebcc;}
|
90 |
-
|
91 |
-
.pmpro_content_message a {margin: 5px 5px 0 0; }
|
92 |
-
|
93 |
-
.pmpro_message a {color: #245269; text-decoration: underline; }
|
94 |
-
.pmpro_success a {color: #2b542c; }
|
95 |
-
.pmpro_error a {color: #843534; }
|
96 |
-
.pmpro_alert a {color: #66512c; }
|
97 |
-
|
98 |
-
input.pmpro_error {background-image: none;}
|
99 |
-
select.pmpro_error {background-image: none;}
|
100 |
-
|
101 |
-
/*---------------------------------------
|
102 |
-
Membership Checkout
|
103 |
-
---------------------------------------*/
|
104 |
-
.pmpro_checkout thead th {font-weight: bold; color: #444; padding: 10px; }
|
105 |
-
.pmpro_checkout tbody td {padding: 10px; }
|
106 |
-
.pmpro_checkout tr.odd td {background: rgba(125,125,125,.1); }
|
107 |
-
.pmpro_checkout tr.selected td {background: #FFC; }
|
108 |
-
.pmpro_checkout tr.active td {background: #FFC; }
|
109 |
-
.pmpro_checkout .name {font-weight: bold; }
|
110 |
-
.pmpro_checkout ul {margin: 5px 0 0 20px; padding: 0; font-size: .8em; color: #444; }
|
111 |
-
|
112 |
-
.pmpro_checkout tfoot td {padding: 10px; color: #444; }
|
113 |
-
.pmpro_checkout .topfoot td {border-top: 2px solid #CCC;}
|
114 |
-
.pmpro_checkout .total td {border-top: 1px solid #CCC; font-size: 1.2em; font-weight: bold; padding-bottom: 30px;}
|
115 |
-
.pmpro_checkout tfoot .entercode td {background: #EEE; }
|
116 |
-
|
117 |
-
.pmpro_checkout td.rtbdr {border-right: 1px solid #CCC; }
|
118 |
-
|
119 |
-
.pmpro_checkout select {font-size: 11px; }
|
120 |
-
|
121 |
-
.pmpro_thead-msg {display: block; float: right; width: auto; font-style: italic; font-weight: normal; text-align: right; white-space: nowrap; }
|
122 |
-
|
123 |
-
.pmpro_ordersummary {float: right; }
|
124 |
-
|
125 |
-
#pmpro_license { background: #FFF; padding: 5px; border: 1px solid #CCC; height: 200px; margin: 3px; color: #666; overflow: auto; }
|
126 |
-
|
127 |
-
.pmpro_sslseal {float: right; clear: none !important; margin: 0 !important; }
|
128 |
-
|
129 |
-
a.pmpro_radio {text-decoration: none; color: #000;}
|
130 |
-
|
131 |
-
/*---------------------------------------
|
132 |
-
Membership Invoice
|
133 |
-
---------------------------------------*/
|
134 |
-
.pmpro_invoice { }
|
135 |
-
|
136 |
-
|
137 |
-
/*---------------------------------------
|
138 |
-
Membership Account
|
139 |
-
---------------------------------------*/
|
140 |
-
#pmpro_account .pmpro_box {border-top: 1px solid #CCC; padding: 1em 0; margin: 1em 0; }
|
141 |
-
#pmpro_account .pmpro_box h3 {margin: 0; padding: 0; border: none; background: none; }
|
142 |
-
#pmpro_account .pmpro_box p {margin: .5em 0 0 0; padding: 0; }
|
143 |
-
#pmpro_account .pmpro_box ul {margin-bottom: 0; }
|
144 |
-
|
145 |
-
#pmpro_account #pmpro_account-membership { }
|
146 |
-
#pmpro_account #pmpro_account-profile { }
|
147 |
-
#pmpro_account #pmpro_account-billing { }
|
148 |
-
#pmpro_account #pmpro_account-invoices { }
|
149 |
-
#pmpro_account #pmpro_account-links { }
|
150 |
-
|
151 |
-
.pmpro_actionlinks {font-size: .8em; margin: .25em 0 0 0; }
|
152 |
-
.pmpro_actionlinks a {display: inline-block; padding: 0 5px 0 0; margin: 0; text-decoration: none; }
|
153 |
-
.pmpro_actionlinks a:last-child {padding: 0; }
|
154 |
-
.pmpro_hidden {display: none;}
|
155 |
-
li.pmpro_more {list-style-type: none; text-align: center; margin-left: -20px; padding-left: 0;}
|
156 |
-
|
157 |
-
/*---------------------------------------
|
158 |
-
Membership Levels
|
159 |
-
---------------------------------------*/
|
160 |
-
#pmpro_levels_table {background: #FFF; }
|
161 |
-
#pmpro_levels_table .pmpro_btn {display: block; }
|
162 |
-
|
163 |
-
/*---------------------------------------
|
164 |
-
Misc
|
165 |
-
---------------------------------------*/
|
166 |
-
.pmpro_a-right {float: right; width: auto; text-align: right; text-decoration: underline; font-size: 11px; }
|
167 |
-
.pmpro_a-print {float: right; width: auto; text-decoration: none; color: #345395; background: url(../images/printer.gif) top left no-repeat; padding: 0px 0px 2px 20px; font-size: 11px; line-height: 16px; cursor: pointer; }
|
168 |
-
|
169 |
-
.pmpro_red {color: #CC0000; }
|
170 |
-
.pmpro_grey {color: #999; }
|
171 |
-
|
172 |
-
.top1em {margin-top: 1em;}
|
173 |
-
.bot1em {margin-bottom: 1em;}
|
174 |
-
.bot0em {margin-bottom: 0em;}
|
175 |
-
.clear {clear: both; }
|
176 |
-
|
177 |
-
.pmpro_small {font-size: .8em;}
|
1 |
+
/*---------------------------------------
|
2 |
+
Buttons
|
3 |
+
---------------------------------------*/
|
4 |
+
.pmpro_btn, .pmpro_btn:link, .pmpro_content_message a, .pmpro_content_message a:link {
|
5 |
+
display: inline-block;
|
6 |
+
background-color: #EFEFEF;
|
7 |
+
background-image: none;
|
8 |
+
border: 1px solid #D6D6D6;
|
9 |
+
-webkit-border-radius: 4px;
|
10 |
+
-moz-border-radius: 4px;
|
11 |
+
border-radius: 4px;
|
12 |
+
padding: 6px 12px;
|
13 |
+
margin: 0;
|
14 |
+
color: #444;
|
15 |
+
font-size: 12px;
|
16 |
+
font-weight: 700;
|
17 |
+
text-transform: none;
|
18 |
+
text-decoration: none;
|
19 |
+
text-align: center;
|
20 |
+
white-space: nowrap;
|
21 |
+
vertical-align: middle;
|
22 |
+
cursor: pointer;
|
23 |
+
-webkit-user-select: none;
|
24 |
+
-moz-user-select: none;
|
25 |
+
-ms-user-select: none;
|
26 |
+
-o-user-select: none;
|
27 |
+
user-select: none;
|
28 |
+
}
|
29 |
+
|
30 |
+
.pmpro_btn:focus, .pmpro_content_message a:focus {
|
31 |
+
outline: thin dotted;
|
32 |
+
outline: 5px auto -webkit-focus-ring-color;
|
33 |
+
outline-offset: -2px;
|
34 |
+
}
|
35 |
+
|
36 |
+
.pmpro_btn:hover, .pmpro_btn:focus, .pmpro_content_message a:focus, .pmpro_content_message a:hover {
|
37 |
+
color: #000;
|
38 |
+
background-color: #FAFAFA;
|
39 |
+
text-decoration: none;
|
40 |
+
}
|
41 |
+
|
42 |
+
.pmpro_btn:active,
|
43 |
+
.pmpro_btn.active {
|
44 |
+
background-image: none;
|
45 |
+
outline: 0;
|
46 |
+
-webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
|
47 |
+
box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
|
48 |
+
}
|
49 |
+
|
50 |
+
.pmpro_btn.disabled,
|
51 |
+
.pmpro_btn[disabled],
|
52 |
+
fieldset[disabled] .pmpro_btn {
|
53 |
+
pointer-events: none;
|
54 |
+
cursor: not-allowed;
|
55 |
+
opacity: 0.65;
|
56 |
+
filter: alpha(opacity=65);
|
57 |
+
-webkit-box-shadow: none;
|
58 |
+
box-shadow: none;
|
59 |
+
}
|
60 |
+
|
61 |
+
.pmpro_btn.pmpro_cancel, .pmpro_btn.pmpro_cancel:link {background: none; border: none; margin: 0 0 0 10px; }
|
62 |
+
/*---------------------------------------
|
63 |
+
Forms
|
64 |
+
---------------------------------------*/
|
65 |
+
form.pmpro_form div {clear: left; margin: .5em 0 1em 0; }
|
66 |
+
form.pmpro_form label {float: left; margin: 3px 10px 0 0; width: 120px; font-weight: bold; text-align: right; }
|
67 |
+
form.pmpro_form label.pmpro_normal {float: none; margin: 0 0 0 0; width: auto; font-weight: normal; text-align: auto;}
|
68 |
+
.pmpro_clickable {cursor: pointer;}
|
69 |
+
form.pmpro_form .likelabel {font-weight: bold; }
|
70 |
+
form.pmpro_form .input, form.pmpro_form textarea, .input, form.pmpro_form select {padding: 3px; border: 1px solid #AAA; margin: 0 3px 0 0; }
|
71 |
+
form.pmpro_form textarea {font-family: Arial, Helvetica, sans-serif; font-size: 12px; }
|
72 |
+
form.pmpro_form select {margin: 2px 0 0 0 ; font-size: 12px;}
|
73 |
+
form.pmpro_form .lite {color: #666; }
|
74 |
+
form.pmpro_form .leftmar {margin: 8px 0 0 130px; }
|
75 |
+
|
76 |
+
form.pmpro_form .pmpro_captcha {margin: 0 0 0 130px !important; }
|
77 |
+
form.pmpro_form .pmpro_captcha div {clear: none; margin: 0; }
|
78 |
+
form.pmpro_form .pmpro_submit {margin-left: 130px; }
|
79 |
+
form.pmpro_form .pmpro_submit span {float: left; }
|
80 |
+
form.pmpro_form #pmpro_processing_message {margin: 5px 0 0 10px; font-style: italic; color: #999; }
|
81 |
+
|
82 |
+
/*--------------------------------------------------
|
83 |
+
Messages - Success, Error, Alert
|
84 |
+
----------------------------------------------------*/
|
85 |
+
.pmpro_message {background-color: #d9edf7; margin: .5em 0; padding: 10px 15px; color: #31708f; font-size: 14px; font-weight: 400; line-height: 1.5em; -webkit-border-radius: 4px; -moz-border-radius: 4px; border-radius: 4px; border: 1px solid #bce8f1; }
|
86 |
+
|
87 |
+
.pmpro_success {background-color: #dff0d8; color: #3c763d; border-color: #d6e9c6; }
|
88 |
+
.pmpro_error {background-color: #f2dede; color: #a94442; border-color: #ebccd1; }
|
89 |
+
.pmpro_alert {background-color: #fcf8e3; color: #8a6d3b; border-color: #faebcc;}
|
90 |
+
|
91 |
+
.pmpro_content_message a {margin: 5px 5px 0 0; }
|
92 |
+
|
93 |
+
.pmpro_message a {color: #245269; text-decoration: underline; }
|
94 |
+
.pmpro_success a {color: #2b542c; }
|
95 |
+
.pmpro_error a {color: #843534; }
|
96 |
+
.pmpro_alert a {color: #66512c; }
|
97 |
+
|
98 |
+
input.pmpro_error {background-image: none;}
|
99 |
+
select.pmpro_error {background-image: none;}
|
100 |
+
|
101 |
+
/*---------------------------------------
|
102 |
+
Membership Checkout
|
103 |
+
---------------------------------------*/
|
104 |
+
.pmpro_checkout thead th {font-weight: bold; color: #444; padding: 10px; }
|
105 |
+
.pmpro_checkout tbody td {padding: 10px; }
|
106 |
+
.pmpro_checkout tr.odd td {background: rgba(125,125,125,.1); }
|
107 |
+
.pmpro_checkout tr.selected td {background: #FFC; }
|
108 |
+
.pmpro_checkout tr.active td {background: #FFC; }
|
109 |
+
.pmpro_checkout .name {font-weight: bold; }
|
110 |
+
.pmpro_checkout ul {margin: 5px 0 0 20px; padding: 0; font-size: .8em; color: #444; }
|
111 |
+
|
112 |
+
.pmpro_checkout tfoot td {padding: 10px; color: #444; }
|
113 |
+
.pmpro_checkout .topfoot td {border-top: 2px solid #CCC;}
|
114 |
+
.pmpro_checkout .total td {border-top: 1px solid #CCC; font-size: 1.2em; font-weight: bold; padding-bottom: 30px;}
|
115 |
+
.pmpro_checkout tfoot .entercode td {background: #EEE; }
|
116 |
+
|
117 |
+
.pmpro_checkout td.rtbdr {border-right: 1px solid #CCC; }
|
118 |
+
|
119 |
+
.pmpro_checkout select {font-size: 11px; }
|
120 |
+
|
121 |
+
.pmpro_thead-msg {display: block; float: right; width: auto; font-style: italic; font-weight: normal; text-align: right; white-space: nowrap; }
|
122 |
+
|
123 |
+
.pmpro_ordersummary {float: right; }
|
124 |
+
|
125 |
+
#pmpro_license { background: #FFF; padding: 5px; border: 1px solid #CCC; height: 200px; margin: 3px; color: #666; overflow: auto; }
|
126 |
+
|
127 |
+
.pmpro_sslseal {float: right; clear: none !important; margin: 0 !important; }
|
128 |
+
|
129 |
+
a.pmpro_radio {text-decoration: none; color: #000;}
|
130 |
+
|
131 |
+
/*---------------------------------------
|
132 |
+
Membership Invoice
|
133 |
+
---------------------------------------*/
|
134 |
+
.pmpro_invoice { }
|
135 |
+
|
136 |
+
|
137 |
+
/*---------------------------------------
|
138 |
+
Membership Account
|
139 |
+
---------------------------------------*/
|
140 |
+
#pmpro_account .pmpro_box {border-top: 1px solid #CCC; padding: 1em 0; margin: 1em 0; }
|
141 |
+
#pmpro_account .pmpro_box h3 {margin: 0; padding: 0; border: none; background: none; }
|
142 |
+
#pmpro_account .pmpro_box p {margin: .5em 0 0 0; padding: 0; }
|
143 |
+
#pmpro_account .pmpro_box ul {margin-bottom: 0; }
|
144 |
+
|
145 |
+
#pmpro_account #pmpro_account-membership { }
|
146 |
+
#pmpro_account #pmpro_account-profile { }
|
147 |
+
#pmpro_account #pmpro_account-billing { }
|
148 |
+
#pmpro_account #pmpro_account-invoices { }
|
149 |
+
#pmpro_account #pmpro_account-links { }
|
150 |
+
|
151 |
+
.pmpro_actionlinks {font-size: .8em; margin: .25em 0 0 0; }
|
152 |
+
.pmpro_actionlinks a {display: inline-block; padding: 0 5px 0 0; margin: 0; text-decoration: none; }
|
153 |
+
.pmpro_actionlinks a:last-child {padding: 0; }
|
154 |
+
.pmpro_hidden {display: none;}
|
155 |
+
li.pmpro_more {list-style-type: none; text-align: center; margin-left: -20px; padding-left: 0;}
|
156 |
+
|
157 |
+
/*---------------------------------------
|
158 |
+
Membership Levels
|
159 |
+
---------------------------------------*/
|
160 |
+
#pmpro_levels_table {background: #FFF; }
|
161 |
+
#pmpro_levels_table .pmpro_btn {display: block; }
|
162 |
+
|
163 |
+
/*---------------------------------------
|
164 |
+
Misc
|
165 |
+
---------------------------------------*/
|
166 |
+
.pmpro_a-right {float: right; width: auto; text-align: right; text-decoration: underline; font-size: 11px; }
|
167 |
+
.pmpro_a-print {float: right; width: auto; text-decoration: none; color: #345395; background: url(../images/printer.gif) top left no-repeat; padding: 0px 0px 2px 20px; font-size: 11px; line-height: 16px; cursor: pointer; }
|
168 |
+
|
169 |
+
.pmpro_red {color: #CC0000; }
|
170 |
+
.pmpro_grey {color: #999; }
|
171 |
+
|
172 |
+
.top1em {margin-top: 1em;}
|
173 |
+
.bot1em {margin-bottom: 1em;}
|
174 |
+
.bot0em {margin-bottom: 0em;}
|
175 |
+
.clear {clear: both; }
|
176 |
+
|
177 |
+
.pmpro_small {font-size: .8em;}
|
css/print.css
CHANGED
@@ -1,5 +1,5 @@
|
|
1 |
@media print {
|
2 |
-
|
3 |
-
.pmpro_a-print {display: none; position: absolute; left: -9999px; }
|
4 |
-
|
5 |
}
|
1 |
@media print {
|
2 |
+
|
3 |
+
.pmpro_a-print {display: none; position: absolute; left: -9999px; }
|
4 |
+
|
5 |
}
|
email/billing.html
CHANGED
@@ -1,12 +1,12 @@
|
|
1 |
<p>Your billing information at !!sitename!! has been changed.</p>
|
2 |
|
3 |
<p>Account: !!display_name!! (!!user_email!!)</p>
|
4 |
-
<p>
|
5 |
Billing Information:<br />
|
6 |
!!billing_address!!
|
7 |
</p>
|
8 |
-
|
9 |
-
<p>
|
10 |
!!cardtype!!: !!accountnumber!!<br />
|
11 |
Expires: !!expirationmonth!!/!!expirationyear!!
|
12 |
</p>
|
1 |
<p>Your billing information at !!sitename!! has been changed.</p>
|
2 |
|
3 |
<p>Account: !!display_name!! (!!user_email!!)</p>
|
4 |
+
<p>
|
5 |
Billing Information:<br />
|
6 |
!!billing_address!!
|
7 |
</p>
|
8 |
+
|
9 |
+
<p>
|
10 |
!!cardtype!!: !!accountnumber!!<br />
|
11 |
Expires: !!expirationmonth!!/!!expirationyear!!
|
12 |
</p>
|
email/billing_admin.html
CHANGED
@@ -1,15 +1,15 @@
|
|
1 |
<p>The billing information for !!display_name!! at !!sitename!! has been changed.</p>
|
2 |
|
3 |
<p>Account: !!display_name!! (!!user_email!!)</p>
|
4 |
-
<p>
|
5 |
Billing Information:<br />
|
6 |
!!billing_name!!<br />
|
7 |
-
!!billing_street!!<br />
|
8 |
!!billing_city!!, !!billing_state!! !!billing_zip!! !!billing_country!!
|
9 |
!!billing_phone!!
|
10 |
</p>
|
11 |
-
|
12 |
-
<p>
|
13 |
!!cardtype!!: !!accountnumber!!<br />
|
14 |
Expires: !!expirationmonth!!/!!expirationyear!!
|
15 |
</p>
|
1 |
<p>The billing information for !!display_name!! at !!sitename!! has been changed.</p>
|
2 |
|
3 |
<p>Account: !!display_name!! (!!user_email!!)</p>
|
4 |
+
<p>
|
5 |
Billing Information:<br />
|
6 |
!!billing_name!!<br />
|
7 |
+
!!billing_street!!<br />
|
8 |
!!billing_city!!, !!billing_state!! !!billing_zip!! !!billing_country!!
|
9 |
!!billing_phone!!
|
10 |
</p>
|
11 |
+
|
12 |
+
<p>
|
13 |
!!cardtype!!: !!accountnumber!!<br />
|
14 |
Expires: !!expirationmonth!!/!!expirationyear!!
|
15 |
</p>
|
email/billing_failure.html
CHANGED
@@ -4,8 +4,8 @@
|
|
4 |
<p>The most recent account information we have on file is:</p>
|
5 |
|
6 |
<p>!!billing_address!!</p>
|
7 |
-
|
8 |
-
<p>
|
9 |
!!cardtype!!: !!accountnumber!!<br />
|
10 |
Expires: !!expirationmonth!!/!!expirationyear!!
|
11 |
</p>
|
4 |
<p>The most recent account information we have on file is:</p>
|
5 |
|
6 |
<p>!!billing_address!!</p>
|
7 |
+
|
8 |
+
<p>
|
9 |
!!cardtype!!: !!accountnumber!!<br />
|
10 |
Expires: !!expirationmonth!!/!!expirationyear!!
|
11 |
</p>
|
email/billing_failure_admin.html
CHANGED
@@ -1,11 +1,11 @@
|
|
1 |
-
<p>Payment Failure</p>
|
2 |
-
|
3 |
-
<p>Account: !!display_name!! (!!user_email!!)</p>
|
4 |
-
<p>The most recent account information we have on file is:</p>
|
5 |
-
|
6 |
-
<p>!!billing_address!!</p>
|
7 |
-
|
8 |
-
<p>
|
9 |
-
!!cardtype!!: !!accountnumber!!<br />
|
10 |
-
Expires: !!expirationmonth!!/!!expirationyear!!
|
11 |
</p>
|
1 |
+
<p>Payment Failure</p>
|
2 |
+
|
3 |
+
<p>Account: !!display_name!! (!!user_email!!)</p>
|
4 |
+
<p>The most recent account information we have on file is:</p>
|
5 |
+
|
6 |
+
<p>!!billing_address!!</p>
|
7 |
+
|
8 |
+
<p>
|
9 |
+
!!cardtype!!: !!accountnumber!!<br />
|
10 |
+
Expires: !!expirationmonth!!/!!expirationyear!!
|
11 |
</p>
|
email/cancel_admin.html
CHANGED
@@ -4,5 +4,5 @@
|
|
4 |
<p>Membership Level: !!membership_level_name!!</p>
|
5 |
<p>Start Date: !!startdate!!</p>
|
6 |
<p>Cancellation Date: !!enddate!!</p>
|
7 |
-
|
8 |
<p>Log in to your WordPress admin here: !!login_link!!</p>
|
4 |
<p>Membership Level: !!membership_level_name!!</p>
|
5 |
<p>Start Date: !!startdate!!</p>
|
6 |
<p>Cancellation Date: !!enddate!!</p>
|
7 |
+
|
8 |
<p>Log in to your WordPress admin here: !!login_link!!</p>
|
email/checkout_freetrial.html
CHANGED
@@ -10,8 +10,8 @@
|
|
10 |
Billing Information on File:<br />
|
11 |
!!billing_address!!
|
12 |
</p>
|
13 |
-
|
14 |
-
<p>
|
15 |
!!cardtype!!: !!accountnumber!!<br />
|
16 |
Expires: !!expirationmonth!!/!!expirationyear!!
|
17 |
</p>
|
10 |
Billing Information on File:<br />
|
11 |
!!billing_address!!
|
12 |
</p>
|
13 |
+
|
14 |
+
<p>
|
15 |
!!cardtype!!: !!accountnumber!!<br />
|
16 |
Expires: !!expirationmonth!!/!!expirationyear!!
|
17 |
</p>
|
email/checkout_freetrial_admin.html
CHANGED
@@ -10,8 +10,8 @@
|
|
10 |
Billing Information on File:<br />
|
11 |
!!billing_address!!
|
12 |
</p>
|
13 |
-
|
14 |
-
<p>
|
15 |
!!cardtype!!: !!accountnumber!!<br />
|
16 |
Expires: !!expirationmonth!!/!!expirationyear!!
|
17 |
</p>
|
10 |
Billing Information on File:<br />
|
11 |
!!billing_address!!
|
12 |
</p>
|
13 |
+
|
14 |
+
<p>
|
15 |
!!cardtype!!: !!accountnumber!!<br />
|
16 |
Expires: !!expirationmonth!!/!!expirationyear!!
|
17 |
</p>
|
email/checkout_paid.html
CHANGED
@@ -14,8 +14,8 @@
|
|
14 |
Billing Information:<br />
|
15 |
!!billing_address!!
|
16 |
</p>
|
17 |
-
|
18 |
-
<p>
|
19 |
!!cardtype!!: !!accountnumber!!<br />
|
20 |
Expires: !!expirationmonth!!/!!expirationyear!!
|
21 |
</p>
|
14 |
Billing Information:<br />
|
15 |
!!billing_address!!
|
16 |
</p>
|
17 |
+
|
18 |
+
<p>
|
19 |
!!cardtype!!: !!accountnumber!!<br />
|
20 |
Expires: !!expirationmonth!!/!!expirationyear!!
|
21 |
</p>
|
email/checkout_paid_admin.html
CHANGED
@@ -14,8 +14,8 @@
|
|
14 |
Billing Information:<br />
|
15 |
!!billing_address!!
|
16 |
</p>
|
17 |
-
|
18 |
-
<p>
|
19 |
!!cardtype!!: !!accountnumber!!<br />
|
20 |
Expires: !!expirationmonth!!/!!expirationyear!!
|
21 |
</p>
|
14 |
Billing Information:<br />
|
15 |
!!billing_address!!
|
16 |
</p>
|
17 |
+
|
18 |
+
<p>
|
19 |
!!cardtype!!: !!accountnumber!!<br />
|
20 |
Expires: !!expirationmonth!!/!!expirationyear!!
|
21 |
</p>
|
email/checkout_trial.html
CHANGED
@@ -14,8 +14,8 @@
|
|
14 |
Billing Information:<br />
|
15 |
!!billing_address!!
|
16 |
</p>
|
17 |
-
|
18 |
-
<p>
|
19 |
!!cardtype!!: !!accountnumber!!<br />
|
20 |
Expires: !!expirationmonth!!/!!expirationyear!!
|
21 |
</p>
|
14 |
Billing Information:<br />
|
15 |
!!billing_address!!
|
16 |
</p>
|
17 |
+
|
18 |
+
<p>
|
19 |
!!cardtype!!: !!accountnumber!!<br />
|
20 |
Expires: !!expirationmonth!!/!!expirationyear!!
|
21 |
</p>
|
email/checkout_trial_admin.html
CHANGED
@@ -14,8 +14,8 @@
|
|
14 |
Billing Information:<br />
|
15 |
!!billing_address!!
|
16 |
</p>
|
17 |
-
|
18 |
-
<p>
|
19 |
!!cardtype!!: !!accountnumber!!<br />
|
20 |
Expires: !!expirationmonth!!/!!expirationyear!!
|
21 |
</p>
|
14 |
Billing Information:<br />
|
15 |
!!billing_address!!
|
16 |
</p>
|
17 |
+
|
18 |
+
<p>
|
19 |
!!cardtype!!: !!accountnumber!!<br />
|
20 |
Expires: !!expirationmonth!!/!!expirationyear!!
|
21 |
</p>
|
email/credit_card_expiring.html
CHANGED
@@ -1,13 +1,13 @@
|
|
1 |
-
<p>The payment method used for your membership at !!sitename!! will expire soon. <strong>Please click the following link to log in and update your billing information to avoid account suspension. !!login_link!!</strong></p>
|
2 |
-
|
3 |
-
<p>Account: !!display_name!! (!!user_email!!)</p>
|
4 |
-
<p>The most recent account information we have on file is:</p>
|
5 |
-
|
6 |
-
<p>!!billing_name!!</br />
|
7 |
-
!!billing_address!!
|
8 |
-
</p>
|
9 |
-
|
10 |
-
<p>
|
11 |
-
!!cardtype!!: !!accountnumber!!<br />
|
12 |
-
Expires: !!expirationmonth!!/!!expirationyear!!
|
13 |
</p>
|
1 |
+
<p>The payment method used for your membership at !!sitename!! will expire soon. <strong>Please click the following link to log in and update your billing information to avoid account suspension. !!login_link!!</strong></p>
|
2 |
+
|
3 |
+
<p>Account: !!display_name!! (!!user_email!!)</p>
|
4 |
+
<p>The most recent account information we have on file is:</p>
|
5 |
+
|
6 |
+
<p>!!billing_name!!</br />
|
7 |
+
!!billing_address!!
|
8 |
+
</p>
|
9 |
+
|
10 |
+
<p>
|
11 |
+
!!cardtype!!: !!accountnumber!!<br />
|
12 |
+
Expires: !!expirationmonth!!/!!expirationyear!!
|
13 |
</p>
|
email/invoice.html
CHANGED
@@ -9,8 +9,8 @@
|
|
9 |
Billing Information:<br />
|
10 |
!!billing_address!!
|
11 |
</p>
|
12 |
-
|
13 |
-
<p>
|
14 |
!!cardtype!!: !!accountnumber!!<br />
|
15 |
Expires: !!expirationmonth!!/!!expirationyear!!
|
16 |
</p>
|
9 |
Billing Information:<br />
|
10 |
!!billing_address!!
|
11 |
</p>
|
12 |
+
|
13 |
+
<p>
|
14 |
!!cardtype!!: !!accountnumber!!<br />
|
15 |
Expires: !!expirationmonth!!/!!expirationyear!!
|
16 |
</p>
|
email/membership_expired.html
CHANGED
@@ -1,7 +1,7 @@
|
|
1 |
-
<p>Your membership at !!sitename!! has ended.</p>
|
2 |
-
|
3 |
-
<p>Thank you for your support.</p>
|
4 |
-
|
5 |
-
<p>View our current membership offerings here: !!levels_link!!</p>
|
6 |
-
|
7 |
<p>Log in to manage your account here: !!login_link!!</p>
|
1 |
+
<p>Your membership at !!sitename!! has ended.</p>
|
2 |
+
|
3 |
+
<p>Thank you for your support.</p>
|
4 |
+
|
5 |
+
<p>View our current membership offerings here: !!levels_link!!</p>
|
6 |
+
|
7 |
<p>Log in to manage your account here: !!login_link!!</p>
|
email/membership_expiring.html
CHANGED
@@ -1,6 +1,6 @@
|
|
1 |
-
<p>Thank you for your membership to !!sitename!!. This is just a reminder that your membership will end on !!enddate!!.</p>
|
2 |
-
|
3 |
-
<p>Account: !!display_name!! (!!user_email!!)</p>
|
4 |
-
<p>Membership Level: !!membership_level_name!!</p>
|
5 |
-
|
6 |
<p>Log in to your membership account here: !!login_link!!</p>
|
1 |
+
<p>Thank you for your membership to !!sitename!!. This is just a reminder that your membership will end on !!enddate!!.</p>
|
2 |
+
|
3 |
+
<p>Account: !!display_name!! (!!user_email!!)</p>
|
4 |
+
<p>Membership Level: !!membership_level_name!!</p>
|
5 |
+
|
6 |
<p>Log in to your membership account here: !!login_link!!</p>
|
includes/adminpages.php
CHANGED
@@ -1,268 +1,272 @@
|
|
1 |
-
<?php
|
2 |
-
/*
|
3 |
-
Get array of PMPro Capabilities
|
4 |
-
*/
|
5 |
-
function pmpro_getPMProCaps()
|
6 |
-
{
|
7 |
-
$pmpro_caps = array(
|
8 |
-
//pmpro_memberships_menu //this controls viewing the menu itself
|
9 |
-
'pmpro_membershiplevels',
|
10 |
-
'pmpro_pagesettings',
|
11 |
-
'pmpro_paymentsettings',
|
12 |
-
'pmpro_emailsettings',
|
13 |
-
'pmpro_advancedsettings',
|
14 |
-
'pmpro_addons',
|
15 |
-
'pmpro_memberslist',
|
16 |
-
'pmpro_reports',
|
17 |
-
'pmpro_orders',
|
18 |
-
'pmpro_discountcodes'
|
19 |
-
);
|
20 |
-
|
21 |
-
return $pmpro_caps;
|
22 |
-
}
|
23 |
-
|
24 |
-
/*
|
25 |
-
Dashboard Menu
|
26 |
-
*/
|
27 |
-
function pmpro_add_pages()
|
28 |
-
{
|
29 |
-
global $wpdb;
|
30 |
-
|
31 |
-
//array of all caps in the menu
|
32 |
-
$pmpro_caps = pmpro_getPMProCaps();
|
33 |
-
|
34 |
-
//the top level menu links to the first page they have access to
|
35 |
-
foreach($pmpro_caps as $cap)
|
36 |
-
{
|
37 |
-
if(current_user_can($cap))
|
38 |
-
{
|
39 |
-
$top_menu_cap = $cap;
|
40 |
-
break;
|
41 |
-
}
|
42 |
-
}
|
43 |
-
|
44 |
-
if(empty($top_menu_cap))
|
45 |
-
return;
|
46 |
-
|
47 |
-
add_menu_page(__('Memberships', 'pmpro'), __('Memberships', 'pmpro'), 'pmpro_memberships_menu', 'pmpro-membershiplevels', $top_menu_cap, 'dashicons-groups');
|
48 |
-
add_submenu_page('pmpro-membershiplevels', __('Page Settings', 'pmpro'), __('Page Settings', 'pmpro'), 'pmpro_pagesettings', 'pmpro-pagesettings', 'pmpro_pagesettings');
|
49 |
-
add_submenu_page('pmpro-membershiplevels', __('Payment Settings', 'pmpro'), __('Payment Settings', 'pmpro'), 'pmpro_paymentsettings', 'pmpro-paymentsettings', 'pmpro_paymentsettings');
|
50 |
-
add_submenu_page('pmpro-membershiplevels', __('Email Settings', 'pmpro'), __('Email Settings', 'pmpro'), 'pmpro_emailsettings', 'pmpro-emailsettings', 'pmpro_emailsettings');
|
51 |
-
add_submenu_page('pmpro-membershiplevels', __('Advanced Settings', 'pmpro'), __('Advanced Settings', 'pmpro'), 'pmpro_advancedsettings', 'pmpro-advancedsettings', 'pmpro_advancedsettings');
|
52 |
-
add_submenu_page('pmpro-membershiplevels', __('Add Ons', 'pmpro'), __('Add Ons', 'pmpro'), 'pmpro_addons', 'pmpro-addons', 'pmpro_addons');
|
53 |
-
add_submenu_page('pmpro-membershiplevels', __('Members List', 'pmpro'), __('Members List', 'pmpro'), 'pmpro_memberslist', 'pmpro-memberslist', 'pmpro_memberslist');
|
54 |
-
add_submenu_page('pmpro-membershiplevels', __('Reports', 'pmpro'), __('Reports', 'pmpro'), 'pmpro_reports', 'pmpro-reports', 'pmpro_reports');
|
55 |
-
add_submenu_page('pmpro-membershiplevels', __('Orders', 'pmpro'), __('Orders', 'pmpro'), 'pmpro_orders', 'pmpro-orders', 'pmpro_orders');
|
56 |
-
add_submenu_page('pmpro-membershiplevels', __('Discount Codes', 'pmpro'), __('Discount Codes', 'pmpro'), 'pmpro_discountcodes', 'pmpro-discountcodes', 'pmpro_discountcodes');
|
57 |
-
|
58 |
-
//rename the automatically added Memberships submenu item
|
59 |
-
global $submenu;
|
60 |
-
if(!empty($submenu['pmpro-membershiplevels']))
|
61 |
-
{
|
62 |
-
if(current_user_can("pmpro_membershiplevels"))
|
63 |
-
{
|
64 |
-
$submenu['pmpro-membershiplevels'][0][0] = __( 'Membership Levels', 'pmpro' );
|
65 |
-
$submenu['pmpro-membershiplevels'][0][3] = __( 'Membership Levels', 'pmpro' );
|
66 |
-
}
|
67 |
-
|
68 |
-
{
|
69 |
-
unset($submenu['pmpro-membershiplevels']);
|
70 |
-
}
|
71 |
-
|
72 |
-
|
73 |
-
|
74 |
-
|
75 |
-
|
76 |
-
|
77 |
-
|
78 |
-
|
79 |
-
|
80 |
-
|
81 |
-
|
82 |
-
|
83 |
-
|
84 |
-
|
85 |
-
//
|
86 |
-
|
87 |
-
|
88 |
-
|
89 |
-
|
90 |
-
|
91 |
-
|
92 |
-
|
93 |
-
|
94 |
-
|
95 |
-
|
96 |
-
|
97 |
-
|
98 |
-
|
99 |
-
|
100 |
-
|
101 |
-
|
102 |
-
|
103 |
-
|
104 |
-
|
105 |
-
|
106 |
-
|
107 |
-
|
108 |
-
|
109 |
-
|
110 |
-
|
111 |
-
|
112 |
-
'
|
113 |
-
|
114 |
-
|
115 |
-
|
116 |
-
|
117 |
-
|
118 |
-
|
119 |
-
'
|
120 |
-
|
121 |
-
|
122 |
-
|
123 |
-
|
124 |
-
|
125 |
-
|
126 |
-
'
|
127 |
-
|
128 |
-
|
129 |
-
|
130 |
-
|
131 |
-
|
132 |
-
|
133 |
-
'
|
134 |
-
|
135 |
-
|
136 |
-
|
137 |
-
|
138 |
-
|
139 |
-
|
140 |
-
'
|
141 |
-
|
142 |
-
|
143 |
-
|
144 |
-
|
145 |
-
|
146 |
-
|
147 |
-
'
|
148 |
-
|
149 |
-
|
150 |
-
|
151 |
-
|
152 |
-
|
153 |
-
|
154 |
-
'
|
155 |
-
|
156 |
-
|
157 |
-
|
158 |
-
|
159 |
-
|
160 |
-
|
161 |
-
'
|
162 |
-
|
163 |
-
|
164 |
-
|
165 |
-
|
166 |
-
|
167 |
-
|
168 |
-
'
|
169 |
-
|
170 |
-
|
171 |
-
|
172 |
-
|
173 |
-
|
174 |
-
|
175 |
-
|
176 |
-
|
177 |
-
|
178 |
-
|
179 |
-
|
180 |
-
|
181 |
-
|
182 |
-
|
183 |
-
|
184 |
-
|
185 |
-
|
186 |
-
|
187 |
-
|
188 |
-
|
189 |
-
|
190 |
-
|
191 |
-
|
192 |
-
|
193 |
-
|
194 |
-
|
195 |
-
|
196 |
-
|
197 |
-
|
198 |
-
|
199 |
-
|
200 |
-
|
201 |
-
|
202 |
-
|
203 |
-
|
204 |
-
|
205 |
-
|
206 |
-
|
207 |
-
|
208 |
-
|
209 |
-
|
210 |
-
|
211 |
-
|
212 |
-
|
213 |
-
|
214 |
-
|
215 |
-
|
216 |
-
|
217 |
-
|
218 |
-
|
219 |
-
|
220 |
-
|
221 |
-
|
222 |
-
|
223 |
-
|
224 |
-
|
225 |
-
|
226 |
-
|
227 |
-
|
228 |
-
|
229 |
-
|
230 |
-
|
231 |
-
|
232 |
-
|
233 |
-
|
234 |
-
|
235 |
-
|
236 |
-
|
237 |
-
|
238 |
-
|
239 |
-
|
240 |
-
|
241 |
-
|
242 |
-
|
243 |
-
|
244 |
-
|
245 |
-
|
246 |
-
|
247 |
-
|
248 |
-
|
249 |
-
|
250 |
-
|
251 |
-
|
252 |
-
|
253 |
-
|
254 |
-
|
255 |
-
|
256 |
-
|
257 |
-
|
258 |
-
|
259 |
-
|
260 |
-
|
261 |
-
|
262 |
-
|
263 |
-
|
264 |
-
$
|
265 |
-
|
266 |
-
|
267 |
-
|
268 |
-
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/*
|
3 |
+
Get array of PMPro Capabilities
|
4 |
+
*/
|
5 |
+
function pmpro_getPMProCaps()
|
6 |
+
{
|
7 |
+
$pmpro_caps = array(
|
8 |
+
//pmpro_memberships_menu //this controls viewing the menu itself
|
9 |
+
'pmpro_membershiplevels',
|
10 |
+
'pmpro_pagesettings',
|
11 |
+
'pmpro_paymentsettings',
|
12 |
+
'pmpro_emailsettings',
|
13 |
+
'pmpro_advancedsettings',
|
14 |
+
'pmpro_addons',
|
15 |
+
'pmpro_memberslist',
|
16 |
+
'pmpro_reports',
|
17 |
+
'pmpro_orders',
|
18 |
+
'pmpro_discountcodes'
|
19 |
+
);
|
20 |
+
|
21 |
+
return $pmpro_caps;
|
22 |
+
}
|
23 |
+
|
24 |
+
/*
|
25 |
+
Dashboard Menu
|
26 |
+
*/
|
27 |
+
function pmpro_add_pages()
|
28 |
+
{
|
29 |
+
global $wpdb;
|
30 |
+
|
31 |
+
//array of all caps in the menu
|
32 |
+
$pmpro_caps = pmpro_getPMProCaps();
|
33 |
+
|
34 |
+
//the top level menu links to the first page they have access to
|
35 |
+
foreach($pmpro_caps as $cap)
|
36 |
+
{
|
37 |
+
if(current_user_can($cap))
|
38 |
+
{
|
39 |
+
$top_menu_cap = $cap;
|
40 |
+
break;
|
41 |
+
}
|
42 |
+
}
|
43 |
+
|
44 |
+
if(empty($top_menu_cap))
|
45 |
+
return;
|
46 |
+
|
47 |
+
add_menu_page(__('Memberships', 'pmpro'), __('Memberships', 'pmpro'), 'pmpro_memberships_menu', 'pmpro-membershiplevels', $top_menu_cap, 'dashicons-groups');
|
48 |
+
add_submenu_page('pmpro-membershiplevels', __('Page Settings', 'pmpro'), __('Page Settings', 'pmpro'), 'pmpro_pagesettings', 'pmpro-pagesettings', 'pmpro_pagesettings');
|
49 |
+
add_submenu_page('pmpro-membershiplevels', __('Payment Settings', 'pmpro'), __('Payment Settings', 'pmpro'), 'pmpro_paymentsettings', 'pmpro-paymentsettings', 'pmpro_paymentsettings');
|
50 |
+
add_submenu_page('pmpro-membershiplevels', __('Email Settings', 'pmpro'), __('Email Settings', 'pmpro'), 'pmpro_emailsettings', 'pmpro-emailsettings', 'pmpro_emailsettings');
|
51 |
+
add_submenu_page('pmpro-membershiplevels', __('Advanced Settings', 'pmpro'), __('Advanced Settings', 'pmpro'), 'pmpro_advancedsettings', 'pmpro-advancedsettings', 'pmpro_advancedsettings');
|
52 |
+
add_submenu_page('pmpro-membershiplevels', __('Add Ons', 'pmpro'), __('Add Ons', 'pmpro'), 'pmpro_addons', 'pmpro-addons', 'pmpro_addons');
|
53 |
+
add_submenu_page('pmpro-membershiplevels', __('Members List', 'pmpro'), __('Members List', 'pmpro'), 'pmpro_memberslist', 'pmpro-memberslist', 'pmpro_memberslist');
|
54 |
+
add_submenu_page('pmpro-membershiplevels', __('Reports', 'pmpro'), __('Reports', 'pmpro'), 'pmpro_reports', 'pmpro-reports', 'pmpro_reports');
|
55 |
+
add_submenu_page('pmpro-membershiplevels', __('Orders', 'pmpro'), __('Orders', 'pmpro'), 'pmpro_orders', 'pmpro-orders', 'pmpro_orders');
|
56 |
+
add_submenu_page('pmpro-membershiplevels', __('Discount Codes', 'pmpro'), __('Discount Codes', 'pmpro'), 'pmpro_discountcodes', 'pmpro-discountcodes', 'pmpro_discountcodes');
|
57 |
+
|
58 |
+
//rename the automatically added Memberships submenu item
|
59 |
+
global $submenu;
|
60 |
+
if(!empty($submenu['pmpro-membershiplevels']))
|
61 |
+
{
|
62 |
+
if(current_user_can("pmpro_membershiplevels"))
|
63 |
+
{
|
64 |
+
$submenu['pmpro-membershiplevels'][0][0] = __( 'Membership Levels', 'pmpro' );
|
65 |
+
$submenu['pmpro-membershiplevels'][0][3] = __( 'Membership Levels', 'pmpro' );
|
66 |
+
}
|
67 |
+
elseif(current_user_can($top_menu_cap))
|
68 |
+
{
|
69 |
+
unset($submenu['pmpro-membershiplevels'][0]);
|
70 |
+
}
|
71 |
+
else
|
72 |
+
{
|
73 |
+
unset($submenu['pmpro-membershiplevels']);
|
74 |
+
}
|
75 |
+
}
|
76 |
+
}
|
77 |
+
add_action('admin_menu', 'pmpro_add_pages');
|
78 |
+
|
79 |
+
/*
|
80 |
+
Admin Bar
|
81 |
+
*/
|
82 |
+
function pmpro_admin_bar_menu() {
|
83 |
+
global $wp_admin_bar;
|
84 |
+
|
85 |
+
//view menu at all?
|
86 |
+
if ( !current_user_can('pmpro_memberships_menu') || !is_admin_bar_showing() )
|
87 |
+
return;
|
88 |
+
|
89 |
+
//array of all caps in the menu
|
90 |
+
$pmpro_caps = pmpro_getPMProCaps();
|
91 |
+
|
92 |
+
//the top level menu links to the first page they have access to
|
93 |
+
foreach($pmpro_caps as $cap)
|
94 |
+
{
|
95 |
+
if(current_user_can($cap))
|
96 |
+
{
|
97 |
+
$top_menu_page = str_replace("_", "-", $cap);
|
98 |
+
break;
|
99 |
+
}
|
100 |
+
}
|
101 |
+
|
102 |
+
$wp_admin_bar->add_menu( array(
|
103 |
+
'id' => 'paid-memberships-pro',
|
104 |
+
'title' => __( '<span class="ab-icon"></span>Memberships', 'pmpro'),
|
105 |
+
'href' => get_admin_url(NULL, '/admin.php?page=' . $top_menu_page) ) );
|
106 |
+
|
107 |
+
if(current_user_can('pmpro_membershiplevels'))
|
108 |
+
$wp_admin_bar->add_menu( array(
|
109 |
+
'id' => 'pmpro-membership-levels',
|
110 |
+
'parent' => 'paid-memberships-pro',
|
111 |
+
'title' => __( 'Membership Levels', 'pmpro'),
|
112 |
+
'href' => get_admin_url(NULL, '/admin.php?page=pmpro-membershiplevels') ) );
|
113 |
+
|
114 |
+
if(current_user_can('pmpro_pagesettings'))
|
115 |
+
$wp_admin_bar->add_menu( array(
|
116 |
+
'id' => 'pmpro-page-settings',
|
117 |
+
'parent' => 'paid-memberships-pro',
|
118 |
+
'title' => __( 'Page Settings', 'pmpro'),
|
119 |
+
'href' => get_admin_url(NULL, '/admin.php?page=pmpro-pagesettings') ) );
|
120 |
+
|
121 |
+
if(current_user_can('pmpro_paymentsettings'))
|
122 |
+
$wp_admin_bar->add_menu( array(
|
123 |
+
'id' => 'pmpro-payment-settings',
|
124 |
+
'parent' => 'paid-memberships-pro',
|
125 |
+
'title' => __( 'Payment Settings', 'pmpro'),
|
126 |
+
'href' => get_admin_url(NULL, '/admin.php?page=pmpro-paymentsettings') ) );
|
127 |
+
|
128 |
+
if(current_user_can('pmpro_emailsettings'))
|
129 |
+
$wp_admin_bar->add_menu( array(
|
130 |
+
'id' => 'pmpro-email-settings',
|
131 |
+
'parent' => 'paid-memberships-pro',
|
132 |
+
'title' => __( 'Email Settings', 'pmpro'),
|
133 |
+
'href' => get_admin_url(NULL, '/admin.php?page=pmpro-emailsettings') ) );
|
134 |
+
|
135 |
+
if(current_user_can('pmpro_advancedsettings'))
|
136 |
+
$wp_admin_bar->add_menu( array(
|
137 |
+
'id' => 'pmpro-advanced-settings',
|
138 |
+
'parent' => 'paid-memberships-pro',
|
139 |
+
'title' => __( 'Advanced Settings', 'pmpro'),
|
140 |
+
'href' => get_admin_url(NULL, '/admin.php?page=pmpro-advancedsettings') ) );
|
141 |
+
|
142 |
+
if(current_user_can('pmpro_addons'))
|
143 |
+
$wp_admin_bar->add_menu( array(
|
144 |
+
'id' => 'pmpro-addons',
|
145 |
+
'parent' => 'paid-memberships-pro',
|
146 |
+
'title' => __( 'Add Ons', 'pmpro'),
|
147 |
+
'href' => get_admin_url(NULL, '/admin.php?page=pmpro-addons') ) );
|
148 |
+
|
149 |
+
if(current_user_can('pmpro_memberslist'))
|
150 |
+
$wp_admin_bar->add_menu( array(
|
151 |
+
'id' => 'pmpro-members-list',
|
152 |
+
'parent' => 'paid-memberships-pro',
|
153 |
+
'title' => __( 'Members List', 'pmpro'),
|
154 |
+
'href' => get_admin_url(NULL, '/admin.php?page=pmpro-memberslist') ) );
|
155 |
+
|
156 |
+
if(current_user_can('pmpro_reports'))
|
157 |
+
$wp_admin_bar->add_menu( array(
|
158 |
+
'id' => 'pmpro-reports',
|
159 |
+
'parent' => 'paid-memberships-pro',
|
160 |
+
'title' => __( 'Reports', 'pmpro'),
|
161 |
+
'href' => get_admin_url(NULL, '/admin.php?page=pmpro-reports') ) );
|
162 |
+
|
163 |
+
if(current_user_can('pmpro_orders'))
|
164 |
+
$wp_admin_bar->add_menu( array(
|
165 |
+
'id' => 'pmpro-orders',
|
166 |
+
'parent' => 'paid-memberships-pro',
|
167 |
+
'title' => __( 'Orders', 'pmpro'),
|
168 |
+
'href' => get_admin_url(NULL, '/admin.php?page=pmpro-orders') ) );
|
169 |
+
|
170 |
+
if(current_user_can('pmpro_discountcodes'))
|
171 |
+
$wp_admin_bar->add_menu( array(
|
172 |
+
'id' => 'pmpro-discount-codes',
|
173 |
+
'parent' => 'paid-memberships-pro',
|
174 |
+
'title' => __( 'Discount Codes', 'pmpro'),
|
175 |
+
'href' => get_admin_url(NULL, '/admin.php?page=pmpro-discountcodes') ) );
|
176 |
+
}
|
177 |
+
add_action('admin_bar_menu', 'pmpro_admin_bar_menu', 1000);
|
178 |
+
|
179 |
+
/*
|
180 |
+
Functions to load pages from adminpages directory
|
181 |
+
*/
|
182 |
+
function pmpro_reports()
|
183 |
+
{
|
184 |
+
require_once(PMPRO_DIR . "/adminpages/reports.php");
|
185 |
+
}
|
186 |
+
|
187 |
+
function pmpro_memberslist()
|
188 |
+
{
|
189 |
+
require_once(PMPRO_DIR . "/adminpages/memberslist.php");
|
190 |
+
}
|
191 |
+
|
192 |
+
function pmpro_discountcodes()
|
193 |
+
{
|
194 |
+
require_once(PMPRO_DIR . "/adminpages/discountcodes.php");
|
195 |
+
}
|
196 |
+
|
197 |
+
function pmpro_membershiplevels()
|
198 |
+
{
|
199 |
+
require_once(PMPRO_DIR . "/adminpages/membershiplevels.php");
|
200 |
+
}
|
201 |
+
|
202 |
+
function pmpro_pagesettings()
|
203 |
+
{
|
204 |
+
require_once(PMPRO_DIR . "/adminpages/pagesettings.php");
|
205 |
+
}
|
206 |
+
|
207 |
+
function pmpro_paymentsettings()
|
208 |
+
{
|
209 |
+
require_once(PMPRO_DIR . "/adminpages/paymentsettings.php");
|
210 |
+
}
|
211 |
+
|
212 |
+
function pmpro_emailsettings()
|
213 |
+
{
|
214 |
+
require_once(PMPRO_DIR . "/adminpages/emailsettings.php");
|
215 |
+
}
|
216 |
+
|
217 |
+
function pmpro_advancedsettings()
|
218 |
+
{
|
219 |
+
require_once(PMPRO_DIR . "/adminpages/advancedsettings.php");
|
220 |
+
}
|
221 |
+
|
222 |
+
function pmpro_addons()
|
223 |
+
{
|
224 |
+
require_once(PMPRO_DIR . "/adminpages/addons.php");
|
225 |
+
}
|
226 |
+
|
227 |
+
function pmpro_orders()
|
228 |
+
{
|
229 |
+
require_once(PMPRO_DIR . "/adminpages/orders.php");
|
230 |
+
}
|
231 |
+
|
232 |
+
|
233 |
+
/*
|
234 |
+
Function to add links to the plugin action links
|
235 |
+
*/
|
236 |
+
function pmpro_add_action_links($links) {
|
237 |
+
|
238 |
+
//array of all caps in the menu
|
239 |
+
$pmpro_caps = pmpro_getPMProCaps();
|
240 |
+
|
241 |
+
//the top level menu links to the first page they have access to
|
242 |
+
foreach($pmpro_caps as $cap)
|
243 |
+
{
|
244 |
+
if(current_user_can($cap))
|
245 |
+
{
|
246 |
+
$top_menu_page = str_replace("_", "-", $cap);
|
247 |
+
break;
|
248 |
+
}
|
249 |
+
}
|
250 |
+
|
251 |
+
$new_links = array(
|
252 |
+
'<a href="' . get_admin_url(NULL, 'admin.php?page=' . $top_menu_page) . '">Settings</a>',
|
253 |
+
);
|
254 |
+
return array_merge($new_links, $links);
|
255 |
+
}
|
256 |
+
add_filter('plugin_action_links_' . plugin_basename(PMPRO_DIR . "/paid-memberships-pro.php"), 'pmpro_add_action_links');
|
257 |
+
|
258 |
+
/*
|
259 |
+
Function to add links to the plugin row meta
|
260 |
+
*/
|
261 |
+
function pmpro_plugin_row_meta($links, $file) {
|
262 |
+
if(strpos($file, 'paid-memberships-pro.php') !== false)
|
263 |
+
{
|
264 |
+
$new_links = array(
|
265 |
+
'<a href="' . esc_url( apply_filters( 'pmpro_docs_url', 'http://paidmembershipspro.com/documentation/' ) ) . '" title="' . esc_attr( __( 'View PMPro Documentation', 'pmpro' ) ) . '">' . __( 'Docs', 'pmpro' ) . '</a>',
|
266 |
+
'<a href="' . esc_url( apply_filters( 'pmpro_support_url', 'http://paidmembershipspro.com/support/' ) ) . '" title="' . esc_attr( __( 'Visit Customer Support Forum', 'pmpro' ) ) . '">' . __( 'Support', 'pmpro' ) . '</a>',
|
267 |
+
);
|
268 |
+
$links = array_merge($links, $new_links);
|
269 |
+
}
|
270 |
+
return $links;
|
271 |
+
}
|
272 |
+
add_filter('plugin_row_meta', 'pmpro_plugin_row_meta', 10, 2);
|
includes/cleanup.php
CHANGED
@@ -1,40 +1,40 @@
|
|
1 |
-
<?php
|
2 |
-
/*
|
3 |
-
Clean things up when deletes happen, etc. (This stuff needs a better home.)
|
4 |
-
*/
|
5 |
-
//deleting a user? remove their account info.
|
6 |
-
function pmpro_delete_user($user_id = NULL)
|
7 |
-
{
|
8 |
-
global $wpdb;
|
9 |
-
|
10 |
-
//changing their membership level to 0 will cancel any subscription and remove their membership level entry
|
11 |
-
//we don't remove the orders because it would affect reporting
|
12 |
-
if(pmpro_changeMembershipLevel(0, $user_id))
|
13 |
-
{
|
14 |
-
//okay
|
15 |
-
}
|
16 |
-
else
|
17 |
-
{
|
18 |
-
//okay, guessing they didn't have a level
|
19 |
-
}
|
20 |
-
}
|
21 |
-
add_action('delete_user', 'pmpro_delete_user');
|
22 |
-
add_action('wpmu_delete_user', 'pmpro_delete_user');
|
23 |
-
|
24 |
-
//deleting a category? remove any level associations
|
25 |
-
function pmpro_delete_category($cat_id = NULL)
|
26 |
-
{
|
27 |
-
global $wpdb;
|
28 |
-
$sqlQuery = "DELETE FROM $wpdb->pmpro_memberships_categories WHERE category_id = '" . $cat_id . "'";
|
29 |
-
$wpdb->query($sqlQuery);
|
30 |
-
}
|
31 |
-
add_action('delete_category', 'pmpro_delete_category');
|
32 |
-
|
33 |
-
//deleting a post? remove any level associations
|
34 |
-
function pmpro_delete_post($post_id = NULL)
|
35 |
-
{
|
36 |
-
global $wpdb;
|
37 |
-
$sqlQuery = "DELETE FROM $wpdb->pmpro_memberships_pages WHERE page_id = '" . $post_id . "'";
|
38 |
-
$wpdb->query($sqlQuery);
|
39 |
-
}
|
40 |
add_action('delete_post', 'pmpro_delete_post');
|
1 |
+
<?php
|
2 |
+
/*
|
3 |
+
Clean things up when deletes happen, etc. (This stuff needs a better home.)
|
4 |
+
*/
|
5 |
+
//deleting a user? remove their account info.
|
6 |
+
function pmpro_delete_user($user_id = NULL)
|
7 |
+
{
|
8 |
+
global $wpdb;
|
9 |
+
|
10 |
+
//changing their membership level to 0 will cancel any subscription and remove their membership level entry
|
11 |
+
//we don't remove the orders because it would affect reporting
|
12 |
+
if(pmpro_changeMembershipLevel(0, $user_id))
|
13 |
+
{
|
14 |
+
//okay
|
15 |
+
}
|
16 |
+
else
|
17 |
+
{
|
18 |
+
//okay, guessing they didn't have a level
|
19 |
+
}
|
20 |
+
}
|
21 |
+
add_action('delete_user', 'pmpro_delete_user');
|
22 |
+
add_action('wpmu_delete_user', 'pmpro_delete_user');
|
23 |
+
|
24 |
+
//deleting a category? remove any level associations
|
25 |
+
function pmpro_delete_category($cat_id = NULL)
|
26 |
+
{
|
27 |
+
global $wpdb;
|
28 |
+
$sqlQuery = "DELETE FROM $wpdb->pmpro_memberships_categories WHERE category_id = '" . $cat_id . "'";
|
29 |
+
$wpdb->query($sqlQuery);
|
30 |
+
}
|
31 |
+
add_action('delete_category', 'pmpro_delete_category');
|
32 |
+
|
33 |
+
//deleting a post? remove any level associations
|
34 |
+
function pmpro_delete_post($post_id = NULL)
|
35 |
+
{
|
36 |
+
global $wpdb;
|
37 |
+
$sqlQuery = "DELETE FROM $wpdb->pmpro_memberships_pages WHERE page_id = '" . $post_id . "'";
|
38 |
+
$wpdb->query($sqlQuery);
|
39 |
+
}
|
40 |
add_action('delete_post', 'pmpro_delete_post');
|
includes/content.php
CHANGED
@@ -1,458 +1,461 @@
|
|
1 |
-
<?php
|
2 |
-
/*
|
3 |
-
Functions to detect member content and protect it.
|
4 |
-
*/
|
5 |
-
function pmpro_has_membership_access($post_id = NULL, $user_id = NULL, $return_membership_levels = false)
|
6 |
-
{
|
7 |
-
global $post, $wpdb, $current_user;
|
8 |
-
//use globals if no values supplied
|
9 |
-
if(!$post_id && !empty($post))
|
10 |
-
$post_id = $post->ID;
|
11 |
-
if(!$user_id)
|
12 |
-
$user_id = $current_user->ID;
|
13 |
-
|
14 |
-
//no post, return true (changed from false in version 1.7.2)
|
15 |
-
if(!$post_id)
|
16 |
-
return true;
|
17 |
-
|
18 |
-
//if no post or current_user object, set them up
|
19 |
-
if(!empty($post->ID) && $post_id == $post->ID)
|
20 |
-
$mypost = $post;
|
21 |
-
else
|
22 |
-
$mypost = get_post($post_id);
|
23 |
-
|
24 |
-
if($user_id == $current_user->ID)
|
25 |
-
$myuser = $current_user;
|
26 |
-
else
|
27 |
-
$myuser = get_userdata($user_id);
|
28 |
-
|
29 |
-
//for these post types, we want to check the parent
|
30 |
-
if($mypost->post_type == "attachment" || $mypost->post_type == "revision")
|
31 |
-
{
|
32 |
-
$mypost = get_post($mypost->post_parent);
|
33 |
-
}
|
34 |
-
|
35 |
-
|
36 |
-
|
37 |
-
|
38 |
-
|
39 |
-
|
40 |
-
|
41 |
-
|
42 |
-
|
43 |
-
|
44 |
-
|
45 |
-
|
46 |
-
|
47 |
-
|
48 |
-
|
49 |
-
|
50 |
-
|
51 |
-
|
52 |
-
|
53 |
-
|
54 |
-
|
55 |
-
|
56 |
-
|
57 |
-
|
58 |
-
|
59 |
-
|
60 |
-
$
|
61 |
-
|
62 |
-
|
63 |
-
|
64 |
-
|
65 |
-
|
66 |
-
|
67 |
-
|
68 |
-
|
69 |
-
|
70 |
-
|
71 |
-
|
72 |
-
|
73 |
-
|
74 |
-
|
75 |
-
|
76 |
-
|
77 |
-
|
78 |
-
|
79 |
-
|
80 |
-
|
81 |
-
|
82 |
-
|
83 |
-
|
84 |
-
|
85 |
-
|
86 |
-
|
87 |
-
|
88 |
-
|
89 |
-
|
90 |
-
|
91 |
-
|
92 |
-
|
93 |
-
|
94 |
-
|
95 |
-
|
96 |
-
|
97 |
-
|
98 |
-
|
99 |
-
|
100 |
-
|
101 |
-
|
102 |
-
|
103 |
-
|
104 |
-
|
105 |
-
|
106 |
-
|
107 |
-
|
108 |
-
|
109 |
-
|
110 |
-
|
111 |
-
|
112 |
-
|
113 |
-
|
114 |
-
|
115 |
-
|
116 |
-
|
117 |
-
|
118 |
-
|
119 |
-
|
120 |
-
|
121 |
-
|
122 |
-
|
123 |
-
|
124 |
-
|
125 |
-
|
126 |
-
|
127 |
-
|
128 |
-
|
129 |
-
|
130 |
-
|
131 |
-
|
132 |
-
|
133 |
-
|
134 |
-
|
135 |
-
|
136 |
-
|
137 |
-
|
138 |
-
|
139 |
-
|
140 |
-
|
141 |
-
|
142 |
-
|
143 |
-
|
144 |
-
|
145 |
-
|
146 |
-
|
147 |
-
|
148 |
-
|
149 |
-
|
150 |
-
|
151 |
-
|
152 |
-
|
153 |
-
|
154 |
-
|
155 |
-
|
156 |
-
|
157 |
-
|
158 |
-
|
159 |
-
|
160 |
-
|
161 |
-
|
162 |
-
|
163 |
-
|
164 |
-
|
165 |
-
|
166 |
-
|
167 |
-
|
168 |
-
|
169 |
-
|
170 |
-
|
171 |
-
|
172 |
-
|
173 |
-
|
174 |
-
|
175 |
-
|
176 |
-
|
177 |
-
|
178 |
-
|
179 |
-
|
180 |
-
|
181 |
-
|
182 |
-
|
183 |
-
|
184 |
-
|
185 |
-
|
186 |
-
|
187 |
-
|
188 |
-
|
189 |
-
|
190 |
-
|
191 |
-
|
192 |
-
|
193 |
-
|
194 |
-
|
195 |
-
|
196 |
-
|
197 |
-
|
198 |
-
}
|
199 |
-
|
200 |
-
|
201 |
-
|
202 |
-
|
203 |
-
|
204 |
-
|
205 |
-
|
206 |
-
|
207 |
-
|
208 |
-
|
209 |
-
|
210 |
-
|
211 |
-
|
212 |
-
|
213 |
-
|
214 |
-
|
215 |
-
|
216 |
-
|
217 |
-
|
218 |
-
|
219 |
-
|
220 |
-
|
221 |
-
|
222 |
-
|
223 |
-
|
224 |
-
|
225 |
-
|
226 |
-
|
227 |
-
|
228 |
-
|
229 |
-
|
230 |
-
|
231 |
-
|
232 |
-
|
233 |
-
|
234 |
-
|
235 |
-
|
236 |
-
|
237 |
-
|
238 |
-
|
239 |
-
|
240 |
-
|
241 |
-
|
242 |
-
|
243 |
-
|
244 |
-
|
245 |
-
|
246 |
-
|
247 |
-
|
248 |
-
|
249 |
-
|
250 |
-
|
251 |
-
|
252 |
-
|
253 |
-
|
254 |
-
|
255 |
-
|
256 |
-
|
257 |
-
|
258 |
-
|
259 |
-
|
260 |
-
|
261 |
-
|
262 |
-
|
263 |
-
|
264 |
-
|
265 |
-
|
266 |
-
|
267 |
-
|
268 |
-
|
269 |
-
|
270 |
-
|
271 |
-
|
272 |
-
|
273 |
-
|
274 |
-
|
275 |
-
|
276 |
-
|
277 |
-
|
278 |
-
|
279 |
-
$
|
280 |
-
$
|
281 |
-
|
282 |
-
|
283 |
-
|
284 |
-
|
285 |
-
|
286 |
-
$content = implode(' ', $words)
|
287 |
-
|
288 |
-
|
289 |
-
|
290 |
-
|
291 |
-
|
292 |
-
|
293 |
-
|
294 |
-
|
295 |
-
|
296 |
-
|
297 |
-
|
298 |
-
|
299 |
-
|
300 |
-
|
301 |
-
if(empty($
|
302 |
-
$
|
303 |
-
|
304 |
-
|
305 |
-
|
306 |
-
|
307 |
-
|
308 |
-
|
309 |
-
|
310 |
-
|
311 |
-
|
312 |
-
|
313 |
-
|
314 |
-
|
315 |
-
|
316 |
-
|
317 |
-
|
318 |
-
|
319 |
-
|
320 |
-
|
321 |
-
|
322 |
-
$
|
323 |
-
$
|
324 |
-
|
325 |
-
|
326 |
-
|
327 |
-
|
328 |
-
|
329 |
-
|
330 |
-
|
331 |
-
|
332 |
-
|
333 |
-
|
334 |
-
|
335 |
-
|
336 |
-
|
337 |
-
|
338 |
-
|
339 |
-
|
340 |
-
|
341 |
-
|
342 |
-
|
343 |
-
|
344 |
-
|
345 |
-
|
346 |
-
}
|
347 |
-
|
348 |
-
|
349 |
-
|
350 |
-
|
351 |
-
|
352 |
-
|
353 |
-
|
354 |
-
|
355 |
-
|
356 |
-
|
357 |
-
|
358 |
-
add_filter('the_content', 'pmpro_membership_content_filter', 5);
|
359 |
-
|
360 |
-
return $content;
|
361 |
-
}
|
362 |
-
function pmpro_membership_get_excerpt_filter_start($content, $skipcheck = false)
|
363 |
-
{
|
364 |
-
remove_filter('the_content', 'pmpro_membership_content_filter', 5);
|
365 |
-
return $content;
|
366 |
-
}
|
367 |
-
function pmpro_membership_get_excerpt_filter_end($content, $skipcheck = false)
|
368 |
-
{
|
369 |
-
add_filter('the_content', 'pmpro_membership_content_filter', 5);
|
370 |
-
return $content;
|
371 |
-
}
|
372 |
-
add_filter('the_excerpt', 'pmpro_membership_excerpt_filter', 15);
|
373 |
-
add_filter('get_the_excerpt', 'pmpro_membership_get_excerpt_filter_start', 1);
|
374 |
-
add_filter('get_the_excerpt', 'pmpro_membership_get_excerpt_filter_end', 100);
|
375 |
-
|
376 |
-
function pmpro_comments_filter($comments, $post_id = NULL)
|
377 |
-
{
|
378 |
-
global $post, $wpdb, $current_user;
|
379 |
-
if(!$post_id)
|
380 |
-
$post_id = $post->ID;
|
381 |
-
|
382 |
-
if(!$comments)
|
383 |
-
return $comments; //if they are closed anyway, we don't need to check
|
384 |
-
|
385 |
-
global $post, $current_user;
|
386 |
-
|
387 |
-
$hasaccess = pmpro_has_membership_access(NULL, NULL, true);
|
388 |
-
if(is_array($hasaccess))
|
389 |
-
{
|
390 |
-
//returned an array to give us the membership level values
|
391 |
-
$post_membership_levels_ids = $hasaccess[1];
|
392 |
-
$post_membership_levels_names = $hasaccess[2];
|
393 |
-
$hasaccess = $hasaccess[0];
|
394 |
-
}
|
395 |
-
|
396 |
-
if($hasaccess)
|
397 |
-
{
|
398 |
-
//all good, return content
|
399 |
-
return $comments;
|
400 |
-
}
|
401 |
-
else
|
402 |
-
{
|
403 |
-
if(!$post_membership_levels_ids)
|
404 |
-
$post_membership_levels_ids = array();
|
405 |
-
|
406 |
-
if(!$post_membership_levels_names)
|
407 |
-
$post_membership_levels_names = array();
|
408 |
-
|
409 |
-
//get the correct message
|
410 |
-
if(is_feed())
|
411 |
-
{
|
412 |
-
if(is_array($comments))
|
413 |
-
return array();
|
414 |
-
else
|
415 |
-
return false;
|
416 |
-
}
|
417 |
-
elseif($current_user->ID)
|
418 |
-
{
|
419 |
-
//not a member
|
420 |
-
if(is_array($comments))
|
421 |
-
return array();
|
422 |
-
else
|
423 |
-
return false;
|
424 |
-
}
|
425 |
-
else
|
426 |
-
{
|
427 |
-
//not logged in!
|
428 |
-
if(is_array($comments))
|
429 |
-
return array();
|
430 |
-
else
|
431 |
-
return false;
|
432 |
-
}
|
433 |
-
}
|
434 |
-
|
435 |
-
return $comments;
|
436 |
-
}
|
437 |
-
add_filter("comments_array", "pmpro_comments_filter");
|
438 |
-
add_filter("comments_open", "pmpro_comments_filter");
|
439 |
-
|
440 |
-
//keep non-members from getting to certain pages (attachments, etc)
|
441 |
-
function pmpro_hide_pages_redirect()
|
442 |
-
{
|
443 |
-
global $post;
|
444 |
-
|
445 |
-
if(!is_admin() && !empty($post->ID))
|
446 |
-
{
|
447 |
-
if($post->post_type == "attachment")
|
448 |
-
{
|
449 |
-
//check if the user has access to the parent
|
450 |
-
if(!pmpro_has_membership_access($post->ID))
|
451 |
-
{
|
452 |
-
wp_redirect(pmpro_url("levels"));
|
453 |
-
exit;
|
454 |
-
}
|
455 |
-
}
|
456 |
-
}
|
457 |
-
}
|
458 |
-
add_action('wp', 'pmpro_hide_pages_redirect');
|
1 |
+
<?php
|
2 |
+
/*
|
3 |
+
Functions to detect member content and protect it.
|
4 |
+
*/
|
5 |
+
function pmpro_has_membership_access($post_id = NULL, $user_id = NULL, $return_membership_levels = false)
|
6 |
+
{
|
7 |
+
global $post, $wpdb, $current_user;
|
8 |
+
//use globals if no values supplied
|
9 |
+
if(!$post_id && !empty($post))
|
10 |
+
$post_id = $post->ID;
|
11 |
+
if(!$user_id)
|
12 |
+
$user_id = $current_user->ID;
|
13 |
+
|
14 |
+
//no post, return true (changed from false in version 1.7.2)
|
15 |
+
if(!$post_id)
|
16 |
+
return true;
|
17 |
+
|
18 |
+
//if no post or current_user object, set them up
|
19 |
+
if(!empty($post->ID) && $post_id == $post->ID)
|
20 |
+
$mypost = $post;
|
21 |
+
else
|
22 |
+
$mypost = get_post($post_id);
|
23 |
+
|
24 |
+
if($user_id == $current_user->ID)
|
25 |
+
$myuser = $current_user;
|
26 |
+
else
|
27 |
+
$myuser = get_userdata($user_id);
|
28 |
+
|
29 |
+
//for these post types, we want to check the parent
|
30 |
+
if($mypost->post_type == "attachment" || $mypost->post_type == "revision")
|
31 |
+
{
|
32 |
+
$mypost = get_post($mypost->post_parent);
|
33 |
+
}
|
34 |
+
|
35 |
+
// Allow plugins and themes to find the protected post
|
36 |
+
$mypost = apply_filters( 'pmpro_membership_access_post', $mypost, $myuser );
|
37 |
+
|
38 |
+
if($mypost->post_type == "post")
|
39 |
+
{
|
40 |
+
$post_categories = wp_get_post_categories($mypost->ID);
|
41 |
+
|
42 |
+
if(!$post_categories)
|
43 |
+
{
|
44 |
+
//just check for entries in the memberships_pages table
|
45 |
+
$sqlQuery = "SELECT m.id, m.name FROM $wpdb->pmpro_memberships_pages mp LEFT JOIN $wpdb->pmpro_membership_levels m ON mp.membership_id = m.id WHERE mp.page_id = '" . $mypost->ID . "'";
|
46 |
+
}
|
47 |
+
else
|
48 |
+
{
|
49 |
+
//are any of the post categories associated with membership levels? also check the memberships_pages table
|
50 |
+
$sqlQuery = "(SELECT m.id, m.name FROM $wpdb->pmpro_memberships_categories mc LEFT JOIN $wpdb->pmpro_membership_levels m ON mc.membership_id = m.id WHERE mc.category_id IN(" . implode(",", $post_categories) . ") AND m.id IS NOT NULL) UNION (SELECT m.id, m.name FROM $wpdb->pmpro_memberships_pages mp LEFT JOIN $wpdb->pmpro_membership_levels m ON mp.membership_id = m.id WHERE mp.page_id = '" . $mypost->ID . "')";
|
51 |
+
}
|
52 |
+
}
|
53 |
+
else
|
54 |
+
{
|
55 |
+
//are any membership levels associated with this page?
|
56 |
+
$sqlQuery = "SELECT m.id, m.name FROM $wpdb->pmpro_memberships_pages mp LEFT JOIN $wpdb->pmpro_membership_levels m ON mp.membership_id = m.id WHERE mp.page_id = '" . $mypost->ID . "'";
|
57 |
+
}
|
58 |
+
|
59 |
+
|
60 |
+
$post_membership_levels = $wpdb->get_results($sqlQuery);
|
61 |
+
|
62 |
+
$post_membership_levels_ids = array();
|
63 |
+
$post_membership_levels_names = array();
|
64 |
+
|
65 |
+
if(!$post_membership_levels)
|
66 |
+
{
|
67 |
+
$hasaccess = true;
|
68 |
+
}
|
69 |
+
else
|
70 |
+
{
|
71 |
+
//we need to see if the user has access
|
72 |
+
foreach($post_membership_levels as $level)
|
73 |
+
{
|
74 |
+
$post_membership_levels_ids[] = $level->id;
|
75 |
+
$post_membership_levels_names[] = $level->name;
|
76 |
+
}
|
77 |
+
|
78 |
+
//levels found. check if this is in a feed or if the current user is in at least one of those membership levels
|
79 |
+
if(is_feed())
|
80 |
+
{
|
81 |
+
//always block restricted feeds
|
82 |
+
$hasaccess = false;
|
83 |
+
}
|
84 |
+
elseif(!empty($myuser->ID))
|
85 |
+
{
|
86 |
+
$myuser->membership_level = pmpro_getMembershipLevelForUser($myuser->ID);
|
87 |
+
if(!empty($myuser->membership_level->ID) && in_array($myuser->membership_level->ID, $post_membership_levels_ids))
|
88 |
+
{
|
89 |
+
//the users membership id is one that will grant access
|
90 |
+
$hasaccess = true;
|
91 |
+
}
|
92 |
+
else
|
93 |
+
{
|
94 |
+
//user isn't a member of a level with access
|
95 |
+
$hasaccess = false;
|
96 |
+
}
|
97 |
+
}
|
98 |
+
else
|
99 |
+
{
|
100 |
+
//user is not logged in and this content requires membership
|
101 |
+
$hasaccess = false;
|
102 |
+
}
|
103 |
+
}
|
104 |
+
|
105 |
+
/*
|
106 |
+
Filters
|
107 |
+
The generic filter is run first. Then if there is a filter for this post type, that is run.
|
108 |
+
*/
|
109 |
+
//general filter for all posts
|
110 |
+
$hasaccess = apply_filters("pmpro_has_membership_access_filter", $hasaccess, $mypost, $myuser, $post_membership_levels);
|
111 |
+
//filter for this post type
|
112 |
+
if(has_filter("pmpro_has_membership_access_filter_" . $mypost->post_type))
|
113 |
+
$hasaccess = apply_filters("pmpro_has_membership_access_filter_" . $mypost->post_type, $hasaccess, $mypost, $myuser, $post_membership_levels);
|
114 |
+
|
115 |
+
//return
|
116 |
+
if($return_membership_levels)
|
117 |
+
return array($hasaccess, $post_membership_levels_ids, $post_membership_levels_names);
|
118 |
+
else
|
119 |
+
return $hasaccess;
|
120 |
+
}
|
121 |
+
|
122 |
+
function pmpro_search_filter($query)
|
123 |
+
{
|
124 |
+
global $current_user, $wpdb, $pmpro_pages;
|
125 |
+
|
126 |
+
//hide pmpro pages from search results
|
127 |
+
if(!$query->is_admin && $query->is_search && empty($query->query['post_parent']))
|
128 |
+
{
|
129 |
+
if(empty($query->query_vars['post_parent'])) //avoiding post_parent queries for now
|
130 |
+
$query->set('post__not_in', $pmpro_pages );
|
131 |
+
|
132 |
+
$query->set('post__not_in', $pmpro_pages ); // id of page or post
|
133 |
+
}
|
134 |
+
|
135 |
+
//hide member pages from non-members (make sure they aren't hidden from members)
|
136 |
+
if(!$query->is_admin &&
|
137 |
+
!$query->is_singular &&
|
138 |
+
empty($query->query['post_parent']) &&
|
139 |
+
(
|
140 |
+
empty($query->query_vars['post_type']) ||
|
141 |
+
in_array($query->query_vars['post_type'], apply_filters('pmpro_search_filter_post_types', array("page", "post")))
|
142 |
+
)
|
143 |
+
)
|
144 |
+
{
|
145 |
+
//get page ids that are in my levels
|
146 |
+
$levels = pmpro_getMembershipLevelsForUser($current_user->ID);
|
147 |
+
$my_pages = array();
|
148 |
+
|
149 |
+
if($levels) {
|
150 |
+
foreach($levels as $key => $level) {
|
151 |
+
//get restricted posts for level
|
152 |
+
$sql = "SELECT page_id FROM $wpdb->pmpro_memberships_pages WHERE membership_id=" . $current_user->membership_level->ID;
|
153 |
+
$member_pages = $wpdb->get_col($sql);
|
154 |
+
$my_pages = array_unique(array_merge($my_pages, $member_pages));
|
155 |
+
}
|
156 |
+
}
|
157 |
+
|
158 |
+
//get hidden page ids
|
159 |
+
if(!empty($my_pages))
|
160 |
+
$sql = "SELECT page_id FROM $wpdb->pmpro_memberships_pages WHERE page_id NOT IN(" . implode(',', $my_pages) . ")";
|
161 |
+
else
|
162 |
+
$sql = "SELECT page_id FROM $wpdb->pmpro_memberships_pages";
|
163 |
+
$hidden_page_ids = array_values(array_unique($wpdb->get_col($sql)));
|
164 |
+
|
165 |
+
if($hidden_page_ids)
|
166 |
+
{
|
167 |
+
if(empty($query->query_vars['post_parent'])) //avoiding post_parent queries for now
|
168 |
+
$query->set('post__not_in', $hidden_page_ids);
|
169 |
+
}
|
170 |
+
|
171 |
+
//get categories that are filtered by level, but not my level
|
172 |
+
global $pmpro_my_cats;
|
173 |
+
$pmpro_my_cats = array();
|
174 |
+
|
175 |
+
if($levels) {
|
176 |
+
foreach($levels as $key => $level) {
|
177 |
+
$member_cats = pmpro_getMembershipCategories($level->id);
|
178 |
+
$pmpro_my_cats = array_unique(array_merge($pmpro_my_cats, $member_cats));
|
179 |
+
}
|
180 |
+
}
|
181 |
+
|
182 |
+
//get hidden cats
|
183 |
+
if(!empty($pmpro_my_cats))
|
184 |
+
$sql = "SELECT category_id FROM $wpdb->pmpro_memberships_categories WHERE category_id NOT IN(" . implode(',', $pmpro_my_cats) . ")";
|
185 |
+
else
|
186 |
+
$sql = "SELECT category_id FROM $wpdb->pmpro_memberships_categories";
|
187 |
+
|
188 |
+
$hidden_cat_ids = array_values(array_unique($wpdb->get_col($sql)));
|
189 |
+
|
190 |
+
//make this work
|
191 |
+
if($hidden_cat_ids)
|
192 |
+
{
|
193 |
+
$query->set('category__not_in', $hidden_cat_ids);
|
194 |
+
|
195 |
+
//filter so posts in this member's categories are allowed
|
196 |
+
add_action('posts_where', 'pmpro_posts_where_unhide_cats');
|
197 |
+
}
|
198 |
+
}
|
199 |
+
|
200 |
+
return $query;
|
201 |
+
}
|
202 |
+
$filterqueries = pmpro_getOption("filterqueries");
|
203 |
+
if(!empty($filterqueries))
|
204 |
+
add_filter( 'pre_get_posts', 'pmpro_search_filter' );
|
205 |
+
|
206 |
+
/*
|
207 |
+
* Find taxonomy filters and make sure member categories are not hidden from members.
|
208 |
+
* @since 1.7.15
|
209 |
+
*/
|
210 |
+
function pmpro_posts_where_unhide_cats($where)
|
211 |
+
{
|
212 |
+
global $pmpro_my_cats, $wpdb;
|
213 |
+
|
214 |
+
//if we have member cats, make sure they are allowed in taxonomy queries
|
215 |
+
if(!empty($where) && !empty($pmpro_my_cats))
|
216 |
+
{
|
217 |
+
$pattern = "/$wpdb->posts.ID NOT IN \(\s*SELECT object_id\s*FROM dev_term_relationships\s*WHERE term_taxonomy_id IN \((.*)\)\s*\)/";
|
218 |
+
$replacement = $wpdb->posts . '.ID NOT IN (
|
219 |
+
SELECT tr1.object_id
|
220 |
+
FROM ' . $wpdb->term_relationships . ' tr1
|
221 |
+
LEFT JOIN ' . $wpdb->term_relationships . ' tr2 ON tr1.object_id = tr2.object_id AND tr2.term_taxonomy_id IN(' . implode($pmpro_my_cats) . ')
|
222 |
+
WHERE tr1.term_taxonomy_id IN(${1}) AND tr2.term_taxonomy_id IS NULL ) ';
|
223 |
+
$where = preg_replace($pattern, $replacement, $where);
|
224 |
+
}
|
225 |
+
|
226 |
+
//remove filter for next query
|
227 |
+
remove_action('posts_where', 'pmpro_posts_where_unhide_cats');
|
228 |
+
|
229 |
+
return $where;
|
230 |
+
}
|
231 |
+
|
232 |
+
function pmpro_membership_content_filter($content, $skipcheck = false)
|
233 |
+
{
|
234 |
+
global $post, $current_user;
|
235 |
+
|
236 |
+
if(!$skipcheck)
|
237 |
+
{
|
238 |
+
$hasaccess = pmpro_has_membership_access(NULL, NULL, true);
|
239 |
+
if(is_array($hasaccess))
|
240 |
+
{
|
241 |
+
//returned an array to give us the membership level values
|
242 |
+
$post_membership_levels_ids = $hasaccess[1];
|
243 |
+
$post_membership_levels_names = $hasaccess[2];
|
244 |
+
$hasaccess = $hasaccess[0];
|
245 |
+
}
|
246 |
+
}
|
247 |
+
|
248 |
+
if($hasaccess)
|
249 |
+
{
|
250 |
+
//all good, return content
|
251 |
+
return $content;
|
252 |
+
}
|
253 |
+
else
|
254 |
+
{
|
255 |
+
//if show excerpts is set, return just the excerpt
|
256 |
+
if(pmpro_getOption("showexcerpts"))
|
257 |
+
{
|
258 |
+
//show excerpt
|
259 |
+
global $post;
|
260 |
+
if($post->post_excerpt)
|
261 |
+
{
|
262 |
+
//defined exerpt
|
263 |
+
$content = wpautop($post->post_excerpt);
|
264 |
+
}
|
265 |
+
elseif(strpos($content, "<span id=\"more-" . $post->ID . "\"></span>") !== false)
|
266 |
+
{
|
267 |
+
//more tag
|
268 |
+
$pos = strpos($content, "<span id=\"more-" . $post->ID . "\"></span>");
|
269 |
+
$content = wpautop(substr($content, 0, $pos));
|
270 |
+
}
|
271 |
+
elseif(strpos($content, 'class="more-link">') !== false)
|
272 |
+
{
|
273 |
+
//more link
|
274 |
+
$content = preg_replace("/\<a.*class\=\"more\-link\".*\>.*\<\/a\>/", "", $content);
|
275 |
+
}
|
276 |
+
else
|
277 |
+
{
|
278 |
+
//auto generated excerpt. pulled from wp_trim_excerpt
|
279 |
+
$content = strip_shortcodes( $content );
|
280 |
+
$content = str_replace(']]>', ']]>', $content);
|
281 |
+
$content = strip_tags($content);
|
282 |
+
$excerpt_length = apply_filters('excerpt_length', 55);
|
283 |
+
$words = preg_split("/[\n\r\t ]+/", $content, $excerpt_length + 1, PREG_SPLIT_NO_EMPTY);
|
284 |
+
if ( count($words) > $excerpt_length ) {
|
285 |
+
array_pop($words);
|
286 |
+
$content = implode(' ', $words);
|
287 |
+
$content = $content . "... ";
|
288 |
+
} else {
|
289 |
+
$content = implode(' ', $words) . "... ";
|
290 |
+
}
|
291 |
+
|
292 |
+
$content = wpautop($content);
|
293 |
+
}
|
294 |
+
}
|
295 |
+
else
|
296 |
+
{
|
297 |
+
//else hide everything
|
298 |
+
$content = "";
|
299 |
+
}
|
300 |
+
|
301 |
+
if(empty($post_membership_levels_ids))
|
302 |
+
$post_membership_levels_ids = array();
|
303 |
+
|
304 |
+
if(empty($post_membership_levels_names))
|
305 |
+
$post_membership_levels_names = array();
|
306 |
+
|
307 |
+
//hide levels which don't allow signups by default
|
308 |
+
if(!apply_filters("pmpro_membership_content_filter_disallowed_levels", false, $post_membership_levels_ids, $post_membership_levels_names))
|
309 |
+
{
|
310 |
+
foreach($post_membership_levels_ids as $key=>$id)
|
311 |
+
{
|
312 |
+
//does this level allow registrations?
|
313 |
+
$level_obj = pmpro_getLevel($id);
|
314 |
+
if(!$level_obj->allow_signups)
|
315 |
+
{
|
316 |
+
unset($post_membership_levels_ids[$key]);
|
317 |
+
unset($post_membership_levels_names[$key]);
|
318 |
+
}
|
319 |
+
}
|
320 |
+
}
|
321 |
+
|
322 |
+
$pmpro_content_message_pre = '<div class="pmpro_content_message">';
|
323 |
+
$pmpro_content_message_post = '</div>';
|
324 |
+
|
325 |
+
$sr_search = array("!!levels!!", "!!referrer!!");
|
326 |
+
$sr_replace = array(pmpro_implodeToEnglish($post_membership_levels_names), $_SERVER['REQUEST_URI']);
|
327 |
+
|
328 |
+
//get the correct message to show at the bottom
|
329 |
+
if(is_feed())
|
330 |
+
{
|
331 |
+
$newcontent = apply_filters("pmpro_rss_text_filter", stripslashes(pmpro_getOption("rsstext")));
|
332 |
+
$content .= $pmpro_content_message_pre . str_replace($sr_search, $sr_replace, $newcontent) . $pmpro_content_message_post;
|
333 |
+
}
|
334 |
+
elseif($current_user->ID)
|
335 |
+
{
|
336 |
+
//not a member
|
337 |
+
$newcontent = apply_filters("pmpro_non_member_text_filter", stripslashes(pmpro_getOption("nonmembertext")));
|
338 |
+
$content .= $pmpro_content_message_pre . str_replace($sr_search, $sr_replace, $newcontent) . $pmpro_content_message_post;
|
339 |
+
}
|
340 |
+
else
|
341 |
+
{
|
342 |
+
//not logged in!
|
343 |
+
$newcontent = apply_filters("pmpro_not_logged_in_text_filter", stripslashes(pmpro_getOption("notloggedintext")));
|
344 |
+
$content .= $pmpro_content_message_pre . str_replace($sr_search, $sr_replace, $newcontent) . $pmpro_content_message_post;
|
345 |
+
}
|
346 |
+
}
|
347 |
+
|
348 |
+
return $content;
|
349 |
+
}
|
350 |
+
add_filter('the_content', 'pmpro_membership_content_filter', 5);
|
351 |
+
add_filter('the_content_rss', 'pmpro_membership_content_filter', 5);
|
352 |
+
add_filter('comment_text_rss', 'pmpro_membership_content_filter', 5);
|
353 |
+
|
354 |
+
/*
|
355 |
+
If the_excerpt is called, we want to disable the_content filters so the PMPro messages aren't added to the content before AND after the ecerpt.
|
356 |
+
*/
|
357 |
+
function pmpro_membership_exce
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|