Jacek Kowalski
2012-08-29 bf675d963ac9a34110d02d6d68259167396a4288
commit | author | age
80ddb4 1 <?php
JK 2 class DownloadHelper {
3     protected $url;
4     protected $curl;
5     protected $headers = array();
6     protected $data = NULL;
7     
8     protected $cacheDir = './cache/';
9     protected $cacheFile;
10     protected $cacheInfo = array();
11     
12     function build_url($components) {
13         return $components['scheme'].'://'.($components['user'] ? $components['user'].($components['pass'] ? ':'.$components['pass'] : '').'@' : '').$components['host'].($components['path'] ? $components['path'] : '/').($components['query'] ? '?'.$components['query'] : '');
14     }
15     
16     function __construct($url) {
17         $this->url = parse_url($url);
18         if(!$this->url) {
19             throw new Exception('Parametr przekazywany do DownloadHelper::__construct() musi być poprawnym adresem URL.');
20         }
21         
22         if($this->url['scheme'] != 'http' && $this->url['scheme'] != 'https') {
23             throw new Exception('Klasa DownloadHelper obsługuje tylko i wyłącznie protokoły HTTP i HTTPS.');
24         }
25         
26         if(strlen($this->url['host']) == 0) {
27             throw new Exception('URL przekazany klasie DownloadHelper jest nieprawidłowy - brak nazwy hosta.');
28         }
29         
30         $url = $this->build_url($this->url);
31         $this->cacheFile = $this->url['host'].'/'.$this->url['scheme'].'-'.sha1($url);
32         
33         $this->curl = curl_init($url);
34     }
35     
36     function setopt($option, $value) {
37         if($option == CURLOPT_HTTPHEADER) {
38             if(is_string($value)) {
39                 $value = array($value);
40             }
41             
42             if(!is_array($value)) {
43                 throw new Exception('Parametr przekazywany jako CURLOPT_HTTPHEADER musi być tablicą.');
44             }
45             
46             $this->headers = array_merge($this->headers, $value);
47         }
48         
49         curl_setopt($this->curl, $option, $value);
50     }
51     
52     function setopt_array($options) {
53         if(!is_array($options)) {
54             throw new Exception('Parametr przekazywany do DownloadHelper::setopt_array() musi być tablicą.');
55         }
56         
57         foreach($options as $option => $value) {
58             $this->setopt($option, $value);
59         }
60     }
61     
62     function cacheDir($directory) {
63         $this->cacheDir = $directory;
64     }
65     
66     function exec() {
67         if(!is_dir($this->cacheDir)) {
68             mkdir($this->cacheDir);
69         }
70         
71         if(!is_dir($this->cacheDir.$this->url['host'])) {
72             mkdir($this->cacheDir.$this->url['host']);
73         }
74         
75         // Sprawdź, czy są dane na temat pliku w cache...
76         if(is_file($this->cacheDir.$this->cacheFile.'-info')) {
77             $this->cacheInfo = unserialize(file_get_contents($this->cacheDir.$this->cacheFile.'-info'));
78             if(!$this->cacheInfo) {
79                 $this->cacheInfo = array();
80             }
81         }
82         else
83         {
84             if(is_file($this->cacheDir.$this->cacheFile)) {
85                 unlink($this->cacheDir.$this->cacheFile);
86             }
87         }
88         
89         // Czy można wykorzystać cache...
90         if(isset($this->cacheInfo['cache']) && $this->cacheInfo['cache'] >= time()) {
91             if(is_file($this->cacheDir.$this->cacheFile)) {
92                 return file_get_contents($this->cacheDir.$this->cacheFile);
93             }
94             else
95             {
96                 return FALSE;
97             }
98         }
99         
100         // Nie można wykorzystać cache, sprawdź czy plik się zmienił...
101         if(isset($this->cacheInfo['last_seen'])) {
102             $this->headers[] = 'If-Modified-Since: '.date(DATE_RFC1123, $this->cacheInfo['last_seen']);
103         }
104         
105         if(count($this->headers) > 0) {
106             curl_setopt($this->curl, CURLOPT_HTTPHEADER, $this->headers);
107         }
108         curl_setopt($this->curl, CURLOPT_RETURNTRANSFER, TRUE);
109         
110         $this->return = curl_exec($this->curl);
111         
112         $this->cacheInfo['last_updated'] = time();
113         $info = $this->getinfo();
114         var_dump($info);
115         
116         if($info['http_code'] == '304') {
117             // Plik się nie zmienił...
118             $this->cacheInfo['last_seen'] = time();
119             
120             if(is_file($this->cacheDir.$this->cacheFile)) {
121                 $this->return = file_get_contents($this->cacheDir.$this->cacheFile);
122             }
123             else
124             {
125                 $this->return = FALSE;
126             }
127         }
128         
129         return $this->return;
130     }
131     
132     function cacheFor($seconds) {
133         $this->cacheUntil(time() + $seconds);
134     }
135     
136     function cacheUntil($timestamp) {
137         if($timestamp >= time()) {
138             // Można cache'ować
139             $this->cacheInfo['cache'] = $timestamp;
140         }
141         else
142         {
143             if(isset($this->cacheInfo['cache'])) {
144                 unset($this->cacheInfo['cache']);
145             }
146         }
147         
148         file_put_contents($this->cacheDir.$this->cacheFile.'-info', serialize($this->cacheInfo));
149         
150         if($this->return === FALSE) {
151             // Usuń stary plik z cache - zapytanie nie powiodło się
152             if(is_file($this->cacheDir.$this->cacheFile)) {
153                 unlink($this->cacheDir.$this->cacheFile);
154             }
155         }
156         elseif($this->return !== NULL) {
157             // Umieść w cache nowy plik...
158             $this->cacheInfo['last_seen'] = $this->cacheInfo['downloaded'] = time();
159             file_put_contents($this->cacheDir.$this->cacheFile, $this->return);
160         }
161     }
162     
163     function invalidate() {
164         if(is_file($this->cacheDir.$this->cacheFile)) {
165             unlink($this->cacheDir.$this->cacheFile);
166         }
167         
168         if(is_file($this->cacheDir.$this->cacheFile.'-info')) {
169             unlink($this->cacheDir.$this->cacheFile.'-info');
170         }
171     }
172     
173     function getinfo() {
174         return curl_getinfo($this->curl);
175     }
176     
177     function __destruct() {
178         curl_close($this->curl);
179     }
180 }
181 ?>