$value) { if (!empty($_data_raw)) { $_data_raw .= '&'; } $_data_raw .= urlencode($key) . '=' . urlencode($value); } return $_data_raw; } /** * A single request, without following redirects * * @todo: Handle redirects? If so, only for GET (i.e. not for POST), and use G2's * WebHelper_simple::_parseLocation logic. */ static function do_request($url, $method='GET', $headers=array(), $body='') { /* Convert illegal characters */ $url = str_replace(' ', '%20', $url); $url_components = self::_parse_url_for_fsockopen($url); $handle = fsockopen( $url_components['fsockhost'], $url_components['port'], $errno, $errstr, 5); if (empty($handle)) { return array(null, null, null); } $header_lines = array('Host: ' . $url_components['host']); foreach ($headers as $key => $value) { $header_lines[] = $key . ': ' . $value; } $success = fwrite($handle, sprintf("%s %s HTTP/1.0\r\n%s\r\n\r\n%s", $method, $url_components['uri'], implode("\r\n", $header_lines), $body)); if (!$success) { // Zero bytes written or false was returned // log "fwrite failed in requestWebPage($url)" . ($success === false ? ' - false' : '' return array(null, null, null); } fflush($handle); /* * Read the status line. fgets stops after newlines. The first line is the protocol * version followed by a numeric status code and its associated textual phrase. */ $response_status = trim(fgets($handle, 4096)); if (empty($response_status)) { // 'Empty http response code, maybe timeout' return array(null, null, null); } /* Read the headers */ $response_headers = array(); while (!feof($handle)) { $line = trim(fgets($handle, 4096)); if (empty($line)) { break; } /* Normalize the line endings */ $line = str_replace("\r", '', $line); list ($key, $value) = explode(':', $line, 2); if (isset($response_headers[$key])) { if (!is_array($response_headers[$key])) { $response_headers[$key] = array($response_headers[$key]); } $response_headers[$key][] = trim($value); } else { $response_headers[$key] = trim($value); } } /* Read the body */ $response_body = ''; while (!feof($handle)) { $response_body .= fread($handle, 4096); } fclose($handle); return array($response_status, $response_headers, $response_body); } /** * Prepare for fsockopen call. * @param string $url * @return array url components * @access private */ private static function _parse_url_for_fsockopen($url) { $url_components = parse_url($url); if (strtolower($url_components['scheme']) == 'https') { $url_components['fsockhost'] = 'ssl://' . $url_components['host']; $default_port = 443; } else { $url_components['fsockhost'] = $url_components['host']; $default_port = 80; } if (empty($url_components['port'])) { $url_components['port'] = $default_port; } if (empty($url_components['path'])) { $url_components['path'] = '/'; } $uri = $url_components['path'] . (empty($url_components['query']) ? '' : '?' . $url_components['query']); /* Unescape ampersands, since if the url comes from form input it will be escaped */ $url_components['uri'] = str_replace('&', '&', $uri); return $url_components; } } // This class does not depend on any Kohana services so that it can be used in non-Kohana // applications. class G3Remote { protected static $_instance; protected $_config; private $_resources; private $_access_token; public static function instance($access_token=null) { if (!isset(G3Remote::$_instance)) { G3Remote::$_instance = new G3Remote($access_token); } return G3Remote::$_instance; } /** * Constructs a new G3Remote object * * @param array Database config array * @return G3Remote */ protected function __construct($access_token) { // Store the config locally $this->_config = Kohana::config("g3_remote"); $this->_access_token = $access_token; } public function get_access_token($user, $password) { $request = "{$this->_config["gallery3_site"]}/access_key"; list ($response_status, $response_headers, $response_body) = url_connection::get($request, array("user" => $user, "password" => $password)); if (url_connection::success($response_status)) { $response = json_decode($response_body); if ($response->status == "OK") { $this->_access_token = $response->token; $this->_identity = $identity; } else { throw new Exception("Remote host failure: {$response->message}"); } } else { throw new Exception("Remote host failure: $response_status"); } return $this->_access_token; } public function get_resource($path, $filter=false, $offset=false, $limit=false) { $request = "{$this->_config["gallery3_site"]}/$path"; $params = array(); if ($filter) { $param["filter"] = $filter; } if ($offset) { $param["offset"] = $offset; } if ($limit) { $param["limit"] = $limit; } $headers = array(); if (!empty($this->_access_token)) { $headers["X_GALLERY_REQUEST_KEY"] = $this->_access_token; } list ($response_status, $response_headers, $response_body) = url_connection::get($request, $params, $headers); if (url_connection::success($response_status)) { $response = json_decode($response_body); if ($response->status != "OK") { throw new Exception("Remote host failure: {$response->message}"); } } else { throw new Exception("Remote host failure: $response_status"); } return $response->resource; } public function delete_resource($path) { $request = "{$this->_config["gallery3_site"]}/$path"; $headers["X_GALLERY_REQUEST_METHOD"] = "DELETE"; Kohana_Log::add("error", "access_token: " . $this->_access_token); if (!empty($this->_access_token)) { $headers["X_GALLERY_REQUEST_KEY"] = $this->_access_token; } list ($response_status, $response_headers, $response_body) = url_connection::post($request, array(), $headers); if (url_connection::success($response_status)) { $response = json_decode($response_body); if ($response->status != "OK") { throw new Exception("Remote host failure: {$response->message}"); } } else { throw new Exception("Remote host failure: $response_status"); } return "success"; } }