11 replies [Last post]
dooffas's picture
Offline
Joined: 01/20/2012
Juice: 47
Was this information Helpful?

Good evening Drupalears... Drupalers?

Anyway...
I have been making custom modules for Drupal that interact with external web services for a while now.
I have now been asked to integrate this with the workflow of Ubercart.

I have been trying to use hook_order to kick off a custom module that will pass data about the customers order to a webservice.
At the moment I cannot get my custom module be activated in the workflow of Ubercart.

example of my code

function functionName_order($ops, &$arg1, $arg2){
   if ($ops == 'update' && $arg1->order_status == "payment_recived"){
     
      //nothing in this block is executed...

   }
}

The custom module is enabled, but whatever order status I change an order to, I cannot get any code to execute.

Can anyone shed any light on what I am doing wrong?

Many thanks

DanLanglois's picture
Offline
Joined: 01/10/2012
Juice: 48
looking to shed light

Hi. --can we work w/an actual example of your code?

You have a uc_order.module that contains this?:

<?php
  hook_order
($op, &$arg1, $arg2)
?>

And you also have something like this?:

<?php

/**
*
* Something like this.
*
* hook_order
*
* @see <a href="http://www.ubercart.org/docs/api/hook_order
" title="http://www.ubercart.org/docs/api/hook_order
">http://www.ubercart.org/docs/api/hook_order
</a> */

function uc_payment_order($op, &$arg1, $arg2) {
  switch (
$op) {
    case
'save':
     
// Do something to save payment info!
     
break;
  }
}
?>
dooffas's picture
Offline
Joined: 01/20/2012
Juice: 47
Sorry, I dont apear to have made myself very clear.

I am trying to find out how to "hook" in to hook_order.

<?php
  
function myFunctionName_order($ops, &$arg1, $arg2){
    global
$user;
   
$userId = $user->uid;
   
    if (
$op == 'update' && $arg1->order_status == "payment_recived"){
           
$client = new
               
SoapClient(
                   
"someWSDL"
               
);
           
$result = $client->getDataSet(array('id' => $userId));   
           
$result = (array)$result;
    }
}
?>

What I hoped the code above would do is:
When hook_order is called by Ubercart my custom function would check if ($op == 'update' && $arg1->order_status == "payment_recived")
and then execute the code within the if.

DanLanglois's picture
Offline
Joined: 01/10/2012
Juice: 48
Re: Sorry, I dont apear to have made myself very clear.

$op is not in the arguments, if you perhaps mean $ops. If your code doesn't appear to execute at all, well, that would do it?

dooffas's picture
Offline
Joined: 01/20/2012
Juice: 47
Opologies

That was a typo.
My code does intact use $ops not $op

TR
TR's picture
Offline
Bug FinderFAQ ModeratorGetting busy with the Ubercode.
Joined: 11/05/2007
Juice: 3292
Re: Sorry, I dont apear to have made myself very clear.

Is your hook_order() even being called? Add a print statement at the top just to see. Note that in Drupal 7 this hook is named hook_uc_order(), not hook_order(). Also, I assume "myFunctionName" is the name of your *module* ? As with all other Drupal hooks, you need to name your hook_order() implementation by replacing "hook" with the name of your custom module. Another thing to check is, do your orders ever get set to payment_received, or do they bypass that status altogether? (I notice you've spelled "payment_received" wrong - that may be another source of the error, and that's one reason you should check to see that your hook_order() is getting called at all.)

Otherwise, it looks like you're going about this the right way. hook_order() is the correct place to put this code. See uc_edi for an example.

<tr>.
dooffas's picture
Offline
Joined: 01/20/2012
Juice: 47
TR wrote: Is your
TR wrote:

Is your hook_order() even being called?

It appears not. I tried adding some prints at the top of the code and nothing is returned.
Any suggestions as to why this would be?
I have ensured that my orders do hit payment_received. I have also tried doing in to the admin panel and manually changing an order status to payment_received.

TR wrote:

Note that in Drupal 7 this hook is named hook_uc_order().

I did not realise that and I have now changed that. However, unfortunately it has not solved the issue.

TR wrote:

Also, I assume "myFunctionName" is the name of your *module* ?

Yes it is, this code is found in myFunctionName.module

TR
TR's picture
Offline
Bug FinderFAQ ModeratorGetting busy with the Ubercode.
Joined: 11/05/2007
Juice: 3292
Re: TR wrote: Is your

hook_uc_order() will be called many times during order placement. If your hook isn't called at all, that pretty much eliminates everything expect a spelling problem (function name is wrong) or a caching problem.

<tr>.
dooffas's picture
Offline
Joined: 01/20/2012
Juice: 47
IT WORKS!

Thanks TR for your help.

It must have been a typo somewhere. I created the module again and it works.

Working code:

<?php
       
function myFunction_uc_order($ops, &$arg1, $arg2){
        global
$user;
       
$userId = $user->uid;
       
        if (
$ops = 'update' && $arg1->order_status == "payment_received" && $arg2 =="completed"){
           
$client = new
           
SoapClient(
               
"WSDL Location"
           
);
           
$result = $client->getDataSet(array('id' => $userId));   
           
$result = (array)$result;
        }
    }
?>

This waits for the order status to be set to completed and then passes the logged in users id to a webservice via a SOAP request.

It does however run twice, presumably this is because hook_uc_order is called twice when the order is in that state?

Thanks again.

dooffas's picture
Offline
Joined: 01/20/2012
Juice: 47
I have been trying to make this a little more robust.

What I am trying to do is ensure that when the order is updated the web service is contacted.
If the service is unavailable I want it to set the order status to my custom order status "order".

I hoped that this would be as simple as encapsulating the web service connection in a try/catch block and then setting $arg1 = "error" and $arg2 = "".
However this does not seem to work. Below is the code I am using:

<?php
function myFunction_uc_order($ops, &$arg1, $arg2){
   global
$user;
  
$userId = $user->uid;
 
   if (
$ops = 'update' && $arg1->order_status == "payment_received" && $arg2 =="completed"){
      try{
        
$client = new
        
SoapClient(
           
"WSDL Location"
        
);
        
$result = $client->getDataSet(array('id' => $userId));
        
$result = (array)$result;
      }
      catch (
SoapFault $e){
        
$ops = 'update';
        
$arg1->order_status = 'error';
        
$arg2 = '';
      }
   }
}
?>

Anyone got any ideas? Am I going about this the wrong way?

Thanks

dooffas's picture
Offline
Joined: 01/20/2012
Juice: 47
I have managed to get a little further.

I have got the module to change the order status.
However, once this code is run and the page redirects the status is changed back to its previous state.
I confirmed that the status is being changed by using the below code.

<?php
$order
= uc_order_load($orderId);
uc_order_update_status($orderId, $orderStatus);
print
$order->order_status;
die();
?>

I have to halt the page here. If the page continues to redirect to the order confirmation page, it resets the order status to "payment_received" (this also happens if I change the order status in the view order page).

Anyone got any ideas how I can stop ubercart from doing this?

Full code being used now:

<?php
function myFunction_uc_order($ops, &$arg1, $arg2){
   global
$user;
  
$userId = $user->uid;
 
   if (
$ops = 'update' && $arg1->order_status == "payment_received" && $arg2 =="completed"){
      try{
        
$client = new
        
SoapClient(
           
"WSDL Location"
        
);
        
$result = $client->getDataSet(array('id' => $userId));
        
$result = (array)$result;
      }
      catch (
SoapFault $e){
         print
"There was an error connecting to the web service: ".$e->faultcode;
        
$order = uc_order_load($orderId);
        
uc_order_update_status($orderId, $orderStatus);
         print
$order->order_status;
         die();
      }
   }
}
?>

Thanks

simonkohli's picture
Offline
Joined: 06/14/2012
Juice: 3
Re: I have managed to get a little further.

I had difficulties with seeing the order array to check which key to use to do my task using hook_uc_order, it turned out to be a caching issue, usually I have found putting code in my custom module works straightaway but with the drupal and ubercart combination I had to clear the cache on nearly every edit of my file.