diff --git a/check_setup.php b/check_setup.php index 056382e..9931a4f 100644 --- a/check_setup.php +++ b/check_setup.php @@ -38,9 +38,9 @@ if (! extension_loaded('pdo_sqlite')) { } // Check for curl -if (! function_exists('curl_init')) { +if (! function_exists('curl_init') || ! ini_get('allow_url_fopen')) { - die('PHP extension required: curl'); + die('You must have "allow_url_fopen=1" or curl extension installed'); } // Check if /data is writeable diff --git a/vendor/PicoDb/Table.php b/vendor/PicoDb/Table.php index 0275c8a..d592eaa 100644 --- a/vendor/PicoDb/Table.php +++ b/vendor/PicoDb/Table.php @@ -259,6 +259,25 @@ class Table } + public function orderBy($column) + { + if ($column[0] == '-') { + $order = 'DESC'; + } else { + $order = 'ASC'; + } + + if ($this->sql_order === '') { + $this->sql_order = ' ORDER BY '.$this->db->escapeIdentifier($column).' '.$order; + } + else { + $this->sql_order .= ', '.$this->db->escapeIdentifier($column).' '.$order; + } + + return $this; + } + + public function asc($column) { if ($this->sql_order === '') { @@ -410,4 +429,4 @@ class Table return $this; } -} \ No newline at end of file +} diff --git a/vendor/PicoFeed/Client.php b/vendor/PicoFeed/Client.php new file mode 100644 index 0000000..c5e75a7 --- /dev/null +++ b/vendor/PicoFeed/Client.php @@ -0,0 +1,139 @@ +url === '') { + throw new \LogicException('The URL is missing'); + } + + Logging::log('Fetch URL: '.$this->url); + Logging::log('Etag: '.$this->etag); + Logging::log('Last-Modified: '.$this->last_modified); + + $response = $this->doRequest(); + + if (is_array($response)) { + + if ($response['status'] == 304) { + $this->is_modified = false; + } + else { + $this->etag = isset($response['headers']['ETag']) ? $response['headers']['ETag'] : ''; + $this->last_modified = isset($response['headers']['Last-Modified']) ? $response['headers']['Last-Modified'] : ''; + $this->content = $response['body']; + } + } + } + + + public function parseHeaders(array $lines) + { + $status = 200; + $headers = array(); + + foreach ($lines as $line) { + + if (strpos($line, 'HTTP') === 0 && strpos($line, '301') === false && strpos($line, '302') === false) { + + $status = (int) substr($line, 9, 3); + } + else if (strpos($line, ':') !== false) { + + list($name, $value) = explode(': ', $line); + $headers[trim($name)] = trim($value); + } + } + + Logging::log('HTTP status code: '.$status); + + foreach ($headers as $name => $value) { + Logging::log('HTTP headers: '.$name.' => '.$value); + } + + return array($status, $headers); + } + + + public function setLastModified($last_modified) + { + $this->last_modified = $last_modified; + return $this; + } + + + public function getLastModified() + { + return $this->last_modified; + } + + + public function setEtag($etag) + { + $this->etag = $etag; + return $this; + } + + + public function getEtag() + { + return $this->etag; + } + + + public function getUrl() + { + return $this->url; + } + + + public function getContent() + { + return $this->content; + } + + + public function isModified() + { + return $this->is_modified; + } +} \ No newline at end of file diff --git a/vendor/PicoFeed/Clients/Curl.php b/vendor/PicoFeed/Clients/Curl.php new file mode 100644 index 0000000..d347cf7 --- /dev/null +++ b/vendor/PicoFeed/Clients/Curl.php @@ -0,0 +1,93 @@ +body_length += $length; + + if ($this->body_length > $this->max_body_size) return -1; + + $this->body .= $buffer; + + return $length; + } + + + public function readHeaders($ch, $buffer) + { + $length = strlen($buffer); + + if ($buffer === "\r\n") { + $this->headers_counter++; + } + else { + + if (! isset($this->headers[$this->headers_counter])) { + $this->headers[$this->headers_counter] = ''; + } + + $this->headers[$this->headers_counter] .= $buffer; + } + + return $length; + } + + + public function doRequest() + { + $request_headers = array('Connection: close'); + + if ($this->etag) $request_headers[] = 'If-None-Match: '.$this->etag; + if ($this->last_modified) $request_headers[] = 'If-Modified-Since: '.$this->last_modified; + + $ch = curl_init(); + + curl_setopt($ch, CURLOPT_URL, $this->url); + curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $this->timeout); + curl_setopt($ch, CURLOPT_TIMEOUT, $this->timeout); + curl_setopt($ch, CURLOPT_USERAGENT, $this->user_agent); + curl_setopt($ch, CURLOPT_HTTPHEADER, $request_headers); + curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); + curl_setopt($ch, CURLOPT_MAXREDIRS, $this->max_redirects); + curl_setopt($ch, CURLOPT_ENCODING, ''); + curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); // For auto-signed certificates... + curl_setopt($ch, CURLOPT_WRITEFUNCTION, array($this, 'readBody')); + curl_setopt($ch, CURLOPT_HEADERFUNCTION, array($this, 'readHeaders')); + curl_exec($ch); + + Logging::log('cURL total time: '.curl_getinfo($ch, CURLINFO_TOTAL_TIME)); + Logging::log('cURL dns lookup time: '.curl_getinfo($ch, CURLINFO_NAMELOOKUP_TIME)); + Logging::log('cURL connect time: '.curl_getinfo($ch, CURLINFO_CONNECT_TIME)); + Logging::log('cURL speed download: '.curl_getinfo($ch, CURLINFO_SPEED_DOWNLOAD)); + + if (curl_errno($ch)) { + + Logging::log('cURL error: '.curl_error($ch)); + + curl_close($ch); + return false; + } + + curl_close($ch); + + list($status, $headers) = $this->parseHeaders(explode("\r\n", $this->headers[$this->headers_counter - 1])); + + return array( + 'status' => $status, + 'body' => $this->body, + 'headers' => $headers + ); + } +} \ No newline at end of file diff --git a/vendor/PicoFeed/Clients/Stream.php b/vendor/PicoFeed/Clients/Stream.php new file mode 100644 index 0000000..de54d4f --- /dev/null +++ b/vendor/PicoFeed/Clients/Stream.php @@ -0,0 +1,56 @@ +user_agent, + ); + + if ($this->etag) $headers[] = 'If-None-Match: '.$this->etag; + if ($this->last_modified) $headers[] = 'If-Modified-Since: '.$this->last_modified; + + // Create context + $context_options = array( + 'http' => array( + 'method' => 'GET', + 'protocol_version' => 1.1, + 'timeout' => $this->timeout, + 'max_redirects' => $this->max_redirects, + 'header' => implode("\r\n", $headers) + ) + ); + + $context = stream_context_create($context_options); + + // Make HTTP request + $stream = @fopen($this->url, 'r', false, $context); + if (! is_resource($stream)) return false; + + // Get the entire body until the max size + $body = stream_get_contents($stream, $this->max_body_size + 1); + + // If the body size is too large abort everything + if (strlen($body) > $this->max_body_size) return false; + + // Get HTTP headers response + $metadata = stream_get_meta_data($stream); + + list($status, $headers) = $this->parseHeaders($metadata['wrapper_data']); + + fclose($stream); + + return array( + 'status' => $status, + 'body' => $body, + 'headers' => $headers + ); + } +} \ No newline at end of file diff --git a/vendor/PicoFeed/Reader.php b/vendor/PicoFeed/Reader.php index 56ea08b..282c6ff 100644 --- a/vendor/PicoFeed/Reader.php +++ b/vendor/PicoFeed/Reader.php @@ -4,7 +4,7 @@ namespace PicoFeed; require_once __DIR__.'/Logging.php'; require_once __DIR__.'/Parser.php'; -require_once __DIR__.'/RemoteResource.php'; +require_once __DIR__.'/Client.php'; class Reader { @@ -26,15 +26,18 @@ class Reader $url = 'http://'.$url; } - $resource = new RemoteResource($url, $timeout, $user_agent); - $resource->setLastModified($last_modified); - $resource->setEtag($etag); - $resource->execute(); + $client = Client::create(); + $client->url = $url; + $client->timeout = $timeout; + $client->user_agent = $user_agent; + $client->last_modified = $last_modified; + $client->etag = $etag; + $client->execute(); - $this->content = $resource->getContent(); - $this->url = $resource->getUrl(); + $this->content = $client->getContent(); + $this->url = $client->getUrl(); - return $resource; + return $client; }