1 <?php
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
17
18 namespace OpenCloud\Common\Resource;
19
20 use Guzzle\Http\Message\Response;
21 use Guzzle\Http\Url;
22 use OpenCloud\Common\Base;
23 use OpenCloud\Common\Exceptions\DocumentError;
24 use OpenCloud\Common\Exceptions\ServiceException;
25 use OpenCloud\Common\Exceptions\UrlError;
26 use OpenCloud\Common\Metadata;
27 use OpenCloud\Common\Service\ServiceInterface;
28 use OpenCloud\Common\Http\Message\Formatter;
29
30 abstract class BaseResource extends Base
31 {
32
33 protected $service;
34
35
36 protected $parent;
37
38
39 protected $metadata;
40
41 42 43 44
45 public function __construct(ServiceInterface $service, $data = null)
46 {
47 $this->setService($service);
48 $this->metadata = new Metadata();
49 $this->populate($data);
50 }
51
52 53 54 55
56 public function setService(ServiceInterface $service)
57 {
58 $this->service = $service;
59
60 return $this;
61 }
62
63 64 65 66
67 public function getService()
68 {
69 if (null === $this->service) {
70 throw new ServiceException('No service defined');
71 }
72
73 return $this->service;
74 }
75
76 77 78 79
80 public function setParent(BaseResource $parent)
81 {
82 $this->parent = $parent;
83
84 return $this;
85 }
86
87 88 89
90 public function getParent()
91 {
92 if (null === $this->parent) {
93 $this->parent = $this->getService();
94 }
95
96 return $this->parent;
97 }
98
99 100 101 102 103
104 public function getClient()
105 {
106 return $this->getService()->getClient();
107 }
108
109 110 111 112
113 public function setMetadata($data)
114 {
115 if ($data instanceof Metadata) {
116 $metadata = $data;
117 } elseif (is_array($data) || is_object($data)) {
118 $metadata = new Metadata();
119 $metadata->setArray($data);
120 } else {
121 throw new \InvalidArgumentException(sprintf(
122 'You must specify either an array/object of parameters, or an '
123 . 'instance of Metadata. You provided: %s',
124 print_r($data, true)
125 ));
126 }
127
128 $this->metadata = $metadata;
129
130 return $this;
131 }
132
133 134 135
136 public function getMetadata()
137 {
138 return $this->metadata;
139 }
140
141 142 143 144 145 146 147
148 public function getUrl($path = null, array $query = array())
149 {
150 if (!$url = $this->findLink('self')) {
151
152
153 $url = $this->getParent()->getUrl($this->resourceName());
154
155
156 if (null !== ($primaryKey = $this->getProperty($this->primaryKeyField()))) {
157 $url->addPath((string) $primaryKey);
158 }
159 }
160
161 if (!$url instanceof Url) {
162 $url = Url::factory($url);
163 }
164
165 return $url->addPath((string) $path)->setQuery($query);
166 }
167
168 169 170
171 public function url($path = null, array $query = array())
172 {
173 return $this->getUrl($path, $query);
174 }
175
176
177 178 179 180 181 182
183 public function findLink($type = 'self')
184 {
185 if (empty($this->links)) {
186 return false;
187 }
188
189 foreach ($this->links as $link) {
190 if ($link->rel == $type) {
191 return $link->href;
192 }
193 }
194
195 return false;
196 }
197
198 199 200 201 202
203 protected function primaryKeyField()
204 {
205 return 'id';
206 }
207
208 209 210 211 212
213 public static function jsonName()
214 {
215 if (isset(static::$json_name)) {
216 return static::$json_name;
217 }
218
219 throw new DocumentError('A top-level JSON document key has not been defined for this resource');
220 }
221
222 223 224 225 226
227 public static function jsonCollectionName()
228 {
229 return isset(static::$json_collection_name) ? static::$json_collection_name : static::$json_name . 's';
230 }
231
232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258
259 public static function jsonCollectionElement()
260 {
261 if (isset(static::$json_collection_element)) {
262 return static::$json_collection_element;
263 }
264 }
265
266 267 268 269 270
271 public static function resourceName()
272 {
273 if (isset(static::$url_resource)) {
274 return static::$url_resource;
275 }
276
277 throw new UrlError('No URL path defined for this resource');
278 }
279
280 281 282 283 284 285
286 public function parseResponse(Response $response)
287 {
288 $document = Formatter::decode($response);
289
290 $topLevelKey = $this->jsonName();
291
292 return ($topLevelKey && isset($document->$topLevelKey)) ? $document->$topLevelKey : $document;
293 }
294 }
295