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

Source for file VFS.php

Documentation is available at VFS.php

  1. <?php
  2.  
  3. require_once 'PEAR.php';
  4. require_once 'Log.php';
  5.  
  6. define('VFS_QUOTA_METRIC_BYTE'1);
  7. define('VFS_QUOTA_METRIC_KB'2);
  8. define('VFS_QUOTA_METRIC_MB'3);
  9. define('VFS_QUOTA_METRIC_GB'4);
  10.  
  11. /**
  12.  * VFS API for abstracted file storage and access.
  13.  *
  14.  * $Horde: framework/VFS/lib/VFS.php,v 1.1.2.8 2009/01/06 15:23:46 jan Exp $
  15.  *
  16.  * Copyright 2002-2009 The Horde Project (http://www.horde.org/)
  17.  *
  18.  * See the enclosed file COPYING for license information (LGPL). If you
  19.  * did not receive this file, see http://www.fsf.org/copyleft/lgpl.html.
  20.  *
  21.  * @author  Chuck Hagenbuch <chuck@horde.org>
  22.  * @package VFS
  23.  * @since   Horde 2.2
  24.  */
  25. class VFS {
  26.  
  27.     /**
  28.      * Hash containing connection parameters.
  29.      *
  30.      * @var array 
  31.      */
  32.     var $_params = array();
  33.  
  34.     /**
  35.      * List of additional credentials required for this VFS backend (example:
  36.      * For FTP, we need a username and password to log in to the server with).
  37.      *
  38.      * @var array 
  39.      */
  40.     var $_credentials = array();
  41.  
  42.     /**
  43.      * List of permissions and if they can be changed in this VFS backend.
  44.      *
  45.      * @var array 
  46.      */
  47.     var $_permissions = array(
  48.         'owner' => array('read' => false'write' => false'execute' => false),
  49.         'group' => array('read' => false'write' => false'execute' => false),
  50.         'all'   => array('read' => false'write' => false'execute' => false));
  51.  
  52.     /**
  53.      * A PEAR Log object. If present, will be used to log errors and
  54.      * informational messages about VFS activity.
  55.      *
  56.      * @var Log 
  57.      */
  58.     var $_logger = null;
  59.  
  60.     /**
  61.      * The log level to use - messages with a higher log level than configured
  62.      * here will not be logged. Defaults to only logging errors or higher.
  63.      *
  64.      * @var integer 
  65.      */
  66.     var $_logLevel = PEAR_LOG_ERR;
  67.  
  68.     /**
  69.      * The current size, in bytes, of the VFS item.
  70.      *
  71.      * @var integer 
  72.      */
  73.     var $_vfsSize = null;
  74.  
  75.     /**
  76.      * Constructor.
  77.      *
  78.      * @param array $params  A hash containing connection parameters.
  79.      */
  80.     function VFS($params = array())
  81.     {
  82.         if (empty($params['user'])) {
  83.             $params['user''';
  84.         }
  85.         if (empty($params['vfs_quotalimit'])) {
  86.             $params['vfs_quotalimit'= -1;
  87.         }
  88.         if (empty($params['vfs_quotaroot'])) {
  89.             $params['vfs_quotaroot''/';
  90.         }
  91.         $this->_params $params;
  92.     }
  93.  
  94.     /**
  95.      * Checks the credentials that we have by calling _connect(), to see if
  96.      * there is a valid login.
  97.      *
  98.      * @return mixed  True on success, PEAR_Error describing the problem if the
  99.      *                 credentials are invalid.
  100.      */
  101.     function checkCredentials()
  102.     {
  103.         return $this->_connect();
  104.     }
  105.  
  106.     /**
  107.      * Sets configuration parameters.
  108.      *
  109.      * @param array $params  An associative array with parameter names as keys.
  110.      */
  111.     function setParams($params = array())
  112.     {
  113.         foreach ($params as $name => $value{
  114.             $this->_params[$name$value;
  115.         }
  116.     }
  117.  
  118.     /**
  119.      * Returns configuration parameters.
  120.      *
  121.      * @param string $name  The parameter to return.
  122.      *
  123.      * @return mixed  The parameter value or null if it doesn't exist.
  124.      */
  125.     function getParam($name)
  126.     {
  127.         return isset($this->_params[$name]$this->_params[$name: null;
  128.     }
  129.  
  130.     /**
  131.      * Logs a message if a PEAR Log object is available, and the message's
  132.      * priority is lower than or equal to the configured log level.
  133.      *
  134.      * @param mixed   $message   The message to be logged.
  135.      * @param integer $priority  The message's priority.
  136.      */
  137.     function log($message$priority = PEAR_LOG_ERR)
  138.     {
  139.         if (!isset($this->_logger|| $priority $this->_logLevel{
  140.             return;
  141.         }
  142.  
  143.         if (is_a($message'PEAR_Error')) {
  144.             $userinfo $message->getUserInfo();
  145.             $message $message->getMessage();
  146.             if ($userinfo{
  147.                 if (is_array($userinfo)) {
  148.                     $userinfo implode(', '$userinfo);
  149.                 }
  150.                 $message .= ': ' $userinfo;
  151.             }
  152.         }
  153.  
  154.         /* Make sure to log in the system's locale. */
  155.         $locale setlocale(LC_TIME0);
  156.         setlocale(LC_TIME'C');
  157.  
  158.         $this->_logger->log($message$priority);
  159.  
  160.         /* Restore original locale. */
  161.         setlocale(LC_TIME$locale);
  162.     }
  163.  
  164.     /**
  165.      * Sets the PEAR Log object used to log informational or error messages.
  166.      *
  167.      * @param Log &$logger  The Log object to use.
  168.      */
  169.     function setLogger(&$logger$logLevel = null)
  170.     {
  171.         if (!is_callable(array($logger'log'))) {
  172.             return false;
  173.         }
  174.  
  175.         $this->_logger &$logger;
  176.         if (!is_null($logLevel)) {
  177.             $this->_logLevel $logLevel;
  178.         }
  179.     }
  180.  
  181.     /**
  182.      * Retrieves the size of a file from the VFS.
  183.      *
  184.      * @abstract
  185.      *
  186.      * @param string $path  The pathname to the file.
  187.      * @param string $name  The filename to retrieve.
  188.      *
  189.      * @return integer The file size.
  190.      */
  191.     function size($path$name)
  192.     {
  193.         return PEAR::raiseError(_("Not supported."));
  194.     }
  195.  
  196.     /**
  197.      * Returns the size of a folder
  198.      *
  199.      * @since Horde 3.1
  200.      *
  201.      * @param string $path  The path to the folder.
  202.      * @param string $name  The name of the folder.
  203.      *
  204.      * @return integer  The size of the folder, in bytes, or PEAR_Error on
  205.      *                   failure.
  206.      */
  207.     function getFolderSize($path = null$name = null)
  208.     {
  209.         $size = 0;
  210.         $root ((!is_null($path)) $path '/' ''$name;
  211.         $object_list $this->listFolder($rootnulltruefalsetrue);
  212.         foreach ($object_list as $key => $val{
  213.             if (isset($val['subdirs'])) {
  214.                 $size += $this->getFolderSize($root$key);
  215.             else {
  216.                 $filesize $this->size($root$key);
  217.                 if (is_a($filesize'PEAR_Error')) {
  218.                     return $filesize;
  219.                 }
  220.                 $size += $filesize;
  221.             }
  222.         }
  223.  
  224.         return $size;
  225.     }
  226.  
  227.     /**
  228.      * Retrieves a file from the VFS.
  229.      *
  230.      * @abstract
  231.      *
  232.      * @param string $path  The pathname to the file.
  233.      * @param string $name  The filename to retrieve.
  234.      *
  235.      * @return string The file data.
  236.      */
  237.     function read($path$name)
  238.     {
  239.         return PEAR::raiseError(_("Not supported."));
  240.     }
  241.  
  242.     /**
  243.      * Retrieves a file from the VFS as an on-disk local file.
  244.      *
  245.      * This function provides a file on local disk with the data of a VFS file
  246.      * in it. This file <em>cannot</em> be modified! The behavior if you do
  247.      * modify it is undefined. It will be removed at the end of the request.
  248.      *
  249.      * @param string $path  The pathname to the file.
  250.      * @param string $name  The filename to retrieve.
  251.      *
  252.      * @return string A local filename.
  253.      */
  254.     function readFile($path$name)
  255.     {
  256.         // Create a temporary file and register it for deletion at the
  257.         // end of this request.
  258.         $localFile $this->_getTempFile();
  259.         if (!$localFile{
  260.             return PEAR::raiseError(_("Unable to create temporary file."));
  261.         }
  262.         register_shutdown_function(create_function('''unlink(\'' addslashes($localFile'\');'));
  263.  
  264.         if (is_callable(array($this'readStream'))) {
  265.             // Use a stream from the VFS if possible, to avoid reading all data
  266.             // into memory.
  267.             $stream $this->readStream($path$name);
  268.             if (is_a($stream'PEAR_Error')) {
  269.                 return $stream;
  270.             }
  271.  
  272.             $localStream fopen($localFile'w');
  273.             if (!$localStream{
  274.                 return PEAR::raiseError(_("Unable to open temporary file."));
  275.             }
  276.  
  277.             if (is_callable('stream_copy_to_stream')) {
  278.                 // If we have stream_copy_to_stream, it can do the data transfer
  279.                 // in one go.
  280.                 stream_copy_to_stream($stream$localStream);
  281.             else {
  282.                 // Otherwise loop through in chunks.
  283.                 while ($buffer fread($stream8192)) {
  284.                     fwrite($localStream$buffer);
  285.                 }
  286.             }
  287.  
  288.             fclose($localStream);
  289.         else {
  290.             // We have to read all of the data in one shot.
  291.             $data $this->read($path$name);
  292.             if (is_a($data'PEAR_Error')) {
  293.                 return $data;
  294.             }
  295.  
  296.             if (is_callable('file_put_contents')) {
  297.                 // file_put_contents is more efficient if we have it.
  298.                 file_put_contents($localFile$data);
  299.             else {
  300.                 // Open the local file and write to it.
  301.                 $localStream fopen($localFile'w');
  302.                 if (!$localStream{
  303.                     return PEAR::raiseError(_("Unable to open temporary file."));
  304.                 }
  305.                 if (!fwrite($localStream$data)) {
  306.                     return PEAR::raiseError(_("Unable to write temporary file."));
  307.                 }
  308.                 fclose($localStream);
  309.             }
  310.         }
  311.  
  312.         // $localFile now has $path/$name's data in it.
  313.         return $localFile;
  314.     }
  315.  
  316.     /**
  317.      * Retrieves a part of a file from the VFS. Particularly useful when
  318.      * reading large files which would exceed the PHP memory limits if they
  319.      * were stored in a string.
  320.      *
  321.      * @abstract
  322.      *
  323.      * @param string  $path       The pathname to the file.
  324.      * @param string  $name       The filename to retrieve.
  325.      * @param integer $offset     The offset of the part. (The new offset will
  326.      *                             be stored in here).
  327.      * @param integer $length     The length of the part. If the length = -1,
  328.      *                             the whole part after the offset is retrieved.
  329.      *                             If more bytes are given as exists after the
  330.      *                             given offset. Only the available bytes are
  331.      *                             read.
  332.      * @param integer $remaining  The bytes that are left, after the part that
  333.      *                             is retrieved.
  334.      *
  335.      * @return string The file data.
  336.      */
  337.     function readByteRange($path$name&$offset$length = -1&$remaining)
  338.     {
  339.         return PEAR::raiseError(_("Not supported."));
  340.     }
  341.  
  342.     /**
  343.      * Stores a file in the VFS.
  344.      *
  345.      * @abstract
  346.      *
  347.      * @param string $path         The path to store the file in.
  348.      * @param string $name         The filename to use.
  349.      * @param string $tmpFile      The temporary file containing the data to
  350.      *                              be stored.
  351.      * @param boolean $autocreate  Automatically create directories?
  352.      *
  353.      * @return mixed  True on success or a PEAR_Error object on failure.
  354.      */
  355.     function write($path$name$tmpFile$autocreate = false)
  356.     {
  357.         return PEAR::raiseError(_("Not supported."));
  358.     }
  359.  
  360.     /**
  361.      * Stores a file in the VFS from raw data.
  362.      *
  363.      * @abstract
  364.      *
  365.      * @param string $path         The path to store the file in.
  366.      * @param string $name         The filename to use.
  367.      * @param string $data         The file data.
  368.      * @param boolean $autocreate  Automatically create directories?
  369.      *
  370.      * @return mixed  True on success or a PEAR_Error object on failure.
  371.      */
  372.     function writeData($path$name$data$autocreate = false)
  373.     {
  374.         return PEAR::raiseError(_("Not supported."));
  375.     }
  376.  
  377.     /**
  378.      * Moves a file through the backend.
  379.      *
  380.      * @param string $path         The path of the original file.
  381.      * @param string $name         The name of the original file.
  382.      * @param string $dest         The destination file name.
  383.      * @param boolean $autocreate  Automatically create directories?
  384.      *
  385.      * @return mixed  True on success or a PEAR_Error object on failure.
  386.      */
  387.     function move($path$name$dest$autocreate = false)
  388.     {
  389.         if (is_a($result $this->copy($path$name$dest$autocreate)'PEAR_Error')) {
  390.             return $result;
  391.         }
  392.         return $this->deleteFile($path$name);
  393.     }
  394.  
  395.     /**
  396.      * Copies a file through the backend.
  397.      *
  398.      * @param string $path         The path of the original file.
  399.      * @param string $name         The name of the original file.
  400.      * @param string $dest         The name of the destination directory.
  401.      * @param boolean $autocreate  Automatically create directories?
  402.      *
  403.      * @return mixed  True on success or a PEAR_Error object on failure.
  404.      */
  405.     function copy($path$name$dest$autocreate = false)
  406.     {
  407.         $orig $this->_getPath($path$name);
  408.         if (preg_match('|^' preg_quote($orig'/?$|'$dest)) {
  409.             return PEAR::raiseError(_("Cannot copy file(s) - source and destination are the same."));
  410.         }
  411.  
  412.         if ($autocreate{
  413.             $result $this->autocreatePath($dest);
  414.             if (is_a($result'PEAR_Error')) {
  415.                 return $result;
  416.             }
  417.         }
  418.         if ($this->isFolder($path$name)) {
  419.             if (is_a($result $this->_copyRecursive($path$name$dest)'PEAR_Error')) {
  420.                 return $result;
  421.             }
  422.         else {
  423.             $data $this->read($path$name);
  424.             if (is_a($data'PEAR_Error')) {
  425.                 return $data;
  426.             }
  427.             return $this->writeData($dest$name$data$autocreate);
  428.         }
  429.         return true;
  430.     }
  431.  
  432.     /**
  433.      * Recursively copies a directory through the backend.
  434.      *
  435.      * @access protected
  436.      *
  437.      * @param string $path         The path of the original file.
  438.      * @param string $name         The name of the original file.
  439.      * @param string $dest         The name of the destination directory.
  440.      */
  441.     function _copyRecursive($path$name$dest)
  442.     {
  443.         if (is_a($result $this->createFolder($dest$name)'PEAR_Error')) {
  444.             return $result;
  445.         }
  446.  
  447.         if (is_a($file_list $this->listFolder($this->_getPath($path$name))'PEAR_Error')) {
  448.             return $file_list;
  449.         }
  450.  
  451.         foreach ($file_list as $file{
  452.             $result $this->copy($this->_getPath($path$name),
  453.                                   $file['name'],
  454.                                   $this->_getPath($dest$name));
  455.             if (is_a($result'PEAR_Error')) {
  456.                 return $result;
  457.             }
  458.         }
  459.     }
  460.  
  461.     /**
  462.      * Alias to deleteFile()
  463.      */
  464.     function delete($path$name)
  465.     {
  466.         return $this->deleteFile($path$name);
  467.     }
  468.  
  469.     /**
  470.      * Deletes a file from the VFS.
  471.      *
  472.      * @abstract
  473.      *
  474.      * @param string $path  The path to delete the file from.
  475.      * @param string $name  The filename to delete.
  476.      *
  477.      * @return mixed  True on success or a PEAR_Error object on failure.
  478.      */
  479.     function deleteFile($path$name)
  480.     {
  481.         return PEAR::raiseError(_("Not supported."));
  482.     }
  483.  
  484.     /**
  485.      * Renames a file in the VFS.
  486.      *
  487.      * @abstract
  488.      *
  489.      * @param string $oldpath  The old path to the file.
  490.      * @param string $oldname  The old filename.
  491.      * @param string $newpath  The new path of the file.
  492.      * @param string $newname  The new filename.
  493.      *
  494.      * @return mixed  True on success or a PEAR_Error object on failure.
  495.      */
  496.     function rename($oldpath$oldname$newpath$newname)
  497.     {
  498.         return PEAR::raiseError(_("Not supported."));
  499.     }
  500.  
  501.     /**
  502.      * Returns if a given file or folder exists in a folder.
  503.      *
  504.      * @param string $path  The path to the folder.
  505.      * @param string $name  The file or folder name.
  506.      *
  507.      * @return boolean  True if it exists, false otherwise.
  508.      */
  509.     function exists($path$name)
  510.     {
  511.         $list $this->listFolder($path);
  512.         if (is_a($list'PEAR_Error')) {
  513.             return false;
  514.         else {
  515.             return isset($list[$name]);
  516.         }
  517.     }
  518.  
  519.     /**
  520.      * Creates a folder in the VFS.
  521.      *
  522.      * @abstract
  523.      *
  524.      * @param string $path  The parent folder.
  525.      * @param string $name  The name of the new folder.
  526.      *
  527.      * @return mixed  True on success or a PEAR_Error object on failure.
  528.      */
  529.     function createFolder($path$name)
  530.     {
  531.         return PEAR::raiseError(_("Not supported."));
  532.     }
  533.  
  534.     /**
  535.      * Automatically creates any necessary parent directories in the specified
  536.      * $path.
  537.      *
  538.      * @param string $path  The VFS path to autocreate.
  539.      */
  540.     function autocreatePath($path)
  541.     {
  542.         $dirs explode('/'$path);
  543.         if (is_array($dirs)) {
  544.             $cur '/';
  545.             foreach ($dirs as $dir{
  546.                 if (!strlen($dir)) {
  547.                     continue;
  548.                 }
  549.                 if (!$this->isFolder($cur$dir)) {
  550.                     $result $this->createFolder($cur$dir);
  551.                     if (is_a($result'PEAR_Error')) {
  552.                         return $result;
  553.                     }
  554.                 }
  555.                 if ($cur != '/'{
  556.                     $cur .= '/';
  557.                 }
  558.                 $cur .= $dir;
  559.             }
  560.         }
  561.  
  562.         return true;
  563.     }
  564.  
  565.     /**
  566.      * Checks if a given item is a folder.
  567.      *
  568.      * @param string $path  The parent folder.
  569.      * @param string $name  The item name.
  570.      *
  571.      * @return boolean  True if it is a folder, false otherwise.
  572.      */
  573.     function isFolder($path$name)
  574.     {
  575.         $folderList $this->listFolder($pathnulltruetrue);
  576.         return isset($folderList[$name]);
  577.     }
  578.  
  579.     /**
  580.      * Deletes a folder from the VFS.
  581.      *
  582.      * @abstract
  583.      *
  584.      * @param string $path        The parent folder.
  585.      * @param string $name        The name of the folder to delete.
  586.      * @param boolean $recursive  Force a recursive delete?
  587.      *
  588.      * @return mixed  True on success or a PEAR_Error object on failure.
  589.      */
  590.     function deleteFolder($path$name$recursive = false)
  591.     {
  592.         return PEAR::raiseError(_("Not supported."));
  593.     }
  594.  
  595.     /**
  596.      * Recursively remove all files and subfolders from the given
  597.      * folder.
  598.      *
  599.      * @param string $path  The path of the folder to empty.
  600.      *
  601.      * @return mixed  True on success or a PEAR_Error object on failure.
  602.      */
  603.     function emptyFolder($path)
  604.     {
  605.         // Get and delete the subfolders.
  606.         $list $this->listFolder($pathnulltruetrue);
  607.         if (is_a($list'PEAR_Error')) {
  608.             return $list;
  609.         }
  610.         foreach ($list as $folder{
  611.             $result $this->deleteFolder($path$folder['name']true);
  612.             if (is_a($result'PEAR_Error')) {
  613.                 return $result;
  614.             }
  615.         }
  616.         // Only files are left, get and delete them.
  617.         $list $this->listFolder($path);
  618.         if (is_a($list'PEAR_Error')) {
  619.             return $list;
  620.         }
  621.         foreach ($list as $file{
  622.             $result $this->deleteFile($path$file['name']);
  623.             if (is_a($result'PEAR_Error')) {
  624.                 return $result;
  625.             }
  626.         }
  627.  
  628.         return true;
  629.     }
  630.  
  631.     /**
  632.      * Returns a file list of the directory passed in.
  633.      *
  634.      * @param string $path        The path of the directory.
  635.      * @param mixed $filter       String/hash to filter file/dirname on.
  636.      * @param boolean $dotfiles   Show dotfiles?
  637.      * @param boolean $dironly    Show only directories?
  638.      * @param boolean $recursive  Return all directory levels recursively?
  639.      *
  640.      * @return array  File list on success or PEAR_Error on failure.
  641.      */
  642.     function listFolder($path$filter = null$dotfiles = true,
  643.                         $dironly = false$recursive = false)
  644.     {
  645.         $list $this->_listFolder($path$filter$dotfiles$dironly);
  646.         if (!$recursive || is_a($list'PEAR_Error')) {
  647.             return $list;
  648.         }
  649.  
  650.         foreach ($list as $name => $values{
  651.             if ($values['type'== '**dir'{
  652.                 $list[$name]['subdirs'$this->listFolder($path '/' $name$filter$dotfiles$dironly$recursive);
  653.             }
  654.         }
  655.  
  656.         return $list;
  657.     }
  658.  
  659.     /**
  660.      * Returns an an unsorted file list of the specified directory.
  661.      *
  662.      * @abstract
  663.      *
  664.      * @param string $path       The path of the directory.
  665.      * @param mixed $filter      String/hash to filter file/dirname on.
  666.      * @param boolean $dotfiles  Show dotfiles?
  667.      * @param boolean $dironly   Show only directories?
  668.      *
  669.      * @return array  File list on success or PEAR_Error on failure.
  670.      */
  671.     function _listFolder($path$filter = null$dotfiles = true,
  672.                          $dironly = false)
  673.     {
  674.         return PEAR::raiseError(_("Not supported."));
  675.     }
  676.  
  677.     /**
  678.      * Returns the current working directory of the VFS backend.
  679.      *
  680.      * @return string  The current working directory.
  681.      */
  682.     function getCurrentDirectory()
  683.     {
  684.         return '';
  685.     }
  686.  
  687.     /**
  688.      * Returns whether or not a filename matches any filter element.
  689.      *
  690.      * @access private
  691.      *
  692.      * @param mixed $filter     String/hash to build the regular expression
  693.      *                           from.
  694.      * @param string $filename  String containing the filename to match.
  695.      *
  696.      * @return boolean  True on match, false on no match.
  697.      */
  698.     function _filterMatch($filter$filename)
  699.     {
  700.         $namefilter = null;
  701.  
  702.         // Build a regexp based on $filter.
  703.         if ($filter !== null{
  704.             $namefilter '/';
  705.             if (is_array($filter)) {
  706.                 $once = false;
  707.                 foreach ($filter as $item{
  708.                     if ($once !== true{
  709.                         $namefilter .= '(';
  710.                         $once = true;
  711.                     else {
  712.                         $namefilter .= '|(';
  713.                     }
  714.                     $namefilter .= $item ')';
  715.                 }
  716.             else {
  717.                 $namefilter .= '(' $filter ')';
  718.             }
  719.             $namefilter .= '/';
  720.         }
  721.  
  722.         $match = false;
  723.         if ($namefilter !== null{
  724.             $match preg_match($namefilter$filename);
  725.         }
  726.  
  727.         return $match;
  728.     }
  729.  
  730.     /**
  731.      * Changes permissions for an item on the VFS.
  732.      *
  733.      * @abstract
  734.      *
  735.      * @param string $path        The parent folder of the item.
  736.      * @param string $name        The name of the item.
  737.      * @param string $permission  The permission to set.
  738.      *
  739.      * @return mixed  True on success or a PEAR_Error object on failure.
  740.      */
  741.     function changePermissions($path$name$permission)
  742.     {
  743.         return PEAR::raiseError(_("Not supported."));
  744.     }
  745.  
  746.     /**
  747.      * Returns a sorted list of folders in the specified directory.
  748.      *
  749.      * @abstract
  750.      *
  751.      * @param string $path         The path of the directory to get the
  752.      *                              directory list for.
  753.      * @param mixed $filter        Hash of items to filter based on folderlist.
  754.      * @param boolean $dotfolders  Include dotfolders?
  755.      *
  756.      * @return mixed  Folder list on success or a PEAR_Error object on failure.
  757.      */
  758.     function listFolders($path ''$filter = null$dotfolders = true)
  759.     {
  760.         return PEAR::raiseError(_("Not supported."));
  761.     }
  762.  
  763.     /**
  764.      * Returns the list of additional credentials required, if any.
  765.      *
  766.      * @return array  Credential list.
  767.      */
  768.     function getRequiredCredentials()
  769.     {
  770.         return array_diff($this->_credentialsarray_keys($this->_params));
  771.     }
  772.  
  773.     /**
  774.      * Returns an array specifying what permissions are changeable for this
  775.      * VFS implementation.
  776.      *
  777.      * @return array  Changeable permisions.
  778.      */
  779.     function getModifiablePermissions()
  780.     {
  781.         return $this->_permissions;
  782.     }
  783.  
  784.     /**
  785.      * Converts a string to all lowercase characters ignoring the current
  786.      * locale.
  787.      *
  788.      * @param string $string  The string to be lowercased
  789.      *
  790.      * @return string  The string with lowercase characters
  791.      */
  792.     function strtolower($string)
  793.     {
  794.         $language setlocale(LC_CTYPE0);
  795.         setlocale(LC_CTYPE'C');
  796.         $string strtolower($string);
  797.         setlocale(LC_CTYPE$language);
  798.         return $string;
  799.     }
  800.  
  801.     /**
  802.      * Returns the character (not byte) length of a string.
  803.      *
  804.      * @param string $string   The string to return the length of.
  805.      * @param string $charset  The charset to use when calculating the
  806.      *                          string's length.
  807.      *
  808.      * @return string  The string's length.
  809.      */
  810.     function strlen($string$charset = null)
  811.     {
  812.         if (extension_loaded('mbstring')) {
  813.             if (is_null($charset)) {
  814.                 $charset 'ISO-8859-1';
  815.             }
  816.             $result @mb_strlen($string$charset);
  817.             if (!empty($result)) {
  818.                 return $result;
  819.             }
  820.         }
  821.         return strlen($string);
  822.     }
  823.  
  824.     /**
  825.      * Returns the size of the VFS item.
  826.      *
  827.      * @since Horde 3.1
  828.      *
  829.      * @return integer  The size, in bytes, of the VFS item.
  830.      */
  831.     function getVFSSize()
  832.     {
  833.         if (is_null($this->_vfsSize)) {
  834.             $this->_vfsSize $this->getFolderSize($this->_params['vfs_quotaroot']);
  835.         }
  836.         return $this->_vfsSize;
  837.     }
  838.  
  839.     /**
  840.      * Sets the VFS quota limit.
  841.      *
  842.      * @since Horde 3.1
  843.      *
  844.      * @param integer $quota   The limit to apply.
  845.      * @param integer $metric  The metric to multiply the quota into.
  846.      */
  847.     function setQuota($quota$metric = VFS_QUOTA_METRIC_BYTE)
  848.     {
  849.         switch ($metric{
  850.         case VFS_QUOTA_METRIC_KB:
  851.             $quota *= pow(210);
  852.             break;
  853.  
  854.         case VFS_QUOTA_METRIC_MB:
  855.             $quota *= pow(220);
  856.             break;
  857.  
  858.         case VFS_QUOTA_METRIC_GB:
  859.             $quota *= pow(230);
  860.             break;
  861.         }
  862.  
  863.         $this->_params['vfs_quotalimit'$quota;
  864.     }
  865.  
  866.     /**
  867.      * Sets the VFS quota root.
  868.      *
  869.      * @since Horde 3.1
  870.      *
  871.      * @param string $dir  The root directory for the quota determination.
  872.      */
  873.     function setQuotaRoot($dir)
  874.     {
  875.         $this->_params['vfs_quotaroot'$dir;
  876.     }
  877.  
  878.     /**
  879.      * Get quota information (used/allocated), in bytes.
  880.      *
  881.      * @since Horde 3.1
  882.      *
  883.      * @return mixed  An associative array.
  884.      *                 'limit' = Maximum quota allowed
  885.      *                 'usage' = Currently used portion of quota (in bytes)
  886.      *                 Returns PEAR_Error on failure.
  887.      */
  888.     function getQuota()
  889.     {
  890.         if (empty($this->_params['vfs_quotalimit'])) {
  891.             return PEAR::raiseError(_("No quota set."));
  892.         }
  893.  
  894.         $usage $this->getVFSSize();
  895.         if (is_a($usage'PEAR_Error')) {
  896.             return $usage;
  897.         else {
  898.             return array('usage' => $usage'limit' => $this->_params['vfs_quotalimit']);
  899.         }
  900.     }
  901.  
  902.     /**
  903.      * Determines the location of the system temporary directory.
  904.      *
  905.      * @access protected
  906.      *
  907.      * @return string  A directory name which can be used for temp files.
  908.      *                  Returns false if one could not be found.
  909.      */
  910.     function _getTempDir()
  911.     {
  912.         $tmp_locations = array('/tmp''/var/tmp''c:\WUTemp''c:\temp',
  913.                                'c:\windows\temp''c:\winnt\temp');
  914.  
  915.         /* Try PHP's upload_tmp_dir directive. */
  916.         $tmp ini_get('upload_tmp_dir');
  917.  
  918.         /* Otherwise, try to determine the TMPDIR environment variable. */
  919.         if (!strlen($tmp)) {
  920.             $tmp getenv('TMPDIR');
  921.         }
  922.  
  923.         /* If we still cannot determine a value, then cycle through a list of
  924.          * preset possibilities. */
  925.         while (!strlen($tmp&& count($tmp_locations)) {
  926.             $tmp_check array_shift($tmp_locations);
  927.             if (@is_dir($tmp_check)) {
  928.                 $tmp $tmp_check;
  929.             }
  930.         }
  931.  
  932.         /* If it is still empty, we have failed, so return false; otherwise
  933.          * return the directory determined. */
  934.         return strlen($tmp$tmp : false;
  935.     }
  936.  
  937.     /**
  938.      * Creates a temporary file.
  939.      *
  940.      * @access protected
  941.      *
  942.      * @return string   Returns the full path-name to the temporary file or
  943.      *                   false if a temporary file could not be created.
  944.      */
  945.     function _getTempFile()
  946.     {
  947.         $tmp_dir $this->_getTempDir();
  948.         if (!strlen($tmp_dir)) {
  949.             return false;
  950.         }
  951.  
  952.         $tmp_file tempnam($tmp_dir'vfs');
  953.         if (!strlen($tmp_file)) {
  954.             return false;
  955.         else {
  956.             return $tmp_file;
  957.         }
  958.     }
  959.  
  960.     /**
  961.      * Checks the quota when preparing to write data.
  962.      *
  963.      * @access private
  964.      *
  965.      * @param string $mode   Either 'string' or 'file'.  If 'string', $data is
  966.      *                        the data to be written.  If 'file', $data is the
  967.      *                        filename containing the data to be written.
  968.      * @param string $data   Either the data or the filename to the data.
  969.      *
  970.      * @return mixed  PEAR_Error on error, true on success.
  971.      */
  972.     function _checkQuotaWrite($mode$data)
  973.     {
  974.         if ($this->_params['vfs_quotalimit'!= -1{
  975.             if ($mode == 'file'{
  976.                 $filesize filesize($data);
  977.                 if ($filesize === false{
  978.                     return PEAR::raiseError(_("Unable to read VFS file (filesize() failed)."));
  979.                }
  980.             else {
  981.                 $filesize strlen($data);
  982.             }
  983.             $vfssize $this->getVFSSize();
  984.             if (is_a($vfssize'PEAR_Error')) {
  985.                 return $vfssize;
  986.             }
  987.             if (($vfssize $filesize$this->_params['vfs_quotalimit']{
  988.                 return PEAR::raiseError(_("Unable to write VFS file, quota will be exceeded."));
  989.             elseif ($this->_vfsSize !== 0{
  990.                 $this->_vfsSize += $filesize;
  991.             }
  992.         }
  993.  
  994.         return true;
  995.     }
  996.  
  997.     /**
  998.      * Checks the quota when preparing to delete data.
  999.      *
  1000.      * @access private
  1001.      *
  1002.      * @param string $path  The path the file is located in.
  1003.      * @param string $name  The filename.
  1004.      *
  1005.      * @return mixed  PEAR_Error on error, true on success.
  1006.      */
  1007.     function _checkQuotaDelete($path$name)
  1008.     {
  1009.         if (($this->_params['vfs_quotalimit'!= -1&&
  1010.             !empty($this->_vfsSize)) {
  1011.             $filesize $this->size($path$name);
  1012.             if (is_a($filesize'PEAR_Error')) {
  1013.                 return PEAR::raiseError(_("Unable to read VFS file (size() failed)."));
  1014.             }
  1015.             $this->_vfsSize -= $filesize;
  1016.         }
  1017.  
  1018.         return true;
  1019.     }
  1020.  
  1021.     /**
  1022.      * Returns the full path of an item.
  1023.      *
  1024.      * @access protected
  1025.      *
  1026.      * @param string $path  The path of directory of the item.
  1027.      * @param string $name  The name of the item.
  1028.      *
  1029.      * @return mixed  Full path when $path isset and just $name when not set.
  1030.      */
  1031.     function _getPath($path$name)
  1032.     {
  1033.         if (strlen($path> 0{
  1034.             if (substr($path-1== '/'{
  1035.                 return $path $name;
  1036.             else {
  1037.                 return $path '/' $name;
  1038.             }
  1039.         else {
  1040.             return $name;
  1041.         }
  1042.     }
  1043.  
  1044.     /**
  1045.      * Attempts to return a concrete VFS instance based on $driver.
  1046.      *
  1047.      * @param mixed $driver  The type of concrete VFS subclass to return. This
  1048.      *                        is based on the storage driver ($driver). The
  1049.      *                        code is dynamically included.
  1050.      * @param array $params  A hash containing any additional configuration or
  1051.      *                        connection parameters a subclass might need.
  1052.      *
  1053.      * @return VFS  The newly created concrete VFS instance, or a PEAR_Error
  1054.      *               on failure.
  1055.      */
  1056.     function &factory($driver$params = array())
  1057.     {
  1058.         $driver basename($driver);
  1059.         $class 'VFS_' $driver;
  1060.         if (!class_exists($class)) {
  1061.             include_once 'VFS/' $driver '.php';
  1062.         }
  1063.  
  1064.         if (class_exists($class)) {
  1065.             $vfs = new $class($params);
  1066.         else {
  1067.             $vfs = PEAR::raiseError(sprintf(_("Class definition of %s not found.")$class));
  1068.         }
  1069.  
  1070.         return $vfs;
  1071.     }
  1072.  
  1073.     /**
  1074.      * Attempts to return a reference to a concrete VFS instance based on
  1075.      * $driver. It will only create a new instance if no VFS instance with the
  1076.      * same parameters currently exists.
  1077.      *
  1078.      * This should be used if multiple types of file backends (and, thus,
  1079.      * multiple VFS instances) are required.
  1080.      *
  1081.      * This method must be invoked as: $var = &VFS::singleton()
  1082.      *
  1083.      * @param mixed $driver  The type of concrete VFS subclass to return. This
  1084.      *                        is based on the storage driver ($driver). The
  1085.      *                        code is dynamically included.
  1086.      * @param array $params  A hash containing any additional configuration or
  1087.      *                        connection parameters a subclass might need.
  1088.      *
  1089.      * @return VFS  The concrete VFS reference, or a PEAR_Error on failure.
  1090.      */
  1091.     function &singleton($driver$params = array())
  1092.     {
  1093.         static $instances = array();
  1094.  
  1095.         $signature = serialize(array($driver$params));
  1096.         if (!isset($instances[$signature])) {
  1097.             $instances[$signature&VFS::factory($driver$params);
  1098.         }
  1099.  
  1100.         return $instances[$signature];
  1101.     }
  1102.  
  1103. }

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