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

Source for file sql_file.php

Documentation is available at sql_file.php

  1. <?php
  2.  
  3. /**
  4.  * File value for vfs_type column.
  5.  */
  6. define('VFS_FILE'1);
  7.  
  8. /**
  9.  * Folder value for vfs_type column.
  10.  */
  11. define('VFS_FOLDER'2);
  12.  
  13. /**
  14.  * VFS:: implementation using PHP's PEAR database abstraction
  15.  * layer and local file system for file storage.
  16.  *
  17.  * Required values for $params:<pre>
  18.  *      'phptype'       The database type (ie. 'pgsql', 'mysql', etc.).
  19.  *      'vfsroot'       The root directory of where the files should be
  20.  *                      actually stored.</pre>
  21.  *
  22.  * Optional values:<pre>
  23.  *      'table'         The name of the vfs table in 'database'. Defaults to
  24.  *                      'horde_vfs'.</pre>
  25.  *
  26.  * Required by some database implementations:<pre>
  27.  *      'hostspec'      The hostname of the database server.
  28.  *      'protocol'      The communication protocol ('tcp', 'unix', etc.).
  29.  *      'database'      The name of the database.
  30.  *      'username'      The username with which to connect to the database.
  31.  *      'password'      The password associated with 'username'.
  32.  *      'options'       Additional options to pass to the database.
  33.  *      'tty'           The TTY on which to connect to the database.
  34.  *      'port'          The port on which to connect to the database.</pre>
  35.  *
  36.  * The table structure for the VFS can be found in
  37.  * data/vfs.sql.
  38.  *
  39.  * $Horde: framework/VFS/VFS/sql_file.php,v 1.68 2006/03/30 08:03:09 selsky Exp $
  40.  *
  41.  * @author  Michael Varghese <mike.varghese@ascellatech.com>
  42.  * @since   Horde 2.2
  43.  * @package VFS
  44.  */
  45. class VFS_sql_file extends VFS {
  46.  
  47.     /**
  48.      * Handle for the current database connection.
  49.      *
  50.      * @var DB 
  51.      */
  52.     var $_db = false;
  53.  
  54.     /**
  55.      * Retrieve a file from the VFS.
  56.      *
  57.      * @param string $path  The pathname to the file.
  58.      * @param string $name  The filename to retrieve.
  59.      *
  60.      * @return string  The file data.
  61.      */
  62.     function read($path$name)
  63.     {
  64.         $conn $this->_connect();
  65.         if (is_a($conn'PEAR_Error')) {
  66.             return $conn;
  67.         }
  68.  
  69.         $file $this->_getNativePath($path$name);
  70.  
  71.         if (function_exists('file_get_contents')) {
  72.             $data file_get_contents($file);
  73.         else {
  74.             $fp @fopen($file'rb');
  75.             if (!$fp{
  76.                 return PEAR::raiseError(_("Unable to open VFS file."));
  77.             }
  78.             $data fread($fpfilesize($file));
  79.             fclose($fp);
  80.         }
  81.  
  82.         return $data;
  83.     }
  84.  
  85.     /**
  86.      * Store a file in the VFS, with the data copied from a temporary
  87.      * file.
  88.      *
  89.      * @param string $path         The path to store the file in.
  90.      * @param string $name         The filename to use.
  91.      * @param string $tmpFile      The temporary file containing the data to be
  92.      *                              stored.
  93.      * @param boolean $autocreate  Automatically create directories?
  94.      *
  95.      * @return mixed  True on success or a PEAR_Error object on failure.
  96.      */
  97.     function write($path$name$tmpFile$autocreate = false)
  98.     {
  99.         /* No need to check quota here as we will check it when we call
  100.          * writeData(). */
  101.  
  102.         if (function_exists('file_get_contents')) {
  103.             $data file_get_contents($tmpFile);
  104.         else {
  105.             $dataFP @fopen($tmpFile'rb');
  106.             $data @fread($dataFPfilesize($tmpFile));
  107.             fclose($dataFP);
  108.         }
  109.         return $this->writeData($path$name$data$autocreate);
  110.     }
  111.  
  112.     /**
  113.      * Store a file in the VFS from raw data.
  114.      *
  115.      * @param string $path         The path to store the file in.
  116.      * @param string $name         The filename to use.
  117.      * @param string $data         The file data.
  118.      * @param boolean $autocreate  Automatically create directories?
  119.      *
  120.      * @return mixed  True on success or a PEAR_Error object on failure.
  121.      */
  122.     function writeData($path$name$data$autocreate = false)
  123.     {
  124.         $res $this->_checkQuotaWrite('string'$data);
  125.         if (is_a($res'PEAR_Error')) {
  126.             return $res;
  127.         }
  128.  
  129.         $fp @fopen($this->_getNativePath($path$name)'w');
  130.         if (!$fp{
  131.             if ($autocreate{
  132.                 $result $this->autocreatePath($path);
  133.                 if (is_a($result'PEAR_Error')) {
  134.                     return $result;
  135.                 }
  136.                 $fp @fopen($this->_getNativePath($path$name)'w');
  137.                 if (!$fp{
  138.                     return PEAR::raiseError(_("Unable to open VFS file for writing."));
  139.                 }
  140.             else {
  141.                 return PEAR::raiseError(_("Unable to open VFS file for writing."));
  142.             }
  143.         }
  144.  
  145.         if (!@fwrite($fp$data)) {
  146.             return PEAR::raiseError(_("Unable to write VFS file data."));
  147.         }
  148.  
  149.         if (is_a($this->_writeSQLData($path$name$autocreate)'PEAR_Error')) {
  150.             @unlink($this->_getNativePath($path$name));
  151.             return PEAR::raiseError(_("Unable to write VFS file data."));
  152.         }
  153.     }
  154.  
  155.     /**
  156.      * Moves a file in the database and the file system.
  157.      *
  158.      * @param string $path         The path to store the file in.
  159.      * @param string $name         The old filename.
  160.      * @param string $dest         The new filename.
  161.      * @param boolean $autocreate  Automatically create directories?
  162.      *
  163.      * @return mixed  True on success or a PEAR_Error object on failure.
  164.      */
  165.     function move($path$name$dest$autocreate = false)
  166.     {
  167.         $orig $this->_getNativePath($path$name);
  168.         if (preg_match('|^' preg_quote($orig'[$/]|'$dest)) {
  169.             return PEAR::raiseError(_("Cannot move file(s) - destination is within source."));
  170.         }
  171.  
  172.         $conn $this->_connect();
  173.         if (is_a($conn'PEAR_Error')) {
  174.             return $conn;
  175.         }
  176.  
  177.         if ($autocreate{
  178.             $result $this->autocreatePath($dest);
  179.             if (is_a($result'PEAR_Error')) {
  180.                 return $result;
  181.             }
  182.         }
  183.  
  184.         $fileCheck $this->listFolder($destnullfalse);
  185.         if (is_a($fileCheck'PEAR_Error')) {
  186.             return $fileCheck;
  187.         }
  188.         foreach ($fileCheck as $file{
  189.             if ($file['name'== $name{
  190.                 return PEAR::raiseError(_("Unable to move VFS file."));
  191.             }
  192.         }
  193.  
  194.         if (strpos($dest$this->_getSQLNativePath($path$name)) !== false{
  195.             return PEAR::raiseError(_("Unable to move VFS file."));
  196.         }
  197.  
  198.         return $this->rename($path$name$dest$name);
  199.     }
  200.  
  201.     /**
  202.      * Copies a file through the backend.
  203.      *
  204.      * @param string $path         The path to store the file in.
  205.      * @param string $name         The filename to use.
  206.      * @param string $dest         The destination of the file.
  207.      * @param boolean $autocreate  Automatically create directories?
  208.      *
  209.      * @return mixed  True on success or a PEAR_Error object on failure.
  210.      */
  211.     function copy($path$name$dest$autocreate = false)
  212.     {
  213.         $orig $this->_getNativePath($path$name);
  214.         if (preg_match('|^' preg_quote($orig'[$/]|'$dest)) {
  215.             return PEAR::raiseError(_("Cannot copy file(s) - source and destination are the same."));
  216.         }
  217.  
  218.         $conn $this->_connect();
  219.         if (is_a($conn'PEAR_Error')) {
  220.             return $conn;
  221.         }
  222.  
  223.         if ($autocreate{
  224.             $result $this->autocreatePath($dest);
  225.             if (is_a($result'PEAR_Error')) {
  226.                 return $result;
  227.             }
  228.         }
  229.  
  230.         $fileCheck $this->listFolder($destnullfalse);
  231.         if (is_a($fileCheck'PEAR_Error')) {
  232.             return $fileCheck;
  233.         }
  234.         foreach ($fileCheck as $file{
  235.             if ($file['name'== $name{
  236.                 return PEAR::raiseError(_("Unable to copy VFS file."));
  237.             }
  238.         }
  239.  
  240.         if (strpos($dest$this->_getSQLNativePath($path$name)) !== false{
  241.             return PEAR::raiseError(_("Unable to copy VFS file."));
  242.         }
  243.  
  244.         if (is_dir($orig)) {
  245.             return $this->_recursiveCopy($path$name$dest);
  246.         }
  247.  
  248.         if (!@copy($orig$this->_getNativePath($dest$name))) {
  249.             return PEAR::raiseError(_("Unable to copy VFS file."));
  250.         }
  251.  
  252.         $id $this->_db->nextId($this->_params['table']);
  253.  
  254.         $query sprintf('INSERT INTO %s (vfs_id, vfs_type, vfs_path, vfs_name, vfs_modified, vfs_owner) VALUES (?, ?, ?, ?, ?, ?)',
  255.                          $this->_params['table']);
  256.         $values = array($idVFS_FILE$dest$nametime()$this->_params['user']);
  257.  
  258.         $result $this->_db->query($query$values);
  259.  
  260.         if (is_a($result'PEAR_Error')) {
  261.             unlink($this->_getNativePath($dest$name));
  262.             return $result;
  263.         }
  264.  
  265.         return true;
  266.     }
  267.  
  268.     /**
  269.      * Creates a folder on the VFS.
  270.      *
  271.      * @param string $path  Holds the path of directory to create folder.
  272.      * @param string $name  Holds the name of the new folder.
  273.      *
  274.      * @return mixed  True on success or a PEAR_Error object on failure.
  275.      */
  276.     function createFolder($path$name)
  277.     {
  278.         $conn $this->_connect();
  279.         if (is_a($conn'PEAR_Error')) {
  280.             return $conn;
  281.         }
  282.  
  283.         $id $this->_db->nextId($this->_params['table']);
  284.         $result $this->_db->query(sprintf('INSERT INTO %s (vfs_id, vfs_type, vfs_path, vfs_name, vfs_modified, vfs_owner)
  285.                                             VALUES (?, ?, ?, ?, ?, ?)',
  286.                                             $this->_params['table']),
  287.                                     array($idVFS_FOLDER$path$nametime()$this->_params['user']));
  288.         if (is_a($result'PEAR_Error')) {
  289.             return $result;
  290.         }
  291.  
  292.         if (!@mkdir($this->_getNativePath($path$name))) {
  293.             $result $this->_db->query(sprintf('DELETE FROM %s WHERE vfs_id = ?',
  294.                                                 $this->_params['table']),
  295.                                         array($id));
  296.             return PEAR::raiseError(_("Unable to create VFS directory."));
  297.         }
  298.  
  299.         return true;
  300.     }
  301.  
  302.     /**
  303.      * Rename a file or folder in the VFS.
  304.      *
  305.      * @param string $oldpath  The old path to the file.
  306.      * @param string $oldname  The old filename.
  307.      * @param string $newpath  The new path of the file.
  308.      * @param string $newname  The new filename.
  309.      *
  310.      * @return mixed  True on success or a PEAR_Error object on failure.
  311.      */
  312.     function rename($oldpath$oldname$newpath$newname)
  313.     {
  314.         $conn $this->_connect();
  315.         if (is_a($conn'PEAR_Error')) {
  316.             return $conn;
  317.         }
  318.  
  319.         if (strpos($newpath'/'=== false{
  320.             $parent '';
  321.             $path $newpath;
  322.         else {
  323.             list($parent$pathexplode('/'$newpath2);
  324.         }
  325.         if (!$this->isFolder($parent$path)) {
  326.             if (is_a($result $this->autocreatePath($newpath)'PEAR_Error')) {
  327.                 return $result;
  328.             }
  329.         }
  330.  
  331.         $result $this->_db->query(sprintf('UPDATE %s SET vfs_path = ?, vfs_name = ?, vfs_modified = ?
  332.                                             WHERE vfs_path = ? AND vfs_name = ?',
  333.                                             $this->_params['table']),
  334.                                     array($newpath$newnametime()$oldpath$oldname));
  335.  
  336.         if ($this->_db->affectedRows(== 0{
  337.             return PEAR::raiseError(_("Unable to rename VFS file."));
  338.         }
  339.  
  340.         if (is_a($this->_recursiveSQLRename($oldpath$oldname$newpath$newname)'PEAR_Error')) {
  341.             $result $this->_db->query(sprintf('UPDATE %s SET vfs_path = ?, vfs_name = ?
  342.                                                 WHERE vfs_path = ? AND vfs_name = ?',
  343.                                                 $this->_params['table']),
  344.                                         array($oldpath$oldname$newpath$newname));
  345.             return PEAR::raiseError(_("Unable to rename VFS directory."));
  346.         }
  347.  
  348.         if (!@is_dir($this->_getNativePath($newpath))) {
  349.             if (is_a($res $this->autocreatePath($newpath)'PEAR_Error')) {
  350.                 return $res;
  351.             }
  352.         }
  353.  
  354.         if (!@rename($this->_getNativePath($oldpath$oldname)$this->_getNativePath($newpath$newname))) {
  355.             $result $this->_db->query(sprintf('UPDATE %s SET vfs_path = ?, vfs_name = ?
  356.                                                 WHERE vfs_path = ? AND vfs_name = ?',
  357.                                                 $this->_params['table']),
  358.                                         array($oldpath$oldname$newpath$newname));
  359.             return PEAR::raiseError(_("Unable to rename VFS file."));
  360.         }
  361.  
  362.         return true;
  363.     }
  364.  
  365.     /**
  366.      * Delete a folder from the VFS.
  367.      *
  368.      * @param string $path        The path to delete the folder from.
  369.      * @param string $name        The foldername to use.
  370.      * @param boolean $recursive  Force a recursive delete?
  371.      *
  372.      * @return mixed  True on success or a PEAR_Error object on failure.
  373.      */
  374.     function deleteFolder($path$name$recursive = false)
  375.     {
  376.         $conn $this->_connect();
  377.         if (is_a($conn'PEAR_Error')) {
  378.             return $conn;
  379.         }
  380.  
  381.         if ($recursive{
  382.             $result $this->emptyFolder($path '/' $name);
  383.             if (is_a($result'PEAR_Error')) {
  384.                 return $result;
  385.             }
  386.         else {
  387.             $list $this->listFolder($path '/' $name);
  388.             if (is_a($list'PEAR_Error')) {
  389.                 return $list;
  390.             }
  391.             if (count($list)) {
  392.                 return PEAR::raiseError(sprintf(_("Unable to delete %s, the directory is not empty"),
  393.                                                 $path '/' $name));
  394.             }
  395.         }
  396.  
  397.         $result $this->_db->query(sprintf('DELETE FROM %s WHERE vfs_type = ? AND vfs_path = ? AND vfs_name = ?',
  398.                                             $this->_params['table']),
  399.                                     array(VFS_FOLDER$path$name));
  400.  
  401.         if ($this->_db->affectedRows(== 0 || is_a($result'PEAR_Error')) {
  402.             return PEAR::raiseError(_("Unable to delete VFS directory."));
  403.         }
  404.  
  405.         if (is_a($this->_recursiveSQLDelete($path$name)'PEAR_Error')) {
  406.             return PEAR::raiseError(_("Unable to delete VFS directory recursively."));
  407.         }
  408.  
  409.         if (is_a($this->_recursiveLFSDelete($path$name)'PEAR_Error')) {
  410.             return PEAR::raiseError(_("Unable to delete VFS directory recursively."));
  411.         }
  412.  
  413.         return $result;
  414.     }
  415.  
  416.     /**
  417.      * Delete a file from the VFS.
  418.      *
  419.      * @param string $path  The path to store the file in.
  420.      * @param string $name  The filename to use.
  421.      *
  422.      * @return mixed  True on success or a PEAR_Error object on failure.
  423.      */
  424.     function deleteFile($path$name)
  425.     {
  426.         $res $this->_checkQuotaDelete($path$name);
  427.         if (is_a($res'PEAR_Error')) {
  428.             return $res;
  429.         }
  430.  
  431.         $conn $this->_connect();
  432.         if (is_a($conn'PEAR_Error')) {
  433.             return $conn;
  434.         }
  435.  
  436.         $result $this->_db->query(sprintf('DELETE FROM %s WHERE vfs_type = ? AND vfs_path = ? AND vfs_name = ?',
  437.                                             $this->_params['table']),
  438.                                     array(VFS_FILE$path$name));
  439.  
  440.         if ($this->_db->affectedRows(== 0{
  441.             return PEAR::raiseError(_("Unable to delete VFS file."));
  442.         }
  443.  
  444.         if (is_a($result'PEAR_Error')) {
  445.             return $result;
  446.         }
  447.  
  448.         if (!@unlink($this->_getNativePath($path$name))) {
  449.             return PEAR::raiseError(_("Unable to delete VFS file."));
  450.         }
  451.  
  452.         return true;
  453.     }
  454.  
  455.     /**
  456.      * Return a list of the contents of a folder.
  457.      *
  458.      * @param string $path       The directory path.
  459.      * @param mixed $filter      String/hash of items to filter based on
  460.      *                            filename.
  461.      * @param boolean $dotfiles  Show dotfiles?
  462.      * @param boolean $dironly   Show directories only?
  463.      *
  464.      * @return mixed  File list on success or false on failure.
  465.      */
  466.     function _listFolder($path$filter = null$dotfiles = true,
  467.                         $dironly = false)
  468.     {
  469.         $conn $this->_connect();
  470.         if (is_a($conn'PEAR_Error')) {
  471.             return $conn;
  472.         }
  473.  
  474.         $files = array();
  475.         $fileList = array();
  476.  
  477.         $fileList $this->_db->getAll(sprintf('SELECT vfs_name, vfs_type, vfs_modified, vfs_owner FROM %s
  478.                                                WHERE vfs_path = ?',
  479.                                                $this->_params['table']),
  480.                                        array($path));
  481.         if (is_a($fileList'PEAR_Error')) {
  482.             return $fileList;
  483.         }
  484.  
  485.         foreach ($fileList as $line{
  486.             // Filter out dotfiles if they aren't wanted.
  487.             if (!$dotfiles && substr($line[0]01== '.'{
  488.                 continue;
  489.             }
  490.  
  491.             $file['name'$line[0];
  492.  
  493.             if ($line[1== VFS_FILE{
  494.                 $name explode('.'$line[0]);
  495.  
  496.                 if (count($name== 1{
  497.                     $file['type''**none';
  498.                 else {
  499.                     $file['type'VFS::strtolower($name[count($name- 1]);
  500.                 }
  501.  
  502.                 $file['size'filesize($this->_getNativePath($path$line[0]));
  503.             elseif ($line[1== VFS_FOLDER{
  504.                 $file['type''**dir';
  505.                 $file['size'= -1;
  506.             }
  507.  
  508.             $file['date'$line[2];
  509.             $file['owner'$line[3];
  510.             $file['perms''';
  511.             $file['group''';
  512.  
  513.             // Filtering.
  514.             if ($this->_filterMatch($filter$file['name'])) {
  515.                 unset($file);
  516.                 continue;
  517.             }
  518.             if ($dironly && $file['type'!== '**dir'{
  519.                 unset($file);
  520.                 continue;
  521.             }
  522.  
  523.             $files[$file['name']] $file;
  524.             unset($file);
  525.         }
  526.  
  527.         return $files;
  528.     }
  529.  
  530.     /**
  531.      * Returns a sorted list of folders in specified directory.
  532.      *
  533.      * @param string $path         The path of the directory to get the
  534.      *                              directory list for.
  535.      * @param mixed $filter        String/hash of items to filter based on
  536.      *                              folderlist.
  537.      * @param boolean $dotfolders  Include dotfolders?
  538.      *
  539.      * @return mixed  Folder list on success or a PEAR_Error object on failure.
  540.      */
  541.     function listFolders($path ''$filter = array()$dotfolders = true)
  542.     {
  543.         $conn $this->_connect();
  544.         if (is_a($conn'PEAR_Error')) {
  545.             return $conn;
  546.         }
  547.  
  548.         $sql sprintf('SELECT vfs_name, vfs_path FROM %s WHERE vfs_path = ? AND vfs_type = ?',
  549.                        $this->_params['table']);
  550.  
  551.         $folderList $this->_db->getAll($sqlarray($path$VFS_FOLDER));
  552.         if (is_a($folderList'PEAR_Error')) {
  553.             return $folderList;
  554.         }
  555.  
  556.         $folders = array();
  557.         foreach ($folderList as $line{
  558.             $folder['val'$this->_getNativePath($line[1]$line[0]);
  559.             $folder['abbrev''';
  560.             $folder['label''';
  561.  
  562.             $count substr_count($folder['val']'/');
  563.  
  564.             $x = 0;
  565.             while ($x $count{
  566.                 $folder['abbrev'.= '    ';
  567.                 $folder['label'.= '    ';
  568.                 $x++;
  569.             }
  570.  
  571.             $folder['abbrev'.= $line[0];
  572.             $folder['label'.= $line[0];
  573.  
  574.             $strlen VFS::strlen($folder['label']);
  575.             if ($strlen > 26{
  576.                 $folder['abbrev'substr($folder['label']0($count * 4));
  577.                 $length (29 - ($count * 4)) / 2;
  578.                 $folder['abbrev'.= substr($folder['label']($count * 4)$length);
  579.                 $folder['abbrev'.= '...';
  580.                 $folder['abbrev'.= substr($folder['label']-1 * $length$length);
  581.             }
  582.  
  583.             $found = false;
  584.             foreach ($filter as $fltr{
  585.                 if ($folder['val'== $fltr{
  586.                     $found = true;
  587.                 }
  588.             }
  589.  
  590.             if (!$found{
  591.                 $folders[$folder['val']] $folder;
  592.             }
  593.         }
  594.  
  595.         ksort($folders);
  596.         return $folders;
  597.     }
  598.  
  599.     /**
  600.      * Recursively copies the contents of a folder to a destination.
  601.      *
  602.      * @access private
  603.      *
  604.      * @param string $path  The path to store the directory in.
  605.      * @param string $name  The name of the directory.
  606.      * @param string $dest  The destination of the directory.
  607.      *
  608.      * @return mixed  True on success or a PEAR_Error object on failure.
  609.      */
  610.     function _recursiveCopy($path$name$dest)
  611.     {
  612.         $result $this->createFolder($dest$name);
  613.  
  614.         if (is_a($result'PEAR_Error')) {
  615.             return $result;
  616.         }
  617.  
  618.         $file_list $this->listFolder($this->_getSQLNativePath($path$name));
  619.  
  620.         foreach ($file_list as $file{
  621.             $result $this->copy($this->_getSQLNativePath($path$name)$file['name']$this->_getSQLNativePath($dest$name));
  622.  
  623.             if (is_a($result'PEAR_Error')) {
  624.                 return $result;
  625.             }
  626.         }
  627.         return true;
  628.      }
  629.  
  630.     /**
  631.      * Store a files information within the database.
  632.      *
  633.      * @access private
  634.      *
  635.      * @param string $path         The path to store the file in.
  636.      * @param string $name         The filename to use.
  637.      * @param boolean $autocreate  Automatically create directories?
  638.      *
  639.      * @return mixed  True on success or a PEAR_Error object on failure.
  640.      */
  641.     function _writeSQLData($path$name$autocreate = false)
  642.     {
  643.         $conn $this->_connect();
  644.         if (is_a($conn'PEAR_Error')) {
  645.             return $conn;
  646.         }
  647.  
  648.         // File already exists in database
  649.         if ($this->exists($path$name)) {
  650.             $query 'UPDATE ' $this->_params['table'.
  651.                      ' SET vfs_modified = ?' .
  652.                      ' WHERE vfs_path = ? AND vfs_name = ?';
  653.             $values = array(time()$path$name);
  654.         else {
  655.             $id $this->_db->nextId($this->_params['table']);
  656.  
  657.             $query 'INSERT INTO ' $this->_params['table'.
  658.                      ' (vfs_id, vfs_type, vfs_path, vfs_name, vfs_modified,' .
  659.                      ' vfs_owner) VALUES (?, ?, ?, ?, ?, ?)';
  660.             $values = array($idVFS_FILE$path$nametime(),
  661.                             $this->_params['user']);
  662.         }
  663.         return $this->_db->query($query$values);
  664.     }
  665.  
  666.     /**
  667.      * Renames all child paths.
  668.      *
  669.      * @access private
  670.      *
  671.      * @param string $oldpath  The old path of the folder to rename.
  672.      * @param string $oldname  The old name.
  673.      * @param string $newpath  The new path of the folder to rename.
  674.      * @param string $newname  The new name.
  675.      *
  676.      * @return mixed  True on success or a PEAR_Error object on failure.
  677.      */
  678.     function _recursiveSQLRename($oldpath$oldname$newpath$newname)
  679.     {
  680.         $folderList $this->_db->getCol(sprintf('SELECT vfs_name FROM %s WHERE vfs_type = ? AND vfs_path = ?',
  681.                                                  $this->_params['table']),
  682.                                          0,
  683.                                          array(VFS_FOLDER$this->_getSQLNativePath($oldpath$oldname)));
  684.  
  685.         foreach ($folderList as $folder{
  686.             $this->_recursiveSQLRename($this->_getSQLNativePath($oldpath$oldname)$folder$this->_getSQLNativePath($newpath$newname)$folder);
  687.         }
  688.  
  689.         $result $this->_db->query(sprintf('UPDATE %s SET vfs_path = ? WHERE vfs_path = ?',
  690.                                             $this->_params['table']),
  691.                                     array($this->_getSQLNativePath($newpath$newname),
  692.                                           $this->_getSQLNativePath($oldpath$oldname)));
  693.  
  694.         if (is_a($result'PEAR_Error')) {
  695.             return $result;
  696.         }
  697.     }
  698.  
  699.     /**
  700.      * Delete a folders contents from the VFS in the SQL database,
  701.      * recursively.
  702.      *
  703.      * @access private
  704.      *
  705.      * @param string $path  The path of the folder.
  706.      * @param string $name  The foldername to use.
  707.      *
  708.      * @return mixed  True on success or a PEAR_Error object on failure.
  709.      */
  710.     function _recursiveSQLDelete($path$name)
  711.     {
  712.         $result $this->_db->query(sprintf('DELETE FROM %s WHERE vfs_type = ? AND vfs_path = ?',
  713.                                             $this->_params['table']),
  714.                                     array(VFS_FILE$this->_getSQLNativePath($path$name)));
  715.         if (is_a($result'PEAR_Error')) {
  716.             return $result;
  717.         }
  718.  
  719.         $folderList $this->_db->getCol(sprintf('SELECT vfs_name FROM %s WHERE vfs_type = ? AND vfs_path = ?',
  720.                                                  $this->_params['table']),
  721.                                          0,
  722.                                          array(VFS_FOLDER$this->_getSQLNativePath($path$name)));
  723.  
  724.         foreach ($folderList as $folder{
  725.             $this->_recursiveSQLDelete($this->_getSQLNativePath($path$name)$folder);
  726.         }
  727.  
  728.         $result $this->_db->query(sprintf('DELETE FROM %s WHERE vfs_type = ? AND vfs_name = ? AND vfs_path = ?',
  729.                                             $this->_params['table']),
  730.                                     array(VFS_FOLDER$name$path));
  731.  
  732.         return $result;
  733.     }
  734.  
  735.     /**
  736.      * Delete a folders contents from the VFS, recursively.
  737.      *
  738.      * @access private
  739.      *
  740.      * @param string $path  The path of the folder.
  741.      * @param string $name  The foldername to use.
  742.      *
  743.      * @return mixed  True on success or a PEAR_Error object on failure.
  744.      */
  745.     function _recursiveLFSDelete($path$name)
  746.     {
  747.         $dir $this->_getNativePath($path$name);
  748.         $dh @opendir($dir);
  749.  
  750.         while (false !== ($file readdir($dh))) {
  751.             if ($file != '.' && $file != '..'{
  752.                 if (is_dir($dir '/' $file)) {
  753.                     $this->_recursiveLFSDelete(empty($path$name $path '/' $name$file);
  754.                 else {
  755.                     @unlink($dir '/' $file);
  756.                 }
  757.             }
  758.         }
  759.         @closedir($dh);
  760.  
  761.         return rmdir($dir);
  762.     }
  763.  
  764.     /**
  765.      * Attempts to open a persistent connection to the SQL server.
  766.      *
  767.      * @access private
  768.      *
  769.      * @return mixed  True on success or a PEAR_Error object on failure.
  770.      */
  771.     function _connect()
  772.     {
  773.         if ($this->_db === false{
  774.             if (!is_array($this->_params)) {
  775.                 return PEAR::raiseError(_("No configuration information specified for SQL-File VFS."));
  776.             }
  777.  
  778.             $required = array('phptype''vfsroot');
  779.             foreach ($required as $val{
  780.                 if (!isset($this->_params[$val])) {
  781.                     return PEAR::raiseError(sprintf(_("Required \"%s\" not specified in VFS configuration.")$val));
  782.                 }
  783.             }
  784.  
  785.             if (!isset($this->_params['database'])) {
  786.                 $this->_params['database''';
  787.             }
  788.  
  789.             if (!isset($this->_params['username'])) {
  790.                 $this->_params['username''';
  791.             }
  792.  
  793.             if (!isset($this->_params['hostspec'])) {
  794.                 $this->_params['hostspec''';
  795.             }
  796.  
  797.             if (!isset($this->_params['table'])) {
  798.                 $this->_params['table''horde_vfs';
  799.             }
  800.  
  801.             /* Connect to the SQL server using the supplied parameters. */
  802.             require_once 'DB.php';
  803.             $this->_db &DB::connect($this->_params,
  804.                                       array('persistent' => !empty($this->_params['persistent'])));
  805.             if (is_a($this->_db'PEAR_Error')) {
  806.                 $error $this->_db;
  807.                 $this->_db = false;
  808.                 return $error;
  809.             }
  810.  
  811.             // Set DB portability options.
  812.             switch ($this->_db->phptype{
  813.             case 'mssql':
  814.                 $this->_db->setOption('portability'DB_PORTABILITY_LOWERCASE | DB_PORTABILITY_ERRORS | DB_PORTABILITY_RTRIM);
  815.                 break;
  816.             default:
  817.                 $this->_db->setOption('portability'DB_PORTABILITY_LOWERCASE | DB_PORTABILITY_ERRORS);
  818.             }
  819.  
  820.         }
  821.  
  822.         return true;
  823.     }
  824.  
  825.     /**
  826.      * Disconnect from the SQL server and clean up the connection.
  827.      *
  828.      * @access private
  829.      */
  830.     function _disconnect()
  831.     {
  832.         if ($this->_db{
  833.             $this->_db->disconnect();
  834.             $this->_db = false;
  835.         }
  836.     }
  837.  
  838.     /**
  839.      * Return a full filename on the native filesystem, from a VFS
  840.      * path and name.
  841.      *
  842.      * @access private
  843.      *
  844.      * @param string $path  The VFS file path.
  845.      * @param string $name  The VFS filename.
  846.      *
  847.      * @return string  The full native filename.
  848.      */
  849.     function _getNativePath($path$name)
  850.     {
  851.         if (!empty($name)) {
  852.             $name '/' $name;
  853.         }
  854.         if (isset($path)) {
  855.             if (isset($this->_params['home']&&
  856.                 preg_match('|^~/?(.*)$|'$path$matches)) {
  857.                 $path $this->_params['home']  '/' $matches[1];
  858.             }
  859.  
  860.             return $this->_params['vfsroot''/' $path $name;
  861.         else {
  862.             return $this->_params['vfsroot'$name;
  863.         }
  864.     }
  865.  
  866.     /**
  867.      * Return a full SQL filename on the native filesystem, from a VFS
  868.      * path and name.
  869.      *
  870.      * @access private
  871.      *
  872.      * @param string $path  The VFS file path.
  873.      * @param string $name  The VFS filename.
  874.      *
  875.      * @return string  The full native filename.
  876.      */
  877.     function _getSQLNativePath($path$name)
  878.     {
  879.         if (empty($path)) {
  880.             return $name;
  881.         }
  882.  
  883.         return $path '/' $name;
  884.     }
  885.  
  886.     /**
  887.      * Returns the size of a file.
  888.      *
  889.      * @access public
  890.      *
  891.      * @param string $path  The path of the file.
  892.      * @param string $name  The filename.
  893.      *
  894.      * @return integer  The size of the file in bytes or PEAR_Error on
  895.      *                   failure.
  896.      */
  897.     function getFileSize($path$name)
  898.     {
  899.         if (($size @filesize($this->_getNativePath($path$name))) === false){
  900.             return PEAR::raiseError(sprintf(_("Unable to check file size of \"%s/%s\"."$path$name)));
  901.         }
  902.  
  903.         return $size;
  904.     }
  905.  
  906. }

Documentation generated on Mon, 11 Mar 2019 14:39:02 -0400 by phpDocumentor 1.4.4. PEAR Logo Copyright © PHP Group 2004.