Mercurial > hg > Members > shoshi > webvirt
comparison cake/libs/file.php @ 0:261e66bd5a0c
hg init
author | Shoshi TAMAKI <shoshi@cr.ie.u-ryukyu.ac.jp> |
---|---|
date | Sun, 24 Jul 2011 21:08:31 +0900 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:261e66bd5a0c |
---|---|
1 <?php | |
2 /** | |
3 * Convenience class for reading, writing and appending to files. | |
4 * | |
5 * PHP versions 4 and 5 | |
6 * | |
7 * CakePHP(tm) : Rapid Development Framework (http://cakephp.org) | |
8 * Copyright 2005-2010, Cake Software Foundation, Inc. (http://cakefoundation.org) | |
9 * | |
10 * Licensed under The MIT License | |
11 * Redistributions of files must retain the above copyright notice. | |
12 * | |
13 * @copyright Copyright 2005-2010, Cake Software Foundation, Inc. (http://cakefoundation.org) | |
14 * @link http://cakephp.org CakePHP(tm) Project | |
15 * @package cake | |
16 * @subpackage cake.cake.libs | |
17 * @since CakePHP(tm) v 0.2.9 | |
18 * @license MIT License (http://www.opensource.org/licenses/mit-license.php) | |
19 */ | |
20 | |
21 /** | |
22 * Included libraries. | |
23 * | |
24 */ | |
25 if (!class_exists('Object')) { | |
26 require LIBS . 'object.php'; | |
27 } | |
28 if (!class_exists('Folder')) { | |
29 require LIBS . 'folder.php'; | |
30 } | |
31 | |
32 /** | |
33 * Convenience class for reading, writing and appending to files. | |
34 * | |
35 * @package cake | |
36 * @subpackage cake.cake.libs | |
37 */ | |
38 class File extends Object { | |
39 | |
40 /** | |
41 * Folder object of the File | |
42 * | |
43 * @var Folder | |
44 * @access public | |
45 */ | |
46 var $Folder = null; | |
47 | |
48 /** | |
49 * Filename | |
50 * | |
51 * @var string | |
52 * @access public | |
53 */ | |
54 var $name = null; | |
55 | |
56 /** | |
57 * file info | |
58 * | |
59 * @var string | |
60 * @access public | |
61 */ | |
62 var $info = array(); | |
63 | |
64 /** | |
65 * Holds the file handler resource if the file is opened | |
66 * | |
67 * @var resource | |
68 * @access public | |
69 */ | |
70 var $handle = null; | |
71 | |
72 /** | |
73 * enable locking for file reading and writing | |
74 * | |
75 * @var boolean | |
76 * @access public | |
77 */ | |
78 var $lock = null; | |
79 | |
80 /** | |
81 * path property | |
82 * | |
83 * Current file's absolute path | |
84 * | |
85 * @var mixed null | |
86 * @access public | |
87 */ | |
88 var $path = null; | |
89 | |
90 /** | |
91 * Constructor | |
92 * | |
93 * @param string $path Path to file | |
94 * @param boolean $create Create file if it does not exist (if true) | |
95 * @param integer $mode Mode to apply to the folder holding the file | |
96 */ | |
97 function __construct($path, $create = false, $mode = 0755) { | |
98 parent::__construct(); | |
99 $this->Folder =& new Folder(dirname($path), $create, $mode); | |
100 if (!is_dir($path)) { | |
101 $this->name = basename($path); | |
102 } | |
103 $this->pwd(); | |
104 $create && !$this->exists() && $this->safe($path) && $this->create(); | |
105 } | |
106 | |
107 /** | |
108 * Closes the current file if it is opened | |
109 * | |
110 */ | |
111 function __destruct() { | |
112 $this->close(); | |
113 } | |
114 | |
115 /** | |
116 * Creates the File. | |
117 * | |
118 * @return boolean Success | |
119 * @access public | |
120 */ | |
121 function create() { | |
122 $dir = $this->Folder->pwd(); | |
123 if (is_dir($dir) && is_writable($dir) && !$this->exists()) { | |
124 $old = umask(0); | |
125 if (touch($this->path)) { | |
126 umask($old); | |
127 return true; | |
128 } | |
129 } | |
130 return false; | |
131 } | |
132 | |
133 /** | |
134 * Opens the current file with a given $mode | |
135 * | |
136 * @param string $mode A valid 'fopen' mode string (r|w|a ...) | |
137 * @param boolean $force If true then the file will be re-opened even if its already opened, otherwise it won't | |
138 * @return boolean True on success, false on failure | |
139 * @access public | |
140 */ | |
141 function open($mode = 'r', $force = false) { | |
142 if (!$force && is_resource($this->handle)) { | |
143 return true; | |
144 } | |
145 clearstatcache(); | |
146 if ($this->exists() === false) { | |
147 if ($this->create() === false) { | |
148 return false; | |
149 } | |
150 } | |
151 | |
152 $this->handle = fopen($this->path, $mode); | |
153 if (is_resource($this->handle)) { | |
154 return true; | |
155 } | |
156 return false; | |
157 } | |
158 | |
159 /** | |
160 * Return the contents of this File as a string. | |
161 * | |
162 * @param string $bytes where to start | |
163 * @param string $mode A `fread` compatible mode. | |
164 * @param boolean $force If true then the file will be re-opened even if its already opened, otherwise it won't | |
165 * @return mixed string on success, false on failure | |
166 * @access public | |
167 */ | |
168 function read($bytes = false, $mode = 'rb', $force = false) { | |
169 if ($bytes === false && $this->lock === null) { | |
170 return file_get_contents($this->path); | |
171 } | |
172 if ($this->open($mode, $force) === false) { | |
173 return false; | |
174 } | |
175 if ($this->lock !== null && flock($this->handle, LOCK_SH) === false) { | |
176 return false; | |
177 } | |
178 if (is_int($bytes)) { | |
179 return fread($this->handle, $bytes); | |
180 } | |
181 | |
182 $data = ''; | |
183 while (!feof($this->handle)) { | |
184 $data .= fgets($this->handle, 4096); | |
185 } | |
186 | |
187 if ($this->lock !== null) { | |
188 flock($this->handle, LOCK_UN); | |
189 } | |
190 if ($bytes === false) { | |
191 $this->close(); | |
192 } | |
193 return trim($data); | |
194 } | |
195 | |
196 /** | |
197 * Sets or gets the offset for the currently opened file. | |
198 * | |
199 * @param mixed $offset The $offset in bytes to seek. If set to false then the current offset is returned. | |
200 * @param integer $seek PHP Constant SEEK_SET | SEEK_CUR | SEEK_END determining what the $offset is relative to | |
201 * @return mixed True on success, false on failure (set mode), false on failure or integer offset on success (get mode) | |
202 * @access public | |
203 */ | |
204 function offset($offset = false, $seek = SEEK_SET) { | |
205 if ($offset === false) { | |
206 if (is_resource($this->handle)) { | |
207 return ftell($this->handle); | |
208 } | |
209 } elseif ($this->open() === true) { | |
210 return fseek($this->handle, $offset, $seek) === 0; | |
211 } | |
212 return false; | |
213 } | |
214 | |
215 /** | |
216 * Prepares a ascii string for writing. Converts line endings to the | |
217 * correct terminator for the current platform. If windows "\r\n" will be used | |
218 * all other platforms will use "\n" | |
219 * | |
220 * @param string $data Data to prepare for writing. | |
221 * @return string The with converted line endings. | |
222 * @access public | |
223 */ | |
224 function prepare($data, $forceWindows = false) { | |
225 $lineBreak = "\n"; | |
226 if (DIRECTORY_SEPARATOR == '\\' || $forceWindows === true) { | |
227 $lineBreak = "\r\n"; | |
228 } | |
229 return strtr($data, array("\r\n" => $lineBreak, "\n" => $lineBreak, "\r" => $lineBreak)); | |
230 } | |
231 | |
232 /** | |
233 * Write given data to this File. | |
234 * | |
235 * @param string $data Data to write to this File. | |
236 * @param string $mode Mode of writing. {@link http://php.net/fwrite See fwrite()}. | |
237 * @param string $force force the file to open | |
238 * @return boolean Success | |
239 * @access public | |
240 */ | |
241 function write($data, $mode = 'w', $force = false) { | |
242 $success = false; | |
243 if ($this->open($mode, $force) === true) { | |
244 if ($this->lock !== null) { | |
245 if (flock($this->handle, LOCK_EX) === false) { | |
246 return false; | |
247 } | |
248 } | |
249 | |
250 if (fwrite($this->handle, $data) !== false) { | |
251 $success = true; | |
252 } | |
253 if ($this->lock !== null) { | |
254 flock($this->handle, LOCK_UN); | |
255 } | |
256 } | |
257 return $success; | |
258 } | |
259 | |
260 /** | |
261 * Append given data string to this File. | |
262 * | |
263 * @param string $data Data to write | |
264 * @param string $force force the file to open | |
265 * @return boolean Success | |
266 * @access public | |
267 */ | |
268 function append($data, $force = false) { | |
269 return $this->write($data, 'a', $force); | |
270 } | |
271 | |
272 /** | |
273 * Closes the current file if it is opened. | |
274 * | |
275 * @return boolean True if closing was successful or file was already closed, otherwise false | |
276 * @access public | |
277 */ | |
278 function close() { | |
279 if (!is_resource($this->handle)) { | |
280 return true; | |
281 } | |
282 return fclose($this->handle); | |
283 } | |
284 | |
285 /** | |
286 * Deletes the File. | |
287 * | |
288 * @return boolean Success | |
289 * @access public | |
290 */ | |
291 function delete() { | |
292 clearstatcache(); | |
293 if ($this->exists()) { | |
294 return unlink($this->path); | |
295 } | |
296 return false; | |
297 } | |
298 | |
299 /** | |
300 * Returns the File info. | |
301 * | |
302 * @return string The File extension | |
303 * @access public | |
304 */ | |
305 function info() { | |
306 if ($this->info == null) { | |
307 $this->info = pathinfo($this->path); | |
308 } | |
309 if (!isset($this->info['filename'])) { | |
310 $this->info['filename'] = $this->name(); | |
311 } | |
312 return $this->info; | |
313 } | |
314 | |
315 /** | |
316 * Returns the File extension. | |
317 * | |
318 * @return string The File extension | |
319 * @access public | |
320 */ | |
321 function ext() { | |
322 if ($this->info == null) { | |
323 $this->info(); | |
324 } | |
325 if (isset($this->info['extension'])) { | |
326 return $this->info['extension']; | |
327 } | |
328 return false; | |
329 } | |
330 | |
331 /** | |
332 * Returns the File name without extension. | |
333 * | |
334 * @return string The File name without extension. | |
335 * @access public | |
336 */ | |
337 function name() { | |
338 if ($this->info == null) { | |
339 $this->info(); | |
340 } | |
341 if (isset($this->info['extension'])) { | |
342 return basename($this->name, '.'.$this->info['extension']); | |
343 } elseif ($this->name) { | |
344 return $this->name; | |
345 } | |
346 return false; | |
347 } | |
348 | |
349 /** | |
350 * makes filename safe for saving | |
351 * | |
352 * @param string $name The name of the file to make safe if different from $this->name | |
353 * @param strin $ext The name of the extension to make safe if different from $this->ext | |
354 * @return string $ext the extension of the file | |
355 * @access public | |
356 */ | |
357 function safe($name = null, $ext = null) { | |
358 if (!$name) { | |
359 $name = $this->name; | |
360 } | |
361 if (!$ext) { | |
362 $ext = $this->ext(); | |
363 } | |
364 return preg_replace( "/(?:[^\w\.-]+)/", "_", basename($name, $ext)); | |
365 } | |
366 | |
367 /** | |
368 * Get md5 Checksum of file with previous check of Filesize | |
369 * | |
370 * @param mixed $maxsize in MB or true to force | |
371 * @return string md5 Checksum {@link http://php.net/md5_file See md5_file()} | |
372 * @access public | |
373 */ | |
374 function md5($maxsize = 5) { | |
375 if ($maxsize === true) { | |
376 return md5_file($this->path); | |
377 } | |
378 | |
379 $size = $this->size(); | |
380 if ($size && $size < ($maxsize * 1024) * 1024) { | |
381 return md5_file($this->path); | |
382 } | |
383 | |
384 return false; | |
385 } | |
386 | |
387 /** | |
388 * Returns the full path of the File. | |
389 * | |
390 * @return string Full path to file | |
391 * @access public | |
392 */ | |
393 function pwd() { | |
394 if (is_null($this->path)) { | |
395 $this->path = $this->Folder->slashTerm($this->Folder->pwd()) . $this->name; | |
396 } | |
397 return $this->path; | |
398 } | |
399 | |
400 /** | |
401 * Returns true if the File exists. | |
402 * | |
403 * @return boolean true if it exists, false otherwise | |
404 * @access public | |
405 */ | |
406 function exists() { | |
407 return (file_exists($this->path) && is_file($this->path)); | |
408 } | |
409 | |
410 /** | |
411 * Returns the "chmod" (permissions) of the File. | |
412 * | |
413 * @return string Permissions for the file | |
414 * @access public | |
415 */ | |
416 function perms() { | |
417 if ($this->exists()) { | |
418 return substr(sprintf('%o', fileperms($this->path)), -4); | |
419 } | |
420 return false; | |
421 } | |
422 | |
423 /** | |
424 * Returns the Filesize | |
425 * | |
426 * @return integer size of the file in bytes, or false in case of an error | |
427 * @access public | |
428 */ | |
429 function size() { | |
430 if ($this->exists()) { | |
431 return filesize($this->path); | |
432 } | |
433 return false; | |
434 } | |
435 | |
436 /** | |
437 * Returns true if the File is writable. | |
438 * | |
439 * @return boolean true if its writable, false otherwise | |
440 * @access public | |
441 */ | |
442 function writable() { | |
443 return is_writable($this->path); | |
444 } | |
445 | |
446 /** | |
447 * Returns true if the File is executable. | |
448 * | |
449 * @return boolean true if its executable, false otherwise | |
450 * @access public | |
451 */ | |
452 function executable() { | |
453 return is_executable($this->path); | |
454 } | |
455 | |
456 /** | |
457 * Returns true if the File is readable. | |
458 * | |
459 * @return boolean true if file is readable, false otherwise | |
460 * @access public | |
461 */ | |
462 function readable() { | |
463 return is_readable($this->path); | |
464 } | |
465 | |
466 /** | |
467 * Returns the File's owner. | |
468 * | |
469 * @return integer the Fileowner | |
470 * @access public | |
471 */ | |
472 function owner() { | |
473 if ($this->exists()) { | |
474 return fileowner($this->path); | |
475 } | |
476 return false; | |
477 } | |
478 | |
479 /** | |
480 * Returns the File's group. | |
481 * | |
482 * @return integer the Filegroup | |
483 * @access public | |
484 */ | |
485 function group() { | |
486 if ($this->exists()) { | |
487 return filegroup($this->path); | |
488 } | |
489 return false; | |
490 } | |
491 | |
492 /** | |
493 * Returns last access time. | |
494 * | |
495 * @return integer timestamp Timestamp of last access time | |
496 * @access public | |
497 */ | |
498 function lastAccess() { | |
499 if ($this->exists()) { | |
500 return fileatime($this->path); | |
501 } | |
502 return false; | |
503 } | |
504 | |
505 /** | |
506 * Returns last modified time. | |
507 * | |
508 * @return integer timestamp Timestamp of last modification | |
509 * @access public | |
510 */ | |
511 function lastChange() { | |
512 if ($this->exists()) { | |
513 return filemtime($this->path); | |
514 } | |
515 return false; | |
516 } | |
517 | |
518 /** | |
519 * Returns the current folder. | |
520 * | |
521 * @return Folder Current folder | |
522 * @access public | |
523 */ | |
524 function &Folder() { | |
525 return $this->Folder; | |
526 } | |
527 | |
528 /** | |
529 * Copy the File to $dest | |
530 * | |
531 * @param string $dest destination for the copy | |
532 * @param boolean $overwrite Overwrite $dest if exists | |
533 * @return boolean Succes | |
534 * @access public | |
535 */ | |
536 function copy($dest, $overwrite = true) { | |
537 if (!$this->exists() || is_file($dest) && !$overwrite) { | |
538 return false; | |
539 } | |
540 return copy($this->path, $dest); | |
541 } | |
542 } |