Problemy z połączeniem SOAP po aktualizacji 1.9.3.0

12

Zaktualizowałem mój Magento Store z 1.9.2.4 do 1.9.3.0

Używamy oprogramowania wysyłkowego (Shipworks), które łączy się za pośrednictwem użytkownika SOAP / XML-RPC.

Po aktualizacji rejestrowanie wysyłek pokazuje tę odpowiedź w dziennikach:

<?xml version="1.0" encoding="UTF-8"?>
-<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
-<SOAP-ENV:Body>
-<SOAP-ENV:Fault>
<faultcode>1</faultcode>
<faultstring>Internal Error. Please see log for details.</faultstring>
</SOAP-ENV:Fault>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>

Poszedłem i włączyłem rejestrowanie wyjątków w Magento i otrzymałem następujący błąd:

2016-10-13T18:24:14+00:00 ERR (3): 
SoapFault exception: [1] Internal Error. Please see log for details. in /public_html/app/code/core/Mage/Api/Model/Server/Adapter/Soap.php:196
Stack trace:
#0 /public_html/app/code/core/Mage/Api/Model/Server/Handler/Abstract.php(140): Mage_Api_Model_Server_Adapter_Soap->fault('1', 'Internal Error....')
#1 /public_html/app/code/core/Mage/Api/Model/Server/Handler/Abstract.php(48): Mage_Api_Model_Server_Handler_Abstract->_fault('internal')
#2 /public_html/app/code/core/Mage/Api/Model/Server/Handler/Abstract.php(559): Mage_Api_Model_Server_Handler_Abstract->handlePhpError(4096, 'Argument 1 pass...', '/home/deepsix/p...', 559, Array)
#3 /public_html/app/code/core/Mage/Api/Model/Server/Handler/Abstract.php(299): Mage_Api_Model_Server_Handler_Abstract->processingMethodResult('<?xml version="...')
#4 [internal function]: Mage_Api_Model_Server_Handler_Abstract->call('ca4d34d100c92c8...', 'shipWorksApi.ge...', Array)
#5 /public_html/lib/Zend/Soap/Server.php(889): SoapServer->handle('<?xml version="...')
#6 /public_html/app/code/core/Mage/Api/Model/Server/Adapter/Soap.php(174): Zend_Soap_Server->handle()
#7 /public_html/app/code/core/Mage/Api/Model/Server.php(138): Mage_Api_Model_Server_Adapter_Soap->run()
#8 /public_html/app/code/core/Mage/Api/controllers/SoapController.php(40): Mage_Api_Model_Server->run()
#9 /public_html/app/code/core/Mage/Core/Controller/Varien/Action.php(418): Mage_Api_SoapController->indexAction()
#10 /public_html/app/code/core/Mage/Core/Controller/Varien/Router/Standard.php(254): Mage_Core_Controller_Varien_Action->dispatch('index')
#11 /public_html/app/code/core/Mage/Core/Controller/Varien/Front.php(172): Mage_Core_Controller_Varien_Router_Standard->match(Object(Mage_Core_Controller_Request_Http))
#12 /public_html/app/code/core/Mage/Core/Model/App.php(365): Mage_Core_Controller_Varien_Front->dispatch()
#13 /public_html/app/Mage.php(684): Mage_Core_Model_App->run(Array)
#14 /public_html/index.php(83): Mage::run('', 'store')
#15 {main}

Więc poszedłem i zrobiłem różnicę między Abstract.php z 1.9.2.4 i 1.9.3.0 i otrzymałem następujące:

290a291
>                 $result = array();
292c293
<                     return $model->$method((is_array($args) ? $args : array($args)));
---
>                     $result = $model->$method((is_array($args) ? $args : array($args)));
294c295
<                     return $model->$method($args);
---
>                     $result = $model->$method($args);
296c297
<                     return call_user_func_array(array(&$model, $method), $args);
---
>                     $result = call_user_func_array(array(&$model, $method), $args);
297a299
>                 return $this->processingMethodResult($result);
403a406
>                     $callResult = array();
405c408
<                         $result[] = $model->$method((is_array($args) ? $args : array($args)));
---
>                         $callResult = $model->$method((is_array($args) ? $args : array($args)));
407c410
<                         $result[] = $model->$method($args);
---
>                         $callResult = $model->$method($args);
409c412
<                         $result[] = call_user_func_array(array(&$model, $method), $args);
---
>                         $callResult = call_user_func_array(array(&$model, $method), $args);
410a414
>                     $result[] = $this->processingMethodResult($callResult);
544a549,585
>     }
> 
>     /**
>      * Prepare Api data for XML exporting
>      * See allowed characters in XML:
>      * @link http://www.w3.org/TR/2000/REC-xml-20001006#NT-Char
>      *
>      * @param array $result
>      * @return mixed
>      */
>     public function processingMethodResult(array $result)
>     {
>         foreach ($result as &$row) {
>             if (!is_null($row) && !is_bool($row) && !is_numeric($row)) {
>                 $row = $this->processingRow($row);
>             }
>         }
>         return $result;
>     }
> 
>     /**
>      * Prepare Api row data for XML exporting
>      * Convert not allowed symbol to numeric character reference
>      *
>      * @param $row
>      * @return mixed
>      */
>     public function processingRow($row)
>     {
>         $row = preg_replace_callback(
>             '/[^\x{0009}\x{000a}\x{000d}\x{0020}-\x{D7FF}\x{E000}-\x{FFFD}\x{10000}-\x{10FFFF}]/u',
>             function ($matches) {
>                 return '&#' . Mage::helper('core/string')->uniOrd($matches[0]) . ';';
>             },
>             $row
>         );
>         return $row;

Każda pomoc będzie mile widziana.

LandonL
źródło

Odpowiedzi:

14

Ten sam błąd z innym rozszerzeniem tutaj. system.log mówi

Argument 1 przekazany do Mage_Api_Model_Server_Handler_Abstract :: processingMethodResult () musi być tablicy typów, podany ciąg znaków, wywoływany w app / code / core / Mage / Api / Model / Server / Handler / Abstract.php ...

Myślę, że problemem jest nowa metoda

Mage_Api_Model_Server_Handler_Abstract::processingMethodResult(array $result)

który akceptuje tylko tablice. Tak więc każda funkcja API zwracająca wartość skalarną wyrzuci ten błąd. Aby uzyskać to tam ponownie skopiowane app/code/core/Mage/Api/Model/Server/Handler/Abstract.phpdo app/code/local/Mage/Api/Model/Server/Handler/Abstract.phpi poprawione processingMethodResult:

public function processingMethodResult($result)
{
    if (is_array($result)) {
        foreach ($result as &$row) {
            if (!is_null($row) && !is_bool($row) && !is_numeric($row)) {
                if (is_array($row)) {
                    $row = $this->processingMethodResult($row);
                } else {
                    $row = $this->processingRow($row);
                }
            }
        }
    } else {
        if (!is_null($result) && !is_bool($result) && !is_numeric($result)) {
            $result = $this->processingRow($result);
        }
    }
    return $result;
}
Belgor
źródło
z której wersji Magento korzystasz?
LandonL
To rozwiązuje problem. Dlaczego i tak tutaj plik rdzenia magento miałby zostać zamieniony na macierz vs ciąg znaków?
LandonL
Doskonałe rozwiązanie, dziękuję. Czy ktoś podniósł to jako błąd w Magento? Wiele osób się tym ugryzie.
BlueC
Zmiana dotyczy bardziej PHP7, zobacz moją odpowiedź poniżej. Ponadto stackoverflow.com/a/4103536/158325 nie jest tak naprawdę błędem, ale zapewnia zgodność API PHP7.
B00MER
1
@LandonL: Zaktualizowałem z 1.9.2.4 do 1.9.3.0.
Belgor,
1

Bardziej niż prawdopodobne, że moduł ShipStation i / lub wersja PHP, z której korzystasz, nie jest kompatybilna:

Zgadywanie zwróconego komunikatu o błędzie PHP, który został zwrócony:

Argument 1 pass...' jest najbardziej prawdopodobne Argument 1 passed to methodhere() must be an instance of string, string given

Jaką wersję PHP używasz i czy skonsultowałeś się ze ShipStation, aby sprawdzić, czy występują jakieś nowsze wersje i / lub problemy ze zgodnością z najnowszą wersją / łatkami Magento.

Możesz także dodać nieco więcej rejestrowania tutaj: https://github.com/OpenMage/magento-mirror/blob/magento-1.9/lib/Zend/Soap/Server.php#L889, aby przechwycić więcej obciętego błędu PHP który jest zwracany, aby uzyskać potwierdzenie, że zwracany jest poprawny błąd.

Mam nadzieję że to pomoże.

B00MER
źródło
Jak uzyskać więcej obciętego błędu? Nie jestem pewien, jak zwiększyć długość linii.
LandonL
System działa obecnie w wersji php 5.6.25, zadzwoniłem dzisiaj do shipworks, ale ponieważ wczoraj pojawiła się aktualizacja magento 1.9.3.0, nie sądzę, aby mieli jeszcze okazję przyjrzeć się temu problemowi.
LandonL
1

Odpowiedź Belgorsa naprawdę mi pomogła, ale ostatecznie zmodyfikowałem łatkę, aby umożliwić dodanie dodatkowych obiektów do reposnse API.

Na przykład teraz otrzymujesz kredyty obiektowe i / lub karty podarunkowe z wyprzedzeniem dzięki wezwaniu Magento XML-RPC w celu uzyskania informacji o zamówieniu.

(kod zaktualizowany z sugestii Björna Tantaua - w celu lepszej pracy z obiektami i kolekcjami)

public function processingMethodResult($result)
{
    if (is_object($result) && is_callable(array($result, 'toArray'))) {
        $result = $result->toArray();
    }
    if (is_array($result)) {
        foreach ($result as &$row) {
            if (is_object($row) && is_callable(array($row, 'toArray'))) {
                $row = $row->toArray();
            }
            if (!is_null($row) && !is_bool($row) && !is_numeric($row)) {
                if (is_array($row)) {
                    $row = $this->processingMethodResult($row);
                } else {
                    $row = $this->processingRow($row);
                }
            }
        }
    } else {
        if (!is_null($result) && !is_bool($result) && !is_numeric($result)) {
            $result = $this->processingRow($result);
        }
    }
    return $result;
}
Christoffer Bubach
źródło