Как создать пагинацию в API Shopify Rest с помощью php

Я создал curl на php для использования API-интерфейса shopify. Теперь я хочу создать в нем разбиение на страницы.

Как создать?

Link: "<https://{shop}.myshopify.com/admin/api/{version}/products.json?page_info={page_info}&limit={limit}>; rel={next}, <https://{shop}.myshopify.com/admin/api/{version}/products.json?page_info={page_info}&limit={limit}>; rel={previous}"

Как использовать ссылку?

Спасибо

3 ответа

Функция ниже может вам помочь. для получения данных с помощью API в Php/Laravel

public function request($method,$url,$param = []){
    $client = new \GuzzleHttp\Client();
    $url = 'https://'.$this->username.':'.$this->password.'@'.$this->domain.'/admin/api/2019-10/'.$url;
    $parameters = [
        'headers' => [
            'Content-Type' => 'application/json',
            'Accept' => 'application/json'
        ]
    ];
    if(!empty($param)){ $parameters['json'] = $param;}
    $response = $client->request($method, $url,$parameters);
    $responseHeaders = $response->getHeaders();
    $tokenType = 'next';
    if(array_key_exists('Link',$responseHeaders)){
        $link = $responseHeaders['Link'][0];
        $tokenType  = strpos($link,'rel="next') !== false ? "next" : "previous";
        $tobeReplace = ["<",">",'rel="next"',";",'rel="previous"'];
        $tobeReplaceWith = ["","","",""];
        parse_str(parse_url(str_replace($tobeReplace,$tobeReplaceWith,$link),PHP_URL_QUERY),$op);
        $pageToken = trim($op['page_info']);
    }
    $rateLimit = explode('/', $responseHeaders["X-Shopify-Shop-Api-Call-Limit"][0]);
    $usedLimitPercentage = (100*$rateLimit[0])/$rateLimit[1];
    if($usedLimitPercentage > 95){sleep(5);}
    $responseBody = json_decode($response->getBody(),true);
    $r['resource'] =  (is_array($responseBody) && count($responseBody) > 0) ? array_shift($responseBody) : $responseBody;
    $r[$tokenType]['page_token'] = isset($pageToken) ? $pageToken : null;
    return $r;
}

Пример использования этой функции

$product_ids = [];
$nextPageToken = null;
do{
    $response = $shop->request('get','products.json?limit=250&page_info='.$nextPageToken);
    foreach($response['resource'] as $product){
        array_push($product_ids, $product['id']);
    }
    $nextPageToken = $response['next']['page_token'] ?? null;
}while($nextPageToken != null);

Если вы хотите использовать api graphQL в php / laravel, то сообщение ниже может вам помочь

Как запросить shopify graphql-admin-api из API?

Начиная с версии API 2019-07 вам действительно нужно использовать разбиение на страницы на основе курсора.

Сначала сделайте обычный вызов API, включите ответ заголовка.

Тогда в заголовке ответа вы увидите ссылку: ... с rel next или previous.

Извлеките page_info, а затем сделайте еще один вызов с помощью page_info.

Первый вызов выглядит примерно так:

https://...:...@xyz.myshopify.com/admin/api/2019-10/products.json?limit=2&published_status=published

Тогда второй звонок

https://...:...@xyz.myshopify.com/admin/api/2019-10/products.json?limit=2&page_info=asdfas1321asdf3as1f651saf61s3f1x32v1akjhfasdj

Когда вы делаете второй вызов, удалите все фильтры, поскольку фильтры будут применяться с первого вызова.

Кстати: если вы тестируете в браузере из-за того, что ссылка находится в угловых скобках, она будет скрыта, поэтому просто просмотрите исходный код в своей среде разработчика.

Ссылка: https://help.shopify.com/en/api/guides/paginated-rest-results

private $shop_url = '';
private $shop_user = '';
private $shop_password = '';

function __construct($shop) {
    $this->shop_url = $shop->url;
    $this->shop_user = $shop->user;
    $this->shop_password = $shop->userpas;
    $this->syncShopifyOrder($shop);
}

private function getOrderRequest($url){
    $client = new \GuzzleHttp\Client();
    $response = $client->request('GET', $url, [
        'auth' => [$this->shop_user, $this->shop_password]
    ]);

    if($response->getStatusCode() !== 200){
        throw new OrderSyncException('Connection problem!');
    }

    $data = [];
    $paginate_links = $response->getHeader('Link');

    if($paginate_links){

        $page_link = $paginate_links[0];
        $links_arr = explode(",", $page_link);

        if($links_arr){

            $tobeReplace = ["<",">",'rel="next"',";",'rel="previous"'];
            $tobeReplaceWith = ["","","",""];

            foreach ($links_arr as $link) {
                $link_type  = strpos($link, 'rel="next') !== false ? "next" : "previous";
                parse_str(parse_url(str_replace($tobeReplace, $tobeReplaceWith, $link), PHP_URL_QUERY), $op);
                $data[$link_type] = trim($op['page_info']);
            }
        }
    }

    $order_data = $response->getBody()->getContents();
    $data['all_orders'] = (json_decode($order_data))->orders;
    return $data;
}


// Shopify Orders
private function syncShopifyOrder($shop)
{
    $count = 0;
    try{
        if($shop){
            $nextPageToken = null;
            do{
                $param = ($nextPageToken)? '&page_info='.$nextPageToken : '&status=any&fulfillment_status=any&order=created_at asc&created_at_min=2020-08-10T13:30:33+02:00';
                $url = $this->shop_url . 'admin/api/2020-01/orders.json?limit=250'.$param;

                $data = $this->getOrderRequest($url);
                $all_orders = $data['all_orders'];
                $nextPageToken = isset($data['next']) ? $data['next'] : null;
                
                if($all_orders){
                    $count += count((array) $all_orders);
                    $this->bulkorderInsertShopify($shop, $all_orders);
                }
            }while($nextPageToken);
        }else{
            throw new OrderSyncException('You have not configured shop!');
        }
        $this->syncSuccessReport($shop, $count);

    }catch(OrderSyncException $e) {
        $this->syncErrorReport($shop, $count, $e->getMessage());
        
    }catch(\Exception $e) {
        $this->syncErrorReportAdmin($shop, $count, $e);
    }
}
Другие вопросы по тегам