简体   繁体   中英

How to create pagination in shopify rest api using php

I created curl in php for use shopify product rest API. Now I want to create pagination in that.

How to create?

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}"

How to use Link ?

Thanks

Below function can help you. to fetch data using API in 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;
}

Example usage of this function

$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);

If you want to use graphQL api in php / laravel then below post can help you

How to request shopify graphql-admin-api from an api?

As of API version 2019-07 you do indeed need to use cursor based pagination.

First make a normal API call, include the header response.

Then in the header response you will see link : ... with rel next or previous.

Extract the page_info and then make another call with page_info.

The first call is something like this:

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

Then the second call is

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

When you make the second call, remove any filers as the filters will be applied from the first call.

Btw: if your testing in a browser due to the way the link is in angle brackets, it will be hidden, so just view source code in your developer environment.

Reference: 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);
    }
}

The Rest API has no next feature. You are making that up. If you wanted to use a next pagination style of call, you'd be using the GraphQL API endpoint instead, and you would be using the cursor feature there, which has a next and previous concept built right in.

So either you replace your next wish with an actual page number which does work with the Rest API, or you switch to GraphQL and offer up next and previous using cursors.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM