⚝
One Hat Cyber Team
⚝
Your IP:
216.73.216.89
Server IP:
41.128.143.86
Server:
Linux host.raqmix.cloud 6.8.0-1025-azure #30~22.04.1-Ubuntu SMP Wed Mar 12 15:28:20 UTC 2025 x86_64
Server Software:
Apache
PHP Version:
8.3.23
Buat File
|
Buat Folder
Eksekusi
Dir :
~
/
usr
/
share
/
psa-pear
/
pear
/
php
/
Horde
/
Vfs
/
Edit File: Sql.php
<?php /** * VFS implementation for Horde's database abstraction layer. * * Required values for $params: * - db: A Horde_Db_Adapter object. * * Optional values: * - table: (string) The name of the vfs table in 'database'. Defaults to * 'horde_vfs'. * * The table structure for the VFS can be created with the horde-db-migrate * script from the Horde_Db package. * * Copyright 2002-2017 Horde LLC (http://www.horde.org/) * * See the enclosed file COPYING for license information (LGPL). If you * did not receive this file, see http://www.horde.org/licenses/lgpl21. * * @author Chuck Hagenbuch <chuck@horde.org> * @author Jan Schneider <jan@horde.org> * @category Horde * @license http://www.horde.org/licenses/lgpl21 LGPL 2.1 * @package VFS */ class Horde_Vfs_Sql extends Horde_Vfs_Base { /* File value for vfs_type column. */ const FILE = 1; /* Folder value for vfs_type column. */ const FOLDER = 2; /** * Handle for the current database connection. * * @var Horde_Db */ protected $_db = false; /** * List of permissions and if they can be changed in this VFS backend. * * @var array */ protected $_permissions = array(); /** * List of features that the VFS driver supports. * * @var array */ protected $_features = array( 'readByteRange' => true, ); /** * Constructor. * * @param array $params A hash containing connection parameters. */ public function __construct($params = array()) { $params = array_merge(array('table' => 'horde_vfs'), $params); parent::__construct($params); $this->_db = $this->_params['db']; unset($this->_params['db']); } /** * Retrieves the filesize from the VFS. * * @param string $path The pathname to the file. * @param string $name The filename to retrieve. * * @return integer The file size. * @throws Horde_Vfs_Exception */ public function size($path, $name) { $length_op = $this->_getFileSizeOp(); $path = $this->_convertPath($path); list($op, $values) = $this->_nullString($path); $sql = sprintf( 'SELECT %s(vfs_data) FROM %s WHERE vfs_path %s AND vfs_name = ?', $length_op, $this->_params['table'], $op ); $values[] = $name; try { $size = $this->_db->selectValue($sql, $values); } catch (Horde_Db_Exception $e) { throw new Horde_Vfs_Exception($e); } if ($size === false) { throw new Horde_Vfs_Exception(sprintf('Unable to check file size of "%s/%s".', $path, $name)); } return $size; } /** * Returns the size of a folder. * * @param string $path The path of the folder. * * @return integer The size of the folder in bytes. * @throws Horde_Vfs_Exception */ public function getFolderSize($path = null) { try { $where = null; $params = array(); if (strlen($path)) { $where = 'WHERE vfs_path = ? OR vfs_path LIKE ?'; $path = $this->_convertPath($path); $params = array($path, $path . '/%'); } $sql = sprintf('SELECT SUM(%s(vfs_data)) FROM %s %s', $this->_getFileSizeOp(), $this->_params['table'], $where); $size = $this->_db->selectValue($sql, $params); } catch (Horde_Db_Exception $e) { throw new Horde_Vfs_Exception($e); } return (int)$size; } /** * Retrieves a file from the VFS. * * @param string $path The pathname to the file. * @param string $name The filename to retrieve. * * @return string The file data. * @throws Horde_Vfs_Exception */ public function read($path, $name) { return $this->_readBlob($this->_params['table'], 'vfs_data', array( 'vfs_path' => $this->_convertPath($path), 'vfs_name' => $name )); } /** * Retrieves a part of a file from the VFS. Particularly useful * when reading large files which would exceed the PHP memory * limits if they were stored in a string. * * @param string $path The pathname to the file. * @param string $name The filename to retrieve. * @param integer $offset The offset of the part. (The new offset will * be stored in here). * @param integer $length The length of the part. If the length = -1, * the whole part after the offset is * retrieved. If more bytes are given as exists * after the given offset. Only the available * bytes are read. * @param integer $remaining The bytes that are left, after the part that * is retrieved. * * @return string The file data. * @throws Horde_Vfs_Exception */ public function readByteRange($path, $name, &$offset, $length, &$remaining) { $data = $this->_readBlob($this->_params['table'], 'vfs_data', array( 'vfs_path' => $this->_convertPath($path), 'vfs_name' => $name )); // Calculate how many bytes MUST be read, so the remainging // bytes and the new offset can be calculated correctly. $size = strlen ($data); if ($length == -1 || (($length + $offset) > $size)) { $length = $size - $offset; } if ($remaining < 0) { $remaining = 0; } $data = substr($data, $offset, $length); $offset = $offset + $length; $remaining = $size - $offset; return $data; } /** * Stores a file in the VFS. * * @param string $path The path to store the file in. * @param string $name The filename to use. * @param string $tmpFile The temporary file containing the data to * be stored. * @param boolean $autocreate Automatically create directories? * * @throws Horde_Vfs_Exception */ public function write($path, $name, $tmpFile, $autocreate = false) { /* Don't need to check quota here since it will be checked when * writeData() is called. */ if (!$stream = @fopen($tmpFile, 'rb')) { throw new Horde_Vfs_Exception('Unable to open ' . $tmpFile); } $result = $this->writeData( $path, $name, $stream, $autocreate); fclose($stream); return $result; } /** * Store 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|resource $data The data as a string or stream resource. * Resources allowed @since 2.4.0 * @param boolean $autocreate Automatically create directories? * * @throws Horde_Vfs_Exception */ public function writeData($path, $name, $data, $autocreate = false) { $data = $this->_ensureSeekable($data); $this->_checkQuotaWrite('string', $data, $path, $name); $path = $this->_convertPath($path); list($op, $values) = $this->_nullString($path); /* Check to see if the data already exists. */ try { $sql = sprintf( 'SELECT vfs_id FROM %s WHERE vfs_path %s AND vfs_name = ?', $this->_params['table'], $op ); $values[] = $name; $id = $this->_db->selectValue($sql, $values); } catch (Horde_Db_Exception $e) { throw new Horde_Vfs_Exception($e); } if ($id) { $this->_updateBlob($this->_params['table'], 'vfs_data', $data, array('vfs_id' => $id), array('vfs_modified' => time())); return; } /* Check to see if the folder already exists. */ $dirs = explode('/', $path); $path_name = array_pop($dirs); $parent = implode('/', $dirs); if (!$this->isFolder($parent, $path_name)) { if (!$autocreate) { throw new Horde_Vfs_Exception(sprintf('Folder "%s" does not exist', $path)); } $this->autocreatePath($path); } return $this->_insertBlob($this->_params['table'], 'vfs_data', $data, array( 'vfs_type' => self::FILE, 'vfs_path' => strlen($path) ? $path : null, 'vfs_name' => $name, 'vfs_modified' => time(), 'vfs_owner' => $this->_params['user'] )); } /** * Delete a file from the VFS. * * @param string $path The path to store the file in. * @param string $name The filename to use. * * @throws Horde_Vfs_Exception */ public function deleteFile($path, $name) { $this->_checkQuotaDelete($path, $name); $path = $this->_convertPath($path); list($op, $values) = $this->_nullString($path); try { $sql = sprintf( 'DELETE FROM %s WHERE vfs_type = ? AND vfs_path %s AND vfs_name = ?', $this->_params['table'], $op ); array_unshift($values, self::FILE); array_push($values, $name); $result = $this->_db->delete($sql, $values); } catch (Horde_Db_Exception $e) { throw new Horde_Vfs_Exception($e); } if ($result == 0) { throw new Horde_Vfs_Exception('Unable to delete VFS file.'); } } /** * Rename 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. * * @throws Horde_Vfs_Exception */ public function rename($oldpath, $oldname, $newpath, $newname) { if (strpos($newpath, '/') === false) { $parent = ''; $path = $newpath; } else { list($parent, $path) = explode('/', $newpath, 2); } if (!$this->isFolder($parent, $path)) { $this->autocreatePath($newpath); } $oldpath = $this->_convertPath($oldpath); $newpath = $this->_convertPath($newpath); if (!strlen($newpath)) { $newpath = null; } list($op, $values) = $this->_nullString($oldpath); $sql = sprintf( 'UPDATE %s SET vfs_path = ?, vfs_name = ?, vfs_modified = ? WHERE vfs_path %s AND vfs_name = ?', $this->_params['table'], $op ); $values = array_merge( array($newpath, $newname, time()), $values, array($oldname) ); try { $result = $this->_db->update($sql, $values); } catch (Horde_Db_Exception $e) { throw new Horde_Vfs_Exception($e); } if ($result == 0) { throw new Horde_Vfs_Exception('Unable to rename VFS file.'); } $this->_recursiveRename($oldpath, $oldname, $newpath, $newname); } /** * 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. * * @throws Horde_Vfs_Exception */ public function createFolder($path, $name) { $path = $this->_convertPath($path); if (!strlen($path)) { $path = null; } $sql = sprintf( 'INSERT INTO %s (vfs_type, vfs_path, vfs_name, vfs_modified, vfs_owner) VALUES (?, ?, ?, ?, ?)', $this->_params['table'] ); $values = array(self::FOLDER, $path, $name, time(), $this->_params['user'] ?: null); try { $this->_db->insert($sql, $values); } catch (Horde_Db_Exception $e) { throw new Horde_Vfs_Exception($e); } } /** * Horde_Vfs_Sql override of isFolder() to check for root folder. * * @param string $path Path to possible folder * @param string $name Name of possible folder * * @return boolean True if $path/$name is a folder */ public function isFolder($path, $name) { $path = $this->_convertPath($path); if ($path == '' && $name == '') { // The root of VFS is always a folder. return true; } $path = $this->_getNativePath($path, $name); $name = basename($path); $path = dirname($path); if ($path == '.') { $path = ''; } list($op, $values) = $this->_nullString($path); try { return (bool)$this->_db->selectValue( sprintf( 'SELECT 1 FROM %s WHERE vfs_type = ? AND vfs_path %s AND vfs_name = ?', $this->_params['table'], $op ), array_merge(array(self::FOLDER), $values, array($name)) ); } catch (Horde_Db_Exception $e) { throw new Horde_Vfs_Exception($e); } } /** * Delete a folder from the VFS. * * @param string $path The path of the folder. * @param string $name The folder name to use. * @param boolean $recursive Force a recursive delete? * * @throws Horde_Vfs_Exception */ public function deleteFolder($path, $name, $recursive = false) { $path = $this->_convertPath($path); $folderPath = $this->_getNativePath($path, $name); /* Check if not recursive and fail if directory not empty */ if (!$recursive) { $folderList = $this->listFolder($folderPath, null, true); if (!empty($folderList)) { throw new Horde_Vfs_Exception(sprintf('Unable to delete %s, the directory is not empty', $path . '/' . $name)); } } /* Remember the size of the folder. */ if (!is_null($this->_vfsSize)) { $size = $this->getFolderSize($folderPath); } /* First delete everything below the folder, so if error we get no * orphans. */ try { $sql = sprintf('DELETE FROM %s WHERE vfs_path %s', $this->_params['table'], ' LIKE ' . $this->_db->quote($this->_getNativePath($folderPath, '%'))); $this->_db->delete($sql); } catch (Horde_Db_Exception $e) { $this->_vfsSize = null; throw new Horde_Vfs_Exception('Unable to delete VFS recursively: ' . $e->getMessage()); } /* Now delete everything inside the folder. */ list ($op, $values) = $this->_nullString($folderPath); try { $sql = sprintf( 'DELETE FROM %s WHERE vfs_path %s', $this->_params['table'], $op ); $this->_db->delete($sql, $values); } catch (Horde_Db_Exception $e) { $this->_vfsSize = null; throw new Horde_Vfs_Exception('Unable to delete VFS directory: ' . $e->getMessage()); } /* All ok now delete the actual folder */ list($op, $values) = $this->_nullString($path); try { $sql = sprintf( 'DELETE FROM %s WHERE vfs_path %s AND vfs_name = ?', $this->_params['table'], $op ); $values[] = $name; $this->_db->delete($sql, $values); } catch (Horde_Db_Exception $e) { $this->_vfsSize = null; throw new Horde_Vfs_Exception('Unable to delete VFS directory: ' . $e->getMessage()); } /* Update VFS size. */ if (!is_null($this->_vfsSize)) { $this->_vfsSize -= $size; } } /** * Returns an an unsorted file list of the specified directory. * * @param string $path The path of the directory. * @param string|array $filter Regular expression(s) to filter * file/directory name on. * @param boolean $dotfiles Show dotfiles? * @param boolean $dironly Show only directories? * * @return array File list. * @throws Horde_Vfs_Exception */ protected function _listFolder($path, $filter = null, $dotfiles = true, $dironly = false) { if (!$this->isFolder(dirname($path), basename($path))) { throw new Horde_Vfs_Exception(sprintf('"%s" is not a folder.', $path)); } $path = $this->_convertPath($path); list($op, $values) = $this->_nullString($path); try { $length_op = $this->_getFileSizeOp(); $sql = sprintf( 'SELECT vfs_name, vfs_type, %s(vfs_data) length, vfs_modified, vfs_owner FROM %s WHERE vfs_path %s', $length_op, $this->_params['table'], $op ); $fileList = $this->_db->select($sql, $values); } catch (Horde_Db_Exception $e) { throw new Horde_Vfs_Exception($e); } $files = array(); foreach ($fileList as $line) { // Filter out dotfiles if they aren't wanted. if (!$dotfiles && substr($line['vfs_name'], 0, 1) == '.') { continue; } $file['name'] = $line['vfs_name']; if ($line['vfs_type'] == self::FILE) { $name = explode('.', $line['vfs_name']); if (count($name) == 1) { $file['type'] = '**none'; } else { $file['type'] = Horde_String::lower($name[count($name) - 1]); } $file['size'] = $line['length']; } elseif ($line['vfs_type'] == self::FOLDER) { $file['type'] = '**dir'; $file['size'] = -1; } $file['date'] = $line['vfs_modified']; $file['owner'] = isset($line['vfs_owner']) ? $line['vfs_owner'] : ''; $file['perms'] = ''; $file['group'] = ''; // filtering if ($this->_filterMatch($filter, $file['name'])) { unset($file); continue; } if ($dironly && $file['type'] !== '**dir') { unset($file); continue; } $files[$file['name']] = $file; unset($file); } return $files; } /** * Garbage collect files in the VFS storage system. * * @param string $path The VFS path to clean. * @param integer $secs The minimum amount of time (in seconds) required * before a file is removed. * * @throws Horde_Vfs_Exception */ public function gc($path, $secs = 345600) { $path = $this->_convertPath($path); list($op, $values) = $this->_nullString($path); $sql = sprintf( 'DELETE FROM %s WHERE vfs_type = ? AND vfs_modified < ? AND (vfs_path %s OR vfs_path LIKE ?)', $this->_params['table'], $op ); $values = array_merge( array(self::FILE, time() - $secs), $values, array($path . '/%') ); try { $this->_db->delete($sql, $values); } catch (Horde_Db_Exception $e) { throw new Horde_Vfs_Exception($e); } } /** * Renames all child paths. * * @param string $path The path of the folder to rename. * @param string $name The foldername to use. * * @throws Horde_Vfs_Exception */ protected function _recursiveRename($oldpath, $oldname, $newpath, $newname) { $oldpath = $this->_convertPath($oldpath); $newpath = $this->_convertPath($newpath); $sql = sprintf( 'SELECT vfs_name FROM %s WHERE vfs_type = ? AND vfs_path = ?', $this->_params['table'] ); $values = array(self::FOLDER, $this->_getNativePath($oldpath, $oldname)); try { $folderList = $this->_db->selectValues($sql, $values); } catch (Horde_Db_Exception $e) { throw new Horde_Vfs_Exception($e); } foreach ($folderList as $folder) { $this->_recursiveRename($this->_getNativePath($oldpath, $oldname), $folder, $this->_getNativePath($newpath, $newname), $folder); } $sql = sprintf( 'UPDATE %s SET vfs_path = ? WHERE vfs_path = ?', $this->_params['table'] ); $values = array( $this->_getNativePath($newpath, $newname), $this->_getNativePath($oldpath, $oldname) ); try { $this->_db->update($sql, $values); } catch (Horde_Db_Exception $e) { throw new Horde_Vfs_Exception($e); } } /** * Return a full filename on the native filesystem, from a VFS * path and name. * * @param string $path The VFS file path. * @param string $name The VFS filename. * * @return string The full native filename. */ protected function _getNativePath($path, $name) { if (!strlen($path)) { return $name; } if (isset($this->_params['home']) && preg_match('|^~/?(.*)$|', $path, $matches)) { $path = $this->_params['home'] . '/' . $matches[1]; } return $path . '/' . $name; } /** * Read file data from the SQL VFS backend. * * @param string $table The VFS table name. * @param string $field TODO * @param array $criteria TODO * * @return mixed TODO * @throws Horde_Vfs_Exception */ protected function _readBlob($table, $field, $criteria) { if (!count($criteria)) { throw new Horde_Vfs_Exception('You must specify the fetch criteria'); } $where = ''; $values = array(); foreach ($criteria as $key => $value) { if (!empty($where)) { $where .= ' AND '; } list($op, $val) = $this->_nullString($value); $where .= $key . ' ' . $op; $values = array_merge($values, $val); } $sql = sprintf( 'SELECT %s FROM %s WHERE %s', $field, $table, $where ); try { $result = $this->_db->selectValue($sql, $values); $columns = $this->_db->columns($table); } catch (Horde_Db_Exception $e) { throw new Horde_Vfs_Exception($e); } if ($result === false) { throw new Horde_Vfs_Exception('Unable to load SQL data.'); } return $columns[$field]->binaryToString($result); } /** * TODO * * @param string $table TODO * @param string $field TODO * @param string $data TODO * @param string $attributes TODO * * @return mixed TODO * @throws Horde_Vfs_Exception */ protected function _insertBlob($table, $field, $data, $attributes) { $attributes[$field] = new Horde_Db_Value_Binary($data); /* Execute the query. */ try { $this->_db->insertBlob($table, $attributes); } catch (Horde_Db_Exception $e) { throw new Horde_Vfs_Exception($e); } } /** * TODO * * @param string $table TODO * @param string $field TODO * @param string $data TODO * @param string $where TODO * @param array $alsoupdate TODO * * @return mixed TODO * @throws Horde_Vfs_Exception */ protected function _updateBlob($table, $field, $data, $where, $alsoupdate) { $wherestring = ''; $wherevalues = array(); foreach ($where as $key => $value) { if (!empty($wherestring)) { $wherestring .= ' AND '; } $wherestring .= $key . ' = ?'; $wherevalues[] = $value; } /* Execute the query. */ try { $this->_db->updateBlob( $table, array_merge( $alsoupdate, array($field => new Horde_Db_Value_Binary($data)) ), array($wherestring, $wherevalues) ); } catch (Horde_Db_Exception $e) { throw new Horde_Vfs_Exception($e); } } /** * Converts the path name from regular filesystem form to the internal * format needed to access the file in the database. * * Namely, we will treat '/' as a base directory as this is pretty much * the standard way to access base directories over most filesystems. * * @param string $path A VFS path. * * @return string The path with any surrouding slashes stripped off. */ protected function _convertPath($path) { return trim($path, '/'); } /** * TODO * * @return string TODO */ protected function _getFileSizeOp() { switch ($this->_db->adapterName()) { case 'PostgreSQL': case 'PDO_PostgreSQL': return 'OCTET_LENGTH'; default: return 'LENGTH'; } } /** * Returns a comparison for a possibly empty string. * * Returns IS NULL instead of an equals operator if the string is empty. * * @param string $value A string. * * @return array */ protected function _nullString($value) { return strlen($value) ? array('= ?', array($value)) : array('IS NULL', array()); } }
Simpan