source: trunk/server/www/cake/libs/file.php @ 310

Last change on this file since 310 was 310, checked in by sander, 11 years ago

Do not assign the return of 'new' by reference or PHP 5.3 will yell

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