<?php
 declare(strict_types=1); namespace Shopify\Clients; class PageInfo { private const LINK_HEADER_REGEXP = '/<([^<]+)>; rel="([^"]+)"/'; private readonly ?array $fields; private readonly ?string $previousPageUrl; private readonly ?string $nextPageUrl; public function __construct( ?array $fields, ?string $previousPageUrl, ?string $nextPageUrl ) { $this->fields = $fields; $this->previousPageUrl = $previousPageUrl; $this->nextPageUrl = $nextPageUrl; } public static function fromLinkHeader(string $linkHeader): PageInfo { $linkHeaderSegments = explode(', ', $linkHeader); $fields = self::parseFields($linkHeaderSegments); list($previousUrl, $nextUrl) = self::parseUrls($linkHeaderSegments); return new PageInfo($fields, $previousUrl, $nextUrl); } private static function parseFields(array $linkHeaderSegments): array { $fields = []; foreach ($linkHeaderSegments as $segment) { $parsedUrl = []; preg_match(self::LINK_HEADER_REGEXP, (string) $segment, $parsedUrl); $linkUrl = $parsedUrl[1]; $queryParams = self::getQueryFromUrl($linkUrl); if (array_key_exists('fields', $queryParams)) { $linkFields = $queryParams['fields']; $fields = explode(',', (string) $linkFields); } } return $fields; } private static function parseUrls(array $linkHeaderSegments): array { $previousUrl = null; $nextUrl = null; foreach ($linkHeaderSegments as $url) { $parsedLink = []; preg_match(self::LINK_HEADER_REGEXP, (string) $url, $parsedLink); $linkRel = $parsedLink[2]; $linkUrl = $parsedLink[1]; switch ($linkRel) { case 'previous': $previousUrl = $linkUrl; break; case 'next': $nextUrl = $linkUrl; break; } } return array($previousUrl, $nextUrl); } public function getPreviousPageUrl(): ?string { return $this->previousPageUrl; } public function getNextPageUrl(): ?string { return $this->nextPageUrl; } public function getFields(): ?array { return $this->fields; } public function getPreviousPageQuery(): array { return self::getQueryFromUrl($this->getPreviousPageUrl()); } public function getNextPageQuery(): array { return self::getQueryFromUrl($this->getNextPageUrl()); } public function hasNextPage(): bool { return $this->getNextPageUrl() !== null; } public function hasPreviousPage(): bool { return self::getPreviousPageUrl() !== null; } private static function getQueryFromUrl(string $url): array { $queryParams = []; parse_str(parse_url($url, PHP_URL_QUERY), $queryParams); return $queryParams; } } 