From 80ddb438c8098a34ecdfadd954353d676acab281 Mon Sep 17 00:00:00 2001 From: Jacek Kowalski <Jacek@jacekk.info> Date: Mon, 27 Aug 2012 18:19:56 +0000 Subject: [PATCH] Nowa klasa DownloadHelper, umożliwiająca pobieranie plików wraz z cache'owaniem. --- class/DownloadHelper.php | 181 +++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 181 insertions(+), 0 deletions(-) diff --git a/class/DownloadHelper.php b/class/DownloadHelper.php new file mode 100644 index 0000000..45cc866 --- /dev/null +++ b/class/DownloadHelper.php @@ -0,0 +1,181 @@ +<?php +class DownloadHelper { + protected $url; + protected $curl; + protected $headers = array(); + protected $data = NULL; + + protected $cacheDir = './cache/'; + protected $cacheFile; + protected $cacheInfo = array(); + + function build_url($components) { + return $components['scheme'].'://'.($components['user'] ? $components['user'].($components['pass'] ? ':'.$components['pass'] : '').'@' : '').$components['host'].($components['path'] ? $components['path'] : '/').($components['query'] ? '?'.$components['query'] : ''); + } + + function __construct($url) { + $this->url = parse_url($url); + if(!$this->url) { + throw new Exception('Parametr przekazywany do DownloadHelper::__construct() musi być poprawnym adresem URL.'); + } + + if($this->url['scheme'] != 'http' && $this->url['scheme'] != 'https') { + throw new Exception('Klasa DownloadHelper obsługuje tylko i wyłącznie protokoły HTTP i HTTPS.'); + } + + if(strlen($this->url['host']) == 0) { + throw new Exception('URL przekazany klasie DownloadHelper jest nieprawidłowy - brak nazwy hosta.'); + } + + $url = $this->build_url($this->url); + $this->cacheFile = $this->url['host'].'/'.$this->url['scheme'].'-'.sha1($url); + + $this->curl = curl_init($url); + } + + function setopt($option, $value) { + if($option == CURLOPT_HTTPHEADER) { + if(is_string($value)) { + $value = array($value); + } + + if(!is_array($value)) { + throw new Exception('Parametr przekazywany jako CURLOPT_HTTPHEADER musi być tablicą.'); + } + + $this->headers = array_merge($this->headers, $value); + } + + curl_setopt($this->curl, $option, $value); + } + + function setopt_array($options) { + if(!is_array($options)) { + throw new Exception('Parametr przekazywany do DownloadHelper::setopt_array() musi być tablicą.'); + } + + foreach($options as $option => $value) { + $this->setopt($option, $value); + } + } + + function cacheDir($directory) { + $this->cacheDir = $directory; + } + + function exec() { + if(!is_dir($this->cacheDir)) { + mkdir($this->cacheDir); + } + + if(!is_dir($this->cacheDir.$this->url['host'])) { + mkdir($this->cacheDir.$this->url['host']); + } + + // Sprawdź, czy są dane na temat pliku w cache... + if(is_file($this->cacheDir.$this->cacheFile.'-info')) { + $this->cacheInfo = unserialize(file_get_contents($this->cacheDir.$this->cacheFile.'-info')); + if(!$this->cacheInfo) { + $this->cacheInfo = array(); + } + } + else + { + if(is_file($this->cacheDir.$this->cacheFile)) { + unlink($this->cacheDir.$this->cacheFile); + } + } + + // Czy można wykorzystać cache... + if(isset($this->cacheInfo['cache']) && $this->cacheInfo['cache'] >= time()) { + if(is_file($this->cacheDir.$this->cacheFile)) { + return file_get_contents($this->cacheDir.$this->cacheFile); + } + else + { + return FALSE; + } + } + + // Nie można wykorzystać cache, sprawdź czy plik się zmienił... + if(isset($this->cacheInfo['last_seen'])) { + $this->headers[] = 'If-Modified-Since: '.date(DATE_RFC1123, $this->cacheInfo['last_seen']); + } + + if(count($this->headers) > 0) { + curl_setopt($this->curl, CURLOPT_HTTPHEADER, $this->headers); + } + curl_setopt($this->curl, CURLOPT_RETURNTRANSFER, TRUE); + + $this->return = curl_exec($this->curl); + + $this->cacheInfo['last_updated'] = time(); + $info = $this->getinfo(); + var_dump($info); + + if($info['http_code'] == '304') { + // Plik się nie zmienił... + $this->cacheInfo['last_seen'] = time(); + + if(is_file($this->cacheDir.$this->cacheFile)) { + $this->return = file_get_contents($this->cacheDir.$this->cacheFile); + } + else + { + $this->return = FALSE; + } + } + + return $this->return; + } + + function cacheFor($seconds) { + $this->cacheUntil(time() + $seconds); + } + + function cacheUntil($timestamp) { + if($timestamp >= time()) { + // Można cache'ować + $this->cacheInfo['cache'] = $timestamp; + } + else + { + if(isset($this->cacheInfo['cache'])) { + unset($this->cacheInfo['cache']); + } + } + + file_put_contents($this->cacheDir.$this->cacheFile.'-info', serialize($this->cacheInfo)); + + if($this->return === FALSE) { + // Usuń stary plik z cache - zapytanie nie powiodło się + if(is_file($this->cacheDir.$this->cacheFile)) { + unlink($this->cacheDir.$this->cacheFile); + } + } + elseif($this->return !== NULL) { + // Umieść w cache nowy plik... + $this->cacheInfo['last_seen'] = $this->cacheInfo['downloaded'] = time(); + file_put_contents($this->cacheDir.$this->cacheFile, $this->return); + } + } + + function invalidate() { + if(is_file($this->cacheDir.$this->cacheFile)) { + unlink($this->cacheDir.$this->cacheFile); + } + + if(is_file($this->cacheDir.$this->cacheFile.'-info')) { + unlink($this->cacheDir.$this->cacheFile.'-info'); + } + } + + function getinfo() { + return curl_getinfo($this->curl); + } + + function __destruct() { + curl_close($this->curl); + } +} +?> \ No newline at end of file -- Gitblit v1.9.1