|
eZ Publish
[trunk]
|
00001 <?php 00002 /** 00003 * File containing the eZFileHandler class. 00004 * 00005 * @copyright Copyright (C) 1999-2012 eZ Systems AS. All rights reserved. 00006 * @license http://www.gnu.org/licenses/gpl-2.0.txt GNU General Public License v2 00007 * @version //autogentag// 00008 * @package lib 00009 */ 00010 00011 /*! 00012 \class eZFileHandler ezfilehandler.php 00013 \brief Interface for file handlers 00014 00015 Generic interface for all file handlers. 00016 00017 Using this class i divided into five areas, they are: 00018 00019 File handling using open(), close(), read(), write() and flush(). 00020 00021 File position handling using seek(), tell(), rewind() and eof(). 00022 00023 Quick output of the file using passtrough(). 00024 00025 Error handling with error(), errorString() and errorNumber(). 00026 00027 \h1 Creating specific handlers 00028 00029 The file handlers must inherit from this class and reimplement 00030 some virtual functions. 00031 00032 For dealing with files the following functions must be reimplemented. 00033 doOpen(), doClose(), doRead(), doWrite() and doFlush(). 00034 00035 For dealing with file positions the following functions must be reimplemented. 00036 doSeek(), doTell(), doRewind() and doEOF(). 00037 00038 For dealing with quick output the passtrough() function must be reimplemented, 00039 if not reimplemented the default implemententation will simply read n bytes 00040 using read() and output it with print. 00041 00042 Also the errorString() and errorNumber() functions must be reimplemented 00043 to provide proper error handler. The error() function is not required 00044 to be implemented since it has a default implementation, for speed 00045 it might be wise to implement the function. 00046 00047 This class will handle most of the generic logic, like checking that 00048 the filename is correct and if the open succeded, and give error 00049 messages based on this. 00050 The actual implementations will only have to execute the specific 00051 code and return a result. 00052 00053 */ 00054 00055 class eZFileHandler 00056 { 00057 /*! 00058 Initializes the handler. Optionally the parameters \a $filename 00059 and \a $mode may be provided to automatically open the file. 00060 */ 00061 function eZFileHandler( $handlerIdentifier = false, $handlerName = false ) 00062 { 00063 if ( !$handlerIdentifier ) 00064 { 00065 $handlerIdentifier = 'plain'; 00066 $handlerName = 'Plain'; 00067 } 00068 $this->Name = $handlerName; 00069 $this->Identifier = $handlerIdentifier; 00070 $this->FileName = false; 00071 $this->FileHandler = false; 00072 $this->Mode = false; 00073 $this->IsOpen = false; 00074 $this->IsBinary = false; 00075 } 00076 00077 /*! 00078 \return \c true if a file is opened, \c false otherwise. 00079 */ 00080 function isOpen() 00081 { 00082 return $this->IsOpen; 00083 } 00084 00085 /*! 00086 \return \c true if the file was opened in binary mode. 00087 */ 00088 function isBinaryMode() 00089 { 00090 return $this->IsBinary; 00091 } 00092 00093 /*! 00094 \return the filename currently in use. 00095 */ 00096 function filename() 00097 { 00098 return $this->FileName; 00099 } 00100 00101 /*! 00102 \return the mode which was used to open the currently used file. 00103 */ 00104 function mode() 00105 { 00106 return $this->Mode; 00107 } 00108 00109 /*! 00110 \return the name of current handler. 00111 \sa identifier 00112 */ 00113 function name() 00114 { 00115 return $this->Name; 00116 } 00117 00118 /*! 00119 \return the identifier of the current handler. 00120 \sa name 00121 */ 00122 function identifier() 00123 { 00124 return $this->Identifier; 00125 } 00126 00127 /*! 00128 \return true if this handler can be used. 00129 \note The default implementation is to return \c true for all handlers. 00130 */ 00131 static function isAvailable() 00132 { 00133 return true; 00134 } 00135 00136 /*! 00137 Links the file \a $sourceFilename to \a $destinationFilename. 00138 If \a $destinationFilename is a directory then the filename is taken from \a $sourceFilename and appended to the destination. 00139 It will use symbolic links for the operating system that support it and file copy for all others. 00140 \param $symbolicLink if \c true then the files will be made as symbolic links, otherwise as hard links. 00141 \return \c true if sucessful or \c false if the copy failed. 00142 */ 00143 static function linkCopy( $sourceFilename, $destinationFilename, $symbolicLink = true ) 00144 { 00145 if ( in_array( eZSys::osType(), 00146 array( 'unix', 'linux', 'mac' ) ) ) 00147 { 00148 if ( $symbolicLink ) 00149 $result = eZFileHandler::symlink( $sourceFilename, $destinationFilename ); 00150 else 00151 $result = eZFileHandler::link( $sourceFilename, $destinationFilename ); 00152 if ( $result ) 00153 return $result; 00154 return eZFileHandler::copy( $sourceFilename, $destinationFilename ); 00155 } 00156 else 00157 { 00158 return eZFileHandler::copy( $sourceFilename, $destinationFilename ); 00159 } 00160 } 00161 00162 /*! 00163 Creates a symbolic link to the file \a $sourceFilename on the destination \a $destinationFilename. 00164 This means that if someone tries to open \a $destinationFilename they will infact open \a $sourceFilename. 00165 If \a $destinationFilename is a directory then the filename is taken from \a $sourceFilename and appended to the destination. 00166 It will first try to rename the file and if that does not work copy the file and unlink. 00167 \return \c true if sucessful or \c false if the copy failed. 00168 */ 00169 static function symlink( $sourceFilename, $destinationFilename ) 00170 { 00171 if ( !file_exists( $sourceFilename ) and 00172 !is_link( $sourceFilename ) ) 00173 { 00174 eZDebug::writeError( "Cannot symbolicly link to file $sourceFilename, it does not exist", __METHOD__ ); 00175 return false; 00176 } 00177 $isDir = false; 00178 if ( is_dir( $destinationFilename ) ) 00179 { 00180 $isDir = true; 00181 $dirPosition = strrpos( $sourceFilename, '/' ); 00182 $filePosition = 0; 00183 if ( $dirPosition !== false ) 00184 $filePosition = $dirPosition + 1; 00185 if ( strlen( $destinationFilename ) > 0 and 00186 $destinationFilename[strlen( $destinationFilename ) - 1] == '/' ) 00187 $destinationFilename .= substr( $sourceFilename, $filePosition ); 00188 else 00189 $destinationFilename .= '/' . substr( $sourceFilename, $filePosition ); 00190 } 00191 $destinationFilename = preg_replace( "#/+#", '/', $destinationFilename ); 00192 $sourceDir = $sourceFilename; 00193 $sourceName = false; 00194 $sourceDirPos = strrpos( $sourceDir, '/' ); 00195 if ( $sourceDirPos !== false ) 00196 { 00197 $sourceName = substr( $sourceDir, $sourceDirPos + 1 ); 00198 $sourceDir = substr( $sourceDir, 0, $sourceDirPos ); 00199 } 00200 $commonOffset = 0; 00201 for ( $i = 0; $i < strlen( $sourceFilename ) and $i < strlen( $sourceDir ); ++$i ) 00202 { 00203 if ( $sourceFilename[$i] != $sourceDir[$i] ) 00204 break; 00205 $commonOffset = $i; 00206 } 00207 if ( $commonOffset > 0 ) 00208 $sourceDir = substr( $sourceDir, $commonOffset + 1 ); 00209 $directoryCount = substr_count( $sourceDir, '/' ); 00210 $cdupText = str_repeat( '../', $directoryCount ); 00211 if ( file_exists( $destinationFilename ) and 00212 !is_dir( $destinationFilename ) ) 00213 { 00214 if ( !@unlink( $destinationFilename ) ) 00215 { 00216 eZDebug::writeError( "Cannot symbolicly link to file $sourceFilename on destination $destinationFilename, destination file cannot be removed", __METHOD__ ); 00217 return false; 00218 } 00219 } 00220 if ( $sourceDir ) 00221 $sourceDir = $sourceDir . '/' . $sourceName; 00222 else 00223 $sourceDir = $sourceName; 00224 if ( symlink( $cdupText . $sourceDir, $destinationFilename ) ) 00225 { 00226 return true; 00227 } 00228 eZDebug::writeError( "Failed to symbolicly link to $sourceFilename on destination $destinationFilename", __METHOD__ ); 00229 return false; 00230 } 00231 00232 /*! 00233 Creates a symbolic link to the file \a $sourceFilename on the destination \a $destinationFilename. 00234 This means that if someone tries to open \a $destinationFilename they will infact open \a $sourceFilename. 00235 If \a $destinationFilename is a directory then the filename is taken from \a $sourceFilename and appended to the destination. 00236 It will first try to rename the file and if that does not work copy the file and unlink. 00237 \return \c true if sucessful or \c false if the copy failed. 00238 */ 00239 static function link( $sourceFilename, $destinationFilename ) 00240 { 00241 if ( !file_exists( $sourceFilename ) and 00242 !is_link( $sourceFilename ) ) 00243 { 00244 eZDebug::writeError( "Cannot link to file $sourceFilename, it does not exist", __METHOD__ ); 00245 return false; 00246 } 00247 $isDir = false; 00248 if ( is_dir( $destinationFilename ) ) 00249 { 00250 $isDir = true; 00251 $dirPosition = strrpos( $sourceFilename, '/' ); 00252 $filePosition = 0; 00253 if ( $dirPosition !== false ) 00254 $filePosition = $dirPosition + 1; 00255 if ( strlen( $destinationFilename ) > 0 and 00256 $destinationFilename[strlen( $destinationFilename ) - 1] == '/' ) 00257 $destinationFilename .= substr( $sourceFilename, $filePosition ); 00258 else 00259 $destinationFilename .= '/' . substr( $sourceFilename, $filePosition ); 00260 } 00261 $destinationFilename = preg_replace( "#/+#", '/', $destinationFilename ); 00262 if ( file_exists( $destinationFilename ) and 00263 !is_dir( $destinationFilename ) ) 00264 { 00265 if ( !@unlink( $destinationFilename ) ) 00266 { 00267 eZDebug::writeError( "Cannot link to file $sourceFilename on destination $destinationFilename, destination file cannot be removed", __METHOD__ ); 00268 return false; 00269 } 00270 } 00271 if ( link( $sourceFilename, $destinationFilename ) ) 00272 { 00273 return true; 00274 } 00275 eZDebug::writeError( "Failed to link to $sourceFilename on destination $destinationFilename", __METHOD__ ); 00276 return false; 00277 } 00278 00279 /*! 00280 Moves the file \a $sourceFilename to \a $destinationFilename. 00281 If \a $destinationFilename is a directory then the filename is taken from \a $sourceFilename and appended to the destination. 00282 It will first try to rename the file and if that does not work copy the file and unlink. 00283 \return \c true if sucessful or \c false if the copy failed. 00284 */ 00285 static function move( $sourceFilename, $destinationFilename ) 00286 { 00287 if ( !file_exists( $sourceFilename ) and 00288 !is_link( $sourceFilename ) ) 00289 { 00290 eZDebug::writeError( "Cannot rename file $sourceFilename, it does not exist", __METHOD__ ); 00291 return false; 00292 } 00293 $isDir = false; 00294 if ( is_dir( $destinationFilename ) ) 00295 { 00296 $isDir = true; 00297 $dirPosition = strrpos( $sourceFilename, '/' ); 00298 $filePosition = 0; 00299 if ( $dirPosition !== false ) 00300 $filePosition = $dirPosition + 1; 00301 if ( strlen( $destinationFilename ) > 0 and 00302 $destinationFilename[strlen( $destinationFilename ) - 1] == '/' ) 00303 $destinationFilename .= substr( $sourceFilename, $filePosition ); 00304 else 00305 $destinationFilename .= '/' . substr( $sourceFilename, $filePosition ); 00306 } 00307 00308 00309 // If source and destination are the same files we just return true 00310 if ( $sourceFilename == $destinationFilename ) 00311 { 00312 return true; 00313 } 00314 00315 if ( file_exists( $destinationFilename ) and 00316 !is_dir( $destinationFilename ) ) 00317 { 00318 if ( !@unlink( $destinationFilename ) ) 00319 { 00320 eZDebug::writeError( "Cannot move file $sourceFilename to destination $destinationFilename, destination file cannot be removed", __METHOD__ ); 00321 return false; 00322 } 00323 } 00324 $isLink = false; 00325 if ( is_link( $sourceFilename ) ) 00326 { 00327 $isLink = true; 00328 } 00329 if ( !$isLink and 00330 eZFile::rename( $sourceFilename, $destinationFilename ) ) 00331 { 00332 return true; 00333 } 00334 if ( eZFileHandler::copy( $sourceFilename, $destinationFilename ) ) 00335 { 00336 if ( !@unlink( $sourceFilename ) ) 00337 { 00338 eZDebug::writeError( "Cannot remove source file $sourceFilename, file was not succesfully moved", __METHOD__ ); 00339 @unlink( $destinationFilename ); 00340 return false; 00341 } 00342 return true; 00343 } 00344 eZDebug::writeError( "Failed to copy $sourceFilename to $destinationFilename, file was not succesfully moved", __METHOD__ ); 00345 return false; 00346 } 00347 00348 /*! 00349 Copies the file \a $sourceFilename to \a $destinationFilename. 00350 \return \c true if sucessful or \c false if the copy failed. 00351 */ 00352 static function copy( $sourceFilename, $destinationFilename ) 00353 { 00354 if ( is_dir( $sourceFilename ) ) 00355 { 00356 eZDebug::writeError( "Unable to copy directory $sourceFilename, use eZDir::copy instead", __METHOD__ ); 00357 return false; 00358 } 00359 $sourceFD = @fopen( $sourceFilename, 'rb' ); 00360 if ( !$sourceFD ) 00361 { 00362 eZDebug::writeError( "Unable to open source file $sourceFilename in read mode", __METHOD__ ); 00363 return false; 00364 } 00365 if ( is_dir( $destinationFilename ) ) 00366 { 00367 $dirPosition = strrpos( $sourceFilename, '/' ); 00368 $filePosition = 0; 00369 if ( $dirPosition !== false ) 00370 $filePosition = $dirPosition + 1; 00371 if ( strlen( $destinationFilename ) > 0 and 00372 $destinationFilename[strlen( $destinationFilename ) - 1] == '/' ) 00373 $destinationFilename .= substr( $sourceFilename, $filePosition ); 00374 else 00375 $destinationFilename .= '/' . substr( $sourceFilename, $filePosition ); 00376 } 00377 00378 // If source and destination are the same files we just return true 00379 if ( $sourceFilename == $destinationFilename ) 00380 { 00381 @fclose( $sourceFD ); 00382 return true; 00383 } 00384 00385 $destinationFD = fopen( $destinationFilename, 'wb' ); 00386 chmod( $destinationFilename, octdec( eZINI::instance()->variable( 'FileSettings', 'StorageFilePermissions' ) ) ); 00387 if ( !$destinationFD ) 00388 { 00389 @fclose( $sourceFD ); 00390 eZDebug::writeError( "Unable to open destination file $destinationFilename in write mode", __METHOD__ ); 00391 return false; 00392 } 00393 $bytesCopied = 0; 00394 do 00395 { 00396 $data = fread( $sourceFD, 4096 ); 00397 if ( strlen( $data ) == 0 ) 00398 break; 00399 fwrite( $destinationFD, $data ); 00400 $bytesCopied += strlen( $data ); 00401 } while( true ); 00402 00403 @fclose( $sourceFD ); 00404 @fclose( $destinationFD ); 00405 return true; 00406 } 00407 00408 /*! 00409 \return \c true if the filename \a $filename exists. 00410 If \a $filename is not specified the filename is taken from the one used in open(). 00411 */ 00412 function exists( $filename = false ) 00413 { 00414 if ( !$filename ) 00415 $filename = $this->FileName; 00416 return $this->doExists( $filename ); 00417 } 00418 00419 /*! 00420 \return \c true if \a $filename is a directory. 00421 */ 00422 function isDirectory( $filename = false ) 00423 { 00424 if ( !$filename ) 00425 $filename = $this->FileName; 00426 return $this->doIsDirectory( $filename ); 00427 } 00428 00429 /*! 00430 \return \c true if \a $filename is executable. 00431 */ 00432 function isExecutable( $filename = false ) 00433 { 00434 if ( !$filename ) 00435 $filename = $this->FileName; 00436 return $this->doIsExecutable( $filename ); 00437 } 00438 00439 /*! 00440 \return \c true if \a $filename is a file. 00441 */ 00442 function isFile( $filename = false ) 00443 { 00444 if ( !$filename ) 00445 $filename = $this->FileName; 00446 return $this->doIsFile( $filename ); 00447 } 00448 00449 /*! 00450 \return \c true if \a $filename is a link. 00451 */ 00452 function isLink( $filename = false ) 00453 { 00454 if ( !$filename ) 00455 $filename = $this->FileName; 00456 return $this->doIsLink( $filename ); 00457 } 00458 00459 /*! 00460 \return \c true if \a $filename is readable. 00461 */ 00462 function isReadable( $filename = false ) 00463 { 00464 if ( !$filename ) 00465 $filename = $this->FileName; 00466 return $this->doIsReadable( $filename ); 00467 } 00468 00469 /*! 00470 \return \c true if \a $filename is writeable. 00471 */ 00472 function isWriteable( $filename = false ) 00473 { 00474 if ( !$filename ) 00475 $filename = $this->FileName; 00476 return $this->doIsWriteable( $filename ); 00477 } 00478 00479 /*! 00480 \return the statitistics for the file \a $filename. 00481 */ 00482 function statistics( $filename = false ) 00483 { 00484 if ( !$filename ) 00485 $filename = $this->FileName; 00486 return $this->doStatistics( $filename ); 00487 } 00488 00489 /*! 00490 Tries to open the file \a $filename with mode \a $mode and returns 00491 the file resource if succesful. 00492 \return \c false if the file could not be opened. 00493 \param $mode If false the file will be opened in read mode using 'r' 00494 \param $binaryFile If true file will be opened in binary mode (default), 00495 otherwise text mode is used. 00496 \note Parameter $binaryFile will only have effect on the Windows operating system. 00497 */ 00498 function open( $filename, $mode, $binaryFile = true ) 00499 { 00500 if ( $this->isOpen() ) 00501 { 00502 eZDebug::writeError( "A file is already open (" . $this->FileName . "), close the file before opening a new one.", 00503 'eZFileHandler::open' ); 00504 return false; 00505 } 00506 if ( !$filename and 00507 !$this->FileName ) 00508 { 00509 eZDebug::writeError( "The supplied filename is empty and no filename set for object, cannot open any file", __METHOD__ ); 00510 return false; 00511 } 00512 if ( !$filename ) 00513 $filename = $this->FileName; 00514 if ( !$mode ) 00515 $mode = 'r'; 00516 if ( strpos( $mode, 'b' ) !== false ) 00517 $binaryFile = true; 00518 $mode = str_replace( 'b', '', $mode ); 00519 if ( $binaryFile ) 00520 $mode .= 'b'; 00521 $this->IsBinary = $binaryFile; 00522 $result = $this->doOpen( $filename, $mode ); 00523 if ( $result ) 00524 { 00525 // eZDebugSetting::writeNotice( 'lib-ezfile-openclose', 00526 // "Opened file $filename with mode '$mode'", 00527 // 'eZFileHandler::open' ); 00528 $this->FileName = $filename; 00529 $this->Mode = $mode; 00530 $this->IsOpen = true; 00531 } 00532 else 00533 eZDebug::writeError( "Failed opening file $filename with mode $mode", __METHOD__ ); 00534 return $result; 00535 } 00536 00537 /*! 00538 Tries to close an open file and returns \c true if succesful, \c false otherwise. 00539 */ 00540 function close() 00541 { 00542 if ( !$this->isOpen() ) 00543 { 00544 eZDebug::writeError( "A file is not currently opened, cannot close.", __METHOD__ ); 00545 return false; 00546 } 00547 // eZDebugSetting::writeNotice( 'lib-ezfile-openclose', 00548 // "Closing file " . $this->filename() . " with previously opened mode '" . $this->mode() . "'", 00549 // 'eZFileHandler::close' ); 00550 $result = $this->doClose(); 00551 if ( !$result ) 00552 eZDebug::writeError( "Failed closing file " . $this->FileName . " opened with mode " . $this->Mode, __METHOD__ ); 00553 else 00554 $this->IsOpen = false; 00555 return $result; 00556 } 00557 00558 /*! 00559 Tries to unlink the file from the file system. 00560 */ 00561 function unlink( $filename = false ) 00562 { 00563 if ( !$filename ) 00564 { 00565 if ( $this->isOpen() ) 00566 $this->close(); 00567 $filename = $this->FileName; 00568 } 00569 $result = eZFileHandler::doUnlink( $filename ); 00570 if ( !$result ) 00571 eZDebug::writeError( "Failed unlinking file " . $filename, __METHOD__ ); 00572 return $result; 00573 } 00574 00575 /*! 00576 Renames the file \a $sourceFilename to \a $destinationFilename. 00577 If \a $sourceFilename is not supplied then filename() is used, 00578 it will also close the current file connection and reopen it again if 00579 was already open. 00580 */ 00581 function rename( $destinationFilename, $sourceFilename = false ) 00582 { 00583 if ( !$sourceFilename ) 00584 { 00585 $wasOpen = $this->isOpen(); 00586 if ( $wasOpen ) 00587 $this->close(); 00588 $result = $this->doRename( $destinationFilename, $this->filename() ); 00589 if ( $wasOpen and 00590 $result ) 00591 $this->open( $destinationFilename, $this->mode() ); 00592 } 00593 else 00594 $result = $this->doRename( $destinationFilename, $sourceFilename ); 00595 return $result; 00596 } 00597 00598 /*! 00599 Reads up to \a $length bytes from file. Reading stops when 00600 \a $length has been read or \c EOF is reached, whichever comes first. 00601 If the optional parameter \a $length is not specified it will 00602 read bytes until \c EOF is reached. 00603 \return a \c string or \c false if something fails. 00604 */ 00605 function read( $length = false ) 00606 { 00607 if ( !$this->isOpen() ) 00608 { 00609 eZDebug::writeError( "A file is not currently opened, cannot read.", __METHOD__ ); 00610 return false; 00611 } 00612 if ( $length < 0 ) 00613 { 00614 eZDebug::writeError( "length cannot be negative ($length)", __METHOD__ ); 00615 return false; 00616 } 00617 if ( $length ) 00618 { 00619 return $this->doRead( $length ); 00620 } 00621 else 00622 { 00623 $string = ''; 00624 $data = false; 00625 do 00626 { 00627 $data = $this->doRead( 1024 ); 00628 if ( $data ) 00629 $string .= $data; 00630 } while( $data ); 00631 return $string; 00632 } 00633 } 00634 00635 /*! 00636 Writes the content of the string \a $data to the file. 00637 If optional \c $length parameter is supplied writing will stop after 00638 length is reached or the end of the string is reached, whichever comes first. 00639 \return the number of bytes that was written. 00640 */ 00641 function write( $data, $length = false ) 00642 { 00643 if ( !$this->isOpen() ) 00644 { 00645 eZDebug::writeError( "A file is not currently opened, cannot write.", __METHOD__ ); 00646 return false; 00647 } 00648 if ( $length < 0 ) 00649 { 00650 eZDebug::writeError( "length cannot be negative ($length)", __METHOD__ ); 00651 return false; 00652 } 00653 return $this->doWrite( $data, $length ); 00654 } 00655 00656 /*! 00657 Force a write of all buffered data. 00658 \return \c true if succesful or \c false if something failed. 00659 */ 00660 function flush() 00661 { 00662 if ( !$this->isOpen() ) 00663 { 00664 eZDebug::writeError( "A file is not currently opened, cannot flush.", __METHOD__ ); 00665 return false; 00666 } 00667 return $this->doFlush(); 00668 } 00669 00670 /*! 00671 Seeks to position in file determined by \a $offset and \a $whence. 00672 - SEEK_SET - Set position equal to offset bytes. 00673 - SEEK_CUR - Set position to current location plus offset. 00674 - SEEK_END - Set position to end-of-file plus offset. (To move to a position before the end-of-file, you need to pass a negative value in offset.) 00675 00676 \note Not all handlers supports all types for \a $whence 00677 \return \c 0 if succesful or \c -1 if something failed. 00678 */ 00679 function seek( $offset, $whence = SEEK_SET ) 00680 { 00681 if ( !$this->isOpen() ) 00682 { 00683 eZDebug::writeError( "A file is not currently opened, cannot seek.", __METHOD__ ); 00684 return false; 00685 } 00686 return $this->doSeek( $offset, $whence ); 00687 } 00688 00689 /*! 00690 Rewinds the file position to the beginning of the file. 00691 \return \c 0 if something went wrong. 00692 */ 00693 function rewind() 00694 { 00695 if ( !$this->isOpen() ) 00696 { 00697 eZDebug::writeError( "A file is not currently opened, cannot rewind.", __METHOD__ ); 00698 return false; 00699 } 00700 return $this->doRewind(); 00701 } 00702 00703 /*! 00704 Tells the current file position. 00705 \return \c false if something failed. 00706 */ 00707 function tell() 00708 { 00709 if ( !$this->isOpen() ) 00710 { 00711 eZDebug::writeError( "A file is not currently opened, cannot tell position.", __METHOD__ ); 00712 return false; 00713 } 00714 return $this->doTell(); 00715 } 00716 00717 /*! 00718 \return \c true if the file pointer is at the end of the file or an error occured, otherwise \c false. 00719 */ 00720 function eof() 00721 { 00722 if ( !$this->isOpen() ) 00723 { 00724 eZDebug::writeError( "A file is not currently opened, cannot report EOF status.", __METHOD__ ); 00725 return false; 00726 } 00727 return $this->doEOF(); 00728 } 00729 00730 /*! 00731 Passes the data from the file to the standard output. 00732 \param $closeFile If \c true the file will be closed after output is done. 00733 \return \c false if something failed. 00734 */ 00735 function passtrough( $closeFile = true ) 00736 { 00737 if ( !$this->isOpen() ) 00738 { 00739 eZDebug::writeError( "A file is not currently opened, cannot do a data passtrough.", __METHOD__ ); 00740 return false; 00741 } 00742 return $this->doPasstrough( $closeFile ); 00743 } 00744 00745 /*! 00746 \pure 00747 Does the actual file opening. 00748 \sa open 00749 */ 00750 function doOpen( $filename, $mode ) 00751 { 00752 $this->FileHandler = @fopen( $filename, $mode ); 00753 return $this->FileHandler; 00754 } 00755 00756 /*! 00757 \pure 00758 Does the actual file closing. 00759 \sa close 00760 */ 00761 function doClose() 00762 { 00763 $result = @fclose( $this->FileHandler ); 00764 $this->FileHandler = false; 00765 return $result; 00766 } 00767 00768 /*! 00769 \pure 00770 Does the actual file unlinking. 00771 \sa unlink 00772 */ 00773 static function doUnlink( $filename ) 00774 { 00775 return @unlink( $filename ); 00776 } 00777 00778 /*! 00779 \pure 00780 Does the actual file exists checking. 00781 \sa exists 00782 */ 00783 static function doExists( $filename ) 00784 { 00785 return file_exists( $filename ); 00786 } 00787 00788 /*! 00789 \pure 00790 Does the actual directory checking. 00791 \sa isDirectory 00792 */ 00793 static function doIsDirectory( $filename ) 00794 { 00795 return is_dir( $filename ); 00796 } 00797 00798 /*! 00799 \pure 00800 Does the actual executable checking. 00801 \sa isExecutable 00802 */ 00803 static function doIsExecutable( $filename ) 00804 { 00805 return is_executable( $filename ); 00806 } 00807 00808 /*! 00809 \pure 00810 Does the actual file checking. 00811 \sa isFile 00812 */ 00813 static function doIsFile( $filename ) 00814 { 00815 return is_file( $filename ); 00816 } 00817 00818 /*! 00819 \pure 00820 Does the actual link checking. 00821 \sa isLink 00822 */ 00823 static function doIsLink( $filename ) 00824 { 00825 return is_link( $filename ); 00826 } 00827 00828 /*! 00829 \pure 00830 Does the actual readable checking. 00831 \sa isReadable 00832 */ 00833 static function doIsReadable( $filename ) 00834 { 00835 return is_readable( $filename ); 00836 } 00837 00838 /*! 00839 \pure 00840 Does the actual writeable checking. 00841 \sa isWriteable 00842 */ 00843 static function doIsWriteable( $filename ) 00844 { 00845 return is_writable( $filename ); 00846 } 00847 00848 /*! 00849 \pure 00850 Does the actual writeable checking. 00851 \sa isWriteable 00852 */ 00853 static function doStatistics( $filename ) 00854 { 00855 return @stat( $filename ); 00856 } 00857 00858 /*! 00859 \pure 00860 Does the actual file seek. 00861 \sa seek 00862 */ 00863 function doSeek( $offset, $whence ) 00864 { 00865 return @fseek( $this->FileHandler, $offset, $whence ); 00866 } 00867 00868 /*! 00869 Does the actual file rewind. 00870 \sa rewind 00871 \note Default implementation calls seek with offset set to 0 from the file start. 00872 */ 00873 function doRewind() 00874 { 00875 $this->doSeek( 0, SEEK_SET ); 00876 } 00877 00878 /*! 00879 \pure 00880 Does the actual file telling. 00881 \sa tell 00882 */ 00883 function doTell() 00884 { 00885 return @ftell( $this->FileHandler ); 00886 } 00887 00888 /*! 00889 \pure 00890 Does the actual file eof detection. 00891 \sa eof 00892 */ 00893 function doEOF() 00894 { 00895 return @feof( $this->FileHandler ); 00896 } 00897 00898 /*! 00899 \pure 00900 Does the actual file passtrough. 00901 \sa eof 00902 */ 00903 function doPasstrough( $closeFile = true ) 00904 { 00905 $result = @fpassthru( $this->FileHandler ); 00906 if ( $closeFile ) 00907 { 00908 @fclose( $this->FileHandler ); 00909 $this->FileHandler = false; 00910 } 00911 } 00912 00913 /*! 00914 \pure 00915 Does the actual file reading. 00916 \sa read 00917 */ 00918 function doRead( $length = false ) 00919 { 00920 return @fread( $this->FileHandler, $length ); 00921 } 00922 00923 /*! 00924 \pure 00925 Does the actual file writing. 00926 \sa write 00927 */ 00928 function doWrite( $data, $length = false ) 00929 { 00930 if ( $length === false ) 00931 return @fwrite( $this->FileHandler, $data ); 00932 else 00933 return @fwrite( $this->FileHandler, $data, $length ); 00934 } 00935 00936 /*! 00937 \pure 00938 Does the actual file flushing. 00939 \sa flush 00940 */ 00941 function doFlush() 00942 { 00943 return @fflush( $this->FileHandler ); 00944 } 00945 00946 /*! 00947 \pure 00948 Does the actual file renaming. 00949 \sa rename 00950 */ 00951 static function doRename( $destinationFilename, $sourceFilename ) 00952 { 00953 return eZFile::rename( $sourceFilename, $destinationFilename ); 00954 } 00955 00956 /*! 00957 Returns error data as an associative array, the array contains: 00958 - string - The error string 00959 - number - The error number 00960 \note The default implementation calls errorString() and errorNumber(). 00961 */ 00962 function error() 00963 { 00964 return array( 'string' => $this->errorString(), 00965 'number' => $this->errorNumber() ); 00966 } 00967 00968 /*! 00969 \pure 00970 \return the error string from the last error that occured. 00971 */ 00972 function errorString() 00973 { 00974 return false; 00975 } 00976 00977 /*! 00978 \pure 00979 \return the error number from the last error that occured. 00980 */ 00981 function errorNumber() 00982 { 00983 return false; 00984 } 00985 00986 /*! 00987 Creates a copy of the current handler and returns a reference to the copy. 00988 \note The default does a simple copy of \c $this, this method must be reimplemented for specific handlers. 00989 */ 00990 function duplicate() 00991 { 00992 $copy = clone $this; 00993 return $copy; 00994 } 00995 00996 /*! 00997 Returns the handler for the identifier \a $identifier. 00998 The parameters \a $filename, \a $mode and \a $binaryFile is passed to the handler. 00999 \return \c false if the handler could not be created. 01000 */ 01001 /** 01002 * Returns a shared instance of the eZFileHandler class. 01003 * $identifier if set is used to specify specific file handlers as 01004 * defined in file.ini [FileSettings]Handlers. 01005 * If $filename and later params are set, then file is opened straigt away. 01006 * 01007 * @param string|false $identifier Global eZFileHandler used if false 01008 * @param string|false $filename 01009 * @param string|false $mode set to 'r' if false 01010 * @param bool $binaryFile Binary or text mode, default true. 01011 * @return eZFileHandler|false 01012 */ 01013 static function instance( $identifier, $filename = false, $mode = false, $binaryFile = true ) 01014 { 01015 $ini = eZINI::instance( 'file.ini' ); 01016 $handlers = $ini->variable( 'FileSettings', 'Handlers' ); 01017 $instance = false; 01018 if ( !$identifier ) 01019 { 01020 $instance = new eZFileHandler(); 01021 } 01022 else if ( isset( $handlers[$identifier] ) ) 01023 { 01024 $className = $handlers[$identifier]; 01025 $includeFile = 'lib/ezfile/classes/' . $className . '.php'; 01026 include_once( $includeFile ); 01027 $instance = new $className(); 01028 if ( $instance->isAvailable() ) 01029 { 01030 if ( $filename ) 01031 $instance->open( $filename, $mode, $binaryFile ); 01032 } 01033 else 01034 { 01035 unset( $instance ); 01036 $instance = false; 01037 } 01038 } 01039 return $instance; 01040 } 01041 01042 /// \privatesection 01043 public $Name; 01044 public $FileName; 01045 public $Mode; 01046 public $IsBinary; 01047 public $IsOpen; 01048 } 01049 01050 ?>