source: vendor/google/apiclient/src/Service/Resource.php@ e3d4e0a

Last change on this file since e3d4e0a was e3d4e0a, checked in by Vlado 222039 <vlado.popovski@…>, 7 days ago

Upload project files

  • Property mode set to 100644
File size: 11.5 KB
RevLine 
[e3d4e0a]1<?php
2/**
3 * Copyright 2010 Google Inc.
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17
18namespace Google\Service;
19
20use Google\Exception as GoogleException;
21use Google\Http\MediaFileUpload;
22use Google\Model;
23use Google\Utils\UriTemplate;
24use GuzzleHttp\Psr7\Request;
25
26/**
27 * Implements the actual methods/resources of the discovered Google API using magic function
28 * calling overloading (__call()), which on call will see if the method name (plus.activities.list)
29 * is available in this service, and if so construct an apiHttpRequest representing it.
30 *
31 */
32class Resource
33{
34 // Valid query parameters that work, but don't appear in discovery.
35 private $stackParameters = [
36 'alt' => ['type' => 'string', 'location' => 'query'],
37 'fields' => ['type' => 'string', 'location' => 'query'],
38 'trace' => ['type' => 'string', 'location' => 'query'],
39 'userIp' => ['type' => 'string', 'location' => 'query'],
40 'quotaUser' => ['type' => 'string', 'location' => 'query'],
41 'data' => ['type' => 'string', 'location' => 'body'],
42 'mimeType' => ['type' => 'string', 'location' => 'header'],
43 'uploadType' => ['type' => 'string', 'location' => 'query'],
44 'mediaUpload' => ['type' => 'complex', 'location' => 'query'],
45 'prettyPrint' => ['type' => 'string', 'location' => 'query'],
46 ];
47
48 /** @var string $rootUrlTemplate */
49 private $rootUrlTemplate;
50
51 /** @var string $apiVersion */
52 protected $apiVersion;
53
54 /** @var \Google\Client $client */
55 private $client;
56
57 /** @var string $serviceName */
58 private $serviceName;
59
60 /** @var string $servicePath */
61 private $servicePath;
62
63 /** @var string $resourceName */
64 private $resourceName;
65
66 /** @var array $methods */
67 private $methods;
68
69 public function __construct($service, $serviceName, $resourceName, $resource)
70 {
71 $this->rootUrlTemplate = $service->rootUrlTemplate ?? $service->rootUrl;
72 $this->client = $service->getClient();
73 $this->servicePath = $service->servicePath;
74 $this->serviceName = $serviceName;
75 $this->resourceName = $resourceName;
76 $this->methods = is_array($resource) && isset($resource['methods']) ?
77 $resource['methods'] :
78 [$resourceName => $resource];
79 }
80
81 /**
82 * TODO: This function needs simplifying.
83 *
84 * @template T
85 * @param string $name
86 * @param array $arguments
87 * @param class-string<T> $expectedClass - optional, the expected class name
88 * @return mixed|T|ResponseInterface|RequestInterface
89 * @throws \Google\Exception
90 */
91 public function call($name, $arguments, $expectedClass = null)
92 {
93 if (! isset($this->methods[$name])) {
94 $this->client->getLogger()->error(
95 'Service method unknown',
96 [
97 'service' => $this->serviceName,
98 'resource' => $this->resourceName,
99 'method' => $name
100 ]
101 );
102
103 throw new GoogleException(
104 "Unknown function: " .
105 "{$this->serviceName}->{$this->resourceName}->{$name}()"
106 );
107 }
108 $method = $this->methods[$name];
109 $parameters = $arguments[0];
110
111 // postBody is a special case since it's not defined in the discovery
112 // document as parameter, but we abuse the param entry for storing it.
113 $postBody = null;
114 if (isset($parameters['postBody'])) {
115 if ($parameters['postBody'] instanceof Model) {
116 // In the cases the post body is an existing object, we want
117 // to use the smart method to create a simple object for
118 // for JSONification.
119 $parameters['postBody'] = $parameters['postBody']->toSimpleObject();
120 } elseif (is_object($parameters['postBody'])) {
121 // If the post body is another kind of object, we will try and
122 // wrangle it into a sensible format.
123 $parameters['postBody'] =
124 $this->convertToArrayAndStripNulls($parameters['postBody']);
125 }
126 $postBody = (array) $parameters['postBody'];
127 unset($parameters['postBody']);
128 }
129
130 // TODO: optParams here probably should have been
131 // handled already - this may well be redundant code.
132 if (isset($parameters['optParams'])) {
133 $optParams = $parameters['optParams'];
134 unset($parameters['optParams']);
135 $parameters = array_merge($parameters, $optParams);
136 }
137
138 if (!isset($method['parameters'])) {
139 $method['parameters'] = [];
140 }
141
142 $method['parameters'] = array_merge(
143 $this->stackParameters,
144 $method['parameters']
145 );
146
147 foreach ($parameters as $key => $val) {
148 if ($key != 'postBody' && !isset($method['parameters'][$key])) {
149 $this->client->getLogger()->error(
150 'Service parameter unknown',
151 [
152 'service' => $this->serviceName,
153 'resource' => $this->resourceName,
154 'method' => $name,
155 'parameter' => $key
156 ]
157 );
158 throw new GoogleException("($name) unknown parameter: '$key'");
159 }
160 }
161
162 foreach ($method['parameters'] as $paramName => $paramSpec) {
163 if (
164 isset($paramSpec['required']) &&
165 $paramSpec['required'] &&
166 ! isset($parameters[$paramName])
167 ) {
168 $this->client->getLogger()->error(
169 'Service parameter missing',
170 [
171 'service' => $this->serviceName,
172 'resource' => $this->resourceName,
173 'method' => $name,
174 'parameter' => $paramName
175 ]
176 );
177 throw new GoogleException("($name) missing required param: '$paramName'");
178 }
179 if (isset($parameters[$paramName])) {
180 $value = $parameters[$paramName];
181 $parameters[$paramName] = $paramSpec;
182 $parameters[$paramName]['value'] = $value;
183 unset($parameters[$paramName]['required']);
184 } else {
185 // Ensure we don't pass nulls.
186 unset($parameters[$paramName]);
187 }
188 }
189
190 $this->client->getLogger()->info(
191 'Service Call',
192 [
193 'service' => $this->serviceName,
194 'resource' => $this->resourceName,
195 'method' => $name,
196 'arguments' => $parameters,
197 ]
198 );
199
200 // build the service uri
201 $url = $this->createRequestUri($method['path'], $parameters);
202
203 // NOTE: because we're creating the request by hand,
204 // and because the service has a rootUrl property
205 // the "base_uri" of the Http Client is not accounted for
206 $request = new Request(
207 $method['httpMethod'],
208 $url,
209 $postBody ? ['content-type' => 'application/json'] : [],
210 $postBody ? json_encode($postBody) : ''
211 );
212
213 // support uploads
214 if (isset($parameters['data'])) {
215 $mimeType = isset($parameters['mimeType'])
216 ? $parameters['mimeType']['value']
217 : 'application/octet-stream';
218 $data = $parameters['data']['value'];
219 $upload = new MediaFileUpload($this->client, $request, $mimeType, $data);
220
221 // pull down the modified request
222 $request = $upload->getRequest();
223 }
224
225 // if this is a media type, we will return the raw response
226 // rather than using an expected class
227 if (isset($parameters['alt']) && $parameters['alt']['value'] == 'media') {
228 $expectedClass = null;
229 }
230
231 // If the class which is extending from this one contains
232 // an Api Version, add it to the header
233 if ($this->apiVersion) {
234 $request = $request
235 ->withHeader('X-Goog-Api-Version', $this->apiVersion);
236 }
237
238 // if the client is marked for deferring, rather than
239 // execute the request, return the response
240 if ($this->client->shouldDefer()) {
241 // @TODO find a better way to do this
242 $request = $request
243 ->withHeader('X-Php-Expected-Class', $expectedClass);
244
245 return $request;
246 }
247
248 return $this->client->execute($request, $expectedClass);
249 }
250
251 protected function convertToArrayAndStripNulls($o)
252 {
253 $o = (array) $o;
254 foreach ($o as $k => $v) {
255 if ($v === null) {
256 unset($o[$k]);
257 } elseif (is_object($v) || is_array($v)) {
258 $o[$k] = $this->convertToArrayAndStripNulls($o[$k]);
259 }
260 }
261 return $o;
262 }
263
264 /**
265 * Parse/expand request parameters and create a fully qualified
266 * request uri.
267 * @static
268 * @param string $restPath
269 * @param array $params
270 * @return string $requestUrl
271 */
272 public function createRequestUri($restPath, $params)
273 {
274 // Override the default servicePath address if the $restPath use a /
275 if ('/' == substr($restPath, 0, 1)) {
276 $requestUrl = substr($restPath, 1);
277 } else {
278 $requestUrl = $this->servicePath . $restPath;
279 }
280
281 if ($this->rootUrlTemplate) {
282 // code for universe domain
283 $rootUrl = str_replace('UNIVERSE_DOMAIN', $this->client->getUniverseDomain(), $this->rootUrlTemplate);
284 // code for leading slash
285 if ('/' !== substr($rootUrl, -1) && '/' !== substr($requestUrl, 0, 1)) {
286 $requestUrl = '/' . $requestUrl;
287 }
288 $requestUrl = $rootUrl . $requestUrl;
289 }
290 $uriTemplateVars = [];
291 $queryVars = [];
292 foreach ($params as $paramName => $paramSpec) {
293 if ($paramSpec['type'] == 'boolean') {
294 $paramSpec['value'] = $paramSpec['value'] ? 'true' : 'false';
295 }
296 if ($paramSpec['location'] == 'path') {
297 $uriTemplateVars[$paramName] = $paramSpec['value'];
298 } elseif ($paramSpec['location'] == 'query') {
299 if (is_array($paramSpec['value'])) {
300 foreach ($paramSpec['value'] as $value) {
301 $queryVars[] = $paramName . '=' . rawurlencode(rawurldecode($value));
302 }
303 } else {
304 $queryVars[] = $paramName . '=' . rawurlencode(rawurldecode($paramSpec['value']));
305 }
306 }
307 }
308
309 if (count($uriTemplateVars)) {
310 $uriTemplateParser = new UriTemplate();
311 $requestUrl = $uriTemplateParser->parse($requestUrl, $uriTemplateVars);
312 }
313
314 if (count($queryVars)) {
315 $requestUrl .= '?' . implode('&', $queryVars);
316 }
317
318 return $requestUrl;
319 }
320}
Note: See TracBrowser for help on using the repository browser.