Jacek Kowalski
2012-08-27 80ddb438c8098a34ecdfadd954353d676acab281
Nowa klasa DownloadHelper, umożliwiająca pobieranie plików wraz z cache'owaniem.
1 files added
181 ■■■■■ changed files
class/DownloadHelper.php 181 ●●●●● patch | view | raw | blame | history
class/DownloadHelper.php
New file
@@ -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);
    }
}
?>