MDL-67115 google: php74 params order for implode()
[moodle.git] / lib / google / src / Google / Http / REST.php
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  */
18 if (!class_exists('Google_Client')) {
19   require_once dirname(__FILE__) . '/../autoload.php';
20 }
22 /**
23  * This class implements the RESTful transport of apiServiceRequest()'s
24  */
25 class Google_Http_REST
26 {
27   /**
28    * Executes a Google_Http_Request and (if applicable) automatically retries
29    * when errors occur.
30    *
31    * @param Google_Client $client
32    * @param Google_Http_Request $req
33    * @return array decoded result
34    * @throws Google_Service_Exception on server side error (ie: not authenticated,
35    *  invalid or malformed post body, invalid url)
36    */
37   public static function execute(Google_Client $client, Google_Http_Request $req)
38   {
39     $runner = new Google_Task_Runner(
40         $client,
41         sprintf('%s %s', $req->getRequestMethod(), $req->getUrl()),
42         array(get_class(), 'doExecute'),
43         array($client, $req)
44     );
46     return $runner->run();
47   }
49   /**
50    * Executes a Google_Http_Request
51    *
52    * @param Google_Client $client
53    * @param Google_Http_Request $req
54    * @return array decoded result
55    * @throws Google_Service_Exception on server side error (ie: not authenticated,
56    *  invalid or malformed post body, invalid url)
57    */
58   public static function doExecute(Google_Client $client, Google_Http_Request $req)
59   {
60     $httpRequest = $client->getIo()->makeRequest($req);
61     $httpRequest->setExpectedClass($req->getExpectedClass());
62     return self::decodeHttpResponse($httpRequest, $client);
63   }
65   /**
66    * Decode an HTTP Response.
67    * @static
68    * @throws Google_Service_Exception
69    * @param Google_Http_Request $response The http response to be decoded.
70    * @param Google_Client $client
71    * @return mixed|null
72    */
73   public static function decodeHttpResponse($response, Google_Client $client = null)
74   {
75     $code = $response->getResponseHttpCode();
76     $body = $response->getResponseBody();
77     $decoded = null;
79     if ((intVal($code)) >= 300) {
80       $decoded = json_decode($body, true);
81       $err = 'Error calling ' . $response->getRequestMethod() . ' ' . $response->getUrl();
82       if (isset($decoded['error']) &&
83           isset($decoded['error']['message'])  &&
84           isset($decoded['error']['code'])) {
85         // if we're getting a json encoded error definition, use that instead of the raw response
86         // body for improved readability
87         $err .= ": ({$decoded['error']['code']}) {$decoded['error']['message']}";
88       } else {
89         $err .= ": ($code) $body";
90       }
92       $errors = null;
93       // Specific check for APIs which don't return error details, such as Blogger.
94       if (isset($decoded['error']) && isset($decoded['error']['errors'])) {
95         $errors = $decoded['error']['errors'];
96       }
98       $map = null;
99       if ($client) {
100         $client->getLogger()->error(
101             $err,
102             array('code' => $code, 'errors' => $errors)
103         );
105         $map = $client->getClassConfig(
106             'Google_Service_Exception',
107             'retry_map'
108         );
109       }
110       throw new Google_Service_Exception($err, $code, null, $errors, $map);
111     }
113     // Only attempt to decode the response, if the response code wasn't (204) 'no content'
114     if ($code != '204') {
115       if ($response->getExpectedRaw()) {
116         return $body;
117       }
118       
119       $decoded = json_decode($body, true);
120       if ($decoded === null || $decoded === "") {
121         $error = "Invalid json in service response: $body";
122         if ($client) {
123           $client->getLogger()->error($error);
124         }
125         throw new Google_Service_Exception($error);
126       }
128       if ($response->getExpectedClass()) {
129         $class = $response->getExpectedClass();
130         $decoded = new $class($decoded);
131       }
132     }
133     return $decoded;
134   }
136   /**
137    * Parse/expand request parameters and create a fully qualified
138    * request uri.
139    * @static
140    * @param string $servicePath
141    * @param string $restPath
142    * @param array $params
143    * @return string $requestUrl
144    */
145   public static function createRequestUri($servicePath, $restPath, $params)
146   {
147     $requestUrl = $servicePath . $restPath;
148     $uriTemplateVars = array();
149     $queryVars = array();
150     foreach ($params as $paramName => $paramSpec) {
151       if ($paramSpec['type'] == 'boolean') {
152         $paramSpec['value'] = ($paramSpec['value']) ? 'true' : 'false';
153       }
154       if ($paramSpec['location'] == 'path') {
155         $uriTemplateVars[$paramName] = $paramSpec['value'];
156       } else if ($paramSpec['location'] == 'query') {
157         if (isset($paramSpec['repeated']) && is_array($paramSpec['value'])) {
158           foreach ($paramSpec['value'] as $value) {
159             $queryVars[] = $paramName . '=' . rawurlencode(rawurldecode($value));
160           }
161         } else {
162           $queryVars[] = $paramName . '=' . rawurlencode(rawurldecode($paramSpec['value']));
163         }
164       }
165     }
167     if (count($uriTemplateVars)) {
168       $uriTemplateParser = new Google_Utils_URITemplate();
169       $requestUrl = $uriTemplateParser->parse($requestUrl, $uriTemplateVars);
170     }
172     if (count($queryVars)) {
173       $requestUrl .= '?' . implode('&', $queryVars);
174     }
176     return $requestUrl;
177   }