VFS
[ class tree: VFS ] [ index: VFS ] [ all elements ]

Source for file file.php

Documentation is available at file.php

  1. <?php
  2. /**
  3.  * VFS implementation for a standard filesystem.
  4.  *
  5.  * Required parameters:<pre>
  6.  *   'vfsroot'  The root path</pre>
  7.  *
  8.  * Note: The user that your webserver runs as (commonly 'nobody',
  9.  * 'apache', or 'www-data') MUST have read/write permission to the
  10.  * directory you specify as the 'vfsroot'.
  11.  *
  12.  * $Horde: framework/VFS/lib/VFS/file.php,v 1.1.2.6 2009/10/15 17:18:48 jan Exp $
  13.  *
  14.  * Copyright 2002-2009 The Horde Project (http://www.horde.org/)
  15.  *
  16.  * See the enclosed file COPYING for license information (LGPL). If you
  17.  * did not receive this file, see http://www.fsf.org/copyleft/lgpl.html.
  18.  *
  19.  * @author  Chuck Hagenbuch
  20.  * @package VFS
  21.  */
  22. class VFS_file extends VFS {
  23.  
  24.     /**
  25.      * List of permissions and if they can be changed in this VFS
  26.      * backend.
  27.      *
  28.      * @var array 
  29.      */
  30.     var $_permissions = array(
  31.         'owner' => array('read' => true, 'write' => true, 'execute' => true),
  32.         'group' => array('read' => true, 'write' => true, 'execute' => true),
  33.         'all'   => array('read' => true, 'write' => true, 'execute' => true)
  34.     );
  35.  
  36.     /**
  37.      * Constructs a new Filesystem based VFS object.
  38.      *
  39.      * @param array $params  A hash containing connection parameters.
  40.      */
  41.     function VFS_file($params = array())
  42.     {
  43.         parent::VFS($params);
  44.  
  45.         if (!empty($this->_params['vfsroot'])) {
  46.             if (substr($this->_params['vfsroot'], -1) == '/' ||
  47.                 substr($this->_params['vfsroot'], -1) == '\\') {
  48.                 $this->_params['vfsroot'] = substr($this->_params['vfsroot'], 0, strlen($this->_params['vfsroot']) - 1);
  49.             }
  50.         }
  51.     }
  52.  
  53.     /**
  54.      * Retrieves the filesize from the VFS.
  55.      *
  56.      * @param string $path  The pathname to the file.
  57.      * @param string $name  The filename to retrieve.
  58.      *
  59.      * @return integer The file size.
  60.      */
  61.     function size($path, $name)
  62.     {
  63.         $size = @filesize($this->_getNativePath($path, $name));
  64.         if ($size === false) {
  65.             return PEAR::raiseError(sprintf(_("Unable to check file size of \"%s/%s\"."), $path, $name));
  66.         }
  67.         return $size;
  68.     }
  69.  
  70.     /**
  71.      * Retrieve a file from the VFS.
  72.      *
  73.      * @param string $path  The pathname to the file.
  74.      * @param string $name  The filename to retrieve.
  75.      *
  76.      * @return string  The file data.
  77.      */
  78.     function read($path, $name)
  79.     {
  80.         $data = @file_get_contents($this->_getNativePath($path, $name));
  81.         if ($data === false) {
  82.             return PEAR::raiseError(_("Unable to open VFS file."));
  83.         }
  84.  
  85.         return $data;
  86.     }
  87.  
  88.     /**
  89.      * Retrieves a file from the VFS as an on-disk local file.
  90.      *
  91.      * This function provides a file on local disk with the data of a VFS file
  92.      * in it. This file <em>cannot</em> be modified! The behavior if you do
  93.      * modify it is undefined. It will be removed at the end of the request.
  94.      *
  95.      * @param string $path  The pathname to the file.
  96.      * @param string $name  The filename to retrieve.
  97.      *
  98.      * @return string A local filename.
  99.      */
  100.     function readFile($path, $name)
  101.     {
  102.         return $this->_getNativePath($path, $name);
  103.     }
  104.  
  105.     /**
  106.      * Open a read-only stream to a file in the VFS.
  107.      *
  108.      * @param string $path  The pathname to the file.
  109.      * @param string $name  The filename to retrieve.
  110.      *
  111.      * @return resource  The stream.
  112.      */
  113.     function readStream($path, $name)
  114.     {
  115.         $mode = OS_WINDOWS ? 'rb' : 'r';
  116.         $stream = @fopen($this->_getNativePath($path, $name), $mode);
  117.         if (!is_resource($stream)) {
  118.             return PEAR::raiseError(_("Unable to open VFS file."));
  119.         }
  120.  
  121.         return $stream;
  122.     }
  123.  
  124.     /**
  125.      * Retrieves a part of a file from the VFS. Particularly useful when
  126.      * reading large files which would exceed the PHP memory limits if they
  127.      * were stored in a string.
  128.      *
  129.      * @abstract
  130.      *
  131.      * @param string  $path       The pathname to the file.
  132.      * @param string  $name       The filename to retrieve.
  133.      * @param integer $offset     The offset of the part. (The new offset will
  134.      *                             be stored in here).
  135.      * @param integer $length     The length of the part. If the length = -1,
  136.      *                             the whole part after the offset is retrieved.
  137.      *                             If more bytes are given as exists after the
  138.      *                             given offset. Only the available bytes are
  139.      *                             read.
  140.      * @param integer $remaining  The bytes that are left, after the part that
  141.      *                             is retrieved.
  142.      *
  143.      * @return string The file data.
  144.      */
  145.     function readByteRange($path, $name, &$offset, $length = -1, &$remaining)
  146.     {
  147.         if ($offset < 0) {
  148.             return PEAR::raiseError(sprintf(_("Wrong offset %d while reading a VFS file."), $offset));
  149.         }
  150.  
  151.         // Calculate how many bytes MUST be read, so the remainging
  152.         // bytes and the new offset can be calculated correctly.
  153.         $file = $this->_getNativePath($path, $name);
  154.         $size = filesize ($file);
  155.         if ($length == -1 || (($length + $offset) > $size)) {
  156.             $length = $size - $offset;
  157.         }
  158.         if ($remaining < 0) {
  159.             $remaining = 0;
  160.         }
  161.  
  162.         $fp = @fopen($file, 'rb');
  163.         if (!$fp) {
  164.             return PEAR::raiseError(_("Unable to open VFS file."));
  165.         }
  166.         fseek($fp, $offset);
  167.         $data = fread($fp, $length);
  168.         $offset = ftell($fp);
  169.         $remaining = $size - $offset;
  170.  
  171.         fclose($fp);
  172.  
  173.         return $data;
  174.     }
  175.  
  176.     /**
  177.      * Store a file in the VFS, with the data copied from a temporary
  178.      * file.
  179.      *
  180.      * @param string $path         The path to store the file in.
  181.      * @param string $name         The filename to use.
  182.      * @param string $tmpFile      The temporary file containing the data to be
  183.      *                              stored.
  184.      * @param boolean $autocreate  Automatically create directories?
  185.      *
  186.      * @return mixed  True on success or a PEAR_Error object on failure.
  187.      */
  188.     function write($path, $name, $tmpFile, $autocreate = true)
  189.     {
  190.         if (!@is_dir($this->_getNativePath($path))) {
  191.             if ($autocreate) {
  192.                 $res = $this->autocreatePath($path);
  193.                 if (is_a($res, 'PEAR_Error')) {
  194.                     return $res;
  195.                 }
  196.             } else {
  197.                 return PEAR::raiseError(_("VFS directory does not exist."));
  198.             }
  199.         }
  200.  
  201.         $res = $this->_checkQuotaWrite('file', $tmpFile);
  202.         if (is_a($res, 'PEAR_Error')) {
  203.             return $res;
  204.         }
  205.  
  206.         // Since we already have the data in a file, don't read it
  207.         // into PHP's memory at all - just copy() it to the new
  208.         // location. We leave it to the caller to clean up the
  209.         // temporary file, so we don't use rename().
  210.         if (@copy($tmpFile, $this->_getNativePath($path, $name))) {
  211.             return true;
  212.         } else {
  213.             return PEAR::raiseError(_("Unable to write VFS file (copy() failed)."));
  214.         }
  215.     }
  216.  
  217.     /**
  218.      * Moves a file in the database and the file system.
  219.      *
  220.      * @param string $path         The path to store the file in.
  221.      * @param string $name         The filename to use.
  222.      * @param string $dest         The destination of the file.
  223.      * @param boolean $autocreate  Automatically create directories?
  224.      *
  225.      * @return mixed  True on success or a PEAR_Error object on failure.
  226.      */
  227.     function move($path, $name, $dest, $autocreate = false)
  228.     {
  229.         $orig = $this->_getNativePath($path, $name);
  230.         if (preg_match('|^' . preg_quote($orig) . '/?$|', $dest)) {
  231.             return PEAR::raiseError(_("Cannot move file(s) - destination is within source."));
  232.         }
  233.  
  234.         if ($autocreate) {
  235.             $result = $this->autocreatePath($dest);
  236.             if (is_a($result, 'PEAR_Error')) {
  237.                 return $result;
  238.             }
  239.         }
  240.  
  241.         $fileCheck = $this->listFolder($dest, false);
  242.         if (is_a($fileCheck, 'PEAR_Error')) {
  243.             return $fileCheck;
  244.         }
  245.         foreach ($fileCheck as $file) {
  246.             if ($file['name'] == $name) {
  247.                 return PEAR::raiseError(_("Unable to move VFS file."));
  248.             }
  249.         }
  250.  
  251.         if (!@rename($orig, $this->_getNativePath($dest, $name))) {
  252.             return PEAR::raiseError(_("Unable to move VFS file."));
  253.         }
  254.  
  255.         return true;
  256.     }
  257.  
  258.     /**
  259.      * Copies a file through the backend.
  260.      *
  261.      * @param string $path         The path to store the file in.
  262.      * @param string $name         The filename to use.
  263.      * @param string $dest         The destination of the file.
  264.      * @param boolean $autocreate  Automatically create directories?
  265.      *
  266.      * @return mixed  True on success or a PEAR_Error object on failure.
  267.      */
  268.     function copy($path, $name, $dest, $autocreate = false)
  269.     {
  270.         $orig = $this->_getNativePath($path, $name);
  271.         if (preg_match('|^' . preg_quote($orig) . '/?$|', $dest)) {
  272.             return PEAR::raiseError(_("Cannot copy file(s) - source and destination are the same."));
  273.         }
  274.  
  275.         if ($autocreate) {
  276.             $result = $this->autocreatePath($dest);
  277.             if (is_a($result, 'PEAR_Error')) {
  278.                 return $result;
  279.             }
  280.         }
  281.  
  282.         $fileCheck = $this->listFolder($dest, false);
  283.         if (is_a($fileCheck, 'PEAR_Error')) {
  284.             return $fileCheck;
  285.         }
  286.         foreach ($fileCheck as $file) {
  287.             if ($file['name'] == $name) {
  288.                 return PEAR::raiseError(_("Unable to copy VFS file."));
  289.             }
  290.         }
  291.  
  292.         $res = $this->_checkQuotaWrite('file', $orig);
  293.         if (is_a($res, 'PEAR_Error')) {
  294.             return $res;
  295.         }
  296.  
  297.         if (!@copy($orig, $this->_getNativePath($dest, $name))) {
  298.             return PEAR::raiseError(_("Unable to copy VFS file."));
  299.         }
  300.  
  301.         return true;
  302.     }
  303.  
  304.     /**
  305.      * Store a file in the VFS from raw data.
  306.      *
  307.      * @param string $path         The path to store the file in.
  308.      * @param string $name         The filename to use.
  309.      * @param string $data         The file data.
  310.      * @param boolean $autocreate  Automatically create directories?
  311.      *
  312.      * @return mixed  True on success or a PEAR_Error object on failure.
  313.      */
  314.     function writeData($path, $name, $data, $autocreate = true)
  315.     {
  316.         if (!@is_dir($this->_getNativePath($path))) {
  317.             if ($autocreate) {
  318.                 $res = $this->autocreatePath($path);
  319.                 if (is_a($res, 'PEAR_Error')) {
  320.                     return $res;
  321.                 }
  322.             } else {
  323.                 return PEAR::raiseError(_("VFS directory does not exist."));
  324.             }
  325.         }
  326.  
  327.         // Treat an attempt to write an empty file as a touch() call,
  328.         // since otherwise the file will not be created at all.
  329.         if (!strlen($data)) {
  330.             if (@touch($this->_getNativePath($path, $name))) {
  331.                 return true;
  332.             } else {
  333.                 return PEAR::raiseError(_("Unable to create empty VFS file."));
  334.             }
  335.         }
  336.  
  337.         $res = $this->_checkQuotaWrite('string', $data);
  338.         if (is_a($res, 'PEAR_Error')) {
  339.             return $res;
  340.         }
  341.  
  342.         // Otherwise we go ahead and try to write out the file.
  343.         if (function_exists('file_put_contents')) {
  344.             if (!@file_put_contents($this->_getNativePath($path, $name), $data)) {
  345.                 return PEAR::raiseError(_("Unable to write VFS file data."));
  346.             }
  347.         } else {
  348.             $fp = @fopen($this->_getNativePath($path, $name), 'w');
  349.             if (!$fp) {
  350.                 return PEAR::raiseError(_("Unable to open VFS file for writing."));
  351.             }
  352.  
  353.             if (!@fwrite($fp, $data)) {
  354.                 return PEAR::raiseError(_("Unable to write VFS file data."));
  355.             }
  356.         }
  357.  
  358.         return true;
  359.     }
  360.  
  361.     /**
  362.      * Delete a file from the VFS.
  363.      *
  364.      * @param string $path  The path to store the file in.
  365.      * @param string $name  The filename to use.
  366.      *
  367.      * @return mixed  True on success or a PEAR_Error object on failure.
  368.      */
  369.     function deleteFile($path, $name)
  370.     {
  371.         $res = $this->_checkQuotaDelete($path, $name);
  372.         if (is_a($res, 'PEAR_Error')) {
  373.             return $res;
  374.         }
  375.  
  376.         if (!@unlink($this->_getNativePath($path, $name))) {
  377.             return PEAR::raiseError(_("Unable to delete VFS file."));
  378.         }
  379.  
  380.         return true;
  381.     }
  382.  
  383.     /**
  384.      * Delete a folder from the VFS.
  385.      *
  386.      * @param string $path        The path to delete the folder from.
  387.      * @param string $name        The foldername to use.
  388.      * @param boolean $recursive  Force a recursive delete?
  389.      *
  390.      * @return mixed True on success or a PEAR_Error object on failure.
  391.      */
  392.     function deleteFolder($path, $name, $recursive = false)
  393.     {
  394.         if ($recursive) {
  395.             $result = $this->emptyFolder($path . '/' . $name);
  396.             if (is_a($result, 'PEAR_Error')) {
  397.                 return $result;
  398.             }
  399.         } else {
  400.             $list = $this->listFolder($path . '/' . $name);
  401.             if (is_a($list, 'PEAR_Error')) {
  402.                 return $list;
  403.             }
  404.             if (count($list)) {
  405.                 return PEAR::raiseError(sprintf(_("Unable to delete %s, the directory is not empty"),
  406.                                                 $path . '/' . $name));
  407.             }
  408.         }
  409.  
  410.         if (!@rmdir($this->_getNativePath($path, $name))) {
  411.             return PEAR::raiseError(_("Unable to delete VFS directory."));
  412.         }
  413.  
  414.         return true;
  415.     }
  416.  
  417.     /**
  418.      * Creates a folder on the VFS.
  419.      *
  420.      * @param string $path  The path to create the folder in.
  421.      * @param string $name  The foldername to use.
  422.      *
  423.      * @return mixed  True on success or a PEAR_Error object on failure.
  424.      */
  425.     function createFolder($path, $name)
  426.     {
  427.         if (!@mkdir($this->_getNativePath($path, $name))) {
  428.             return PEAR::raiseError(_("Unable to create VFS directory."));
  429.         }
  430.  
  431.         return true;
  432.     }
  433.  
  434.     /**
  435.      * Check if a given pathname is a folder.
  436.      *
  437.      * @param string $path  The path to the folder.
  438.      * @param string $name  The file/folder name.
  439.      *
  440.      * @return boolean  True if it is a folder, false otherwise.
  441.      */
  442.     function isFolder($path, $name)
  443.     {
  444.         return @is_dir($this->_getNativePath($path, $name));
  445.     }
  446.  
  447.     /**
  448.      * Changes permissions for an item in the VFS.
  449.      *
  450.      * @param string $path         The path of directory of the item.
  451.      * @param string $name         The name of the item.
  452.      * @param integer $permission  The octal value of the new permission.
  453.      *
  454.      * @return mixed  True on success or a PEAR_Error object on failure.
  455.      */
  456.     function changePermissions($path, $name, $permission)
  457.     {
  458.         if (!@chmod($this->_getNativePath($path, $name), $permission)) {
  459.             return PEAR::raiseError(sprintf(_("Unable to change permission for VFS file %s/%s."), $path, $name));
  460.         }
  461.  
  462.         return true;
  463.     }
  464.  
  465.     /**
  466.      * Return a list of the contents of a folder.
  467.      *
  468.      * @param string $path       The path of the directory.
  469.      * @param mixed $filter      String/hash to filter file/dirname on.
  470.      * @param boolean $dotfiles  Show dotfiles?
  471.      * @param boolean $dironly   Show only directories?
  472.      *
  473.      * @return array  File list on success, PEAR_Error on error.
  474.      */
  475.     function _listFolder($path, $filter = null, $dotfiles = true,
  476.                          $dironly = false)
  477.     {
  478.         $files = array();
  479.         $path = isset($path) ? $this->_getNativePath($path) : $this->_getNativePath();
  480.  
  481.         if (!@is_dir($path)) {
  482.             return PEAR::raiseError(_("Not a directory"));
  483.         }
  484.  
  485.         if (!@chdir($path)) {
  486.             return PEAR::raiseError(_("Unable to access VFS directory."));
  487.         }
  488.  
  489.         $handle = opendir($path);
  490.         while (($entry = readdir($handle)) !== false) {
  491.             // Filter out '.' and '..' entries.
  492.             if ($entry == '.' || $entry == '..') {
  493.                 continue;
  494.             }
  495.  
  496.             // Filter out dotfiles if they aren't wanted.
  497.             if (!$dotfiles && substr($entry, 0, 1) == '.') {
  498.                 continue;
  499.             }
  500.  
  501.             // File name
  502.             $file['name'] = $entry;
  503.  
  504.             // Unix style file permissions
  505.             $file['perms'] = $this->_getUnixPerms(fileperms($entry));
  506.  
  507.             // Owner
  508.             $file['owner'] = fileowner($entry);
  509.             if (function_exists('posix_getpwuid')) {
  510.                 $owner = posix_getpwuid($file['owner']);
  511.                 $file['owner'] = $owner['name'];
  512.             }
  513.  
  514.             // Group
  515.             $file['group'] = filegroup($entry);
  516.             if (function_exists('posix_getgrgid')) {
  517.                 if (PHP_VERSION != '5.2.1') {
  518.                     $group = posix_getgrgid($file['group']);
  519.                     $file['group'] = $group['name'];
  520.                 }
  521.             }
  522.  
  523.             // Size
  524.             $file['size'] = filesize($entry);
  525.  
  526.             // Date
  527.             $file['date'] = filemtime($entry);
  528.  
  529.             // Type
  530.             if (@is_dir($entry) && !is_link($entry)) {
  531.                 $file['perms'] = 'd' . $file['perms'];
  532.                 $file['type'] = '**dir';
  533.                 $file['size'] = -1;
  534.             } elseif (is_link($entry)) {
  535.                 $file['perms'] = 'l' . $file['perms'];
  536.                 $file['type'] = '**sym';
  537.                 $file['link'] = readlink($entry);
  538.                 $file['linktype'] = '**none';
  539.                 if (file_exists($file['link'])) {
  540.                     if (is_dir($file['link'])) {
  541.                         $file['linktype'] = '**dir';
  542.                     } elseif (is_link($file['link'])) {
  543.                         $file['linktype'] = '**sym';
  544.                     } elseif (is_file($file['link'])) {
  545.                         $ext = explode('.', $file['link']);
  546.                         if (!(count($ext) == 1 || ($ext[0] === '' && count($ext) == 2))) {
  547.                             $file['linktype'] = VFS::strtolower($ext[count($ext) - 1]);
  548.                         }
  549.                     }
  550.                 } else {
  551.                     $file['linktype'] = '**broken';
  552.                 }
  553.             } elseif (is_file($entry)) {
  554.                 $file['perms'] = '-' . $file['perms'];
  555.                 $ext = explode('.', $entry);
  556.  
  557.                 if (count($ext) == 1 || (substr($file['name'], 0, 1) === '.' && count($ext) == 2)) {
  558.                     $file['type'] = '**none';
  559.                 } else {
  560.                     $file['type'] = VFS::strtolower($ext[count($ext) - 1]);
  561.                 }
  562.             } else {
  563.                 $file['type'] = '**none';
  564.                 if ((fileperms($entry) & 0xC000) == 0xC000) {
  565.                     $file['perms'] = 's' . $file['perms'];
  566.                 } elseif ((fileperms($entry) & 0x6000) == 0x6000) {
  567.                     $file['perms'] = 'b' . $file['perms'];
  568.                 } elseif ((fileperms($entry) & 0x2000) == 0x2000) {
  569.                     $file['perms'] = 'c' . $file['perms'];
  570.                 } elseif ((fileperms($entry) & 0x1000) == 0x1000) {
  571.                     $file['perms'] = 'p' . $file['perms'];
  572.                 } else {
  573.                     $file['perms'] = '?' . $file['perms'];
  574.                 }
  575.             }
  576.  
  577.             // Filtering.
  578.             if ($this->_filterMatch($filter, $file['name'])) {
  579.                 unset($file);
  580.                 continue;
  581.             }
  582.             if ($dironly && $file['type'] !== '**dir') {
  583.                 unset($file);
  584.                 continue;
  585.             }
  586.  
  587.             $files[$file['name']] = $file;
  588.             unset($file);
  589.         }
  590.  
  591.         return $files;
  592.     }
  593.  
  594.     /**
  595.      * Returns a sorted list of folders in specified directory.
  596.      *
  597.      * @param string $path         The path of the directory to get the
  598.      *                              directory list for.
  599.      * @param mixed $filter        Hash of items to filter based on folderlist.
  600.      * @param boolean $dotfolders  Include dotfolders?
  601.      *
  602.      * @return mixed  Folder list on success or a PEAR_Error object on failure.
  603.      */
  604.     function listFolders($path = '', $filter = null, $dotfolders = true)
  605.     {
  606.         $conn = $this->_connect();
  607.         if (is_a($conn, 'PEAR_Error')) {
  608.             return $conn;
  609.         }
  610.  
  611.         $folders = array();
  612.         $folders[dirname($path)] = array('val' => dirname($path),
  613.                                          'abbrev' => '..',
  614.                                          'label' => '..');
  615.  
  616.         $folderList = $this->listFolder($path, null, $dotfolders, true);
  617.         if (is_a($folderList, 'PEAR_Error')) {
  618.             return $folderList;
  619.         }
  620.  
  621.         foreach ($folderList as $name => $files) {
  622.             $folders[$name] = array('val' => $path . '/' . $files['name'],
  623.                                     'abbrev' => $files['name'],
  624.                                     'label' => $path . '/' . $files['name']);
  625.         }
  626.  
  627.         ksort($folders);
  628.  
  629.         return $folders;
  630.     }
  631.  
  632.     /**
  633.      * Return Unix style perms.
  634.      *
  635.      * @access private
  636.      *
  637.      * @param integer $perms  The permissions to set.
  638.      *
  639.      * @return string  Unix style perms.
  640.      */
  641.     function _getUnixPerms($perms)
  642.     {
  643.         // Determine permissions
  644.         $owner['read']    = ($perms & 00400) ? 'r' : '-';
  645.         $owner['write']   = ($perms & 00200) ? 'w' : '-';
  646.         $owner['execute'] = ($perms & 00100) ? 'x' : '-';
  647.         $group['read']    = ($perms & 00040) ? 'r' : '-';
  648.         $group['write']   = ($perms & 00020) ? 'w' : '-';
  649.         $group['execute'] = ($perms & 00010) ? 'x' : '-';
  650.         $world['read']    = ($perms & 00004) ? 'r' : '-';
  651.         $world['write']   = ($perms & 00002) ? 'w' : '-';
  652.         $world['execute'] = ($perms & 00001) ? 'x' : '-';
  653.  
  654.         // Adjust for SUID, SGID and sticky bit
  655.         if ($perms & 0x800) {
  656.             $owner['execute'] = ($owner['execute'] == 'x') ? 's' : 'S';
  657.         }
  658.         if ($perms & 0x400) {
  659.             $group['execute'] = ($group['execute'] == 'x') ? 's' : 'S';
  660.         }
  661.         if ($perms & 0x200) {
  662.             $world['execute'] = ($world['execute'] == 'x') ? 't' : 'T';
  663.         }
  664.  
  665.         $unixPerms = $owner['read'] . $owner['write'] . $owner['execute'] .
  666.                      $group['read'] . $group['write'] . $group['execute'] .
  667.                      $world['read'] . $world['write'] . $world['execute'];
  668.  
  669.         return $unixPerms;
  670.     }
  671.  
  672.     /**
  673.      * Rename a file or folder in the VFS.
  674.      *
  675.      * @param string $oldpath  The old path to the file.
  676.      * @param string $oldname  The old filename.
  677.      * @param string $newpath  The new path of the file.
  678.      * @param string $newname  The new filename.
  679.      *
  680.      * @return mixed  True on success or a PEAR_Error object on failure.
  681.      */
  682.     function rename($oldpath, $oldname, $newpath, $newname)
  683.     {
  684.         if (!@is_dir($this->_getNativePath($newpath))) {
  685.             if (is_a($res = $this->autocreatePath($newpath), 'PEAR_Error')) {
  686.                 return $res;
  687.             }
  688.         }
  689.  
  690.         if (!@rename($this->_getNativePath($oldpath, $oldname),
  691.                      $this->_getNativePath($newpath, $newname))) {
  692.             return PEAR::raiseError(sprintf(_("Unable to rename VFS file %s/%s."), $oldpath, $oldname));
  693.         }
  694.  
  695.         return true;
  696.     }
  697.  
  698.     /**
  699.      * Returns if a given file or folder exists in a folder.
  700.      *
  701.      * @param string $path  The path to the folder.
  702.      * @param string $name  The file or folder name.
  703.      *
  704.      * @return boolean  True if it exists, false otherwise.
  705.      */
  706.     function exists($path, $name)
  707.     {
  708.         return file_exists($this->_getNativePath($path, $name));
  709.     }
  710.  
  711.     /**
  712.      * Return a full filename on the native filesystem, from a VFS
  713.      * path and name.
  714.      *
  715.      * @access private
  716.      *
  717.      * @param string $path  The VFS file path.
  718.      * @param string $name  The VFS filename.
  719.      *
  720.      * @return string  The full native filename.
  721.      */
  722.     function _getNativePath($path = '', $name = '')
  723.     {
  724.         $name = basename($name);
  725.         if (strlen($name)) {
  726.             $name = str_replace('..', '', $name);
  727.             if (substr($name, 0, 1) != '/') {
  728.                 $name = '/' . $name;
  729.             }
  730.         }
  731.  
  732.         if (strlen($path)) {
  733.             if (isset($this->_params['home']) &&
  734.                 preg_match('|^~/?(.*)$|', $path, $matches)) {
  735.                 $path = $this->_params['home'] . '/' . $matches[1];
  736.             }
  737.  
  738.             $path = str_replace('..', '', $path);
  739.             if (substr($path, 0, 1) == '/') {
  740.                 return $this->_params['vfsroot'] . $path . $name;
  741.             } else {
  742.                 return $this->_params['vfsroot'] . '/' . $path . $name;
  743.             }
  744.         } else {
  745.             return $this->_params['vfsroot'] . $name;
  746.         }
  747.     }
  748.  
  749.     /**
  750.      * Stub to check if we have a valid connection. Makes sure that
  751.      * the vfsroot is readable.
  752.      *
  753.      * @access private
  754.      *
  755.      * @return mixed  True if vfsroot is readable, PEAR_Error if it isn't.
  756.      */
  757.     function _connect()
  758.     {
  759.         if ((@is_dir($this->_params['vfsroot']) &&
  760.              is_readable($this->_params['vfsroot'])) ||
  761.             @mkdir($this->_params['vfsroot'])) {
  762.             return true;
  763.         } else {
  764.             return PEAR::raiseError(_("Unable to read the vfsroot directory."));
  765.         }
  766.     }
  767.  
  768. }

Documentation generated on Mon, 11 Mar 2019 15:34:53 -0400 by phpDocumentor 1.4.4. PEAR Logo Copyright © PHP Group 2004.