Source for file musql.php
Documentation is available at musql.php
require_once dirname (__FILE__ ) . '/sql.php';
* Permission for read access.
* Permission for read access.
* Multi User VFS implementation for PHP's PEAR database
* Required values for $params:<pre>
* 'phptype' The database type (ie. 'pgsql', 'mysql', etc.).</pre>
* 'table' The name of the vfs table in 'database'. Defaults to
* Required by some database implementations:<pre>
* 'hostspec' The hostname of the database server.
* 'protocol' The communication protocol ('tcp', 'unix', etc.).
* 'database' The name of the database.
* 'username' The username with which to connect to the database.
* 'password' The password associated with 'username'.
* 'options' Additional options to pass to the database.
* 'tty' The TTY on which to connect to the database.
* 'port' The port on which to connect to the database.</pre>
* Delete is not recusive, so files and folders that used to be in a folder
* that gets deleted live forever in the database, or re-appear when the folder
* Rename has the same issue, so files are lost if a folder is renamed.
* The table structure for the VFS can be found in
* Database specific notes:
* - The vfs_data field must be of type IMAGE.
* - You need the following php.ini settings:
* ; Valid range 0 - 2147483647. Default = 4096.
* mssql.textlimit = 0 ; zero to pass through
* ; Valid range 0 - 2147483647. Default = 4096.
* mssql.textsize = 0 ; zero to pass through
* $Horde: framework/VFS/lib/VFS/musql.php,v 1.1.2.4 2009/01/06 15:23:47 jan Exp $
* Copyright 2002-2009 The Horde Project (http://www.horde.org/)
* See the enclosed file COPYING for license information (LGPL). If you
* did not receive this file, see http://www.fsf.org/copyleft/lgpl.html.
* @author Chuck Hagenbuch <chuck@horde.org>
* @author Mike Cochrane <mike@graftonhall.co.nz>
* List of permissions and if they can be changed in this VFS
var $_permissions = array (
'owner' => array ('read' => false , 'write' => false , 'execute' => false ),
'group' => array ('read' => false , 'write' => false , 'execute' => false ),
'all' => array ('read' => true , 'write' => true , 'execute' => false )
* Stores a file in the VFS from raw data.
* @param string $path The path to store the file in.
* @param string $name The filename to use.
* @param string $data The file data.
* @param boolean $autocreate Automatically create directories?
* @return mixed True on success or a PEAR_Error object on failure.
function writeData($path, $name, $data, $autocreate = false )
$conn = $this->_connect ();
if (PEAR ::isError ($conn)) {
/* Make sure we have write access to this and all parent paths. */
sprintf(_("Folder \"%s\" does not exist"), $path),
if (is_a($result, 'PEAR_Error')) {
foreach ($paths as $thispath) {
$sql = sprintf('SELECT vfs_owner, vfs_perms FROM %s
WHERE vfs_path = ? AND vfs_name= ?',
$this->_params['table']);
$this->log($sql, PEAR_LOG_DEBUG );
$results = $this->_db->getAll ($sql, array ($previous, $thispath));
if (is_a($results, 'PEAR_Error')) {
$this->log($results, PEAR_LOG_ERR );
return PEAR ::raiseError (_("Unable to create VFS file."));
foreach ($results as $result) {
if ($result[0 ] == $this->_params['user'] ||
return PEAR ::raiseError (_("Access denied creating VFS file."));
return parent ::writeData($path, $name, $data, $autocreate);
* Deletes a file from the VFS.
* @param string $path The path to store the file in.
* @param string $name The filename to use.
* @return mixed True on success or a PEAR_Error object on failure.
$conn = $this->_connect ();
if (PEAR ::isError ($conn)) {
$sql = sprintf('SELECT vfs_id, vfs_owner, vfs_perms FROM %s
WHERE vfs_path = ? AND vfs_name= ? AND vfs_type = ?',
$this->_params['table']);
$this->log($sql, PEAR_LOG_DEBUG );
$fileList = $this->_db->getAll ($sql, array ($path, $name, VFS_FILE));
if (is_a($fileList, 'PEAR_Error')) {
$this->log($fileList, PEAR_LOG_ERR );
return PEAR ::raiseError (_("Unable to delete VFS file."));
/* There may be one or more files with the same name but the user may
* not have read access to them, so doesn't see them. So we have to
* delete the one they have access to. */
foreach ($fileList as $file) {
if ($file[1 ] == $this->_params['user'] ||
$sql = sprintf('DELETE FROM %s WHERE vfs_id = ?',
$this->_params['table']);
$this->log($sql, PEAR_LOG_DEBUG );
$result = $this->_db->query ($sql, array ($file[0 ]));
if (is_a($result, 'PEAR_Error')) {
$this->log($result, PEAR_LOG_ERR );
if ($this->_db->affectedRows () == 0 ) {
return PEAR ::raiseError (_("Unable to delete VFS file."));
// FIXME: 'Access Denied deleting file %s/%s'
return PEAR ::raiseError (_("Unable to delete VFS file."));
* Renames a file or folder in the VFS.
* @param string $oldpath The old path to the file.
* @param string $oldname The old filename.
* @param string $newpath The new path of the file.
* @param string $newname The new filename.
* @return mixed True on success or a PEAR_Error object on failure.
function rename($oldpath, $oldname, $newpath, $newname)
$conn = $this->_connect ();
if (PEAR ::isError ($conn)) {
$sql = sprintf('SELECT vfs_id, vfs_owner, vfs_perms FROM %s
WHERE vfs_path = ? AND vfs_name= ?',
$this->_params['table']);
$this->log($sql, PEAR_LOG_DEBUG );
$fileList = $this->_db->getAll ($sql, array ($oldpath, $oldname));
if (is_a($fileList, 'PEAR_Error')) {
$this->log($fileList, PEAR_LOG_ERR );
return PEAR ::raiseError (_("Unable to rename VFS file."));
if (strpos($newpath, '/') === false ) {
list ($parent, $path) = explode('/', $newpath, 2 );
/* There may be one or more files with the same name but the user may
* not have read access to them, so doesn't see them. So we have to
* rename the one they have access to. */
foreach ($fileList as $file) {
if ($file[1 ] == $this->_params['user'] ||
$sql = sprintf('UPDATE %s SET vfs_path = ?, vfs_name = ?, vfs_modified = ?
$this->_params['table']);
$this->log($sql, PEAR_LOG_DEBUG );
$result = $this->_db->query (
array ($newpath, $newname, time(), $file[0 ]));
if (is_a($result, 'PEAR_Error')) {
$this->log($result, PEAR_LOG_ERR );
return PEAR ::raiseError (sprintf(_("Unable to rename VFS file %s/%s."),
* Creates a folder on the VFS.
* @param string $path Holds the path of directory to create folder.
* @param string $name Holds the name of the new folder.
* @return mixed True on success or a PEAR_Error object on failure.
$conn = $this->_connect ();
if (PEAR ::isError ($conn)) {
/* Make sure we have write access to this and all parent paths. */
foreach ($paths as $thispath) {
$sql = sprintf('SELECT vfs_owner, vfs_perms FROM %s
WHERE vfs_path = ? AND vfs_name= ?',
$this->_params['table']);
$this->log($sql, PEAR_LOG_DEBUG );
$results = $this->_db->getAll ($sql, array ($previous, $thispath));
if (is_a($results, 'PEAR_Error')) {
$this->log($results, PEAR_LOG_ERR );
return PEAR ::raiseError (_("Unable to create VFS directory."));
foreach ($results as $result) {
if ($result[0 ] == $this->_params['user'] ||
return PEAR ::raiseError (_("Access denied creating VFS directory."));
$id = $this->_db->nextId ($this->_params['table']);
(vfs_id, vfs_type, vfs_path, vfs_name, vfs_modified, vfs_owner, vfs_perms)
VALUES (?, ?, ?, ?, ?, ?, ?)',
$this->_params['table']);
$this->log($sql, PEAR_LOG_DEBUG );
$result = $this->_db->query (
array ($id, VFS_FOLDER, $path, $name, time(), $this->_params['user'], 0 ));
if (is_a($result, 'PEAR_Error')) {
$this->log($result, PEAR_LOG_ERR );
* Deletes a folder from the VFS.
* @param string $path The path to delete the folder from.
* @param string $name The foldername to use.
* @param boolean $recursive Force a recursive delete?
* @return mixed True on success or a PEAR_Error object on failure.
$conn = $this->_connect ();
if (PEAR ::isError ($conn)) {
if (is_a($result, 'PEAR_Error')) {
if (is_a($list, 'PEAR_Error')) {
sprintf(_("Unable to delete %s, the directory is not empty"),
$sql = sprintf('SELECT vfs_id, vfs_owner, vfs_perms FROM %s
WHERE vfs_path = ? AND vfs_name= ? AND vfs_type = ?',
$this->_params['table']);
$this->log($sql, PEAR_LOG_DEBUG );
$fileList = $this->_db->getAll ($sql, array ($path, $name, VFS_FOLDER));
if (is_a($fileList, 'PEAR_Error')) {
$this->log($fileList, PEAR_LOG_ERR );
return PEAR ::raiseError (_("Unable to delete VFS directory."));
/* There may be one or more folders with the same name but as the user
* may not have read access to them, they don't see them. So we have
* to delete the one they have access to */
foreach ($fileList as $file) {
if ($file[1 ] == $this->_params['user'] ||
$sql = sprintf('DELETE FROM %s WHERE vfs_id = ?',
$this->_params['table']);
$this->log($sql, PEAR_LOG_DEBUG );
$result = $this->_db->query ($sql, array ($file[0 ]));
if (is_a($result, 'PEAR_Error')) {
$this->log($result, PEAR_LOG_ERR );
if ($this->_db->affectedRows () == 0 ) {
return PEAR ::raiseError (_("Unable to delete VFS directory."));
// FIXME: 'Access Denied deleting folder %s/%s'
return PEAR ::raiseError (_("Unable to delete VFS directory."));
* Returns a list of the contents of a folder.
* @param string $path The path of the directory.
* @param mixed $filter String/hash to filter file/dirname on.
* @param boolean $dotfiles Show dotfiles?
* @param boolean $dironly Show only directories?
* @return mixed File list on success or false on failure.
function _listFolder ($path, $filter = null , $dotfiles = true ,
$conn = $this->_connect ();
if (is_a($conn, 'PEAR_Error')) {
$length_op = $this->_getFileSizeOp ();
$sql = sprintf('SELECT vfs_name, vfs_type, vfs_modified, vfs_owner, vfs_perms, %s(vfs_data) FROM %s
WHERE vfs_path = ? AND (vfs_owner = ? OR vfs_perms \&\& ?)',
$length_op, $this->_params['table']);
$this->log($sql, PEAR_LOG_DEBUG );
$fileList = $this->_db->getAll (
if (is_a($fileList, 'PEAR_Error')) {
$this->log($fileList, PEAR_LOG_ERR );
foreach ($fileList as $line) {
// Filter out dotfiles if they aren't wanted.
if (!$dotfiles && substr($line[0 ], 0 , 1 ) == '.') {
$file['type'] = '**none';
$file['size'] = $line[5 ];
$file['date'] = $line[2 ];
$file['owner'] = $line[3 ];
$file['perms'] = ($line[1 ] == VFS_FOLDER) ? 'd' : '-';
if ($this->_filterMatch ($filter, $file['name'])) {
if ($dironly && $file['type'] !== '**dir') {
$files[$file['name']] = $file;
* Changes permissions for an Item on the VFS.
* @param string $path Holds the path of directory of the Item.
* @param string $name Holds the name of the Item.
* @return mixed True on success or a PEAR_Error object on failure.
$conn = $this->_connect ();
if (PEAR ::isError ($conn)) {
$sql = sprintf('SELECT vfs_id, vfs_owner, vfs_perms FROM %s
WHERE vfs_path = ? AND vfs_name= ?',
$this->_params['table']);
$this->log($sql, PEAR_LOG_DEBUG );
$fileList = $this->_db->getAll ($sql, array ($path, $name));
if (is_a($fileList, 'PEAR_Error')) {
$this->log($fileList, PEAR_LOG_ERR );
return PEAR ::raiseError (_("Unable to rename VFS file."));
/* There may be one or more files with the same name but the user may
* not have read access to them, so doesn't see them. So we have to
* chmod the one they have access to. */
foreach ($fileList as $file) {
if ($file[1 ] == $this->_params['user'] ||
$sql = sprintf('UPDATE %s SET vfs_perms = ?
$this->_params['table']);
$this->log($sql, PEAR_LOG_DEBUG );
$result = $this->_db->query ($sql, array ($perm, $file[0 ]));
sprintf(_("Unable to change permission for VFS file %s/%s."),
Documentation generated on Mon, 11 Mar 2019 15:34:54 -0400 by phpDocumentor 1.4.4. PEAR Logo Copyright © PHP Group 2004.
|