-
Notifications
You must be signed in to change notification settings - Fork 31
Expand file tree
/
Copy pathResourceWithReferences.php
More file actions
117 lines (103 loc) · 4.13 KB
/
ResourceWithReferences.php
File metadata and controls
117 lines (103 loc) · 4.13 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
<?php
declare(strict_types=1);
namespace Platformsh\Client\Model;
use GuzzleHttp\ClientInterface;
use GuzzleHttp\Exception\BadResponseException;
use GuzzleHttp\Psr7\Request;
use GuzzleHttp\Psr7\Uri;
use Platformsh\Client\Model\Ref\Resolver;
class ResourceWithReferences extends ApiResourceBase
{
protected static ?string $collectionItemsKey = 'items';
public static function wrapCollection(array|Collection $data, string $baseUrl, ClientInterface $client): array
{
if ($data instanceof Collection) {
$parent = $data;
$data = $data->getData();
} else {
$parent = new Collection($data, $client, $baseUrl);
}
$data = self::resolveReferences(new Resolver($client, $baseUrl), $data);
$parent->setData($data);
// Add referenced information for the whole collection onto individual
// resources, based on this map of resource keys to reference API sets.
$map = [
'project_id' => 'projects',
'owner_id' => 'users',
'user_id' => 'users',
'organization_id' => 'organizations',
'team_id' => 'teams',
];
$resources = [];
foreach ($data[static::$collectionItemsKey] as $item) {
if (isset($item['resource_type'], $item['resource_id'])) {
$set = $item['resource_type'] . 's';
if (isset($data['ref:' . $set][$item['resource_id']])) {
$item['ref:' . $set][$item['resource_id']] = $data['ref:' . $set][$item['resource_id']];
}
}
foreach ($map as $key => $set) {
if (isset($item[$key]) && isset($data['ref:' . $set][$item[$key]])) {
$item['ref:' . $set][$item[$key]] = $data['ref:' . $set][$item[$key]];
}
}
$resource = new static($item, $baseUrl, $client);
$resource->setParentCollection($parent);
$resources[] = $resource;
}
return $resources;
}
/**
* Returns a paginated list of resources.
*
* This is the equivalent of getCollection() with pagination logic.
*
* If 'items' is non-empty and if a non-null 'next' URL is returned, this
* call may be repeated with the new URL to fetch the next page.
*
* Use $options['query']['page'] to specify a page number explicitly.
*
* @return array{items: static[], next: ?string, previous: ?string}
*/
public static function getPagedCollection(string $url, ClientInterface $client, array $options = []): array
{
$request = new Request('get', $url);
$data = static::send($request, $client, $options);
$items = static::wrapCollection($data, $url, $client);
$ret = [
'items' => $items,
'next' => null,
'previous' => null,
];
$base = new Uri($url);
foreach (['previous', 'next'] as $rel) {
if (isset($data['_links'][$rel]['href'])) {
$next = new Uri($data['_links'][$rel]['href']);
$resolved = $base->withPath($next->getPath())->withQuery($next->getQuery());
$ret[$rel] = $resolved->__toString();
}
}
return $ret;
}
protected function setData(array $data): void
{
// References are resolved upon initialization so that the links are less likely to have expired.
$data = self::resolveReferences(new Resolver($this->client, $this->baseUrl), $data);
parent::setData($data);
}
protected static function resolveReferences(Resolver $resolver, array $data): array
{
if (isset($data['_links'])) {
try {
$data = $resolver->resolveReferences($data);
} catch (\Exception $e) {
$message = $e->getMessage();
if ($e instanceof BadResponseException) {
$message = \sprintf('status code %d', $e->getResponse()->getStatusCode());
}
\trigger_error('Unable to resolve references: ' . $message, E_USER_WARNING);
}
}
return $data;
}
}