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.3 2008/02/03 17:59:40 jan Exp $
  15.  *
  16.  * Copyright 2002-2008 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_a($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 part of a file from the VFS. Particularly useful when
  244.      * reading large files which would exceed the PHP memory limits if they
  245.      * were stored in a string.
  246.      *
  247.      * @abstract
  248.      *
  249.      * @param string  $path       The pathname to the file.
  250.      * @param string  $name       The filename to retrieve.
  251.      * @param integer $offset     The offset of the part. (The new offset will
  252.      *                             be stored in here).
  253.      * @param integer $length     The length of the part. If the length = -1,
  254.      *                             the whole part after the offset is retrieved.
  255.      *                             If more bytes are given as exists after the
  256.      *                             given offset. Only the available bytes are
  257.      *                             read.
  258.      * @param integer $remaining  The bytes that are left, after the part that
  259.      *                             is retrieved.
  260.      *
  261.      * @return string The file data.
  262.      */
  263.     function readByteRange($path$name&$offset$length = -1&$remaining)
  264.     {
  265.         return PEAR::raiseError(_("Not supported."));
  266.     }
  267.  
  268.     /**
  269.      * Stores a file in the VFS.
  270.      *
  271.      * @abstract
  272.      *
  273.      * @param string $path         The path to store the file in.
  274.      * @param string $name         The filename to use.
  275.      * @param string $tmpFile      The temporary file containing the data to
  276.      *                              be stored.
  277.      * @param boolean $autocreate  Automatically create directories?
  278.      *
  279.      * @return mixed  True on success or a PEAR_Error object on failure.
  280.      */
  281.     function write($path$name$tmpFile$autocreate = false)
  282.     {
  283.         return PEAR::raiseError(_("Not supported."));
  284.     }
  285.  
  286.     /**
  287.      * Stores a file in the VFS from raw data.
  288.      *
  289.      * @abstract
  290.      *
  291.      * @param string $path         The path to store the file in.
  292.      * @param string $name         The filename to use.
  293.      * @param string $data         The file data.
  294.      * @param boolean $autocreate  Automatically create directories?
  295.      *
  296.      * @return mixed  True on success or a PEAR_Error object on failure.
  297.      */
  298.     function writeData($path$name$data$autocreate = false)
  299.     {
  300.         return PEAR::raiseError(_("Not supported."));
  301.     }
  302.  
  303.     /**
  304.      * Moves a file through the backend.
  305.      *
  306.      * @param string $path         The path of the original file.
  307.      * @param string $name         The name of the original file.
  308.      * @param string $dest         The destination file name.
  309.      * @param boolean $autocreate  Automatically create directories?
  310.      *
  311.      * @return mixed  True on success or a PEAR_Error object on failure.
  312.      */
  313.     function move($path$name$dest$autocreate = false)
  314.     {
  315.         if (is_a($result $this->copy($path$name$dest$autocreate)'PEAR_Error')) {
  316.             return $result;
  317.         }
  318.         return $this->deleteFile($path$name);
  319.     }
  320.  
  321.     /**
  322.      * Copies a file through the backend.
  323.      *
  324.      * @param string $path         The path of the original file.
  325.      * @param string $name         The name of the original file.
  326.      * @param string $dest         The name of the destination directory.
  327.      * @param boolean $autocreate  Automatically create directories?
  328.      *
  329.      * @return mixed  True on success or a PEAR_Error object on failure.
  330.      */
  331.     function copy($path$name$dest$autocreate = false)
  332.     {
  333.         $orig $this->_getPath($path$name);
  334.         if (preg_match('|^' preg_quote($orig'/?$|'$dest)) {
  335.             return PEAR::raiseError(_("Cannot copy file(s) - source and destination are the same."));
  336.         }
  337.  
  338.         if ($autocreate{
  339.             $result $this->autocreatePath($dest);
  340.             if (is_a($result'PEAR_Error')) {
  341.                 return $result;
  342.             }
  343.         }
  344.         if ($this->isFolder($path$name)) {
  345.             if (is_a($result $this->_copyRecursive($path$name$dest)'PEAR_Error')) {
  346.                 return $result;
  347.             }
  348.         else {
  349.             $data $this->read($path$name);
  350.             if (is_a($data'PEAR_Error')) {
  351.                 return $data;
  352.             }
  353.             return $this->writeData($dest$name$data$autocreate);
  354.         }
  355.         return true;
  356.     }
  357.  
  358.     /**
  359.      * Recursively copies a directory through the backend.
  360.      *
  361.      * @access protected
  362.      *
  363.      * @param string $path         The path of the original file.
  364.      * @param string $name         The name of the original file.
  365.      * @param string $dest         The name of the destination directory.
  366.      */
  367.     function _copyRecursive($path$name$dest)
  368.     {
  369.         if (is_a($result $this->createFolder($dest$name)'PEAR_Error')) {
  370.             return $result;
  371.         }
  372.  
  373.         if (is_a($file_list $this->listFolder($this->_getPath($path$name))'PEAR_Error')) {
  374.             return $file_list;
  375.         }
  376.  
  377.         foreach ($file_list as $file{
  378.             $result $this->copy($this->_getPath($path$name),
  379.                                   $file['name'],
  380.                                   $this->_getPath($dest$name));
  381.             if (is_a($result'PEAR_Error')) {
  382.                 return $result;
  383.             }
  384.         }
  385.     }
  386.  
  387.     /**
  388.      * Deletes a file from the VFS.
  389.      *
  390.      * @abstract
  391.      *
  392.      * @param string $path  The path to delete the file from.
  393.      * @param string $name  The filename to delete.
  394.      *
  395.      * @return mixed  True on success or a PEAR_Error object on failure.
  396.      */
  397.     function deleteFile($path$name)
  398.     {
  399.         return PEAR::raiseError(_("Not supported."));
  400.     }
  401.  
  402.     /**
  403.      * Renames a file in the VFS.
  404.      *
  405.      * @abstract
  406.      *
  407.      * @param string $oldpath  The old path to the file.
  408.      * @param string $oldname  The old filename.
  409.      * @param string $newpath  The new path of the file.
  410.      * @param string $newname  The new filename.
  411.      *
  412.      * @return mixed  True on success or a PEAR_Error object on failure.
  413.      */
  414.     function rename($oldpath$oldname$newpath$newname)
  415.     {
  416.         return PEAR::raiseError(_("Not supported."));
  417.     }
  418.  
  419.     /**
  420.      * Returns if a given file or folder exists in a folder.
  421.      *
  422.      * @param string $path  The path to the folder.
  423.      * @param string $name  The file or folder name.
  424.      *
  425.      * @return boolean  True if it exists, false otherwise.
  426.      */
  427.     function exists($path$name)
  428.     {
  429.         $list $this->listFolder($path);
  430.         if (is_a($list'PEAR_Error')) {
  431.             return false;
  432.         else {
  433.             return isset($list[$name]);
  434.         }
  435.     }
  436.  
  437.     /**
  438.      * Creates a folder in the VFS.
  439.      *
  440.      * @abstract
  441.      *
  442.      * @param string $path  The parent folder.
  443.      * @param string $name  The name of the new folder.
  444.      *
  445.      * @return mixed  True on success or a PEAR_Error object on failure.
  446.      */
  447.     function createFolder($path$name)
  448.     {
  449.         return PEAR::raiseError(_("Not supported."));
  450.     }
  451.  
  452.     /**
  453.      * Automatically creates any necessary parent directories in the specified
  454.      * $path.
  455.      *
  456.      * @param string $path  The VFS path to autocreate.
  457.      */
  458.     function autocreatePath($path)
  459.     {
  460.         $dirs explode('/'$path);
  461.         if (is_array($dirs)) {
  462.             $cur '/';
  463.             foreach ($dirs as $dir{
  464.                 if (!strlen($dir)) {
  465.                     continue;
  466.                 }
  467.                 if (!$this->isFolder($cur$dir)) {
  468.                     $result $this->createFolder($cur$dir);
  469.                     if (is_a($result'PEAR_Error')) {
  470.                         return $result;
  471.                     }
  472.                 }
  473.                 if ($cur != '/'{
  474.                     $cur .= '/';
  475.                 }
  476.                 $cur .= $dir;
  477.             }
  478.         }
  479.  
  480.         return true;
  481.     }
  482.  
  483.     /**
  484.      * Checks if a given item is a folder.
  485.      *
  486.      * @param string $path  The parent folder.
  487.      * @param string $name  The item name.
  488.      *
  489.      * @return boolean  True if it is a folder, false otherwise.
  490.      */
  491.     function isFolder($path$name)
  492.     {
  493.         $folderList $this->listFolder($pathnulltruetrue);
  494.         return isset($folderList[$name]);
  495.     }
  496.  
  497.     /**
  498.      * Deletes a folder from the VFS.
  499.      *
  500.      * @abstract
  501.      *
  502.      * @param string $path        The parent folder.
  503.      * @param string $name        The name of the folder to delete.
  504.      * @param boolean $recursive  Force a recursive delete?
  505.      *
  506.      * @return mixed  True on success or a PEAR_Error object on failure.
  507.      */
  508.     function deleteFolder($path$name$recursive = false)
  509.     {
  510.         return PEAR::raiseError(_("Not supported."));
  511.     }
  512.  
  513.     /**
  514.      * Recursively remove all files and subfolders from the given
  515.      * folder.
  516.      *
  517.      * @param string $path  The path of the folder to empty.
  518.      *
  519.      * @return mixed  True on success or a PEAR_Error object on failure.
  520.      */
  521.     function emptyFolder($path)
  522.     {
  523.         // Get and delete the subfolders.
  524.         $list $this->listFolder($pathnulltruetrue);
  525.         if (is_a($list'PEAR_Error')) {
  526.             return $list;
  527.         }
  528.         foreach ($list as $folder{
  529.             $result $this->deleteFolder($path$folder['name']true);
  530.             if (is_a($result'PEAR_Error')) {
  531.                 return $result;
  532.             }
  533.         }
  534.         // Only files are left, get and delete them.
  535.         $list $this->listFolder($path);
  536.         if (is_a($list'PEAR_Error')) {
  537.             return $list;
  538.         }
  539.         foreach ($list as $file{
  540.             $result $this->deleteFile($path$file['name']);
  541.             if (is_a($result'PEAR_Error')) {
  542.                 return $result;
  543.             }
  544.         }
  545.  
  546.         return true;
  547.     }
  548.  
  549.     /**
  550.      * Returns a file list of the directory passed in.
  551.      *
  552.      * @param string $path        The path of the directory.
  553.      * @param mixed $filter       String/hash to filter file/dirname on.
  554.      * @param boolean $dotfiles   Show dotfiles?
  555.      * @param boolean $dironly    Show only directories?
  556.      * @param boolean $recursive  Return all directory levels recursively?
  557.      *
  558.      * @return array  File list on success or PEAR_Error on failure.
  559.      */
  560.     function listFolder($path$filter = null$dotfiles = true,
  561.                         $dironly = false$recursive = false)
  562.     {
  563.         $list $this->_listFolder($path$filter$dotfiles$dironly);
  564.         if (!$recursive || is_a($list'PEAR_Error')) {
  565.             return $list;
  566.         }
  567.  
  568.         foreach ($list as $name => $values{
  569.             if ($values['type'== '**dir'{
  570.                 $list[$name]['subdirs'$this->listFolder($path '/' $name$filter$dotfiles$dironly$recursive);
  571.             }
  572.         }
  573.  
  574.         return $list;
  575.     }
  576.  
  577.     /**
  578.      * Returns an an unsorted file list of the specified directory.
  579.      *
  580.      * @abstract
  581.      *
  582.      * @param string $path       The path of the directory.
  583.      * @param mixed $filter      String/hash to filter file/dirname on.
  584.      * @param boolean $dotfiles  Show dotfiles?
  585.      * @param boolean $dironly   Show only directories?
  586.      *
  587.      * @return array  File list on success or PEAR_Error on failure.
  588.      */
  589.     function _listFolder($path$filter = null$dotfiles = true,
  590.                          $dironly = false)
  591.     {
  592.         return PEAR::raiseError(_("Not supported."));
  593.     }
  594.  
  595.     /**
  596.      * Returns the current working directory of the VFS backend.
  597.      *
  598.      * @return string  The current working directory.
  599.      */
  600.     function getCurrentDirectory()
  601.     {
  602.         return '';
  603.     }
  604.  
  605.     /**
  606.      * Returns whether or not a filename matches any filter element.
  607.      *
  608.      * @access private
  609.      *
  610.      * @param mixed $filter     String/hash to build the regular expression
  611.      *                           from.
  612.      * @param string $filename  String containing the filename to match.
  613.      *
  614.      * @return boolean  True on match, false on no match.
  615.      */
  616.     function _filterMatch($filter$filename)
  617.     {
  618.         $namefilter = null;
  619.  
  620.         // Build a regexp based on $filter.
  621.         if ($filter !== null{
  622.             $namefilter '/';
  623.             if (is_array($filter)) {
  624.                 $once = false;
  625.                 foreach ($filter as $item{
  626.                     if ($once !== true{
  627.                         $namefilter .= '(';
  628.                         $once = true;
  629.                     else {
  630.                         $namefilter .= '|(';
  631.                     }
  632.                     $namefilter .= $item ')';
  633.                 }
  634.             else {
  635.                 $namefilter .= '(' $filter ')';
  636.             }
  637.             $namefilter .= '/';
  638.         }
  639.  
  640.         $match = false;
  641.         if ($namefilter !== null{
  642.             $match preg_match($namefilter$filename);
  643.         }
  644.  
  645.         return $match;
  646.     }
  647.  
  648.     /**
  649.      * Changes permissions for an item on the VFS.
  650.      *
  651.      * @abstract
  652.      *
  653.      * @param string $path        The parent folder of the item.
  654.      * @param string $name        The name of the item.
  655.      * @param string $permission  The permission to set.
  656.      *
  657.      * @return mixed  True on success or a PEAR_Error object on failure.
  658.      */
  659.     function changePermissions($path$name$permission)
  660.     {
  661.         return PEAR::raiseError(_("Not supported."));
  662.     }
  663.  
  664.     /**
  665.      * Returns a sorted list of folders in the specified directory.
  666.      *
  667.      * @abstract
  668.      *
  669.      * @param string $path         The path of the directory to get the
  670.      *                              directory list for.
  671.      * @param mixed $filter        Hash of items to filter based on folderlist.
  672.      * @param boolean $dotfolders  Include dotfolders?
  673.      *
  674.      * @return mixed  Folder list on success or a PEAR_Error object on failure.
  675.      */
  676.     function listFolders($path ''$filter = null$dotfolders = true)
  677.     {
  678.         return PEAR::raiseError(_("Not supported."));
  679.     }
  680.  
  681.     /**
  682.      * Returns the list of additional credentials required, if any.
  683.      *
  684.      * @return array  Credential list.
  685.      */
  686.     function getRequiredCredentials()
  687.     {
  688.         return array_diff($this->_credentialsarray_keys($this->_params));
  689.     }
  690.  
  691.     /**
  692.      * Returns an array specifying what permissions are changeable for this
  693.      * VFS implementation.
  694.      *
  695.      * @return array  Changeable permisions.
  696.      */
  697.     function getModifiablePermissions()
  698.     {
  699.         return $this->_permissions;
  700.     }
  701.  
  702.     /**
  703.      * Converts a string to all lowercase characters ignoring the current
  704.      * locale.
  705.      *
  706.      * @param string $string  The string to be lowercased
  707.      *
  708.      * @return string  The string with lowercase characters
  709.      */
  710.     function strtolower($string)
  711.     {
  712.         $language setlocale(LC_CTYPE0);
  713.         setlocale(LC_CTYPE'C');
  714.         $string strtolower($string);
  715.         setlocale(LC_CTYPE$language);
  716.         return $string;
  717.     }
  718.  
  719.     /**
  720.      * Returns the character (not byte) length of a string.
  721.      *
  722.      * @param string $string   The string to return the length of.
  723.      * @param string $charset  The charset to use when calculating the
  724.      *                          string's length.
  725.      *
  726.      * @return string  The string's length.
  727.      */
  728.     function strlen($string$charset = null)
  729.     {
  730.         if (extension_loaded('mbstring')) {
  731.             if (is_null($charset)) {
  732.                 $charset 'ISO-8859-1';
  733.             }
  734.             $result @mb_strlen($string$charset);
  735.             if (!empty($result)) {
  736.                 return $result;
  737.             }
  738.         }
  739.         return strlen($string);
  740.     }
  741.  
  742.     /**
  743.      * Returns the size of the VFS item.
  744.      *
  745.      * @since Horde 3.1
  746.      *
  747.      * @return integer  The size, in bytes, of the VFS item.
  748.      */
  749.     function getVFSSize()
  750.     {
  751.         if (is_null($this->_vfsSize)) {
  752.             $this->_vfsSize $this->getFolderSize($this->_params['vfs_quotaroot']);
  753.         }
  754.         return $this->_vfsSize;
  755.     }
  756.  
  757.     /**
  758.      * Sets the VFS quota limit.
  759.      *
  760.      * @since Horde 3.1
  761.      *
  762.      * @param integer $quota   The limit to apply.
  763.      * @param integer $metric  The metric to multiply the quota into.
  764.      */
  765.     function setQuota($quota$metric = VFS_QUOTA_METRIC_BYTE)
  766.     {
  767.         switch ($metric{
  768.         case VFS_QUOTA_METRIC_KB:
  769.             $quota *= pow(210);
  770.             break;
  771.  
  772.         case VFS_QUOTA_METRIC_MB:
  773.             $quota *= pow(220);
  774.             break;
  775.  
  776.         case VFS_QUOTA_METRIC_GB:
  777.             $quota *= pow(230);
  778.             break;
  779.         }
  780.  
  781.         $this->_params['vfs_quotalimit'$quota;
  782.     }
  783.  
  784.     /**
  785.      * Sets the VFS quota root.
  786.      *
  787.      * @since Horde 3.1
  788.      *
  789.      * @param string $dir  The root directory for the quota determination.
  790.      */
  791.     function setQuotaRoot($dir)
  792.     {
  793.         $this->_params['vfs_quotaroot'$dir;
  794.     }
  795.  
  796.     /**
  797.      * Get quota information (used/allocated), in bytes.
  798.      *
  799.      * @since Horde 3.1
  800.      *
  801.      * @return mixed  An associative array.
  802.      *                 'limit' = Maximum quota allowed
  803.      *                 'usage' = Currently used portion of quota (in bytes)
  804.      *                 Returns PEAR_Error on failure.
  805.      */
  806.     function getQuota()
  807.     {
  808.         if (empty($this->_params['vfs_quotalimit'])) {
  809.             return PEAR::raiseError(_("No quota set."));
  810.         }
  811.  
  812.         $usage $this->getVFSSize();
  813.         if (is_a($usage'PEAR_Error')) {
  814.             return $usage;
  815.         else {
  816.             return array('usage' => $usage'limit' => $this->_params['vfs_quotalimit']);
  817.         }
  818.     }
  819.  
  820.     /**
  821.      * Determines the location of the system temporary directory.
  822.      *
  823.      * @access protected
  824.      *
  825.      * @return string  A directory name which can be used for temp files.
  826.      *                  Returns false if one could not be found.
  827.      */
  828.     function _getTempDir()
  829.     {
  830.         $tmp_locations = array('/tmp''/var/tmp''c:\WUTemp''c:\temp',
  831.                                'c:\windows\temp''c:\winnt\temp');
  832.  
  833.         /* Try PHP's upload_tmp_dir directive. */
  834.         $tmp ini_get('upload_tmp_dir');
  835.  
  836.         /* Otherwise, try to determine the TMPDIR environment variable. */
  837.         if (!strlen($tmp)) {
  838.             $tmp getenv('TMPDIR');
  839.         }
  840.  
  841.         /* If we still cannot determine a value, then cycle through a list of
  842.          * preset possibilities. */
  843.         while (!strlen($tmp&& count($tmp_locations)) {
  844.             $tmp_check array_shift($tmp_locations);
  845.             if (@is_dir($tmp_check)) {
  846.                 $tmp $tmp_check;
  847.             }
  848.         }
  849.  
  850.         /* If it is still empty, we have failed, so return false; otherwise
  851.          * return the directory determined. */
  852.         return strlen($tmp$tmp : false;
  853.     }
  854.  
  855.     /**
  856.      * Creates a temporary file.
  857.      *
  858.      * @access protected
  859.      *
  860.      * @return string   Returns the full path-name to the temporary file or
  861.      *                   false if a temporary file could not be created.
  862.      */
  863.     function _getTempFile()
  864.     {
  865.         $tmp_dir $this->_getTempDir();
  866.         if (!strlen($tmp_dir)) {
  867.             return false;
  868.         }
  869.  
  870.         $tmp_file tempnam($tmp_dir'vfs');
  871.  
  872.         /* If the file was created, then register it for deletion and
  873.          * return. */
  874.         if (!strlen($tmp_file)) {
  875.             return false;
  876.         else {
  877.             return $tmp_file;
  878.         }
  879.     }
  880.  
  881.     /**
  882.      * Checks the quota when preparing to write data.
  883.      *
  884.      * @access private
  885.      *
  886.      * @param string $mode   Either 'string' or 'file'.  If 'string', $data is
  887.      *                        the data to be written.  If 'file', $data is the
  888.      *                        filename containing the data to be written.
  889.      * @param string &$data  Either the data or the filename to the data.
  890.      *
  891.      * @return mixed  PEAR_Error on error, true on success.
  892.      */
  893.     function _checkQuotaWrite($mode&$data)
  894.     {
  895.         if ($this->_params['vfs_quotalimit'!= -1{
  896.             if ($mode == 'file'{
  897.                 $filesize filesize($data);
  898.                 if ($filesize === false{
  899.                     return PEAR::raiseError(_("Unable to read VFS file (filesize() failed)."));
  900.                }
  901.             else {
  902.                 $filesize strlen($data);
  903.             }
  904.             $vfssize $this->getVFSSize();
  905.             if (is_a($vfssize'PEAR_Error')) {
  906.                 return $vfssize;
  907.             }
  908.             if (($vfssize $filesize$this->_params['vfs_quotalimit']{
  909.                 return PEAR::raiseError(_("Unable to write VFS file, quota will be exceeded."));
  910.             elseif ($this->_vfsSize !== 0{
  911.                 $this->_vfsSize += $filesize;
  912.             }
  913.         }
  914.  
  915.         return true;
  916.     }
  917.  
  918.     /**
  919.      * Checks the quota when preparing to delete data.
  920.      *
  921.      * @access private
  922.      *
  923.      * @param string $path  The path the file is located in.
  924.      * @param string $name  The filename.
  925.      *
  926.      * @return mixed  PEAR_Error on error, true on success.
  927.      */
  928.     function _checkQuotaDelete($path$name)
  929.     {
  930.         if (($this->_params['vfs_quotalimit'!= -1&&
  931.             !empty($this->_vfsSize)) {
  932.             $filesize $this->size($path$name);
  933.             if (is_a($filesize'PEAR_Error')) {
  934.                 return PEAR::raiseError(_("Unable to read VFS file (size() failed)."));
  935.             }
  936.             $this->_vfsSize -= $filesize;
  937.         }
  938.  
  939.         return true;
  940.     }
  941.  
  942.     /**
  943.      * Returns the full path of an item.
  944.      *
  945.      * @access protected
  946.      *
  947.      * @param string $path  The path of directory of the item.
  948.      * @param string $name  The name of the item.
  949.      *
  950.      * @return mixed  Full path when $path isset and just $name when not set.
  951.      */
  952.     function _getPath($path$name)
  953.     {
  954.         if (strlen($path> 0{
  955.             if (substr($path-1== '/'{
  956.                 return $path $name;
  957.             else {
  958.                 return $path '/' $name;
  959.             }
  960.         else {
  961.             return $name;
  962.         }
  963.     }
  964.  
  965.     /**
  966.      * Attempts to return a concrete VFS instance based on $driver.
  967.      *
  968.      * @param mixed $driver  The type of concrete VFS subclass to return. This
  969.      *                        is based on the storage driver ($driver). The
  970.      *                        code is dynamically included.
  971.      * @param array $params  A hash containing any additional configuration or
  972.      *                        connection parameters a subclass might need.
  973.      *
  974.      * @return VFS  The newly created concrete VFS instance, or a PEAR_Error
  975.      *               on failure.
  976.      */
  977.     function &factory($driver$params = array())
  978.     {
  979.         $driver basename($driver);
  980.         $class 'VFS_' $driver;
  981.         if (!class_exists($class)) {
  982.             include_once 'VFS/' $driver '.php';
  983.         }
  984.  
  985.         if (class_exists($class)) {
  986.             $vfs = new $class($params);
  987.         else {
  988.             $vfs = PEAR::raiseError(sprintf(_("Class definition of %s not found.")$class));
  989.         }
  990.  
  991.         return $vfs;
  992.     }
  993.  
  994.     /**
  995.      * Attempts to return a reference to a concrete VFS instance based on
  996.      * $driver. It will only create a new instance if no VFS instance with the
  997.      * same parameters currently exists.
  998.      *
  999.      * This should be used if multiple types of file backends (and, thus,
  1000.      * multiple VFS instances) are required.
  1001.      *
  1002.      * This method must be invoked as: $var = &VFS::singleton()
  1003.      *
  1004.      * @param mixed $driver  The type of concrete VFS subclass to return. This
  1005.      *                        is based on the storage driver ($driver). The
  1006.      *                        code is dynamically included.
  1007.      * @param array $params  A hash containing any additional configuration or
  1008.      *                        connection parameters a subclass might need.
  1009.      *
  1010.      * @return VFS  The concrete VFS reference, or a PEAR_Error on failure.
  1011.      */
  1012.     function &singleton($driver$params = array())
  1013.     {
  1014.         static $instances;
  1015.         if (!isset($instances)) {
  1016.             $instances = array();
  1017.         }
  1018.  
  1019.         $signature serialize(array($driver$params));
  1020.         if (!isset($instances[$signature])) {
  1021.             $instances[$signature&VFS::factory($driver$params);
  1022.         }
  1023.  
  1024.         return $instances[$signature];
  1025.     }
  1026.  
  1027. }

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