michaelkmartin / laravel-magento-integration

A simple Magento Integration using SOAP v1 and v2
34 stars 13 forks source link

Product update "Array to string conversion" error #3

Open mroffice opened 9 years ago

mroffice commented 9 years ago

Getting product lists and info are working perfectly for me. But I can't seem to get update functions to work - always giving me "Array to string conversion" error because of the multiple arguments.

If I only use one argument, the $productId, $result returns true. I've also tried catalogProductUpdate with the same result.

Am I doing something wrong here?

As a side-issue I have tried customerCustomerUpdate (for example) which returns true even with multiple arguments - but when I login and look at the list of customers on Magento admin nothing has changed?

If anyone can point me in the right direction that would be great.

e.g.

$sessionId = Session::get('magento'); // this was stored earlier
$productId = '6333'; // example SKU or ID
$params = array(
  "qty" => "1",
  "is_in_stock" => 1
);
$result = Magento::catalogInventoryStockItemUpdate($sessionId, $productId, $params);
mroffice commented 9 years ago

Still debugging this issue. What I've found is that the Magento SOAP requests for update functions need an extra paramater - so the __soapCall() function is being given paramater data in the wrong format.

To continue my example from before the format for catalogInventoryStockItemUpdate params are as follows: (string)$sessionId, (string)$productId, (array)$data.

But the MagentoSoapClient method __call() is following this: $this->__soapCall($method, array($this->session, $args))

Whereas it needs to be something like this: $this->__soapCall($method, array($this->session, $args[0], array_pop($args)));

In my previous comment I mentioned that the customerCustomerUpdate works as expected and I was very confused by this. It is because the second paramater required (the customer ID) is an integer, not a string like the product ID/SKU of catalogInventoryStockItemUpdate. So when you pass in an array and the request is expecting an integer, the array is cast as an integer which gives a value of 1. This validates because the function is essentially running an update on the customer ID 1, with no parameters.

Basically - if you cast an array as a string, you get a fatal, if you cast an array as an integer you get value 1.

So as a temporary solution I'm adding in an extra else if to determine if the method is one of these update methods, and if so then reformat the SOAP params accordingly. I think what needs to be done is to find out all the methods that have extra parameters and find a way of incorporating a conditional clause so they can be 'caught' and formatted correctly - I'm afraid I'm not smart enough to do this and issue a pull request. :)

Here is my temporary code from MagentoSoapClient.php starting on line 102.

        if ( $method == 'login' ) {
            $this->results = $this->__soapCall($method, $args);
        } elseif ($method == 'call') {
            $this->results = $this->__soapCall($method, $args);
        } elseif ($method == 'catalogInventoryStockItemUpdate' || $method == 'customerCustomerUpdate') {
            $this->results = $this->__soapCall($method, array($this->session, $args[0], array_pop($args)));
        } else {
            $this->results = $this->__soapCall($method, array($this->session, $args));
        }
Beaudinn commented 9 years ago

@mroffice It is not the intention to remove the first element of the array? I mean that array_pop should be array_shift?

mroffice commented 9 years ago

Hi @Beaudinn,

The example is a little confusing - I used the return value of array_pop() which is in fact the last value of the array - rather than the new value of $args which would indeed be the array minus the last element.

This may have been an accident actually, as I don't recall knowing that array_pop and array_shift have return values! But may be one of those times where you learn something and use it immediately without writing it down for future reference! :)

See here - http://php.net/manual/en/function.array-pop.php

Beaudinn commented 9 years ago

Hey @mroffice It is certainly confusing, but get it now. However, about the solution of the problem of this ticket since the problem only appears when the argument array contains a array. I use count() twice one time in default mode and one time in recursive mode. If the values not match, the array is multidimensional, if thats true I just add the session to the arguments.

            if ( $method == 'login' ) {
                $this->results = $this->__soapCall($method, $args);
            } elseif ($method == 'call') {
                $this->results = $this->__soapCall($method, $args);
            } elseif (count($args) != count($args, COUNT_RECURSIVE)) {
                array_unshift($args, $this->session);
                $this->results = $this->__soapCall($method, $args);                 
            } else {
                $this->results = $this->__soapCall($method, array($this->session, $args));
            }
mroffice commented 9 years ago

Looks good :+1:

This is the first 'ticket' I've opened on Github - do I close it? Or maybe I should be finding out how to create a pull request?

iveoles commented 7 years ago

I assume this is never getting merged in? It's still an issue.