Hello,
I don't know what category this should really go under... I recently installed the uc_recurring module for a site I'm doing for a customer. However, upon installation I found that it was returning various errors. I tracked down some of the errors and I've made some modifications to the code to make it work w/the latest versions of Ubercart and Drupal.
Some of the items I fixed looked like they were typos, and there were others that were using function calls that either didn't exist anymore in Ubercart, or the function had changed to something different.
For the uc_order_admin function, I simply copied the function from an older version of uc_order. This is not intended as a permanent fix, rather as a band-aid until a view can be created for this purpose. (see http://drupal.org/node/1283352)
Most of the changes are related to the paypal portion of the module, since that was the payment processor that my client needed.
I hope my changes are useful to someone else, I've attached diffs below of what I've changed.
(I did these changes on the 7.x-2.x-dev version dated 2011-Dec-16)
-kevin hanser
Energy Web Design
http://www.energywebdevelopment.com
uc_recurring.module.diff
--- /sites/all/modules/uc_recurring/uc_recurring.module Tue Jan 10 16:16:37 2012
+++ /sites/all/modules/uc_recurring/uc_recurring.module.updated Tue Jan 10 16:14:46 2012
@@ -1233,3 +1233,122 @@
'path' => drupal_get_path('module', 'uc_recurring') . '/views',
);
}
+
+/**
+ * Latest version of ubercart 3.x doesn't have this function anymore.
+ * (uses views instead to create the admin interface)
+ * However uc_recurring currently still looks for this function (see http://drupal.org/node/1283352)
+ *
+ * As a temporary work-around, this function was copied
+ * from ubercart-7.x-3.0-beta4/uc_order/uc_order.admin.inc
+ *
+ */
+
+/**
+ * Displays the main order admin screen, an overview of all received orders.
+ */
+function uc_order_admin($condition = NULL, $search = FALSE) {
+ $header = array(
+ array('data' => t('Actions')),
+ array('data' => t('Order ID'), 'field' => 'o.order_id', 'sort' => 'desc'),
+ array('data' => t('Customer')),
+ array('data' => t('Total'), 'align' => 'center', 'field' => 'o.order_total'),
+ array('data' => t('Purchase date'), 'align' => 'center', 'field' => 'o.created'),
+ array('data' => t('Status'), 'field' => 'os.title'),
+ );
+
+ $address = variable_get('uc_customer_list_address', 'billing') == 'shipping' ? 'delivery' : 'billing';
+
+ $query = db_select('uc_orders', 'o')
+ ->fields('o', array(
+ 'order_id',
+ 'uid',
+ 'order_total',
+ 'created',
+ $address . '_first_name',
+ $address . '_last_name',
+ 'order_status',
+ ));
+
+ $query->leftJoin('uc_order_statuses', 'os', 'o.order_status = os.order_status_id');
+ $query->fields('os', array('title'));
+
+ if (!is_null($condition) && $condition->count()) {
+ $query->condition($condition);
+ }
+
+ if (!isset($_GET['status']) || $_GET['status'] != 'all') {
+ if (!empty($_GET['status']) && is_string($_GET['status'])) {
+ $query->condition('o.order_status', $_GET['status']);
+ }
+ else {
+ $query->condition('o.order_status', uc_order_status_list('general', TRUE), 'IN');
+ }
+ }
+
+ $query = $query->extend('PagerDefault')->extend('TableSort')
+ ->orderByHeader($header)
+ ->limit(variable_get('uc_order_number_displayed', 30));
+
+ $rows = array();
+
+ $result = $query->execute();
+ foreach ($result as $order) {
+ $order_name = trim($order->{$address . '_first_name'} . ' ' . $order->{$address . '_last_name'});
+ if (!$order_name) {
+ if ($order->uid && $account = db_query("SELECT name FROM {users} WHERE uid = :uid", array(':uid' => $order->uid))->fetchField()) {
+ $order_name = t('User: !name', array('!name' => $account));
+ }
+ else {
+ $order_name = t('User: none');
+ }
+ }
+
+ $rows[] = array(
+ 'data' => array(
+ array('data' => uc_order_actions($order, TRUE), 'nowrap' => 'nowrap'),
+ array('data' => $order->order_id),
+ array('data' => check_plain($order_name), 'nowrap' => 'nowrap'),
+ array('data' => array('#theme' => 'uc_price', '#price' => $order->order_total), 'align' => 'right'),
+ array('data' => format_date($order->created, 'uc_store'), 'align' => 'center'),
+ array('data' => $order->title),
+ ),
+ 'id' => 'order-' . $order->order_id,
+ );
+ }
+
+ drupal_add_js(array(
+ 'ucURL' => array(
+ 'adminOrders' => url('admin/store/orders/'),
+ ),
+ ), 'setting');
+ drupal_add_js(drupal_get_path('module', 'uc_order') . '/uc_order.js');
+
+ $build = array();
+
+ if ($search === FALSE) {
+ $build['order_overview_select_form'] = drupal_get_form('uc_order_select_form') + array(
+ '#prefix' => '<div class="order-overview-form">',
+ '#suffix' => '</div>',
+ );
+ $build['order_overview_admin_sort_form'] = drupal_get_form('uc_order_admin_sort_form') + array(
+ '#prefix' => '<div class="order-overview-form">',
+ '#suffix' => '</div>',
+ );
+ }
+
+ $build['orders'] = array(
+ '#theme' => 'table',
+ '#header' => $header,
+ '#rows' => $rows,
+ '#attributes' => array('class' => array('uc-orders-table')),
+ '#weight' => 1,
+ );
+ $build['pager'] = array(
+ '#theme' => 'pager',
+ '#element' => 0,
+ '#weight' => 5,
+ );
+
+ return $build;
+}
modules/uc_recurring_hosted/uc_recurring_hosted.module.diff
--- /sites/all/modules/uc_recurring/modules/uc_recurring_hosted/uc_recurring_hosted.module Tue Jan 10 16:20:08 2012
+++ /sites/all/modules/uc_recurring/modules/uc_recurring_hosted/uc_recurring_hosted.module.updated Fri Jan 6 12:40:27 2012
@@ -24,7 +24,7 @@
$items['uc_recurring_hosted/paypal/ipn'] = array(
'title' => 'PayPal IPN',
'page callback' => 'uc_recurring_hosted_paypal_ipn',
- 'access callback' => 'uc_paypal_ipn_access',
+ 'access callback' => TRUE, //'uc_paypal_ipn_access',
'type' => MENU_CALLBACK,
'file' => 'uc_recurring_hosted.paypal_ipn.inc',
);
@@ -32,7 +32,7 @@
'title' => 'PayPal IPN',
'page callback' => 'uc_recurring_hosted_paypal_ipn',
'page arguments' => array(3),
- 'access callback' => 'uc_paypal_ipn_access',
+ 'access callback' => TRUE, //'uc_paypal_ipn_access',
'type' => MENU_CALLBACK,
'file' => 'uc_recurring_hosted.paypal_ipn.inc',
);
@@ -575,8 +575,10 @@
* same trick to alter the paypal form, its a messy hack but works for now.
*/
function uc_recurring_hosted_form_uc_paypal_wps_form_alter(&$form, $form_state) {
- $order = $form['#parameters'][2];
-
+// $order = $form['#parameters'][2];
+// fix from: http://drupal.org/node/1380694
+ $order = $form_state['build_info']['args'][0];
+
$recurring_fees = array();
// if recurring fees exist in the order
if (module_exists('uc_recurring_product')) {
modules/uc_recurring_hosted/uc_recurring_hosted.paypal_ipn.inc.diff
--- /sites/all/modules/uc_recurring/modules/uc_recurring_hosted/uc_recurring_hosted.paypal_ipn.inc Tue Jan 10 16:20:39 2012
+++ /sites/all/modules/uc_recurring/modules/uc_recurring_hosted/uc_recurring_hosted.paypal_ipn.inc.updated Fri Jan 6 16:44:57 2012
@@ -35,6 +35,7 @@
}
if (_uc_recurring_hosted_paypal_ipn_validate($ipn)) {
+ watchdog('uc_recurring_hosted', 'Paypal IPN transaction type %txn_type for order id @order_id', array('%txn_type' => $ipn->txn_type, '@order_id' => $order->order_id));
switch ($ipn->txn_type) {
case 'subscr_signup':
case 'recurring_payment_profile_created':
@@ -139,14 +140,15 @@
switch ($ipn->payment_status) {
case 'Canceled_Reversal':
- uc_order_comment_save($ipn->order_id, 0, t('PayPal has cancelled the reversal and returned !amount !currency to your account.', array('!amount' => uc_price($ipn->mc_gross, $context, $options), '!currency' => $ipn->mc_currency)), 'admin');
+ uc_order_comment_save($ipn->order_id, 0, t('PayPal has cancelled the reversal and returned !amount !currency to your account.', array('!amount' => uc_currency_format($ipn->mc_gross, $options['sign']), '!currency' => $ipn->mc_currency)), 'admin');
break;
case 'Completed':
$comment = t('PayPal transaction ID: @txn_id', array('@txn_id' => $ipn->txn_id));
+ // save the transaction in the order log
+ uc_order_comment_save($ipn->order_id, 0, t('Payment of @amount @currency submitted through PayPal.', array('@amount' => uc_currency_format($ipn->mc_gross, $options['sign']), '@currency' => $ipn->mc_currency)), 'order', 'payment_received');
+ uc_order_comment_save($ipn->order_id, 0, t('PayPal IPN reported a payment of @amount @currency.', array('@amount' => uc_currency_format($ipn->mc_gross, $options['sign']), '@currency' => $ipn->mc_currency)));
uc_payment_enter($ipn->order_id, 'paypal_wps', $ipn->mc_gross, $user->uid, NULL, $comment);
- uc_order_comment_save($ipn->order_id, 0, t('Payment of @amount @currency submitted through PayPal.', array('@amount' => uc_price($ipn->mc_gross, $context, $options), '@currency' => $ipn->mc_currency)), 'order', 'payment_received');
- uc_order_comment_save($ipn->order_id, 0, t('PayPal IPN reported a payment of @amount @currency.', array('@amount' => uc_price($ipn->mc_gross, $context, $options), '@currency' => $ipn->mc_currency)));
break;
case 'Denied':
@@ -184,6 +186,11 @@
case 'Voided':
uc_order_comment_save($ipn->order_id, 0, t('The authorization has been voided.'), 'admin');
break;
+
+ default:
+ watchdog('uc_recurring_hosted', 'Payment status @status not recognized. Nothing to do. !debug',
+ array('@status' => $ipn->payment_status, '!debug' => variable_get('uc_paypal_wps_debug_ipn', FALSE) ? '<pre>' . check_plain(print_r($_POST, TRUE)) . '</pre>' : ''));
+ break;
}
}
@@ -248,11 +255,11 @@
else {
$host = variable_get('uc_paypal_wps_server', 'https://www.sandbox.paypal.com/cgi-bin/webscr');
}
- $response = drupal_http_request($host, array('headers' => array('headers' => array(
+ $response = drupal_http_request($host, array(
'headers' => array(),
'method' => 'POST',
'data' => $req,
- ))));
+ ));
// @todo: Change this to property_exists when we have a PHP requirement >= 5.1.
if (array_key_exists('error', $response)) {
@@ -275,17 +282,14 @@
* Check if we have already recieved a IPN with the same details.
*/
function _uc_recurring_hosted_paypal_ipn_is_duplicate($ipn) {
- if ($ipn->txn_id) {
- $duplicate = db_query("SELECT COUNT(*) FROM {uc_payment_paypal_ipn} WHERE txn_id = :txn_id AND txn_type = :txn_type AND status <> :status", array(':txn_id' => : txn_id, ':txn_type' => : txn_type, ':status' => : status, '' => array(
- ':txn_id' => : txn_id,
- ':txn_type' => : txn_type,
- ':status' => : status,
- '' => array(
+ if (isset($ipn->txn_id)) {
+ $duplicate = db_query("SELECT COUNT(*) FROM {uc_payment_paypal_ipn} WHERE txn_id = :txn_id AND txn_type = :txn_type AND status <> :status",
+ array(
':txn_id' => $ipn->txn_id,
':txn_type' => $ipn->txn_type,
':status' => 'Pending',
- ),
- )))->fetchField();
+ )
+ )->fetchField();
if ($duplicate > 0) {
watchdog('uc_recurring_hosted', 'IPN (Order:@order_id Txn: @txn_id) has been processed before.', array('@order_id' => $ipn->order_id, '@txn_id' => $ipn->txn_id), WATCHDOG_NOTICE);
return TRUE;
| Comment | File | Size | Author |
|---|---|---|---|
| uc_recurring_hosted.paypal_ipn.inc_.diff | 4.47 KB | kmhanser | |
| uc_recurring_hosted.module.diff | 1.42 KB | kmhanser | |
| uc_recurring.module.diff | 4.17 KB | kmhanser |
Comments
Comment #1
SeanA commentedHi Kevin,
The issue dealing with the removal of uc_order_admin is here: #1372106: remove the use of the uc_order_admin
I took a quick look at your other changes and I think it would be less confusing and easier on the maintainers if there's just a single problem being addressed in each issue. For example, it would be more productive to roll a small patch for issue #1380694: Notice: Undefined index: #parameters Error at checkout and post it there. (If it's a proper fix for the bug.)
This change
doesn't seem right to me... it bypasses the access check, and I'm not sure we want to do that =). You could open a separate issue for that (as long as there isn't already one open for it).
So we can make this issue about your final patch: uc_recurring_hosted.paypal_ipn.inc_.diff. Changing title and status accordingly. Looks good, but needs proper testing and review. Sorry, I don't have a need for this feature or time to test it right now.
Comment #2
kmhanser commentedRe: uc_order_admin "fix": Yeah, I know it's not the right way to do it, but I didn't have the time to write a view and do it properly. I just needed the module to work for a customer's site I was working on and this seemed the easiest way to make it work for now :)
I wasn't sure about that access callback. Honestly I'm not sure why there would be a need for an access callback on that particular page -- that's the page that handles the IPN data that paypal sends. It seems to me that any sort of access restrictions on this page / handler would make it so paypal couldn't send IPN data to your site -- which is what was happening w/the access callback the way it was.
So with that thinking, that's why I just set the access callback to TRUE. It seems like extra work to make an access callback function for a page that is always going to be accessed by anonymous users. I don't know though, maybe there's something I'm missing and there's a reason to explicitly declare through a function that anyone can access the pages?
Yes, most of the changes/patching was for the uc_recurring_hosted paypal module. I wasn't sure what to call it since there were a bunch of "little things" that I had done. The title change you made seems much better/appropriate.
thx!
-kevin hanser
Energy Web Design
http://www.energywebdevelopment.com
Comment #3
emilymoi commentedRan into these problems myself. Not sure why this module is even considered alpha right now because the module isn't even valid PHP.
Regarding the access callback--uc_paypal_ipn_access doesn't even exist, so it needs to be changed to something. Using TRUE at least makes things work.
The code in _uc_recurring_hosted_paypal_ipn_is_duplicate is just plain broken. PHP syntax isn't even correct.
It would be nice to at least roll in the changes from the original post to get the module working as the current alpha release is not working. Without a working module, I'm not sure how we can even move forward with this.
Comment #4
SeanA commentedFor the access callback, I'd suggest opening a new issue for that. (Instead of just using TRUE in the callback definition, it would probably be better to create a dummy function that returns 'true'. Then at least the structure is there to put in the proper logic at some point.)
For this issue, I'd say test the uc_recurring_hosted_paypal patch until it's ready to go in. Looks like it needs more work at this point.
I don't need this feature and don't really have time to work on it, but breaking this into discrete issues should help get the fixes in.
Comment #5
emilymoi commentedI have been testing with both the uc_recurring_hosted.module and uc_recurring_hosted.paypal_ipn.inc patches from above and they are working well for me.
Comment #6
Rafal LukawieckiHi, are the above being rolled into the dev version of this module any time soon, or is the plan to keep them as standalone patches for now? Many thanks.
Comment #7
kmhanser commentedThat's up to the module maintainers... I just put the code here so it could be useful to anyone else that runs into the same issues I did w/the module.
According to the module page, it looks like the maintainers are:
2.x development by Chris (univate) of Univate, valuable advice and assistance also contributed by Amitaibu.
I'm not sure what we would need to do to draw their attention to this thread though...
-kevin
Energy Web Design
http://www.energywebdevelopment.com
Comment #8
arekanderu commentedI can't believe that this hasn't been resolved yet by the authors...
I confirm that the patches worked for me as well. I didn't review them however.
Comment #9
key4ce commentedHello,
I'm trying to make Paypal work with recurring payments, i applied the patches etc..
however after i paid (using sandbox) it's not picked up as paid at all.. i just get back to the shopping cart with the order still in there..
(same issue as described at: #1380694: Notice: Undefined index: #parameters Error at checkout )
Is those patches supposed to resolv this? if so.. can you please tell me what i'm missing as it's just not working >.<
Regards,
Marco
Comment #10
key4ce commented>.< right.. it kind of helps to re-install the module while it's changing perms..
sorry for the false alarm.. works as a charm :-)
Comment #11
particlegirl commentedthank you have implemented these with no new errors etc :-) now for subscriptions...
Comment #12
kmhanser commentedCool, glad to hear that the patches are working so far!
In relation to key4ce's post: did you get it working on sandbox? I see in your follow-up post that you said it works like a charm now I guess that includes sandbox?
I don't know that I've ever gotten the paypal sandbox working right so I'm pretty sure that's something I didn't test when I made the changes. So if it's working in sandbox then that's good news :D
When I wrote this patch it wasn't important for the site I was working on so I didn't really look @ the sandbox code at all...
I just wrote these patches because we needed recurring subscriptions on a website or two. There's probably plenty of code in the module still that's not "quite right"; my goal was never to re-write the whole module, just to get it working in some form :)
And for anyone else installing these patches, don't forget to clear all caches after appying the patches so that Drupal picks up the changes!
-kevin hanser
Energy Web Design
http://energywebdevelopment.com
Comment #13
univate commentedfixed everything except the first patch which is a duplicate of #1372106: remove the use of the uc_order_admin
Comment #14
key4ce commentedHey.. sorry for my late reply.
It works with the sandbox. there is ONE big ass but:
the Cancel feature doesn't work at all (user and admin side)
And a side issue:
on paypal sandbox --> If you check out the product.. finish paypal payment etc etc --> the product stays in the cart.
Following google this is because it's sandbox and not live. (so will test it once the cancel feature is working again .. kinda handy if i can cancel a live order haha ;-))
I'm currently paying a company to make the cancel feature work for us (as it's kind of urgeant).
Once their done with the code i will post the codes in total. (sorry i'm not a dev.. so i can't really pick apart their work from existing.. so it will be the total code .. hopefully you can figure out the rest easily :D)
Comment #15
kmhanser commentedcool!
hahah, yeah I don't know that I ever tested the 'cancel' feature.... Shouldn't be too hard to fix that, just need to fix the submit function i think(?) That's great that you've got someone to fix this, if it ends up taking them too long or costing you too much let me know and I can take a look @ it. I have other projects to work on that are more pressing though so you and/or your people will most likely get to it before I do :)
thx
-k
Comment #16
key4ce commentedRighty.. Little update:
The Cancel function IS working but apparently only in Linux servers.
(At the moment we have our drupal in a Windows loadbalanced cluster untill the Linux loadbalanced cluster has finished).
and little reply to previouse comments:
Devs are always expencive and always slow haha :P (atleast in my expirience)
Tho the cancel function should be nearly working.. on both linux and windows i might add ;-)