0

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

3 Answers 3

5

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?

Sign up to request clarification or add additional context in comments.

2 Comments

this looks like exactly what I require however I am struggling to understand how this has been set up in Laravel. Can this be done in one function in a controller and then returned to a view or persisted to a "products" table in a db?
I am also using Laravel and above function I have included in my Model ( Shop model which is associated with the table where Access Token is stored ) and called in the Controller. ----------------- First code block is MODEL and second Code Block is Controller
2

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://...:[email protected]/admin/api/2019-10/products.json?limit=2&published_status=published

Then the second call is

https://...:[email protected]/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

Comments

1
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);
    }
}

1 Comment

Welcome to Stackoverflow! Please comment your code to explain what it does to help any future visitors to your answers.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.