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 }