slince / shopify-api-php

:rocket: Shopify API Client for PHP
MIT License
128 stars 48 forks source link

How to paginate orders #60

Open abishekrsrikaanth opened 4 years ago

abishekrsrikaanth commented 4 years ago

I am using the API version 2020-01. How do I go about paginating the orders?

Here is the code I have so far

$client = new Client($credential, 'shop_ name.myshopify.com', [
            'metaCacheDir' => './tmp',
        ]);

        $orders = $client->getOrderManager()->findAll([
            'since_id' => 'order_id_goes_here',
            'limit'    => 250,
            'status'   => 'any',
        ]);

Not quite sure, how to proceed after this.

benholmen commented 4 years ago

Did you solve this? I'm currently working on upgrading my script to use pagination.

Here's my code - it runs fine, but for some reason is returning no orders in my testing. It might help you, and if you've already solved it, I'm curious how you did it.

$client = new Client($credential, 'shop_name.myshopify.com', [
    'metaCacheDir' => './tmp',
]);

$pagination = $client->getOrderManager()->paginate([
    'limit' => 20,
    'created_at_min' => $created_at_min,
]);
$orders = $pagination->current();
update_orders($orders); // internal fn to do things with orders
while ($pagination->hasNext()) {
    $orders = $pagination->next();
    update_orders($orders); // internal fn to do things with orders
}
abishekrsrikaanth commented 4 years ago

I tried that and had the same issue, couldn't debug further to figure out the issue in the package, has a bit of a time crunch. I had to write my own function to get the next page information from the header and pass that to the request to get the next page.

https://shopify.dev/tutorials/make-paginated-requests-to-rest-admin-api

Here is the function that I created, hope it helps to fix the issue:

/**
     * Gets next page info string for use in pagination
     *
     * @param $headerLine
     *
     * @return string
     */
    public function parseNextPageInfo($headerLine)
    {
        if ($headerLine) {
            $matchData = [];
            if (preg_match("/<([^>]*)>; rel=\"next\"/", $headerLine, $matchData)) {
                // found rel="next"
                $query = parse_url($matchData[1], PHP_URL_QUERY);
                $pairs = explode("&", $query);
                foreach ($pairs as $p) {
                    [
                        $key,
                        $value,
                    ] = explode("=", $p);
                    if ($key == "page_info") {
                        return $value;
                    }
                }
            }
        }

        return false;
    }

    public function hasNextPageInfo()
    {
        return !empty($this->getNextPageInfo());
    }

    public function getNextPageInfo()
    {
        return $this->parseNextPageInfo($this->client->getLastResponse()->getHeaderLine('Link'));
    }
baorv commented 4 years ago

Did you solve this? I'm currently working on upgrading my script to use pagination.

Here's my code - it runs fine, but for some reason is returning no orders in my testing. It might help you, and if you've already solved it, I'm curious how you did it.

$client = new Client($credential, 'shop_name.myshopify.com', [
    'metaCacheDir' => './tmp',
]);

$pagination = $client->getOrderManager()->paginate([
    'limit' => 20,
    'created_at_min' => $created_at_min,
]);
$orders = $pagination->current();
update_orders($orders); // internal fn to do things with orders
while ($pagination->hasNext()) {
    $orders = $pagination->next();
    update_orders($orders); // internal fn to do things with orders
}

I think it should be:

$pagination = $client->getOrderManager()->paginate([
    'limit' => 20,
    'created_at_min' => $created_at_min,
    'status' => 'any'
]);
benholmen commented 4 years ago

Bob - I think you're right about the status=any addition. I've also tested that but had no luck.

Since I posted this comment I've done a lot of troubleshooting and I'm getting the same empty result set even when I hit the API directly with curl. I've found a group of users reporting the same issue - I think it is a Shopify API issue not a slince/shopify-api-php issue.

benholmen commented 4 years ago

The issue was not with slince/shopify-api-php - it was due to a change in the Shopify Order API. My app was configured as a sales channel and they changed the API response to only return orders made through my app.

I worked with a Shopify rep to remove the sales channel privilege from my app (not reversible) and I now have access to 60 days of orders.

slince commented 4 years ago

Hello In version 2.4.1, you can get page info like this

$nextPageInfo = $pagination->getNextPageInfo();
$prevPageInfo = $pagination->getPrevPageInfo();

$products = $pagination->current($nextPageInfo);
imandydoan commented 4 years ago

It is awesome! Thank you so much @slince.