home *** CD-ROM | disk | FTP | other *** search
/ Cricao de Sites - 650 Layouts Prontos / WebMasters.iso / Servidores / xampp-win32-1.6.7-installer.exe / php / PEAR / phing / system / io / PhingFile.php < prev    next >
Encoding:
PHP Script  |  2007-10-20  |  31.6 KB  |  870 lines

  1. <?php
  2. /*
  3.  *  $Id: PhingFile.php 258 2007-10-21 00:46:45Z hans $
  4.  *
  5.  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  6.  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  7.  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  8.  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  9.  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  10.  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  11.  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  12.  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  13.  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  14.  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  15.  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  16.  *
  17.  * This software consists of voluntary contributions made by many individuals
  18.  * and is licensed under the LGPL. For more information please see
  19.  * <http://phing.info>.
  20.  */
  21.  
  22. include_once 'phing/system/io/FileSystem.php';
  23. include_once 'phing/system/lang/NullPointerException.php';
  24.  
  25. /**
  26.  * An abstract representation of file and directory pathnames.
  27.  *
  28.  * @version   $Revision: 1.1 $
  29.  * @package   phing.system.io
  30.  */
  31. class PhingFile {
  32.  
  33.     /** separator string, static, obtained from FileSystem */
  34.     public static $separator;
  35.  
  36.     /** path separator string, static, obtained from FileSystem (; or :)*/
  37.     public static $pathSeparator;
  38.     
  39.     /**
  40.      * This abstract pathname's normalized pathname string.  A normalized
  41.      * pathname string uses the default name-separator character and does not
  42.      * contain any duplicate or redundant separators.
  43.      */
  44.     private $path = null;
  45.  
  46.     /** The length of this abstract pathname's prefix, or zero if it has no prefix. */
  47.     private $prefixLength = 0;
  48.  
  49.     /** constructor */
  50.     function __construct($arg1 = null, $arg2 = null) {
  51.         
  52.         if (self::$separator === null || self::$pathSeparator === null) {
  53.             $fs = FileSystem::getFileSystem();
  54.             self::$separator = $fs->getSeparator();
  55.             self::$pathSeparator = $fs->getPathSeparator();
  56.         }
  57.  
  58.         /* simulate signature identified constructors */
  59.         if ($arg1 instanceof PhingFile && is_string($arg2)) {
  60.             $this->_constructFileParentStringChild($arg1, $arg2);
  61.         } elseif (is_string($arg1) && ($arg2 === null)) {
  62.             $this->_constructPathname($arg1);
  63.         } elseif(is_string($arg1) && is_string($arg2)) {
  64.             $this->_constructStringParentStringChild($arg1, $arg2);
  65.         } else {
  66.             if ($arg1 === null) {
  67.                 throw new NullPointerException("Argument1 to function must not be null");
  68.             }
  69.             $this->path = (string) $arg1;
  70.             $this->prefixLength = (int) $arg2;
  71.         }
  72.     }
  73.  
  74.     /** Returns the length of this abstract pathname's prefix. */
  75.     function getPrefixLength() {
  76.         return (int) $this->prefixLength;
  77.     }
  78.     
  79.     /* -- constructors not called by signature match, so we need some helpers --*/
  80.  
  81.     function _constructPathname($pathname) {
  82.         // obtain ref to the filesystem layer
  83.         $fs = FileSystem::getFileSystem();
  84.  
  85.         if ($pathname === null) {
  86.             throw new NullPointerException("Argument to function must not be null");
  87.         }
  88.  
  89.         $this->path = (string) $fs->normalize($pathname);
  90.         $this->prefixLength = (int) $fs->prefixLength($this->path);
  91.     }
  92.  
  93.     function _constructStringParentStringChild($parent, $child = null) {
  94.         // obtain ref to the filesystem layer
  95.         $fs = FileSystem::getFileSystem();
  96.  
  97.         if ($child === null) {
  98.             throw new NullPointerException("Argument to function must not be null");
  99.         }
  100.         if ($parent !== null) {
  101.             if ($parent === "") {
  102.                 $this->path = $fs->resolve($fs->getDefaultParent(), $fs->normalize($child));
  103.             } else {
  104.                 $this->path = $fs->resolve($fs->normalize($parent), $fs->normalize($child));
  105.             }
  106.         } else {
  107.             $this->path = (string) $fs->normalize($child);
  108.         }
  109.         $this->prefixLength = (int) $fs->prefixLength($this->path);
  110.     }
  111.  
  112.     function _constructFileParentStringChild($parent, $child = null) {
  113.         // obtain ref to the filesystem layer
  114.         $fs = FileSystem::getFileSystem();
  115.  
  116.         if ($child === null) {
  117.             throw new NullPointerException("Argument to function must not be null");
  118.         }
  119.  
  120.         if ($parent !== null) {
  121.             if ($parent->path === "") {
  122.                 $this->path = $fs->resolve($fs->getDefaultParent(), $fs->normalize($child));
  123.             } else {
  124.                 $this->path = $fs->resolve($parent->path, $fs->normalize($child));
  125.             }
  126.         } else {
  127.             $this->path = $fs->normalize($child);
  128.         }
  129.         $this->prefixLength = $fs->prefixLength($this->path);
  130.     }
  131.  
  132.     /* -- Path-component accessors -- */
  133.  
  134.     /**
  135.      * Returns the name of the file or directory denoted by this abstract
  136.      * pathname.  This is just the last name in the pathname's name
  137.      * sequence.  If the pathname's name sequence is empty, then the empty
  138.      * string is returned.
  139.      *
  140.      * @return  The name of the file or directory denoted by this abstract
  141.      *          pathname, or the empty string if this pathname's name sequence
  142.      *          is empty
  143.      */
  144.     function getName() {
  145.         // that's a lastIndexOf
  146.         $index = ((($res = strrpos($this->path, self::$separator)) === false) ? -1 : $res);
  147.         if ($index < $this->prefixLength) {
  148.             return substr($this->path, $this->prefixLength);
  149.         }
  150.         return substr($this->path, $index + 1);
  151.     }
  152.  
  153.     /**
  154.      * Returns the pathname string of this abstract pathname's parent, or
  155.      * null if this pathname does not name a parent directory.
  156.      *
  157.      * The parent of an abstract pathname consists of the pathname's prefix,
  158.      * if any, and each name in the pathname's name sequence except for the last.
  159.      * If the name sequence is empty then the pathname does not name a parent
  160.      * directory.
  161.      *
  162.      * @return  The pathname string of the parent directory named by this
  163.      *          abstract pathname, or null if this pathname does not name a parent
  164.      */
  165.     function getParent() {
  166.         // that's a lastIndexOf
  167.         $index = ((($res = strrpos($this->path, self::$separator)) === false) ? -1 : $res);
  168.         if ($index < $this->prefixLength) {
  169.             if (($this->prefixLength > 0) && (strlen($this->path > $this->prefixLength))) {
  170.                 return substr($this->path, 0, $this->prefixLength);
  171.             }
  172.             return null;
  173.         }
  174.         return substr($this->path, 0, $index);
  175.     }
  176.  
  177.     /**
  178.      * Returns the abstract pathname of this abstract pathname's parent,
  179.      * or null if this pathname does not name a parent directory.
  180.      *
  181.      * The parent of an abstract pathname consists of the pathname's prefix,
  182.      * if any, and each name in the pathname's name sequence except for the
  183.      * last.  If the name sequence is empty then the pathname does not name
  184.      * a parent directory.
  185.      *
  186.      * @return  The abstract pathname of the parent directory named by this
  187.      *          abstract pathname, or null if this pathname
  188.      *          does not name a parent
  189.      */
  190.     function getParentFile() {
  191.         $p = $this->getParent();
  192.         if ($p === null) {
  193.             return null;
  194.         }
  195.         return new PhingFile((string) $p, (int) $this->prefixLength);
  196.     }
  197.  
  198.     /**
  199.      * Converts this abstract pathname into a pathname string.  The resulting
  200.      * string uses the default name-separator character to separate the names
  201.      * in the name sequence.
  202.      *
  203.      * @return  The string form of this abstract pathname
  204.      */
  205.     function getPath() {
  206.         return (string) $this->path;
  207.     }
  208.  
  209.     /**
  210.      * Tests whether this abstract pathname is absolute.  The definition of
  211.      * absolute pathname is system dependent.  On UNIX systems, a pathname is
  212.      * absolute if its prefix is "/".  On Win32 systems, a pathname is absolute
  213.      * if its prefix is a drive specifier followed by "\\", or if its prefix
  214.      * is "\\".
  215.      *
  216.      * @return  true if this abstract pathname is absolute, false otherwise
  217.      */
  218.     function isAbsolute() {
  219.         return ($this->prefixLength !== 0);
  220.     }
  221.  
  222.  
  223.     /**
  224.      * Returns the absolute pathname string of this abstract pathname.
  225.      *
  226.      * If this abstract pathname is already absolute, then the pathname
  227.      * string is simply returned as if by the getPath method.
  228.      * If this abstract pathname is the empty abstract pathname then
  229.      * the pathname string of the current user directory, which is named by the
  230.      * system property user.dir, is returned.  Otherwise this
  231.      * pathname is resolved in a system-dependent way.  On UNIX systems, a
  232.      * relative pathname is made absolute by resolving it against the current
  233.      * user directory.  On Win32 systems, a relative pathname is made absolute
  234.      * by resolving it against the current directory of the drive named by the
  235.      * pathname, if any; if not, it is resolved against the current user
  236.      * directory.
  237.      *
  238.      * @return  The absolute pathname string denoting the same file or
  239.      *          directory as this abstract pathname
  240.      * @see     #isAbsolute()
  241.      */
  242.     function getAbsolutePath() {
  243.         $fs = FileSystem::getFileSystem();        
  244.         return $fs->resolveFile($this);
  245.     }
  246.  
  247.     /**
  248.      * Returns the absolute form of this abstract pathname.  Equivalent to
  249.      * getAbsolutePath.
  250.      *
  251.      * @return  The absolute abstract pathname denoting the same file or
  252.      *          directory as this abstract pathname
  253.      */
  254.     function getAbsoluteFile() {
  255.         return new PhingFile((string) $this->getAbsolutePath());
  256.     }
  257.  
  258.  
  259.     /**
  260.      * Returns the canonical pathname string of this abstract pathname.
  261.      *
  262.      * A canonical pathname is both absolute and unique. The precise
  263.      * definition of canonical form is system-dependent. This method first
  264.      * converts this pathname to absolute form if necessary, as if by invoking the
  265.      * getAbsolutePath() method, and then maps it to its unique form in a
  266.      * system-dependent way.  This typically involves removing redundant names
  267.      * such as "." and .. from the pathname, resolving symbolic links
  268.      * (on UNIX platforms), and converting drive letters to a standard case
  269.      * (on Win32 platforms).
  270.      *
  271.      * Every pathname that denotes an existing file or directory has a
  272.      * unique canonical form.  Every pathname that denotes a nonexistent file
  273.      * or directory also has a unique canonical form.  The canonical form of
  274.      * the pathname of a nonexistent file or directory may be different from
  275.      * the canonical form of the same pathname after the file or directory is
  276.      * created.  Similarly, the canonical form of the pathname of an existing
  277.      * file or directory may be different from the canonical form of the same
  278.      * pathname after the file or directory is deleted.
  279.      *
  280.      * @return  The canonical pathname string denoting the same file or
  281.      *          directory as this abstract pathname
  282.      */
  283.     function getCanonicalPath() {
  284.         $fs = FileSystem::getFileSystem();
  285.         return $fs->canonicalize($this->path);
  286.     }
  287.  
  288.  
  289.     /**
  290.      * Returns the canonical form of this abstract pathname.  Equivalent to
  291.      * getCanonicalPath(.
  292.      *
  293.      * @return  PhingFile The canonical pathname string denoting the same file or
  294.      *          directory as this abstract pathname
  295.      */
  296.     function getCanonicalFile() {
  297.         return new PhingFile($this->getCanonicalPath());
  298.     }
  299.  
  300.     /**
  301.      * Converts this abstract pathname into a file: URL.  The
  302.      * exact form of the URL is system-dependent.  If it can be determined that
  303.      * the file denoted by this abstract pathname is a directory, then the
  304.      * resulting URL will end with a slash.
  305.      *
  306.      * Usage note: This method does not automatically escape
  307.      * characters that are illegal in URLs.  It is recommended that new code
  308.      * convert an abstract pathname into a URL by first converting it into a
  309.      * URI, via the toURI() method, and then converting the URI
  310.      * into a URL via the URI::toURL()
  311.      *
  312.      * @return  A URL object representing the equivalent file URL
  313.      *
  314.      *
  315.      */
  316.     function toURL() {
  317.         /*
  318.         // URL class not implemented yet
  319.         return new URL("file", "", $this->_slashify($this->getAbsolutePath(), $this->isDirectory()));
  320.         */
  321.     }
  322.  
  323.     /**
  324.      * Constructs a file: URI that represents this abstract pathname.
  325.      * Not implemented yet
  326.      */
  327.     function toURI() {
  328.         /*
  329.         $f = $this->getAbsoluteFile();
  330.            $sp = (string) $this->slashify($f->getPath(), $f->isDirectory());
  331.            if (StringHelper::startsWith('//', $sp))
  332.         $sp = '//' + sp;
  333.            return new URI('file', null, $sp, null);
  334.         */
  335.     }
  336.  
  337.     function _slashify($path, $isDirectory) {
  338.         $p = (string) $path;
  339.  
  340.         if (self::$separator !== '/') {
  341.             $p = str_replace(self::$separator, '/', $p);
  342.         }
  343.  
  344.         if (!StringHelper::startsWith('/', $p)) {
  345.             $p = '/'.$p;
  346.         }
  347.  
  348.         if (!StringHelper::endsWith('/', $p) && $isDirectory) {
  349.             $p = $p.'/';
  350.         }
  351.  
  352.         return $p;
  353.     }
  354.  
  355.     /* -- Attribute accessors -- */
  356.  
  357.     /**
  358.      * Tests whether the application can read the file denoted by this
  359.      * abstract pathname.
  360.      *
  361.      * @return  true if and only if the file specified by this
  362.      *          abstract pathname exists and can be read by the
  363.      *          application; false otherwise
  364.      */
  365.     function canRead() {
  366.         $fs = FileSystem::getFileSystem();
  367.  
  368.         if ($fs->checkAccess($this)) {
  369.             return (boolean) @is_readable($this->getAbsolutePath());
  370.         }
  371.         return false;
  372.     }
  373.  
  374.     /**
  375.      * Tests whether the application can modify to the file denoted by this
  376.      * abstract pathname.
  377.      *
  378.      * @return  true if and only if the file system actually
  379.      *          contains a file denoted by this abstract pathname and
  380.      *          the application is allowed to write to the file;
  381.      *          false otherwise.
  382.      *
  383.      */
  384.     function canWrite() {
  385.         $fs = FileSystem::getFileSystem();
  386.         return $fs->checkAccess($this, true);
  387.     }
  388.  
  389.     /**
  390.      * Tests whether the file denoted by this abstract pathname exists.
  391.      *
  392.      * @return  true if and only if the file denoted by this
  393.      *          abstract pathname exists; false otherwise
  394.      *
  395.      */
  396.     function exists() {                
  397.         clearstatcache();
  398.         if ($this->isFile()) {
  399.             return @file_exists($this->path);
  400.         } else {
  401.             return @is_dir($this->path);
  402.         }
  403.     }
  404.  
  405.     /**
  406.      * Tests whether the file denoted by this abstract pathname is a
  407.      * directory.
  408.      *
  409.      * @return true if and only if the file denoted by this
  410.      *         abstract pathname exists and is a directory;
  411.      *         false otherwise
  412.      *
  413.      */
  414.     function isDirectory() {
  415.         clearstatcache();
  416.         $fs = FileSystem::getFileSystem();
  417.         if ($fs->checkAccess($this) !== true) {
  418.             throw new IOException("No read access to ".$this->path);
  419.         }
  420.         return @is_dir($this->path);
  421.     }
  422.  
  423.     /**
  424.      * Tests whether the file denoted by this abstract pathname is a normal
  425.      * file.  A file is normal if it is not a directory and, in
  426.      * addition, satisfies other system-dependent criteria.  Any non-directory
  427.      * file created by a Java application is guaranteed to be a normal file.
  428.      *
  429.      * @return  true if and only if the file denoted by this
  430.      *          abstract pathname exists and is a normal file;
  431.      *          false otherwise
  432.      */
  433.     function isFile() {
  434.         clearstatcache();
  435.         //$fs = FileSystem::getFileSystem();
  436.         return @is_file($this->path);
  437.     }
  438.  
  439.     /**
  440.      * Tests whether the file named by this abstract pathname is a hidden
  441.      * file.  The exact definition of hidden is system-dependent.  On
  442.      * UNIX systems, a file is considered to be hidden if its name begins with
  443.      * a period character ('.').  On Win32 systems, a file is considered to be
  444.      * hidden if it has been marked as such in the filesystem. Currently there
  445.      * seems to be no way to dermine isHidden on Win file systems via PHP
  446.      *
  447.      * @return  true if and only if the file denoted by this
  448.      *          abstract pathname is hidden according to the conventions of the
  449.      *          underlying platform
  450.      */
  451.     function isHidden() {
  452.         $fs = FileSystem::getFileSystem();
  453.         if ($fs->checkAccess($this) !== true) {
  454.             throw new IOException("No read access to ".$this->path);
  455.         }
  456.         return (($fs->getBooleanAttributes($this) & $fs->BA_HIDDEN) !== 0);
  457.     }
  458.  
  459.     /**
  460.      * Returns the time that the file denoted by this abstract pathname was
  461.      * last modified.
  462.      *
  463.      * @return  A integer value representing the time the file was
  464.      *          last modified, measured in milliseconds since the epoch
  465.      *          (00:00:00 GMT, January 1, 1970), or 0 if the
  466.      *          file does not exist or if an I/O error occurs
  467.      */
  468.     function lastModified() {
  469.         $fs = FileSystem::getFileSystem();
  470.         if ($fs->checkAccess($this) !== true) {
  471.             throw new IOException("No read access to " . $this->path);
  472.         }
  473.         return $fs->getLastModifiedTime($this);
  474.     }
  475.  
  476.     /**
  477.      * Returns the length of the file denoted by this abstract pathname.
  478.      * The return value is unspecified if this pathname denotes a directory.
  479.      *
  480.      * @return  The length, in bytes, of the file denoted by this abstract
  481.      *          pathname, or 0 if the file does not exist
  482.      */
  483.     function length() {
  484.         $fs = FileSystem::getFileSystem();
  485.         if ($fs->checkAccess($this) !== true) {
  486.             throw new IOException("No read access to ".$this->path."\n");
  487.         }
  488.         return $fs->getLength($this);
  489.     }
  490.  
  491.     /**
  492.      * Convenience method for returning the contents of this file as a string.
  493.      * This method uses file_get_contents() to read file in an optimized way.
  494.      * @return string
  495.      * @throws Exception - if file cannot be read
  496.      */
  497.     function contents() {
  498.         if (!$this->canRead() || !$this->isFile()) {
  499.             throw new IOException("Cannot read file contents!");
  500.         }
  501.         return file_get_contents($this->getAbsolutePath());
  502.     }
  503.     
  504.     /* -- File operations -- */
  505.  
  506.     /**
  507.      * Atomically creates a new, empty file named by this abstract pathname if
  508.      * and only if a file with this name does not yet exist.  The check for the
  509.      * existence of the file and the creation of the file if it does not exist
  510.      * are a single operation that is atomic with respect to all other
  511.      * filesystem activities that might affect the file.
  512.      *
  513.      * @return  true if the named file does not exist and was
  514.      *          successfully created; <code>false</code> if the named file
  515.      *          already exists
  516.      * @throws IOException if file can't be created
  517.      */
  518.     function createNewFile($parents=true, $mode=0777) {
  519.         $file = FileSystem::getFileSystem()->createNewFile($this->path);
  520.         return $file;
  521.     }
  522.  
  523.     /**
  524.      * Deletes the file or directory denoted by this abstract pathname.  If
  525.      * this pathname denotes a directory, then the directory must be empty in
  526.      * order to be deleted.
  527.      *
  528.      * @return  true if and only if the file or directory is
  529.      *          successfully deleted; false otherwise
  530.      */
  531.     function delete() {
  532.         $fs = FileSystem::getFileSystem();
  533.         if ($fs->canDelete($this) !== true) {
  534.             throw new IOException("Cannot delete " . $this->path . "\n"); 
  535.         }
  536.         return $fs->delete($this);
  537.     }
  538.  
  539.     /**
  540.      * Requests that the file or directory denoted by this abstract pathname
  541.      * be deleted when php terminates.  Deletion will be attempted only for
  542.      * normal termination of php and if and if only Phing::shutdown() is
  543.      * called.
  544.      *
  545.      * Once deletion has been requested, it is not possible to cancel the
  546.      * request.  This method should therefore be used with care.
  547.      *
  548.      */
  549.     function deleteOnExit() {
  550.         $fs = FileSystem::getFileSystem();
  551.         $fs->deleteOnExit($this);
  552.     }
  553.  
  554.     /**
  555.      * Returns an array of strings naming the files and directories in the
  556.      * directory denoted by this abstract pathname.
  557.      *
  558.      * If this abstract pathname does not denote a directory, then this
  559.      * method returns null  Otherwise an array of strings is
  560.      * returned, one for each file or directory in the directory.  Names
  561.      * denoting the directory itself and the directory's parent directory are
  562.      * not included in the result.  Each string is a file name rather than a
  563.      * complete path.
  564.      *
  565.      * There is no guarantee that the name strings in the resulting array
  566.      * will appear in any specific order; they are not, in particular,
  567.      * guaranteed to appear in alphabetical order.
  568.      *
  569.      * @return  An array of strings naming the files and directories in the
  570.      *          directory denoted by this abstract pathname.  The array will be
  571.      *          empty if the directory is empty.  Returns null if
  572.      *          this abstract pathname does not denote a directory, or if an
  573.      *          I/O error occurs.
  574.      *
  575.      */
  576.     function listDir($filter = null) {
  577.         $fs = FileSystem::getFileSystem();
  578.         return $fs->lister($this, $filter);
  579.     }
  580.  
  581.     function listFiles($filter = null) {
  582.         $ss = $this->listDir($filter);
  583.         if ($ss === null) {
  584.             return null;
  585.         }
  586.         $n = count($ss);
  587.         $fs = array();
  588.         for ($i = 0; $i < $n; $i++) {
  589.             $fs[$i] = new PhingFile((string)$this->path, (string)$ss[$i]);
  590.         }
  591.         return $fs;
  592.     }
  593.  
  594.     /**
  595.      * Creates the directory named by this abstract pathname, including any
  596.      * necessary but nonexistent parent directories.  Note that if this
  597.      * operation fails it may have succeeded in creating some of the necessary
  598.      * parent directories.
  599.      *
  600.      * @return  true if and only if the directory was created,
  601.      *          along with all necessary parent directories; false
  602.      *          otherwise
  603.      * @throws  IOException
  604.      */
  605.     function mkdirs() {
  606.         if ($this->exists()) {
  607.             return false;
  608.         }
  609.         try {
  610.             if ($this->mkdir()) {
  611.                 return true;
  612.             }
  613.         } catch (IOException $ioe) {
  614.             // IOException from mkdir() means that directory propbably didn't exist.
  615.         }        
  616.         $parentFile = $this->getParentFile();
  617.         return (($parentFile !== null) && ($parentFile->mkdirs() && $this->mkdir()));
  618.     }
  619.  
  620.     /**
  621.      * Creates the directory named by this abstract pathname.
  622.      *
  623.      * @return  true if and only if the directory was created; false otherwise
  624.      * @throws  IOException
  625.      */
  626.     function mkdir() {
  627.         $fs = FileSystem::getFileSystem();
  628.  
  629.         if ($fs->checkAccess(new PhingFile($this->path), true) !== true) {
  630.             throw new IOException("No write access to " . $this->getPath());
  631.         }
  632.         return $fs->createDirectory($this);
  633.     }
  634.  
  635.     /**
  636.      * Renames the file denoted by this abstract pathname.
  637.      *
  638.      * @param   destFile  The new abstract pathname for the named file
  639.      * @return  true if and only if the renaming succeeded; false otherwise
  640.      */
  641.     function renameTo(PhingFile $destFile) {
  642.         $fs = FileSystem::getFileSystem();
  643.         if ($fs->checkAccess($this) !== true) {
  644.             throw new IOException("No write access to ".$this->getPath());
  645.         }
  646.         return $fs->rename($this, $destFile);
  647.     }
  648.  
  649.     /**
  650.      * Simple-copies file denoted by this abstract pathname into another
  651.      * PhingFile
  652.      *
  653.      * @param PhingFile $destFile  The new abstract pathname for the named file
  654.      * @return true if and only if the renaming succeeded; false otherwise
  655.      */
  656.     function copyTo(PhingFile $destFile) {
  657.         $fs = FileSystem::getFileSystem();
  658.  
  659.         if ($fs->checkAccess($this) !== true) {
  660.             throw new IOException("No read access to ".$this->getPath()."\n");
  661.         }
  662.  
  663.         if ($fs->checkAccess($destFile, true) !== true) {
  664.             throw new IOException("File::copyTo() No write access to ".$destFile->getPath());
  665.         }
  666.         return $fs->copy($this, $destFile);
  667.     }
  668.  
  669.     /**
  670.      * Sets the last-modified time of the file or directory named by this
  671.      * abstract pathname.
  672.      *
  673.      * All platforms support file-modification times to the nearest second,
  674.      * but some provide more precision.  The argument will be truncated to fit
  675.      * the supported precision.  If the operation succeeds and no intervening
  676.      * operations on the file take place, then the next invocation of the
  677.      * lastModified method will return the (possibly truncated) time argument
  678.      * that was passed to this method.
  679.      *
  680.      * @param  time  The new last-modified time, measured in milliseconds since
  681.      *               the epoch (00:00:00 GMT, January 1, 1970)
  682.      * @return true if and only if the operation succeeded; false otherwise
  683.      */
  684.     function setLastModified($time) {
  685.         $time = (int) $time;
  686.         if ($time < 0) {
  687.             throw new Exception("IllegalArgumentException, Negative $time\n");
  688.         }
  689.  
  690.         // FIXME check if accessible
  691.         $fs = FileSystem::getFileSystem();
  692.         if ($fs->checkAccess($this, true) !== true) {
  693.             throw new IOException("File::setLastModified(). No write access to file\n");
  694.         }
  695.         return $fs->setLastModifiedTime($this, $time);
  696.     }
  697.  
  698.     /**
  699.      * Marks the file or directory named by this abstract pathname so that
  700.      * only read operations are allowed.  After invoking this method the file
  701.      * or directory is guaranteed not to change until it is either deleted or
  702.      * marked to allow write access.  Whether or not a read-only file or
  703.      * directory may be deleted depends upon the underlying system.
  704.      *
  705.      * @return true if and only if the operation succeeded; false otherwise
  706.      */
  707.     function setReadOnly() {
  708.         $fs = FileSystem::getFileSystem();
  709.         if ($fs->checkAccess($this, true) !== true) {
  710.             // Error, no write access
  711.             throw new IOException("No write access to " . $this->getPath());
  712.         }
  713.         return $fs->setReadOnly($this);
  714.     }
  715.  
  716.     /**
  717.      * Sets the mode of the file
  718.      * @param int $mode Ocatal mode.
  719.      */
  720.     function setMode($mode) {
  721.         $fs = FileSystem::getFileSystem();
  722.         return $fs->chmod($this->getPath(), $mode);
  723.     }
  724.  
  725.     /**
  726.      * Retrieve the mode of this file.
  727.      * @return int
  728.      */
  729.     function getMode() {
  730.         return @fileperms($this->getPath());
  731.     }
  732.  
  733.     /* -- Filesystem interface -- */
  734.  
  735.     /**
  736.      * List the available filesystem roots.
  737.      *
  738.      * A particular platform may support zero or more hierarchically-organized
  739.      * file systems.  Each file system has a root  directory from which all
  740.      * other files in that file system can be reached.
  741.      * Windows platforms, for example, have a root directory for each active
  742.      * drive; UNIX platforms have a single root directory, namely "/".
  743.      * The set of available filesystem roots is affected by various system-level
  744.      * operations such the insertion or ejection of removable media and the
  745.      * disconnecting or unmounting of physical or virtual disk drives.
  746.      *
  747.      * This method returns an array of PhingFile objects that
  748.      * denote the root directories of the available filesystem roots.  It is
  749.      * guaranteed that the canonical pathname of any file physically present on
  750.      * the local machine will begin with one of the roots returned by this
  751.      * method.
  752.      *
  753.      * The canonical pathname of a file that resides on some other machine
  754.      * and is accessed via a remote-filesystem protocol such as SMB or NFS may
  755.      * or may not begin with one of the roots returned by this method.  If the
  756.      * pathname of a remote file is syntactically indistinguishable from the
  757.      * pathname of a local file then it will begin with one of the roots
  758.      * returned by this method.  Thus, for example, PhingFile objects
  759.      * denoting the root directories of the mapped network drives of a Windows
  760.      * platform will be returned by this method, while PhingFile
  761.      * objects containing UNC pathnames will not be returned by this method.
  762.      *
  763.      * @return  An array of PhingFile objects denoting the available
  764.      *          filesystem roots, or null if the set of roots
  765.      *          could not be determined.  The array will be empty if there are
  766.      *          no filesystem roots.
  767.      */
  768.     function listRoots() {
  769.         $fs = FileSystem::getFileSystem();
  770.         return (array) $fs->listRoots();
  771.     }
  772.  
  773.     /* -- Tempfile management -- */
  774.  
  775.     /**
  776.      * Returns the path to the temp directory.
  777.      */
  778.     function getTempDir() {
  779.         return Phing::getProperty('php.tmpdir');
  780.     }
  781.  
  782.     /**
  783.      * Static method that creates a unique filename whose name begins with
  784.      * $prefix and ends with $suffix in the directory $directory. $directory
  785.      * is a reference to a PhingFile Object.
  786.      * Then, the file is locked for exclusive reading/writing.
  787.      *
  788.      * @author      manuel holtgrewe, grin@gmx.net
  789.      * @throws      IOException
  790.      * @access      public
  791.      */
  792.     function createTempFile($prefix, $suffix, PhingFile $directory) {
  793.         
  794.         // quick but efficient hack to create a unique filename ;-)
  795.         $result = null;
  796.         do {
  797.             $result = new PhingFile($directory, $prefix . substr(md5(time()), 0, 8) . $suffix);
  798.         } while (file_exists($result->getPath()));
  799.  
  800.         $fs = FileSystem::getFileSystem();
  801.         $fs->createNewFile($result->getPath());
  802.         $fs->lock($result);
  803.  
  804.         return $result;
  805.     }
  806.  
  807.     /**
  808.      * If necessary, $File the lock on $File is removed and then the file is
  809.      * deleted
  810.      *
  811.      * @access      public
  812.      */
  813.     function removeTempFile() {
  814.         $fs = FileSystem::getFileSystem();
  815.         // catch IO Exception
  816.         $fs->unlock($this);
  817.         $this->delete();
  818.     }
  819.  
  820.  
  821.     /* -- Basic infrastructure -- */
  822.  
  823.     /**
  824.      * Compares two abstract pathnames lexicographically.  The ordering
  825.      * defined by this method depends upon the underlying system.  On UNIX
  826.      * systems, alphabetic case is significant in comparing pathnames; on Win32
  827.      * systems it is not.
  828.      *
  829.      * @param PhingFile $file Th file whose pathname sould be compared to the pathname of this file.
  830.      *
  831.      * @return int Zero if the argument is equal to this abstract pathname, a
  832.      *        value less than zero if this abstract pathname is
  833.      *        lexicographically less than the argument, or a value greater
  834.      *        than zero if this abstract pathname is lexicographically
  835.      *        greater than the argument
  836.      */
  837.     function compareTo(PhingFile $file) {
  838.         $fs = FileSystem::getFileSystem();
  839.         return $fs->compare($this, $file);
  840.     }
  841.  
  842.     /**
  843.      * Tests this abstract pathname for equality with the given object.
  844.      * Returns <code>true</code> if and only if the argument is not
  845.      * <code>null</code> and is an abstract pathname that denotes the same file
  846.      * or directory as this abstract pathname.  Whether or not two abstract
  847.      * pathnames are equal depends upon the underlying system.  On UNIX
  848.      * systems, alphabetic case is significant in comparing pathnames; on Win32
  849.      * systems it is not.
  850.      * @return boolean
  851.      */
  852.     function equals($obj) {
  853.         if (($obj !== null) && ($obj instanceof PhingFile)) {
  854.             return ($this->compareTo($obj) === 0);
  855.         }
  856.         return false;
  857.     }
  858.  
  859.     /** Backwards compatibility -- use PHP5's native __tostring method. */
  860.     function toString() {
  861.         return $this->getPath();
  862.     }
  863.     
  864.     /** PHP5's native method. */
  865.     function __toString() {
  866.         return $this->getPath();
  867.     }
  868. }
  869. ?>
  870.