/** * */ public function onError() { if (isset($this->response) && is_string($this->response)) { if (preg_match('/<\\?xml /', $this->response)) { App::import('Core', 'Xml'); $Xml = new Xml($this->response); $this->response = $Xml->toArray(false); $Xml->__destruct(); $Xml = null; unset($Xml); if (isset($this->response['hash'])) { $this->response = $this->response['hash']; } } else { $this->response = array('error' => $this->response); } } parent::onError(); }
/** * Issues request and returns response as an array decoded according to the * response's content type if the response code is 200, else triggers the * $model->onError() method (if it exists) and finally returns false. * * @param mixed $model Either a CakePHP model with a request property, or an * array in the format expected by HttpSocket::request or a string which is a * URI. * @return mixed The response or false */ public function request(&$model) { if (is_object($model)) { $request = $model->request; } elseif (is_array($model)) { $request = $model; } elseif (is_string($model)) { $request = array('uri' => $model); } // Remove unwanted elements from request array $request = array_intersect_key($request, $this->Http->request); // Issues request $response = $this->Http->request($request); // Get content type header $contentType = $this->Http->response['header']['Content-Type']; // Extract content type from content type header if (preg_match('/^([a-z0-9\\/\\+]+);\\s*charset=([a-z0-9\\-]+)/i', $contentType, $matches)) { $contentType = $matches[1]; $charset = $matches[2]; } // Decode response according to content type switch ($contentType) { case 'application/xml': case 'application/atom+xml': case 'application/rss+xml': // If making multiple requests that return xml, I found that using the // same Xml object with Xml::load() to load new responses did not work, // consequently it is necessary to create a whole new instance of the // Xml class. This can use a lot of memory so we have to manually // garbage collect the Xml object when we've finished with it, i.e. got // it to transform the xml string response into a php array. App::import('Core', 'Xml'); $Xml = new Xml($response); $response = $Xml->toArray(false); // Send false to get separate elements $Xml->__destruct(); $Xml = null; unset($Xml); break; case 'application/json': case 'text/javascript': $response = json_decode($response, true); break; } if (is_object($model)) { $model->response = $response; } // Check response status code for success or failure if (substr($this->Http->response['status']['code'], 0, 1) != 2) { if (is_object($model) && method_exists($model, 'onError')) { $model->onError(); } return false; } return $response; }
/** * Decodes the response based on the content type * * @param string $response * @return void * @author Dean Sofer */ public function decode($response) { // Get content type header $contentType = $this->Http->response['header']['Content-Type']; // Extract content type from content type header if (preg_match('/^([a-z0-9\\/\\+]+);\\s*charset=([a-z0-9\\-]+)/i', $contentType, $matches)) { $contentType = $matches[1]; $charset = $matches[2]; } // Decode response according to content type switch ($contentType) { case 'application/xml': case 'application/atom+xml': case 'application/rss+xml': // If making multiple requests that return xml, I found that using the // same Xml object with Xml::load() to load new responses did not work, // consequently it is necessary to create a whole new instance of the // Xml class. This can use a lot of memory so we have to manually // garbage collect the Xml object when we've finished with it, i.e. got // it to transform the xml string response into a php array. App::uses('Xml', 'Utility'); $Xml = new Xml($response); $response = $Xml->toArray(false); // Send false to get separate elements $Xml->__destruct(); $Xml = null; unset($Xml); break; case 'application/json': case 'application/javascript': case 'text/javascript': $response = json_decode($response, true); break; } return $response; }
/** * Issues request and returns response as an array decoded according to the * response's content type if the response code is 200, else triggers the * $model->onError() method (if it exists) and finally returns false. * * @param mixed $model Either a CakePHP model with a request property, or an * array in the format expected by HttpSocket::request or a string which is a * URI. * @return mixed The response or false */ public function request(&$model) { if (is_object($model)) { $request = $model->request; } elseif (is_array($model)) { $request = $model; } elseif (is_string($model)) { $request = array('uri' => $model); } // Remove unwanted elements from request array $request = array_intersect_key($request, $this->Http->request); $timerStart = microtime(true); // Issues request $response = $this->Http->request($request); $timerEnd = microtime(true); // Log the request in the query log if (Configure::read('debug')) { $logText = ''; foreach (array('request', 'response') as $logPart) { $logTextForThisPart = $this->Http->{$logPart}['raw']; if ($logPart == 'response') { $logTextForThisPart = $logTextForThisPart['response']; } if (strlen($logTextForThisPart) > $this->_logLimitBytes) { $logTextForThisPart = substr($logTextForThisPart, 0, $this->_logLimitBytes) . ' [ ... truncated ...]'; } $logText .= '---' . strtoupper($logPart) . "---\n" . $logTextForThisPart . "\n\n"; } $took = round(($timerEnd - $timerStart) / 1000); $newLog = array('query' => $logText, 'error' => '', 'affected' => '', 'numRows' => '', 'took' => $took); $this->__requestLog[] = $newLog; } // Get content type header $contentType = $this->Http->response['header']['Content-Type']; // Extract content type from content type header if (preg_match('/^([a-z0-9\\/\\+]+);\\s*charset=([a-z0-9\\-]+)/i', $contentType, $matches)) { $contentType = $matches[1]; $charset = $matches[2]; } // Decode response according to content type switch ($contentType) { case 'application/xml': case 'application/atom+xml': case 'application/rss+xml': // If making multiple requests that return xml, I found that using the // same Xml object with Xml::load() to load new responses did not work, // consequently it is necessary to create a whole new instance of the // Xml class. This can use a lot of memory so we have to manually // garbage collect the Xml object when we've finished with it, i.e. got // it to transform the xml string response into a php array. App::import('Core', 'Xml'); $Xml = new Xml($response); $response = $Xml->toArray(false); // Send false to get separate elements $Xml->__destruct(); $Xml = null; unset($Xml); break; case 'application/json': case 'text/javascript': $response = json_decode($response, true); break; } if (is_object($model)) { $model->response = $response; } // Check response status code for success or failure if (substr($this->Http->response['status']['code'], 0, 1) != 2) { if (is_object($model) && method_exists($model, 'onError')) { $model->onError(); } return false; } return $response; }
/** * Decodes the response based on the content type * * @param string $response * @return void * @author Dean Sofer */ private function _decode($response, $contentType = 'application/xml') { // Extract content type from content type header if (preg_match('/^([a-z0-9\\/\\+]+);\\s*charset=([a-z0-9\\-]+)/i', $contentType, $matches)) { $contentType = $matches[1]; $charset = $matches[2]; } // Decode response according to content type switch ($contentType) { case 'application/xml': case 'application/atom+xml': case 'application/rss+xml': App::import('Core', 'Xml'); $Xml = new Xml($response); $response = $Xml->toArray(false); // Send false to get separate elements $Xml->__destruct(); $Xml = null; unset($Xml); break; case 'application/json': case 'text/javascript': $response = json_decode($response, true); break; } return $response; }