|
1 <?php |
|
2 /** |
|
3 * Zend Framework |
|
4 * |
|
5 * LICENSE |
|
6 * |
|
7 * This source file is subject to the new BSD license that is bundled |
|
8 * with this package in the file LICENSE.txt. |
|
9 * It is also available through the world-wide-web at this URL: |
|
10 * http://framework.zend.com/license/new-bsd |
|
11 * If you did not receive a copy of the license and are unable to |
|
12 * obtain it through the world-wide-web, please send an email |
|
13 * to license@zend.com so we can send you a copy immediately. |
|
14 * |
|
15 * @category Zend |
|
16 * @package Zend_Search_Lucene |
|
17 * @subpackage Storage |
|
18 * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com) |
|
19 * @license http://framework.zend.com/license/new-bsd New BSD License |
|
20 * @version $Id: Filesystem.php 20096 2010-01-06 02:05:09Z bkarwin $ |
|
21 */ |
|
22 |
|
23 |
|
24 /** Zend_Search_Lucene_Storage_Directory */ |
|
25 require_once 'Zend/Search/Lucene/Storage/Directory.php'; |
|
26 |
|
27 |
|
28 /** |
|
29 * FileSystem implementation of Directory abstraction. |
|
30 * |
|
31 * @category Zend |
|
32 * @package Zend_Search_Lucene |
|
33 * @subpackage Storage |
|
34 * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com) |
|
35 * @license http://framework.zend.com/license/new-bsd New BSD License |
|
36 */ |
|
37 class Zend_Search_Lucene_Storage_Directory_Filesystem extends Zend_Search_Lucene_Storage_Directory |
|
38 { |
|
39 /** |
|
40 * Filesystem path to the directory |
|
41 * |
|
42 * @var string |
|
43 */ |
|
44 protected $_dirPath = null; |
|
45 |
|
46 /** |
|
47 * Cache for Zend_Search_Lucene_Storage_File_Filesystem objects |
|
48 * Array: filename => Zend_Search_Lucene_Storage_File object |
|
49 * |
|
50 * @var array |
|
51 * @throws Zend_Search_Lucene_Exception |
|
52 */ |
|
53 protected $_fileHandlers; |
|
54 |
|
55 /** |
|
56 * Default file permissions |
|
57 * |
|
58 * @var integer |
|
59 */ |
|
60 protected static $_defaultFilePermissions = 0666; |
|
61 |
|
62 |
|
63 /** |
|
64 * Get default file permissions |
|
65 * |
|
66 * @return integer |
|
67 */ |
|
68 public static function getDefaultFilePermissions() |
|
69 { |
|
70 return self::$_defaultFilePermissions; |
|
71 } |
|
72 |
|
73 /** |
|
74 * Set default file permissions |
|
75 * |
|
76 * @param integer $mode |
|
77 */ |
|
78 public static function setDefaultFilePermissions($mode) |
|
79 { |
|
80 self::$_defaultFilePermissions = $mode; |
|
81 } |
|
82 |
|
83 |
|
84 /** |
|
85 * Utility function to recursive directory creation |
|
86 * |
|
87 * @param string $dir |
|
88 * @param integer $mode |
|
89 * @param boolean $recursive |
|
90 * @return boolean |
|
91 */ |
|
92 |
|
93 public static function mkdirs($dir, $mode = 0777, $recursive = true) |
|
94 { |
|
95 if (($dir === null) || $dir === '') { |
|
96 return false; |
|
97 } |
|
98 if (is_dir($dir) || $dir === '/') { |
|
99 return true; |
|
100 } |
|
101 if (self::mkdirs(dirname($dir), $mode, $recursive)) { |
|
102 return mkdir($dir, $mode); |
|
103 } |
|
104 return false; |
|
105 } |
|
106 |
|
107 |
|
108 /** |
|
109 * Object constructor |
|
110 * Checks if $path is a directory or tries to create it. |
|
111 * |
|
112 * @param string $path |
|
113 * @throws Zend_Search_Lucene_Exception |
|
114 */ |
|
115 public function __construct($path) |
|
116 { |
|
117 if (!is_dir($path)) { |
|
118 if (file_exists($path)) { |
|
119 require_once 'Zend/Search/Lucene/Exception.php'; |
|
120 throw new Zend_Search_Lucene_Exception('Path exists, but it\'s not a directory'); |
|
121 } else { |
|
122 if (!self::mkdirs($path)) { |
|
123 require_once 'Zend/Search/Lucene/Exception.php'; |
|
124 throw new Zend_Search_Lucene_Exception("Can't create directory '$path'."); |
|
125 } |
|
126 } |
|
127 } |
|
128 $this->_dirPath = $path; |
|
129 $this->_fileHandlers = array(); |
|
130 } |
|
131 |
|
132 |
|
133 /** |
|
134 * Closes the store. |
|
135 * |
|
136 * @return void |
|
137 */ |
|
138 public function close() |
|
139 { |
|
140 foreach ($this->_fileHandlers as $fileObject) { |
|
141 $fileObject->close(); |
|
142 } |
|
143 |
|
144 $this->_fileHandlers = array(); |
|
145 } |
|
146 |
|
147 |
|
148 /** |
|
149 * Returns an array of strings, one for each file in the directory. |
|
150 * |
|
151 * @return array |
|
152 */ |
|
153 public function fileList() |
|
154 { |
|
155 $result = array(); |
|
156 |
|
157 $dirContent = opendir( $this->_dirPath ); |
|
158 while (($file = readdir($dirContent)) !== false) { |
|
159 if (($file == '..')||($file == '.')) continue; |
|
160 |
|
161 if( !is_dir($this->_dirPath . '/' . $file) ) { |
|
162 $result[] = $file; |
|
163 } |
|
164 } |
|
165 closedir($dirContent); |
|
166 |
|
167 return $result; |
|
168 } |
|
169 |
|
170 /** |
|
171 * Creates a new, empty file in the directory with the given $filename. |
|
172 * |
|
173 * @param string $filename |
|
174 * @return Zend_Search_Lucene_Storage_File |
|
175 * @throws Zend_Search_Lucene_Exception |
|
176 */ |
|
177 public function createFile($filename) |
|
178 { |
|
179 if (isset($this->_fileHandlers[$filename])) { |
|
180 $this->_fileHandlers[$filename]->close(); |
|
181 } |
|
182 unset($this->_fileHandlers[$filename]); |
|
183 require_once 'Zend/Search/Lucene/Storage/File/Filesystem.php'; |
|
184 $this->_fileHandlers[$filename] = new Zend_Search_Lucene_Storage_File_Filesystem($this->_dirPath . '/' . $filename, 'w+b'); |
|
185 |
|
186 // Set file permissions, but don't care about any possible failures, since file may be already |
|
187 // created by anther user which has to care about right permissions |
|
188 @chmod($this->_dirPath . '/' . $filename, self::$_defaultFilePermissions); |
|
189 |
|
190 return $this->_fileHandlers[$filename]; |
|
191 } |
|
192 |
|
193 |
|
194 /** |
|
195 * Removes an existing $filename in the directory. |
|
196 * |
|
197 * @param string $filename |
|
198 * @return void |
|
199 * @throws Zend_Search_Lucene_Exception |
|
200 */ |
|
201 public function deleteFile($filename) |
|
202 { |
|
203 if (isset($this->_fileHandlers[$filename])) { |
|
204 $this->_fileHandlers[$filename]->close(); |
|
205 } |
|
206 unset($this->_fileHandlers[$filename]); |
|
207 |
|
208 global $php_errormsg; |
|
209 $trackErrors = ini_get('track_errors'); ini_set('track_errors', '1'); |
|
210 if (!@unlink($this->_dirPath . '/' . $filename)) { |
|
211 ini_set('track_errors', $trackErrors); |
|
212 require_once 'Zend/Search/Lucene/Exception.php'; |
|
213 throw new Zend_Search_Lucene_Exception('Can\'t delete file: ' . $php_errormsg); |
|
214 } |
|
215 ini_set('track_errors', $trackErrors); |
|
216 } |
|
217 |
|
218 /** |
|
219 * Purge file if it's cached by directory object |
|
220 * |
|
221 * Method is used to prevent 'too many open files' error |
|
222 * |
|
223 * @param string $filename |
|
224 * @return void |
|
225 */ |
|
226 public function purgeFile($filename) |
|
227 { |
|
228 if (isset($this->_fileHandlers[$filename])) { |
|
229 $this->_fileHandlers[$filename]->close(); |
|
230 } |
|
231 unset($this->_fileHandlers[$filename]); |
|
232 } |
|
233 |
|
234 |
|
235 /** |
|
236 * Returns true if a file with the given $filename exists. |
|
237 * |
|
238 * @param string $filename |
|
239 * @return boolean |
|
240 */ |
|
241 public function fileExists($filename) |
|
242 { |
|
243 return isset($this->_fileHandlers[$filename]) || |
|
244 file_exists($this->_dirPath . '/' . $filename); |
|
245 } |
|
246 |
|
247 |
|
248 /** |
|
249 * Returns the length of a $filename in the directory. |
|
250 * |
|
251 * @param string $filename |
|
252 * @return integer |
|
253 */ |
|
254 public function fileLength($filename) |
|
255 { |
|
256 if (isset( $this->_fileHandlers[$filename] )) { |
|
257 return $this->_fileHandlers[$filename]->size(); |
|
258 } |
|
259 return filesize($this->_dirPath .'/'. $filename); |
|
260 } |
|
261 |
|
262 |
|
263 /** |
|
264 * Returns the UNIX timestamp $filename was last modified. |
|
265 * |
|
266 * @param string $filename |
|
267 * @return integer |
|
268 */ |
|
269 public function fileModified($filename) |
|
270 { |
|
271 return filemtime($this->_dirPath .'/'. $filename); |
|
272 } |
|
273 |
|
274 |
|
275 /** |
|
276 * Renames an existing file in the directory. |
|
277 * |
|
278 * @param string $from |
|
279 * @param string $to |
|
280 * @return void |
|
281 * @throws Zend_Search_Lucene_Exception |
|
282 */ |
|
283 public function renameFile($from, $to) |
|
284 { |
|
285 global $php_errormsg; |
|
286 |
|
287 if (isset($this->_fileHandlers[$from])) { |
|
288 $this->_fileHandlers[$from]->close(); |
|
289 } |
|
290 unset($this->_fileHandlers[$from]); |
|
291 |
|
292 if (isset($this->_fileHandlers[$to])) { |
|
293 $this->_fileHandlers[$to]->close(); |
|
294 } |
|
295 unset($this->_fileHandlers[$to]); |
|
296 |
|
297 if (file_exists($this->_dirPath . '/' . $to)) { |
|
298 if (!unlink($this->_dirPath . '/' . $to)) { |
|
299 require_once 'Zend/Search/Lucene/Exception.php'; |
|
300 throw new Zend_Search_Lucene_Exception('Delete operation failed'); |
|
301 } |
|
302 } |
|
303 |
|
304 $trackErrors = ini_get('track_errors'); |
|
305 ini_set('track_errors', '1'); |
|
306 |
|
307 $success = @rename($this->_dirPath . '/' . $from, $this->_dirPath . '/' . $to); |
|
308 if (!$success) { |
|
309 ini_set('track_errors', $trackErrors); |
|
310 require_once 'Zend/Search/Lucene/Exception.php'; |
|
311 throw new Zend_Search_Lucene_Exception($php_errormsg); |
|
312 } |
|
313 |
|
314 ini_set('track_errors', $trackErrors); |
|
315 |
|
316 return $success; |
|
317 } |
|
318 |
|
319 |
|
320 /** |
|
321 * Sets the modified time of $filename to now. |
|
322 * |
|
323 * @param string $filename |
|
324 * @return void |
|
325 */ |
|
326 public function touchFile($filename) |
|
327 { |
|
328 return touch($this->_dirPath .'/'. $filename); |
|
329 } |
|
330 |
|
331 |
|
332 /** |
|
333 * Returns a Zend_Search_Lucene_Storage_File object for a given $filename in the directory. |
|
334 * |
|
335 * If $shareHandler option is true, then file handler can be shared between File Object |
|
336 * requests. It speed-ups performance, but makes problems with file position. |
|
337 * Shared handler are good for short atomic requests. |
|
338 * Non-shared handlers are useful for stream file reading (especial for compound files). |
|
339 * |
|
340 * @param string $filename |
|
341 * @param boolean $shareHandler |
|
342 * @return Zend_Search_Lucene_Storage_File |
|
343 */ |
|
344 public function getFileObject($filename, $shareHandler = true) |
|
345 { |
|
346 $fullFilename = $this->_dirPath . '/' . $filename; |
|
347 |
|
348 require_once 'Zend/Search/Lucene/Storage/File/Filesystem.php'; |
|
349 if (!$shareHandler) { |
|
350 return new Zend_Search_Lucene_Storage_File_Filesystem($fullFilename); |
|
351 } |
|
352 |
|
353 if (isset( $this->_fileHandlers[$filename] )) { |
|
354 $this->_fileHandlers[$filename]->seek(0); |
|
355 return $this->_fileHandlers[$filename]; |
|
356 } |
|
357 |
|
358 $this->_fileHandlers[$filename] = new Zend_Search_Lucene_Storage_File_Filesystem($fullFilename); |
|
359 return $this->_fileHandlers[$filename]; |
|
360 } |
|
361 } |
|
362 |