/** * Set an curl_exec wrapper function($ch, $method, $url, $options) * * @param $call */ public static function exec($call) { if (is_object($call) && $call instanceof ExecInterface) { ParseCurl::$exec = $call; } elseif (is_callable($call)) { ParseCurl::$exec = $call; } }
/** * Called by ParseCurl * * @param $ch * @param $method * @param $url * @param $options * * @return mixed */ public function exec($ch, $method, $url, $options) { $self = $this; // set curl progress options curl_setopt($ch, CURLOPT_NOPROGRESS, 0); curl_setopt($ch, CURLOPT_PROGRESSFUNCTION, function ($download_size, $downloaded, $upload_size, $uploaded) use($ch, $url, $method, $options, $self) { // call $this->progress $self->progress($ch, $url, $method, $options, $download_size, $downloaded, $upload_size, $uploaded); }); // call chained curl_exec return ParseCurl::curl_exec($ch, $method, $url, $options, $this->exec); }
/** * Exec method called by ParseCurl * * @param $ch * @param $method * @param $url * @param $options * * @return mixed */ public function exec($ch, $method, $url, $options) { // Single object requests without additional parameters in query string if (!parse_url($url, PHP_URL_QUERY) && preg_match(':^/[0-9]+/classes/([^/]+)/([^/]+)$:', $path = parse_url($url, PHP_URL_PATH), $m)) { $cacheKey = $this->getCacheKey($className = $m[1], $objectId = $m[2]); // fetch a single object already in local storage if ($method == 'GET' && $this->cacheStorage->get($cacheKey)) { // restore curl_getinfo, curl_errno and curl_error ParseCurl::curl_setinfo_array($ch, $this->cacheStorage->get($cacheKey)['infos']); ParseCurl::curl_errno_set($ch, $this->cacheStorage->get($cacheKey)['errno']); ParseCurl::curl_error_set($ch, $this->cacheStorage->get($cacheKey)['error']); // return stored request result return $this->cacheStorage->get($cacheKey)['response']; } elseif ($method == 'GET') { // get chained curl_exec response $response = ParseCurl::curl_exec($ch, $method, $url, $options, $this->chainExecHandler); if (curl_errno($ch)) { throw new ParseException(curl_error($ch), curl_errno($ch)); } $contentType = curl_getinfo($ch, CURLINFO_CONTENT_TYPE); if (strpos($contentType, 'text/html') !== false) { throw new ParseException('Bad Request', -1); } // not in storage, fetch and store $this->cacheStorage->set($cacheKey, array('errno' => $errno = ParseCurl::curl_errno($ch), 'error' => $error = ParseCurl::curl_error($ch), 'infos' => $infos = ParseCurl::curl_getinfo($ch), 'response' => $response)); // return request result return $response; } elseif ($this->stor($cacheKey)) { // any other methods like POST, PUT, DELETE ... invalidate storage $this->cacheStorage->remove($cacheKey); } } elseif ($method == 'GET' && $this->cacheListObjects && preg_match(':^/[0-9]+/classes/([^/]+)$:', $path = parse_url($url, PHP_URL_PATH), $m)) { $className = $m[1]; // get chained curl_exec response $response = ParseCurl::curl_exec($ch, $method, $url, $options, $this->chainExecHandler); if (curl_errno($ch)) { throw new ParseException(curl_error($ch), curl_errno($ch)); } $contentType = curl_getinfo($ch, CURLINFO_CONTENT_TYPE); if (strpos($contentType, 'text/html') !== false) { throw new ParseException('Bad Request', -1); } $decoded = json_decode($response, true); if (isset($decoded['error'])) { throw new ParseException($decoded['error'], isset($decoded['code']) ? $decoded['code'] : 0); } if (array_key_exists('results', $decoded)) { foreach ($decoded['results'] as $result) { if (array_key_exists('objectId', $result)) { $this->cacheStorage->set($this->getCacheKey($className, $result['objectId']), array('errno' => $errno = ParseCurl::curl_errno($ch), 'error' => $error = ParseCurl::curl_error($ch), 'infos' => $infos = ParseCurl::curl_getinfo($ch), 'response' => json_encode($result))); } } } // return request result return $response; } // Call chained curl_exec return ParseCurl::curl_exec($ch, $method, $url, $options, $this->chainExecHandler); }