使用CakePHP Http客户端和Magento2 rest API搜索条件

我试图发送一个GET请求到本地的Magento2 rest API以在特定时间后获得所有订单。 我遵循http://devdocs.magento.com/guides/v2.1/howdoi/webapi/search-criteria.html#simple-search-using-a-timestamp。 我正在使用CakePHP 3.4的Http Client(https://book.cakephp.org/3.0/en/core-libraries/httpclient.html),并且已经成功地使用Oauth1与Magento集成,并且对于更简单的GET请求也没有问题,例如http://www.magento.dev.com/rest/V1/stockItems/:productSku 。 传递搜索条件是个问题。 响应始终是401 Invalid Signature

使用邮差,我可以得到一个有效的回应http://www.magento.dev.com/rest/V1/orders?searchCriteria[filter_groups][0][filters][0][field]=created_at&searchCriteria[filter_groups][0][filters][0][value]=2016-07-01 00:00:00&searchCriteria[filter_groups][0][filters][0][condition_type]=gt

这是我到目前为止/我如何发送请求:

在Model / Table / OrdersTable.php中:

public function importNewOrders(AppModelEntityOauthIntegration $integrationDetails)
    {
       $this->OauthIntegrations = TableRegistry::get('OauthIntegrations');
       $this->Orders = TableRegistry::get('Orders');
       $timeCutOff = '2015-01-01 00:00:00';
       $search = [
           'searchCriteria' => [
                'filterGroups' => [
                    0 => [
                        'filters' => [
                            0 => [
                                'field' => 'created_at',
                                'value' => $timeCutOff,
                                'condition_type' => 'gt'
                            ]
                        ]
                    ]
                ]
           ]
        ];
//           'searchCriteria[filter_groups][0][filters][0][field]' => 'created_at',
//           'searchCriteria[filter_groups][0][filters][0][value]' => $timeCutOff, 
//           'searchCriteria[filter_groups][0][filters][0][condition_type]' => 'gt'

       $action = '/V1/orders';

       $type = "GET";
       $response = $this->OauthIntegrations->sendRequest(
               $integrationDetails, 
               $action, 
               $type,
               '',
               $search);

       Log::write('debug', $response->body());
       return $response;
    }

并在Model Table OauthIntegrationsTable.php中:

public function sendRequest(AppModelEntityOauthIntegration $integrationDetails, 
            string $action, string $method = "GET", string $data = '', array $search = null)
    {

        $http = new Client([
            'auth' => [
                'type' => 'oauth',
                'consumerKey' => $integrationDetails->oauth_consumer_key,
                'consumerSecret' => $integrationDetails->oauth_consumer_secret,
                'token' => $integrationDetails->oauth_token,
                'tokenSecret' => $integrationDetails->oauth_token_secret
              ]
          ]);
        $url = $integrationDetails->store_base_url . 'rest' . $action;
        if ($method == 'GET'){
            if (!isset($search)){
                $search = [];
            }
            $response = $http->get($url, $search, []);

        } else if ($method == 'POST'){

            $response = $http->post($url, $data, [
              'type' => 'json',

            ]);

        } else if($method == 'PUT'){
            $response = $http->put($url, $data, [
              'type' => 'json',
            ]);
        }
        Log::write('debug', 'url: ' . $url . ' and status code: ' . $response->getStatusCode());
        return $response;
    }

这是错误(我希望)是无效签名响应的原因:

2017-03-28 10:07:01 Notice: Notice (8): Array to string conversion in [/var/www/cakephp/html/beacon/vendor/cakephp/cakephp/src/Http/Client/Auth/Oauth.php, line 315]
Trace:
CakeErrorBaseErrorHandler::handleError() - CORE/src/Error/BaseErrorHandler.php, line 153
CakeHttpClientAuthOauth::_normalizedParams() - CORE/src/Http/Client/Auth/Oauth.php, line 315
CakeHttpClientAuthOauth::baseString() - CORE/src/Http/Client/Auth/Oauth.php, line 246
CakeHttpClientAuthOauth::_hmacSha1() - CORE/src/Http/Client/Auth/Oauth.php, line 143
CakeHttpClientAuthOauth::authentication() - CORE/src/Http/Client/Auth/Oauth.php, line 61
CakeHttpClient::_addAuthentication() - CORE/src/Http/Client.php, line 501
CakeHttpClient::_createRequest() - CORE/src/Http/Client.php, line 448
CakeHttpClient::_doRequest() - CORE/src/Http/Client.php, line 341
CakeHttpClient::get() - CORE/src/Http/Client.php, line 211
AppModelTableOauthIntegrationsTable::sendRequest() - APP/Model/Table/OauthIntegrationsTable.php, line 134
AppModelTableOrdersTable::importNewOrders() - APP/Model/Table/OrdersTable.php, line 672
AppShellMagentoShell::main() - APP/Shell/MagentoShell.php, line 36
CakeConsoleShell::runCommand() - CORE/src/Console/Shell.php, line 472
CakeConsoleShellDispatcher::_dispatch() - CORE/src/Console/ShellDispatcher.php, line 227
CakeConsoleShellDispatcher::dispatch() - CORE/src/Console/ShellDispatcher.php, line 182
CakeConsoleShellDispatcher::run() - CORE/src/Console/ShellDispatcher.php, line 128
[main] - ROOT/bin/cake.php, line 33

来自Http Client Oauth.php的代码发生错误:

        $pairs = [];
        foreach ($args as $k => $val) {
            if (is_array($val)) {
                sort($val, SORT_STRING);
                Log::write('debug', 'about to go through foreach($val as $nestedVal)');
                foreach ($val as $nestedVal) {
                    Log::write('debug', $nestedVal);
                    $pairs[] = "$k=$nestedVal"; // <<< HERE
                }
            } else {
                $pairs[] = "$k=$val";
            }
        }

从上面调试结果如下:

2017-03-28 10:07:01 Debug: about to go through foreach($val as $nestedVal)
2017-03-28 10:07:01 Debug: Array
(
    [0] => Array
        (
            [filters] => Array
                (
                    [0] => Array
                        (
                            [field] => created_at
                            [value] => 2015-01-01 00:00:00
                            [condition_type] => gt
                        )

                )

        )

)

总之,是否可以使用Cake的Http Client将多维数组传递给get请求中的第二个参数?

// Is it possible to replace ['q' => 'widget'] with a multi-dimensional array??
$response = $http->get('http://example.com/search', ['q' => 'widget']);

如果不是,使用Cake的Http客户端发送GET请求的最佳方法是什么: http://www.magento.dev.com/rest/V1/orders?searchCriteria[filter_groups][0][filters][0][field]=created_at&searchCriteria[filter_groups][0][filters][0][value]=2016-07-01 00:00:00&searchCriteria[filter_groups][0][filters][0][condition_type]=gt : http://www.magento.dev.com/rest/V1/orders?searchCriteria[filter_groups][0][filters][0][field]=created_at&searchCriteria[filter_groups][0][filters][0][value]=2016-07-01 00:00:00&searchCriteria[filter_groups][0][filters][0][condition_type]=gt searchCriteria[filter_groups][0][filters http://www.magento.dev.com/rest/V1/orders?searchCriteria[filter_groups][0][filters][0][field]=created_at&searchCriteria[filter_groups][0][filters][0][value]=2016-07-01 00:00:00&searchCriteria[filter_groups][0][filters][0][condition_type]=gt

提前致谢!!!


可能的错误

这可能被认为是一个可能的错误。 我不认为OAuth规范考虑了URL中的PHP样式括号内容,因此排序/编码参数仅限于flat key=value集合,即关键字是

searchCriteria[filter_groups][0][filters][0][field]

价值会是

created_at

CakePHP OAuth适配器会将请求查询字符串解析为可能深度嵌套的数组结构,然后该结构将失败,因为它不处理该情况。

我建议你报告这是一个可能的错误 。 进一步的问题可能会发生,因为在排序之前编码似乎被应用,在CakePHP实现中,在排序之后应用了附加参数编码(虽然我可能确实没有问题,但实际上可能还行)。

尝试使用自定义OAuth适配器作为解决方法

在这个问题被修正/增强之前,您可以使用自定义的OAuth适配器来处理“正确”的事情(无论在这种情况下是什么意思)。 这里有一个快速和肮脏的例子(适用于我的Magento API)。

创建src / Http / Client / Auth / AppOAuth.php

<?php
namespace AppHttpClientAuth;

use CakeHttpClientAuthOauth;

class AppOAuth extends Oauth
{
    protected function _normalizedParams($request, $oauthValues)
    {
        $query = parse_url($request->url(), PHP_URL_QUERY);
        parse_str($query, $queryArgs);

        $post = [];
        $body = $request->body();
        if (is_string($body) &&
            $request->getHeaderLine('content-type') === 'application/x-www-form-urlencoded'
        ) {
            parse_str($body, $post);
        }
        if (is_array($body)) {
            $post = $body;
        }

        $args = array_merge($queryArgs, $oauthValues, $post);
        $query = http_build_query($args);

        $args = [];
        foreach (explode('&', $query) as $value) {
            $pair = explode('=', $value, 2);
            $args[] =
                rawurlencode(rawurldecode($pair[0])) .
                '=' .
                rawurlencode(rawurldecode($pair[1]));
        }
        usort($args, 'strcmp');

        return implode('&', $args);
    }
}

Cake Http Client Auth Oauth :: _ normalizedParams()比较

通过在客户端实例的type选项中指定classname来使用它:

'type' => 'AppOAuth',

PS

不应该是filter_groups而不是你的$search数组中的filterGroups

链接地址: http://www.djcxy.com/p/70173.html

上一篇: Use CakePHP Http Client with Magento2 rest API search criteria

下一篇: http url parameter Invalid Character Error