Файловый менеджер - Редактировать - /home/lmsyaran/public_html/pusher/Filesystem.tar
Назад
File.php 0000644 00000037010 15117132553 0006140 0 ustar 00 <?php /** * Joomla! Content Management System * * @copyright (C) 2006 Open Source Matters, Inc. <https://www.joomla.org> * @license GNU General Public License version 2 or later; see LICENSE.txt */ namespace Joomla\CMS\Filesystem; defined('JPATH_PLATFORM') or die; use Joomla\CMS\Factory; use Joomla\CMS\Log\Log; use Joomla\CMS\Language\Text; use Joomla\CMS\Filesystem\Path; use Joomla\CMS\Filesystem\Wrapper\PathWrapper; use Joomla\CMS\Filesystem\Wrapper\FolderWrapper; use Joomla\CMS\Client\ClientHelper; use Joomla\CMS\Client\FtpClient; /** * A File handling class * * @since 1.7.0 */ class File { /** * Gets the extension of a file name * * @param string $file The file name * * @return string The file extension * * @since 1.7.0 */ public static function getExt($file) { // String manipulation should be faster than pathinfo() on newer PHP versions. $dot = strrpos($file, '.'); if ($dot === false) { return ''; } $ext = substr($file, $dot + 1); // Extension cannot contain slashes. if (strpos($ext, '/') !== false || (DIRECTORY_SEPARATOR === '\\' && strpos($ext, '\\') !== false)) { return ''; } return $ext; } /** * Strips the last extension off of a file name * * @param string $file The file name * * @return string The file name without the extension * * @since 1.7.0 */ public static function stripExt($file) { return preg_replace('#\.[^.]*$#', '', $file); } /** * Makes file name safe to use * * @param string $file The name of the file [not full path] * * @return string The sanitised string * * @since 1.7.0 */ public static function makeSafe($file) { // Remove any trailing dots, as those aren't ever valid file names. $file = rtrim($file, '.'); $regex = array('#(\.){2,}#', '#[^A-Za-z0-9\.\_\- ]#', '#^\.#'); return trim(preg_replace($regex, '', $file)); } /** * Copies a file * * @param string $src The path to the source file * @param string $dest The path to the destination file * @param string $path An optional base path to prefix to the file names * @param boolean $useStreams True to use streams * * @return boolean True on success * * @since 1.7.0 */ public static function copy($src, $dest, $path = null, $useStreams = false) { $pathObject = new PathWrapper; // Prepend a base path if it exists if ($path) { $src = $pathObject->clean($path . '/' . $src); $dest = $pathObject->clean($path . '/' . $dest); } // Check src path if (!is_readable($src)) { Log::add(Text::sprintf('JLIB_FILESYSTEM_ERROR_JFILE_FIND_COPY', $src), Log::WARNING, 'jerror'); return false; } if ($useStreams) { $stream = Factory::getStream(); if (!$stream->copy($src, $dest)) { Log::add(Text::sprintf('JLIB_FILESYSTEM_ERROR_JFILE_STREAMS', $src, $dest, $stream->getError()), Log::WARNING, 'jerror'); return false; } return true; } else { $FTPOptions = ClientHelper::getCredentials('ftp'); if ($FTPOptions['enabled'] == 1) { // Connect the FTP client $ftp = FtpClient::getInstance($FTPOptions['host'], $FTPOptions['port'], array(), $FTPOptions['user'], $FTPOptions['pass']); // If the parent folder doesn't exist we must create it if (!file_exists(dirname($dest))) { $folderObject = new FolderWrapper; $folderObject->create(dirname($dest)); } // Translate the destination path for the FTP account $dest = $pathObject->clean(str_replace(JPATH_ROOT, $FTPOptions['root'], $dest), '/'); if (!$ftp->store($src, $dest)) { // FTP connector throws an error return false; } $ret = true; } else { if (!@ copy($src, $dest)) { Log::add(Text::sprintf('JLIB_FILESYSTEM_ERROR_COPY_FAILED_ERR01', $src, $dest), Log::WARNING, 'jerror'); return false; } $ret = true; } return $ret; } } /** * Delete a file or array of files * * @param mixed $file The file name or an array of file names * * @return boolean True on success * * @since 1.7.0 */ public static function delete($file) { $FTPOptions = ClientHelper::getCredentials('ftp'); $pathObject = new PathWrapper; if (is_array($file)) { $files = $file; } else { $files[] = $file; } // Do NOT use ftp if it is not enabled if ($FTPOptions['enabled'] == 1) { // Connect the FTP client $ftp = FtpClient::getInstance($FTPOptions['host'], $FTPOptions['port'], array(), $FTPOptions['user'], $FTPOptions['pass']); } foreach ($files as $file) { $file = $pathObject->clean($file); if (!is_file($file)) { continue; } // Try making the file writable first. If it's read-only, it can't be deleted // on Windows, even if the parent folder is writable @chmod($file, 0777); // In case of restricted permissions we zap it one way or the other // as long as the owner is either the webserver or the ftp if (@unlink($file)) { // Do nothing } elseif ($FTPOptions['enabled'] == 1) { $file = $pathObject->clean(str_replace(JPATH_ROOT, $FTPOptions['root'], $file), '/'); if (!$ftp->delete($file)) { // FTP connector throws an error return false; } } else { $filename = basename($file); Log::add(Text::sprintf('JLIB_FILESYSTEM_DELETE_FAILED', $filename), Log::WARNING, 'jerror'); return false; } } return true; } /** * Moves a file * * @param string $src The path to the source file * @param string $dest The path to the destination file * @param string $path An optional base path to prefix to the file names * @param boolean $useStreams True to use streams * * @return boolean True on success * * @since 1.7.0 */ public static function move($src, $dest, $path = '', $useStreams = false) { $pathObject = new PathWrapper; if ($path) { $src = $pathObject->clean($path . '/' . $src); $dest = $pathObject->clean($path . '/' . $dest); } // Check src path if (!is_readable($src)) { Log::add(Text::_('JLIB_FILESYSTEM_CANNOT_FIND_SOURCE_FILE'), Log::WARNING, 'jerror'); return false; } if ($useStreams) { $stream = Factory::getStream(); if (!$stream->move($src, $dest)) { Log::add(Text::sprintf('JLIB_FILESYSTEM_ERROR_JFILE_MOVE_STREAMS', $stream->getError()), Log::WARNING, 'jerror'); return false; } return true; } else { $FTPOptions = ClientHelper::getCredentials('ftp'); if ($FTPOptions['enabled'] == 1) { // Connect the FTP client $ftp = FtpClient::getInstance($FTPOptions['host'], $FTPOptions['port'], array(), $FTPOptions['user'], $FTPOptions['pass']); // Translate path for the FTP account $src = $pathObject->clean(str_replace(JPATH_ROOT, $FTPOptions['root'], $src), '/'); $dest = $pathObject->clean(str_replace(JPATH_ROOT, $FTPOptions['root'], $dest), '/'); // Use FTP rename to simulate move if (!$ftp->rename($src, $dest)) { Log::add(Text::_('JLIB_FILESYSTEM_ERROR_RENAME_FILE'), Log::WARNING, 'jerror'); return false; } } else { if (!@ rename($src, $dest)) { Log::add(Text::_('JLIB_FILESYSTEM_ERROR_RENAME_FILE'), Log::WARNING, 'jerror'); return false; } } return true; } } /** * Read the contents of a file * * @param string $filename The full file path * @param boolean $incpath Use include path * @param integer $amount Amount of file to read * @param integer $chunksize Size of chunks to read * @param integer $offset Offset of the file * * @return mixed Returns file contents or boolean False if failed * * @since 1.7.0 * @deprecated 4.0 - Use the native file_get_contents() instead. */ public static function read($filename, $incpath = false, $amount = 0, $chunksize = 8192, $offset = 0) { Log::add(__METHOD__ . ' is deprecated. Use native file_get_contents() syntax.', Log::WARNING, 'deprecated'); $data = null; if ($amount && $chunksize > $amount) { $chunksize = $amount; } if (false === $fh = fopen($filename, 'rb', $incpath)) { Log::add(Text::sprintf('JLIB_FILESYSTEM_ERROR_READ_UNABLE_TO_OPEN_FILE', $filename), Log::WARNING, 'jerror'); return false; } clearstatcache(); if ($offset) { fseek($fh, $offset); } if ($fsize = @ filesize($filename)) { if ($amount && $fsize > $amount) { $data = fread($fh, $amount); } else { $data = fread($fh, $fsize); } } else { $data = ''; /* * While it's: * 1: Not the end of the file AND * 2a: No Max Amount set OR * 2b: The length of the data is less than the max amount we want */ while (!feof($fh) && (!$amount || strlen($data) < $amount)) { $data .= fread($fh, $chunksize); } } fclose($fh); return $data; } /** * Write contents to a file * * @param string $file The full file path * @param string $buffer The buffer to write * @param boolean $useStreams Use streams * * @return boolean True on success * * @since 1.7.0 */ public static function write($file, $buffer, $useStreams = false) { @set_time_limit(ini_get('max_execution_time')); // If the destination directory doesn't exist we need to create it if (!file_exists(dirname($file))) { $folderObject = new FolderWrapper; if ($folderObject->create(dirname($file)) == false) { return false; } } if ($useStreams) { $stream = Factory::getStream(); // Beef up the chunk size to a meg $stream->set('chunksize', (1024 * 1024)); if (!$stream->writeFile($file, $buffer)) { Log::add(Text::sprintf('JLIB_FILESYSTEM_ERROR_WRITE_STREAMS', $file, $stream->getError()), Log::WARNING, 'jerror'); return false; } return true; } else { $FTPOptions = ClientHelper::getCredentials('ftp'); $pathObject = new PathWrapper; if ($FTPOptions['enabled'] == 1) { // Connect the FTP client $ftp = FtpClient::getInstance($FTPOptions['host'], $FTPOptions['port'], array(), $FTPOptions['user'], $FTPOptions['pass']); // Translate path for the FTP account and use FTP write buffer to file $file = $pathObject->clean(str_replace(JPATH_ROOT, $FTPOptions['root'], $file), '/'); $ret = $ftp->write($file, $buffer); } else { $file = $pathObject->clean($file); $ret = is_int(file_put_contents($file, $buffer)) ? true : false; } return $ret; } } /** * Append contents to a file * * @param string $file The full file path * @param string $buffer The buffer to write * @param boolean $useStreams Use streams * * @return boolean True on success * * @since 3.6.0 */ public static function append($file, $buffer, $useStreams = false) { @set_time_limit(ini_get('max_execution_time')); // If the file doesn't exist, just write instead of append if (!file_exists($file)) { return self::write($file, $buffer, $useStreams); } if ($useStreams) { $stream = Factory::getStream(); // Beef up the chunk size to a meg $stream->set('chunksize', (1024 * 1024)); if ($stream->open($file, 'ab') && $stream->write($buffer) && $stream->close()) { return true; } Log::add(Text::sprintf('JLIB_FILESYSTEM_ERROR_WRITE_STREAMS', $file, $stream->getError()), Log::WARNING, 'jerror'); return false; } else { // Initialise variables. $FTPOptions = ClientHelper::getCredentials('ftp'); if ($FTPOptions['enabled'] == 1) { // Connect the FTP client $ftp = FtpClient::getInstance($FTPOptions['host'], $FTPOptions['port'], array(), $FTPOptions['user'], $FTPOptions['pass']); // Translate path for the FTP account and use FTP write buffer to file $file = Path::clean(str_replace(JPATH_ROOT, $FTPOptions['root'], $file), '/'); $ret = $ftp->append($file, $buffer); } else { $file = Path::clean($file); $ret = is_int(file_put_contents($file, $buffer, FILE_APPEND)); } return $ret; } } /** * Moves an uploaded file to a destination folder * * @param string $src The name of the php (temporary) uploaded file * @param string $dest The path (including filename) to move the uploaded file to * @param boolean $useStreams True to use streams * @param boolean $allowUnsafe Allow the upload of unsafe files * @param boolean $safeFileOptions Options to \JFilterInput::isSafeFile * * @return boolean True on success * * @since 1.7.0 */ public static function upload($src, $dest, $useStreams = false, $allowUnsafe = false, $safeFileOptions = array()) { if (!$allowUnsafe) { $descriptor = array( 'tmp_name' => $src, 'name' => basename($dest), 'type' => '', 'error' => '', 'size' => '', ); $isSafe = \JFilterInput::isSafeFile($descriptor, $safeFileOptions); if (!$isSafe) { Log::add(Text::sprintf('JLIB_FILESYSTEM_ERROR_WARNFS_ERR03', $dest), Log::WARNING, 'jerror'); return false; } } // Ensure that the path is valid and clean $pathObject = new PathWrapper; $dest = $pathObject->clean($dest); // Create the destination directory if it does not exist $baseDir = dirname($dest); if (!file_exists($baseDir)) { $folderObject = new FolderWrapper; $folderObject->create($baseDir); } if ($useStreams) { $stream = Factory::getStream(); if (!$stream->upload($src, $dest)) { Log::add(Text::sprintf('JLIB_FILESYSTEM_ERROR_UPLOAD', $stream->getError()), Log::WARNING, 'jerror'); return false; } return true; } else { $FTPOptions = ClientHelper::getCredentials('ftp'); $ret = false; if ($FTPOptions['enabled'] == 1) { // Connect the FTP client $ftp = FtpClient::getInstance($FTPOptions['host'], $FTPOptions['port'], array(), $FTPOptions['user'], $FTPOptions['pass']); // Translate path for the FTP account $dest = $pathObject->clean(str_replace(JPATH_ROOT, $FTPOptions['root'], $dest), '/'); // Copy the file to the destination directory if (is_uploaded_file($src) && $ftp->store($src, $dest)) { unlink($src); $ret = true; } else { Log::add(Text::sprintf('JLIB_FILESYSTEM_ERROR_WARNFS_ERR04', $src, $dest), Log::WARNING, 'jerror'); } } else { if (is_writeable($baseDir) && move_uploaded_file($src, $dest)) { // Short circuit to prevent file permission errors if ($pathObject->setPermissions($dest)) { $ret = true; } else { Log::add(Text::_('JLIB_FILESYSTEM_ERROR_WARNFS_ERR01'), Log::WARNING, 'jerror'); } } else { Log::add(Text::sprintf('JLIB_FILESYSTEM_ERROR_WARNFS_ERR04', $src, $dest), Log::WARNING, 'jerror'); } } return $ret; } } /** * Wrapper for the standard file_exists function * * @param string $file File path * * @return boolean True if path is a file * * @since 1.7.0 */ public static function exists($file) { $pathObject = new PathWrapper; return is_file($pathObject->clean($file)); } /** * Returns the name, without any path. * * @param string $file File path * * @return string filename * * @since 1.7.0 * @deprecated 4.0 - Use basename() instead. */ public static function getName($file) { Log::add(__METHOD__ . ' is deprecated. Use native basename() syntax.', Log::WARNING, 'deprecated'); // Convert back slashes to forward slashes $file = str_replace('\\', '/', $file); $slash = strrpos($file, '/'); if ($slash !== false) { return substr($file, $slash + 1); } else { return $file; } } } FilesystemHelper.php 0000644 00000016024 15117132553 0010547 0 ustar 00 <?php /** * Joomla! Content Management System * * @copyright (C) 2008 Open Source Matters, Inc. <https://www.joomla.org> * @license GNU General Public License version 2 or later; see LICENSE.txt */ namespace Joomla\CMS\Filesystem; defined('JPATH_PLATFORM') or die; /** * File system helper * * Holds support functions for the filesystem, particularly the stream * * @since 1.7.0 */ class FilesystemHelper { /** * Remote file size function for streams that don't support it * * @param string $url TODO Add text * * @return mixed * * @link https://www.php.net/manual/en/function.filesize.php * @since 1.7.0 */ public static function remotefsize($url) { $sch = parse_url($url, PHP_URL_SCHEME); if (($sch != 'http') && ($sch != 'https') && ($sch != 'ftp') && ($sch != 'ftps')) { return false; } if (($sch == 'http') || ($sch == 'https')) { $headers = get_headers($url, 1); if ((!array_key_exists('Content-Length', $headers))) { return false; } return $headers['Content-Length']; } if (($sch == 'ftp') || ($sch == 'ftps')) { $server = parse_url($url, PHP_URL_HOST); $port = parse_url($url, PHP_URL_PORT); $path = parse_url($url, PHP_URL_PATH); $user = parse_url($url, PHP_URL_USER); $pass = parse_url($url, PHP_URL_PASS); if ((!$server) || (!$path)) { return false; } if (!$port) { $port = 21; } if (!$user) { $user = 'anonymous'; } if (!$pass) { $pass = ''; } switch ($sch) { case 'ftp': $ftpid = ftp_connect($server, $port); break; case 'ftps': $ftpid = ftp_ssl_connect($server, $port); break; } if (!$ftpid) { return false; } $login = ftp_login($ftpid, $user, $pass); if (!$login) { return false; } $ftpsize = ftp_size($ftpid, $path); ftp_close($ftpid); if ($ftpsize == -1) { return false; } return $ftpsize; } } /** * Quick FTP chmod * * @param string $url Link identifier * @param integer $mode The new permissions, given as an octal value. * * @return mixed * * @link https://www.php.net/manual/en/function.ftp-chmod.php * @since 1.7.0 */ public static function ftpChmod($url, $mode) { $sch = parse_url($url, PHP_URL_SCHEME); if (($sch != 'ftp') && ($sch != 'ftps')) { return false; } $server = parse_url($url, PHP_URL_HOST); $port = parse_url($url, PHP_URL_PORT); $path = parse_url($url, PHP_URL_PATH); $user = parse_url($url, PHP_URL_USER); $pass = parse_url($url, PHP_URL_PASS); if ((!$server) || (!$path)) { return false; } if (!$port) { $port = 21; } if (!$user) { $user = 'anonymous'; } if (!$pass) { $pass = ''; } switch ($sch) { case 'ftp': $ftpid = ftp_connect($server, $port); break; case 'ftps': $ftpid = ftp_ssl_connect($server, $port); break; } if (!$ftpid) { return false; } $login = ftp_login($ftpid, $user, $pass); if (!$login) { return false; } $res = ftp_chmod($ftpid, $mode, $path); ftp_close($ftpid); return $res; } /** * Modes that require a write operation * * @return array * * @since 1.7.0 */ public static function getWriteModes() { return array('w', 'w+', 'a', 'a+', 'r+', 'x', 'x+'); } /** * Stream and Filter Support Operations * * Returns the supported streams, in addition to direct file access * Also includes Joomla! streams as well as PHP streams * * @return array Streams * * @since 1.7.0 */ public static function getSupported() { // Really quite cool what php can do with arrays when you let it... static $streams; if (!$streams) { $streams = array_merge(stream_get_wrappers(), self::getJStreams()); } return $streams; } /** * Returns a list of transports * * @return array * * @since 1.7.0 */ public static function getTransports() { // Is this overkill? return stream_get_transports(); } /** * Returns a list of filters * * @return array * * @since 1.7.0 */ public static function getFilters() { // Note: This will look like the getSupported() function with J! filters. // TODO: add user space filter loading like user space stream loading return stream_get_filters(); } /** * Returns a list of J! streams * * @return array * * @since 1.7.0 */ public static function getJStreams() { static $streams = array(); if (!$streams) { $files = new \DirectoryIterator(__DIR__ . '/Streams'); /* @type $file DirectoryIterator */ foreach ($files as $file) { // Only load for php files. if (!$file->isFile() || $file->getExtension() !== 'php') { continue; } $streams[] = str_replace('stream', '', strtolower($file->getBasename('.php'))); } } return $streams; } /** * Determine if a stream is a Joomla stream. * * @param string $streamname The name of a stream * * @return boolean True for a Joomla Stream * * @since 1.7.0 */ public static function isJoomlaStream($streamname) { return in_array($streamname, self::getJStreams()); } /** * Calculates the maximum upload file size and returns string with unit or the size in bytes * * Call it with JFilesystemHelper::fileUploadMaxSize(); * * @param bool $unitOutput This parameter determines whether the return value should be a string with a unit * * @return float|string The maximum upload size of files with the appropriate unit or in bytes * * @since 3.4 */ public static function fileUploadMaxSize($unitOutput = true) { static $max_size = false; static $output_type = true; if ($max_size === false || $output_type != $unitOutput) { $max_size = self::parseSize(ini_get('post_max_size')); $upload_max = self::parseSize(ini_get('upload_max_filesize')); if ($upload_max > 0 && ($upload_max < $max_size || $max_size == 0)) { $max_size = $upload_max; } if ($unitOutput == true) { $max_size = self::parseSizeUnit($max_size); } $output_type = $unitOutput; } return $max_size; } /** * Returns the size in bytes without the unit for the comparison * * @param string $size The size which is received from the PHP settings * * @return float The size in bytes without the unit * * @since 3.4 */ private static function parseSize($size) { $unit = preg_replace('/[^bkmgtpezy]/i', '', $size); $size = preg_replace('/[^0-9\.]/', '', $size); $return = round($size); if ($unit) { $return = round($size * pow(1024, stripos('bkmgtpezy', $unit[0]))); } return $return; } /** * Creates the rounded size of the size with the appropriate unit * * @param float $maxSize The maximum size which is allowed for the uploads * * @return string String with the size and the appropriate unit * * @since 3.4 */ private static function parseSizeUnit($maxSize) { $base = log($maxSize) / log(1024); $suffixes = array('', 'k', 'M', 'G', 'T'); return round(pow(1024, $base - floor($base)), 0) . $suffixes[floor($base)]; } } Folder.php 0000644 00000044655 15117132553 0006511 0 ustar 00 <?php /** * Joomla! Content Management System * * @copyright (C) 2006 Open Source Matters, Inc. <https://www.joomla.org> * @license GNU General Public License version 2 or later; see LICENSE.txt */ namespace Joomla\CMS\Filesystem; defined('JPATH_PLATFORM') or die; use Joomla\CMS\Factory; use Joomla\CMS\Log\Log; use Joomla\CMS\Filesystem\Wrapper\PathWrapper; use Joomla\CMS\Filesystem\Wrapper\FileWrapper; use Joomla\CMS\Client\ClientHelper; use Joomla\CMS\Client\FtpClient; use Joomla\CMS\Language\Text; /** * A Folder handling class * * @since 1.7.0 */ abstract class Folder { /** * Copy a folder. * * @param string $src The path to the source folder. * @param string $dest The path to the destination folder. * @param string $path An optional base path to prefix to the file names. * @param boolean $force Force copy. * @param boolean $useStreams Optionally force folder/file overwrites. * * @return boolean True on success. * * @since 1.7.0 * @throws \RuntimeException */ public static function copy($src, $dest, $path = '', $force = false, $useStreams = false) { @set_time_limit(ini_get('max_execution_time')); $FTPOptions = ClientHelper::getCredentials('ftp'); $pathObject = new PathWrapper; if ($path) { $src = $pathObject->clean($path . '/' . $src); $dest = $pathObject->clean($path . '/' . $dest); } // Eliminate trailing directory separators, if any $src = rtrim($src, DIRECTORY_SEPARATOR); $dest = rtrim($dest, DIRECTORY_SEPARATOR); if (!self::exists($src)) { throw new \RuntimeException('Source folder not found', -1); } if (self::exists($dest) && !$force) { throw new \RuntimeException('Destination folder already exists', -1); } // Make sure the destination exists if (!self::create($dest)) { throw new \RuntimeException('Cannot create destination folder', -1); } // If we're using ftp and don't have streams enabled if ($FTPOptions['enabled'] == 1 && !$useStreams) { // Connect the FTP client $ftp = FtpClient::getInstance($FTPOptions['host'], $FTPOptions['port'], array(), $FTPOptions['user'], $FTPOptions['pass']); if (!($dh = @opendir($src))) { throw new \RuntimeException('Cannot open source folder', -1); } // Walk through the directory copying files and recursing into folders. while (($file = readdir($dh)) !== false) { $sfid = $src . '/' . $file; $dfid = $dest . '/' . $file; switch (filetype($sfid)) { case 'dir': if ($file != '.' && $file != '..') { $ret = self::copy($sfid, $dfid, null, $force); if ($ret !== true) { return $ret; } } break; case 'file': // Translate path for the FTP account $dfid = $pathObject->clean(str_replace(JPATH_ROOT, $FTPOptions['root'], $dfid), '/'); if (!$ftp->store($sfid, $dfid)) { throw new \RuntimeException('Copy file failed', -1); } break; } } } else { if (!($dh = @opendir($src))) { throw new \RuntimeException('Cannot open source folder', -1); } // Walk through the directory copying files and recursing into folders. while (($file = readdir($dh)) !== false) { $sfid = $src . '/' . $file; $dfid = $dest . '/' . $file; switch (filetype($sfid)) { case 'dir': if ($file != '.' && $file != '..') { $ret = self::copy($sfid, $dfid, null, $force, $useStreams); if ($ret !== true) { return $ret; } } break; case 'file': if ($useStreams) { $stream = Factory::getStream(); if (!$stream->copy($sfid, $dfid)) { throw new \RuntimeException( 'Cannot copy file: ' . Path::removeRoot($stream->getError()), -1 ); } } else { if (!@copy($sfid, $dfid)) { throw new \RuntimeException('Copy file failed', -1); } } break; } } } return true; } /** * Create a folder -- and all necessary parent folders. * * @param string $path A path to create from the base path. * @param integer $mode Directory permissions to set for folders created. 0755 by default. * * @return boolean True if successful. * * @since 1.7.0 */ public static function create($path = '', $mode = 0755) { $FTPOptions = ClientHelper::getCredentials('ftp'); static $nested = 0; // Check to make sure the path valid and clean $pathObject = new PathWrapper; $path = $pathObject->clean($path); // Check if parent dir exists $parent = dirname($path); if (!self::exists($parent)) { // Prevent infinite loops! $nested++; if (($nested > 20) || ($parent == $path)) { Log::add(__METHOD__ . ': ' . Text::_('JLIB_FILESYSTEM_ERROR_FOLDER_LOOP'), Log::WARNING, 'jerror'); $nested--; return false; } // Create the parent directory if (self::create($parent, $mode) !== true) { // JFolder::create throws an error $nested--; return false; } // OK, parent directory has been created $nested--; } // Check if dir already exists if (self::exists($path)) { return true; } // Check for safe mode if ($FTPOptions['enabled'] == 1) { // Connect the FTP client $ftp = FtpClient::getInstance($FTPOptions['host'], $FTPOptions['port'], array(), $FTPOptions['user'], $FTPOptions['pass']); // Translate path to FTP path $path = $pathObject->clean(str_replace(JPATH_ROOT, $FTPOptions['root'], $path), '/'); $ret = $ftp->mkdir($path); $ftp->chmod($path, $mode); } else { // We need to get and explode the open_basedir paths $obd = ini_get('open_basedir'); // If open_basedir is set we need to get the open_basedir that the path is in if ($obd != null) { if (IS_WIN) { $obdSeparator = ';'; } else { $obdSeparator = ':'; } // Create the array of open_basedir paths $obdArray = explode($obdSeparator, $obd); $inBaseDir = false; // Iterate through open_basedir paths looking for a match foreach ($obdArray as $test) { $test = $pathObject->clean($test); if (strpos($path, $test) === 0 || strpos($path, realpath($test)) === 0) { $inBaseDir = true; break; } } if ($inBaseDir == false) { // Return false for JFolder::create because the path to be created is not in open_basedir Log::add(__METHOD__ . ': ' . Text::_('JLIB_FILESYSTEM_ERROR_FOLDER_PATH'), Log::WARNING, 'jerror'); return false; } } // First set umask $origmask = @umask(0); // Create the path if (!$ret = @mkdir($path, $mode)) { @umask($origmask); Log::add( __METHOD__ . ': ' . Text::_('JLIB_FILESYSTEM_ERROR_COULD_NOT_CREATE_DIRECTORY') . 'Path: ' . $path, Log::WARNING, 'jerror' ); return false; } // Reset umask @umask($origmask); } return $ret; } /** * Delete a folder. * * @param string $path The path to the folder to delete. * * @return boolean True on success. * * @since 1.7.0 */ public static function delete($path) { @set_time_limit(ini_get('max_execution_time')); $pathObject = new PathWrapper; // Sanity check if (!$path) { // Bad programmer! Bad Bad programmer! Log::add(__METHOD__ . ': ' . Text::_('JLIB_FILESYSTEM_ERROR_DELETE_BASE_DIRECTORY'), Log::WARNING, 'jerror'); return false; } $FTPOptions = ClientHelper::getCredentials('ftp'); // Check to make sure the path valid and clean $path = $pathObject->clean($path); // Is this really a folder? if (!is_dir($path)) { Log::add(Text::sprintf('JLIB_FILESYSTEM_ERROR_PATH_IS_NOT_A_FOLDER', $path), Log::WARNING, 'jerror'); return false; } // Remove all the files in folder if they exist; disable all filtering $files = self::files($path, '.', false, true, array(), array()); if (!empty($files)) { $file = new FileWrapper; if ($file->delete($files) !== true) { // JFile::delete throws an error return false; } } // Remove sub-folders of folder; disable all filtering $folders = self::folders($path, '.', false, true, array(), array()); foreach ($folders as $folder) { if (is_link($folder)) { // Don't descend into linked directories, just delete the link. $file = new FileWrapper; if ($file->delete($folder) !== true) { // JFile::delete throws an error return false; } } elseif (self::delete($folder) !== true) { // JFolder::delete throws an error return false; } } if ($FTPOptions['enabled'] == 1) { // Connect the FTP client $ftp = FtpClient::getInstance($FTPOptions['host'], $FTPOptions['port'], array(), $FTPOptions['user'], $FTPOptions['pass']); } // In case of restricted permissions we zap it one way or the other // as long as the owner is either the webserver or the ftp. if (@rmdir($path)) { $ret = true; } elseif ($FTPOptions['enabled'] == 1) { // Translate path and delete $path = $pathObject->clean(str_replace(JPATH_ROOT, $FTPOptions['root'], $path), '/'); // FTP connector throws an error $ret = $ftp->delete($path); } else { Log::add(Text::sprintf('JLIB_FILESYSTEM_ERROR_FOLDER_DELETE', $path), Log::WARNING, 'jerror'); $ret = false; } return $ret; } /** * Moves a folder. * * @param string $src The path to the source folder. * @param string $dest The path to the destination folder. * @param string $path An optional base path to prefix to the file names. * @param boolean $useStreams Optionally use streams. * * @return mixed Error message on false or boolean true on success. * * @since 1.7.0 */ public static function move($src, $dest, $path = '', $useStreams = false) { $FTPOptions = ClientHelper::getCredentials('ftp'); $pathObject = new PathWrapper; if ($path) { $src = $pathObject->clean($path . '/' . $src); $dest = $pathObject->clean($path . '/' . $dest); } if (!self::exists($src)) { return Text::_('JLIB_FILESYSTEM_ERROR_FIND_SOURCE_FOLDER'); } if (self::exists($dest)) { return Text::_('JLIB_FILESYSTEM_ERROR_FOLDER_EXISTS'); } if ($useStreams) { $stream = Factory::getStream(); if (!$stream->move($src, $dest)) { return Text::sprintf('JLIB_FILESYSTEM_ERROR_FOLDER_RENAME', $stream->getError()); } $ret = true; } else { if ($FTPOptions['enabled'] == 1) { // Connect the FTP client $ftp = FtpClient::getInstance($FTPOptions['host'], $FTPOptions['port'], array(), $FTPOptions['user'], $FTPOptions['pass']); // Translate path for the FTP account $src = $pathObject->clean(str_replace(JPATH_ROOT, $FTPOptions['root'], $src), '/'); $dest = $pathObject->clean(str_replace(JPATH_ROOT, $FTPOptions['root'], $dest), '/'); // Use FTP rename to simulate move if (!$ftp->rename($src, $dest)) { return Text::_('JLIB_FILESYSTEM_ERROR_RENAME_FILE'); } $ret = true; } else { if (!@rename($src, $dest)) { return Text::_('JLIB_FILESYSTEM_ERROR_RENAME_FILE'); } $ret = true; } } return $ret; } /** * Wrapper for the standard file_exists function * * @param string $path Folder name relative to installation dir * * @return boolean True if path is a folder * * @since 1.7.0 */ public static function exists($path) { $pathObject = new PathWrapper; return is_dir($pathObject->clean($path)); } /** * Utility function to read the files in a folder. * * @param string $path The path of the folder to read. * @param string $filter A filter for file names. * @param mixed $recurse True to recursively search into sub-folders, or an integer to specify the maximum depth. * @param boolean $full True to return the full path to the file. * @param array $exclude Array with names of files which should not be shown in the result. * @param array $excludeFilter Array of filter to exclude * @param boolean $naturalSort False for asort, true for natsort * * @return array Files in the given folder. * * @since 1.7.0 */ public static function files($path, $filter = '.', $recurse = false, $full = false, $exclude = array('.svn', 'CVS', '.DS_Store', '__MACOSX'), $excludeFilter = array('^\..*', '.*~'), $naturalSort = false) { // Check to make sure the path valid and clean $pathObject = new PathWrapper; $path = $pathObject->clean($path); // Is the path a folder? if (!is_dir($path)) { Log::add(Text::sprintf('JLIB_FILESYSTEM_ERROR_PATH_IS_NOT_A_FOLDER_FILES', $path), Log::WARNING, 'jerror'); return false; } // Compute the excludefilter string if (count($excludeFilter)) { $excludefilter_string = '/(' . implode('|', $excludeFilter) . ')/'; } else { $excludefilter_string = ''; } // Get the files $arr = self::_items($path, $filter, $recurse, $full, $exclude, $excludefilter_string, true); // Sort the files based on either natural or alpha method if ($naturalSort) { natsort($arr); } else { asort($arr); } return array_values($arr); } /** * Utility function to read the folders in a folder. * * @param string $path The path of the folder to read. * @param string $filter A filter for folder names. * @param mixed $recurse True to recursively search into sub-folders, or an integer to specify the maximum depth. * @param boolean $full True to return the full path to the folders. * @param array $exclude Array with names of folders which should not be shown in the result. * @param array $excludeFilter Array with regular expressions matching folders which should not be shown in the result. * * @return array Folders in the given folder. * * @since 1.7.0 */ public static function folders($path, $filter = '.', $recurse = false, $full = false, $exclude = array('.svn', 'CVS', '.DS_Store', '__MACOSX'), $excludeFilter = array('^\..*')) { // Check to make sure the path valid and clean $pathObject = new PathWrapper; $path = $pathObject->clean($path); // Is the path a folder? if (!is_dir($path)) { Log::add(Text::sprintf('JLIB_FILESYSTEM_ERROR_PATH_IS_NOT_A_FOLDER_FOLDER', $path), Log::WARNING, 'jerror'); return false; } // Compute the excludefilter string if (count($excludeFilter)) { $excludefilter_string = '/(' . implode('|', $excludeFilter) . ')/'; } else { $excludefilter_string = ''; } // Get the folders $arr = self::_items($path, $filter, $recurse, $full, $exclude, $excludefilter_string, false); // Sort the folders asort($arr); return array_values($arr); } /** * Function to read the files/folders in a folder. * * @param string $path The path of the folder to read. * @param string $filter A filter for file names. * @param mixed $recurse True to recursively search into sub-folders, or an integer to specify the maximum depth. * @param boolean $full True to return the full path to the file. * @param array $exclude Array with names of files which should not be shown in the result. * @param string $excludeFilterString Regexp of files to exclude * @param boolean $findFiles True to read the files, false to read the folders * * @return array Files. * * @since 1.7.0 */ protected static function _items($path, $filter, $recurse, $full, $exclude, $excludeFilterString, $findFiles) { @set_time_limit(ini_get('max_execution_time')); $arr = array(); // Read the source directory if (!($handle = @opendir($path))) { return $arr; } while (($file = readdir($handle)) !== false) { if ($file != '.' && $file != '..' && !in_array($file, $exclude) && (empty($excludeFilterString) || !preg_match($excludeFilterString, $file))) { // Compute the fullpath $fullpath = $path . '/' . $file; // Compute the isDir flag $isDir = is_dir($fullpath); if (($isDir xor $findFiles) && preg_match("/$filter/", $file)) { // (fullpath is dir and folders are searched or fullpath is not dir and files are searched) and file matches the filter if ($full) { // Full path is requested $arr[] = $fullpath; } else { // Filename is requested $arr[] = $file; } } if ($isDir && $recurse) { // Search recursively if (is_int($recurse)) { // Until depth 0 is reached $arr = array_merge($arr, self::_items($fullpath, $filter, $recurse - 1, $full, $exclude, $excludeFilterString, $findFiles)); } else { $arr = array_merge($arr, self::_items($fullpath, $filter, $recurse, $full, $exclude, $excludeFilterString, $findFiles)); } } } } closedir($handle); return $arr; } /** * Lists folder in format suitable for tree display. * * @param string $path The path of the folder to read. * @param string $filter A filter for folder names. * @param integer $maxLevel The maximum number of levels to recursively read, defaults to three. * @param integer $level The current level, optional. * @param integer $parent Unique identifier of the parent folder, if any. * * @return array Folders in the given folder. * * @since 1.7.0 */ public static function listFolderTree($path, $filter, $maxLevel = 3, $level = 0, $parent = 0) { $dirs = array(); if ($level == 0) { $GLOBALS['_JFolder_folder_tree_index'] = 0; } if ($level < $maxLevel) { $folders = self::folders($path, $filter); $pathObject = new PathWrapper; // First path, index foldernames foreach ($folders as $name) { $id = ++$GLOBALS['_JFolder_folder_tree_index']; $fullName = $pathObject->clean($path . '/' . $name); $dirs[] = array( 'id' => $id, 'parent' => $parent, 'name' => $name, 'fullname' => $fullName, 'relname' => str_replace(JPATH_ROOT, '', $fullName), ); $dirs2 = self::listFolderTree($fullName, $filter, $maxLevel, $level + 1, $id); $dirs = array_merge($dirs, $dirs2); } } return $dirs; } /** * Makes path name safe to use. * * @param string $path The full path to sanitise. * * @return string The sanitised string. * * @since 1.7.0 */ public static function makeSafe($path) { $regex = array('#[^A-Za-z0-9_\\\/\(\)\[\]\{\}\#\$\^\+\.\'~`!@&=;,-]#'); return preg_replace($regex, '', $path); } } Meta/language/en-GB/en-GB.lib_joomla_filesystem_patcher.ini 0000644 00000001300 15117132553 0017553 0 ustar 00 ; Joomla! Project ; (C) 2012 Open Source Matters, Inc. <https://www.joomla.org> ; License GNU General Public License version 2 or later; see LICENSE.txt ; Note : All ini files need to be saved as UTF-8 JLIB_FILESYSTEM_PATCHER_FAILED_VERIFY="Failed source verification of file %s at line %d" JLIB_FILESYSTEM_PATCHER_INVALID_DIFF="Invalid unified diff block" JLIB_FILESYSTEM_PATCHER_INVALID_INPUT="Invalid input" JLIB_FILESYSTEM_PATCHER_UNEXISING_SOURCE="Unexisting source file" JLIB_FILESYSTEM_PATCHER_UNEXPECTED_ADD_LINE="Unexpected add line at line %d'" JLIB_FILESYSTEM_PATCHER_UNEXPECTED_EOF="Unexpected end of file" JLIB_FILESYSTEM_PATCHER_UNEXPECTED_REMOVE_LINE="Unexpected remove line at line %d" Patcher.php 0000644 00000026416 15117132553 0006657 0 ustar 00 <?php /** * Joomla! Content Management System * * @copyright (C) 2012 Open Source Matters, Inc. <https://www.joomla.org> * @license GNU General Public License version 2 or later; see LICENSE.txt */ namespace Joomla\CMS\Filesystem; defined('JPATH_PLATFORM') or die; use Joomla\CMS\Log\Log; use Joomla\CMS\Language\Text; /** * A Unified Diff Format Patcher class * * @link http://sourceforge.net/projects/phppatcher/ This has been derived from the PhpPatcher version 0.1.1 written by Giuseppe Mazzotta * @since 3.0.0 */ class Patcher { /** * Regular expression for searching source files */ const SRC_FILE = '/^---\\s+(\\S+)\s+\\d{1,4}-\\d{1,2}-\\d{1,2}\\s+\\d{1,2}:\\d{1,2}:\\d{1,2}(\\.\\d+)?\\s+(\+|-)\\d{4}/A'; /** * Regular expression for searching destination files */ const DST_FILE = '/^\\+\\+\\+\\s+(\\S+)\s+\\d{1,4}-\\d{1,2}-\\d{1,2}\\s+\\d{1,2}:\\d{1,2}:\\d{1,2}(\\.\\d+)?\\s+(\+|-)\\d{4}/A'; /** * Regular expression for searching hunks of differences */ const HUNK = '/@@ -(\\d+)(,(\\d+))?\\s+\\+(\\d+)(,(\\d+))?\\s+@@($)/A'; /** * Regular expression for splitting lines */ const SPLIT = '/(\r\n)|(\r)|(\n)/'; /** * @var array sources files * @since 3.0.0 */ protected $sources = array(); /** * @var array destination files * @since 3.0.0 */ protected $destinations = array(); /** * @var array removal files * @since 3.0.0 */ protected $removals = array(); /** * @var array patches * @since 3.0.0 */ protected $patches = array(); /** * @var array instance of this class * @since 3.0.0 */ protected static $instance; /** * Constructor * * The constructor is protected to force the use of FilesystemPatcher::getInstance() * * @since 3.0.0 */ protected function __construct() { } /** * Method to get a patcher * * @return FilesystemPatcher an instance of the patcher * * @since 3.0.0 */ public static function getInstance() { if (!isset(static::$instance)) { static::$instance = new static; } return static::$instance; } /** * Reset the pacher * * @return FilesystemPatcher This object for chaining * * @since 3.0.0 */ public function reset() { $this->sources = array(); $this->destinations = array(); $this->removals = array(); $this->patches = array(); return $this; } /** * Apply the patches * * @return integer The number of files patched * * @since 3.0.0 * @throws \RuntimeException */ public function apply() { foreach ($this->patches as $patch) { // Separate the input into lines $lines = self::splitLines($patch['udiff']); // Loop for each header while (self::findHeader($lines, $src, $dst)) { $done = false; $regex = '#^([^/]*/)*#'; if ($patch['strip'] !== null) { $regex = '#^([^/]*/){' . (int) $patch['strip'] . '}#'; } $src = $patch['root'] . preg_replace($regex, '', $src); $dst = $patch['root'] . preg_replace($regex, '', $dst); // Loop for each hunk of differences while (self::findHunk($lines, $src_line, $src_size, $dst_line, $dst_size)) { $done = true; // Apply the hunk of differences $this->applyHunk($lines, $src, $dst, $src_line, $src_size, $dst_line, $dst_size); } // If no modifications were found, throw an exception if (!$done) { throw new \RuntimeException('Invalid Diff'); } } } // Initialize the counter $done = 0; // Patch each destination file foreach ($this->destinations as $file => $content) { $buffer = implode("\n", $content); if (File::write($file, $buffer)) { if (isset($this->sources[$file])) { $this->sources[$file] = $content; } $done++; } } // Remove each removed file foreach ($this->removals as $file) { if (File::delete($file)) { if (isset($this->sources[$file])) { unset($this->sources[$file]); } $done++; } } // Clear the destinations cache $this->destinations = array(); // Clear the removals $this->removals = array(); // Clear the patches $this->patches = array(); return $done; } /** * Add a unified diff file to the patcher * * @param string $filename Path to the unified diff file * @param string $root The files root path * @param string $strip The number of '/' to strip * * @return FilesystemPatcher $this for chaining * * @since 3.0.0 */ public function addFile($filename, $root = JPATH_BASE, $strip = 0) { return $this->add(file_get_contents($filename), $root, $strip); } /** * Add a unified diff string to the patcher * * @param string $udiff Unified diff input string * @param string $root The files root path * @param string $strip The number of '/' to strip * * @return FilesystemPatcher $this for chaining * * @since 3.0.0 */ public function add($udiff, $root = JPATH_BASE, $strip = 0) { $this->patches[] = array( 'udiff' => $udiff, 'root' => isset($root) ? rtrim($root, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR : '', 'strip' => $strip, ); return $this; } /** * Separate CR or CRLF lines * * @param string $data Input string * * @return array The lines of the inputdestination file * * @since 3.0.0 */ protected static function splitLines($data) { return preg_split(self::SPLIT, $data); } /** * Find the diff header * * The internal array pointer of $lines is on the next line after the finding * * @param array &$lines The udiff array of lines * @param string &$src The source file * @param string &$dst The destination file * * @return boolean TRUE in case of success, FALSE in case of failure * * @since 3.0.0 * @throws \RuntimeException */ protected static function findHeader(&$lines, &$src, &$dst) { // Get the current line $line = current($lines); // Search for the header while ($line !== false && !preg_match(self::SRC_FILE, $line, $m)) { $line = next($lines); } if ($line === false) { // No header found, return false return false; } // Set the source file $src = $m[1]; // Advance to the next line $line = next($lines); if ($line === false) { throw new \RuntimeException('Unexpected EOF'); } // Search the destination file if (!preg_match(self::DST_FILE, $line, $m)) { throw new \RuntimeException('Invalid Diff file'); } // Set the destination file $dst = $m[1]; // Advance to the next line if (next($lines) === false) { throw new \RuntimeException('Unexpected EOF'); } return true; } /** * Find the next hunk of difference * * The internal array pointer of $lines is on the next line after the finding * * @param array &$lines The udiff array of lines * @param string &$srcLine The beginning of the patch for the source file * @param string &$srcSize The size of the patch for the source file * @param string &$dstLine The beginning of the patch for the destination file * @param string &$dstSize The size of the patch for the destination file * * @return boolean TRUE in case of success, false in case of failure * * @since 3.0.0 * @throws \RuntimeException */ protected static function findHunk(&$lines, &$srcLine, &$srcSize, &$dstLine, &$dstSize) { $line = current($lines); if (preg_match(self::HUNK, $line, $m)) { $srcLine = (int) $m[1]; $srcSize = 1; if ($m[3] !== '') { $srcSize = (int) $m[3]; } $dstLine = (int) $m[4]; $dstSize = 1; if ($m[6] !== '') { $dstSize = (int) $m[6]; } if (next($lines) === false) { throw new \RuntimeException('Unexpected EOF'); } return true; } return false; } /** * Apply the patch * * @param array &$lines The udiff array of lines * @param string $src The source file * @param string $dst The destination file * @param string $srcLine The beginning of the patch for the source file * @param string $srcSize The size of the patch for the source file * @param string $dstLine The beginning of the patch for the destination file * @param string $dstSize The size of the patch for the destination file * * @return void * * @since 3.0.0 * @throws \RuntimeException */ protected function applyHunk(&$lines, $src, $dst, $srcLine, $srcSize, $dstLine, $dstSize) { $srcLine--; $dstLine--; $line = current($lines); // Source lines (old file) $source = array(); // New lines (new file) $destin = array(); $src_left = $srcSize; $dst_left = $dstSize; do { if (!isset($line[0])) { $source[] = ''; $destin[] = ''; $src_left--; $dst_left--; } elseif ($line[0] == '-') { if ($src_left == 0) { throw new \RuntimeException(Text::sprintf('JLIB_FILESYSTEM_PATCHER_UNEXPECTED_REMOVE_LINE', key($lines))); } $source[] = substr($line, 1); $src_left--; } elseif ($line[0] == '+') { if ($dst_left == 0) { throw new \RuntimeException(Text::sprintf('JLIB_FILESYSTEM_PATCHER_UNEXPECTED_ADD_LINE', key($lines))); } $destin[] = substr($line, 1); $dst_left--; } elseif ($line != '\\ No newline at end of file') { $line = substr($line, 1); $source[] = $line; $destin[] = $line; $src_left--; $dst_left--; } if ($src_left == 0 && $dst_left == 0) { // Now apply the patch, finally! if ($srcSize > 0) { $src_lines = & $this->getSource($src); if (!isset($src_lines)) { throw new \RuntimeException( Text::sprintf( 'JLIB_FILESYSTEM_PATCHER_UNEXISING_SOURCE', Path::removeRoot($src) ) ); } } if ($dstSize > 0) { if ($srcSize > 0) { $dst_lines = & $this->getDestination($dst, $src); $src_bottom = $srcLine + count($source); for ($l = $srcLine;$l < $src_bottom;$l++) { if ($src_lines[$l] != $source[$l - $srcLine]) { throw new \RuntimeException( Text::sprintf( 'JLIB_FILESYSTEM_PATCHER_FAILED_VERIFY', Path::removeRoot($src), $l ) ); } } array_splice($dst_lines, $dstLine, count($source), $destin); } else { $this->destinations[$dst] = $destin; } } else { $this->removals[] = $src; } next($lines); return; } $line = next($lines); } while ($line !== false); throw new \RuntimeException('Unexpected EOF'); } /** * Get the lines of a source file * * @param string $src The path of a file * * @return array The lines of the source file * * @since 3.0.0 */ protected function &getSource($src) { if (!isset($this->sources[$src])) { $this->sources[$src] = null; if (is_readable($src)) { $this->sources[$src] = self::splitLines(file_get_contents($src)); } } return $this->sources[$src]; } /** * Get the lines of a destination file * * @param string $dst The path of a destination file * @param string $src The path of a source file * * @return array The lines of the destination file * * @since 3.0.0 */ protected function &getDestination($dst, $src) { if (!isset($this->destinations[$dst])) { $this->destinations[$dst] = $this->getSource($src); } return $this->destinations[$dst]; } } Path.php 0000644 00000021560 15117132553 0006160 0 ustar 00 <?php /** * Joomla! Content Management System * * @copyright (C) 2006 Open Source Matters, Inc. <https://www.joomla.org> * @license GNU General Public License version 2 or later; see LICENSE.txt */ namespace Joomla\CMS\Filesystem; defined('JPATH_PLATFORM') or die; use Joomla\CMS\Filesystem\Wrapper\PathWrapper; use Joomla\CMS\Filesystem\Wrapper\FileWrapper; use Joomla\CMS\Crypt\Crypt; if (!defined('JPATH_ROOT')) { // Define a string constant for the root directory of the file system in native format $pathHelper = new PathWrapper; define('JPATH_ROOT', $pathHelper->clean(JPATH_SITE)); } /** * A Path handling class * * @since 1.7.0 */ class Path { /** * Checks if a path's permissions can be changed. * * @param string $path Path to check. * * @return boolean True if path can have mode changed. * * @since 1.7.0 */ public static function canChmod($path) { $perms = fileperms($path); if ($perms !== false) { if (@chmod($path, $perms ^ 0001)) { @chmod($path, $perms); return true; } } return false; } /** * Chmods files and directories recursively to given permissions. * * @param string $path Root path to begin changing mode [without trailing slash]. * @param string $filemode Octal representation of the value to change file mode to [null = no change]. * @param string $foldermode Octal representation of the value to change folder mode to [null = no change]. * * @return boolean True if successful [one fail means the whole operation failed]. * * @since 1.7.0 */ public static function setPermissions($path, $filemode = '0644', $foldermode = '0755') { // Initialise return value $ret = true; if (is_dir($path)) { $dh = opendir($path); while ($file = readdir($dh)) { if ($file != '.' && $file != '..') { $fullpath = $path . '/' . $file; if (is_dir($fullpath)) { if (!self::setPermissions($fullpath, $filemode, $foldermode)) { $ret = false; } } else { if (isset($filemode)) { if (!@ chmod($fullpath, octdec($filemode))) { $ret = false; } } } } } closedir($dh); if (isset($foldermode)) { if (!@ chmod($path, octdec($foldermode))) { $ret = false; } } } else { if (isset($filemode)) { $ret = @ chmod($path, octdec($filemode)); } } return $ret; } /** * Get the permissions of the file/folder at a given path. * * @param string $path The path of a file/folder. * * @return string Filesystem permissions. * * @since 1.7.0 */ public static function getPermissions($path) { $path = self::clean($path); $mode = @ decoct(@ fileperms($path) & 0777); if (strlen($mode) < 3) { return '---------'; } $parsed_mode = ''; for ($i = 0; $i < 3; $i++) { // Read $parsed_mode .= ($mode[$i] & 04) ? 'r' : '-'; // Write $parsed_mode .= ($mode[$i] & 02) ? 'w' : '-'; // Execute $parsed_mode .= ($mode[$i] & 01) ? 'x' : '-'; } return $parsed_mode; } /** * Checks for snooping outside of the file system root. * * @param string $path A file system path to check. * * @return string A cleaned version of the path or exit on error. * * @since 1.7.0 * @throws Exception */ public static function check($path) { if (strpos($path, '..') !== false) { // Don't translate throw new \Exception( sprintf( '%s() - Use of relative paths not permitted', __METHOD__ ), 20 ); } $path = self::clean($path); if ((JPATH_ROOT != '') && strpos($path, self::clean(JPATH_ROOT)) !== 0) { throw new \Exception( sprintf( '%1$s() - Snooping out of bounds @ %2$s', __METHOD__, self::removeRoot($path) ), 20 ); } return $path; } /** * Function to strip additional / or \ in a path name. * * @param string $path The path to clean. * @param string $ds Directory separator (optional). * * @return string The cleaned path. * * @since 1.7.0 * @throws UnexpectedValueException */ public static function clean($path, $ds = DIRECTORY_SEPARATOR) { if (!is_string($path) && !empty($path)) { throw new \UnexpectedValueException( sprintf( '%s() - $path is not a string', __METHOD__ ), 20 ); } $path = trim($path); if (empty($path)) { $path = JPATH_ROOT; } // Remove double slashes and backslashes and convert all slashes and backslashes to DIRECTORY_SEPARATOR // If dealing with a UNC path don't forget to prepend the path with a backslash. elseif (($ds == '\\') && substr($path, 0, 2) == '\\\\') { $path = "\\" . preg_replace('#[/\\\\]+#', $ds, $path); } else { $path = preg_replace('#[/\\\\]+#', $ds, $path); } return $path; } /** * Method to determine if script owns the path. * * @param string $path Path to check ownership. * * @return boolean True if the php script owns the path passed. * * @since 1.7.0 */ public static function isOwner($path) { $tmp = md5(Crypt::genRandomBytes()); $ssp = ini_get('session.save_path'); $jtp = JPATH_SITE . '/tmp'; // Try to find a writable directory $dir = false; foreach (array($jtp, $ssp, '/tmp') as $currentDir) { if (is_writable($currentDir)) { $dir = $currentDir; break; } } if ($dir) { $fileObject = new FileWrapper; $test = $dir . '/' . $tmp; // Create the test file $blank = ''; $fileObject->write($test, $blank, false); // Test ownership $return = (fileowner($test) == fileowner($path)); // Delete the test file $fileObject->delete($test); return $return; } return false; } /** * Searches the directory paths for a given file. * * @param mixed $paths An path string or array of path strings to search in * @param string $file The file name to look for. * * @return mixed The full path and file name for the target file, or boolean false if the file is not found in any of the paths. * * @since 1.7.0 */ public static function find($paths, $file) { // Force to array if (!is_array($paths) && !($paths instanceof \Iterator)) { settype($paths, 'array'); } // Start looping through the path set foreach ($paths as $path) { // Get the path to the file $fullname = $path . '/' . $file; // Is the path based on a stream? if (strpos($path, '://') === false) { // Not a stream, so do a realpath() to avoid directory // traversal attempts on the local file system. // Needed for substr() later $path = realpath($path); $fullname = realpath($fullname); } /* * The substr() check added to make sure that the realpath() * results in a directory registered so that * non-registered directories are not accessible via directory * traversal attempts. */ if (file_exists($fullname) && substr($fullname, 0, strlen($path)) == $path) { return $fullname; } } // Could not find the file in the set of paths return false; } /** * Resolves /./, /../ and multiple / in a string and returns the resulting absolute path, inspired by Flysystem * Removes trailing slashes * * @param string $path A path to resolve * * @return string The resolved path * * @since 3.9.25 */ public static function resolve($path) { $path = static::clean($path); // Save start character for absolute path $startCharacter = ($path[0] === DIRECTORY_SEPARATOR) ? DIRECTORY_SEPARATOR : ''; $parts = array(); foreach (explode(DIRECTORY_SEPARATOR, $path) as $part) { switch ($part) { case '': case '.': break; case '..': if (empty($parts)) { throw new \Exception('Path is outside of the defined root'); } array_pop($parts); break; default: $parts[] = $part; break; } } return $startCharacter . implode(DIRECTORY_SEPARATOR, $parts); } /** * Remove all references to root directory path and the system tmp path from a message * * @param string $message The message to be cleaned * @param string $rootDirectory Optional root directory, defaults to JPATH_ROOT * * @return string * * @since 3.10.7 */ public static function removeRoot($message, $rootDirectory = null) { if (empty($rootDirectory)) { $rootDirectory = JPATH_ROOT; } $replacements = array( self::makePattern(static::clean($rootDirectory)) => '[ROOT]', self::makePattern(sys_get_temp_dir()) => '[TMP]', ); return preg_replace(array_keys($replacements), array_values($replacements), $message); } /** * Turn directory separators into match classes * * @param string $dir A directory name * * @return string * * @since 3.10.7 */ private static function makePattern($dir) { return '~' . str_replace('~', '\\~', preg_replace('~[/\\\\]+~', '[/\\\\\\\\]+', $dir)) . '~'; } } Stream.php 0000644 00000074475 15117132553 0006534 0 ustar 00 <?php /** * Joomla! Content Management System * * @copyright (C) 2008 Open Source Matters, Inc. <https://www.joomla.org> * @license GNU General Public License version 2 or later; see LICENSE.txt */ namespace Joomla\CMS\Filesystem; defined('JPATH_PLATFORM') or die; use Joomla\CMS\Object\CMSObject; use Joomla\CMS\Language\Text; /** * Joomla! Stream Interface * * The Joomla! stream interface is designed to handle files as streams * where as the legacy File static class treated files in a rather * atomic manner. * * @note This class adheres to the stream wrapper operations: * @link https://www.php.net/manual/en/function.stream-get-wrappers.php * @link https://www.php.net/manual/en/intro.stream.php PHP Stream Manual * @link https://www.php.net/manual/en/wrappers.php Stream Wrappers * @link https://www.php.net/manual/en/filters.php Stream Filters * @link https://www.php.net/manual/en/transports.php Socket Transports (used by some options, particularly HTTP proxy) * @since 1.7.0 */ class Stream extends CMSObject { /** * File Mode * * @var integer * @since 1.7.0 */ protected $filemode = 0644; /** * Directory Mode * * @var integer * @since 1.7.0 */ protected $dirmode = 0755; /** * Default Chunk Size * * @var integer * @since 1.7.0 */ protected $chunksize = 8192; /** * Filename * * @var string * @since 1.7.0 */ protected $filename; /** * Prefix of the connection for writing * * @var string * @since 1.7.0 */ protected $writeprefix; /** * Prefix of the connection for reading * * @var string * @since 1.7.0 */ protected $readprefix; /** * Read Processing method * @var string gz, bz, f * If a scheme is detected, fopen will be defaulted * To use compression with a network stream use a filter * @since 1.7.0 */ protected $processingmethod = 'f'; /** * Filters applied to the current stream * * @var array * @since 1.7.0 */ protected $filters = array(); /** * File Handle * * @var resource * @since 3.0.0 */ protected $fh; /** * File size * * @var integer * @since 3.0.0 */ protected $filesize; /** * Context to use when opening the connection * * @var resource * @since 3.0.0 */ protected $context = null; /** * Context options; used to rebuild the context * * @var array * @since 3.0.0 */ protected $contextOptions; /** * The mode under which the file was opened * * @var string * @since 3.0.0 */ protected $openmode; /** * Constructor * * @param string $writeprefix Prefix of the stream (optional). Unlike the JPATH_*, this has a final path separator! * @param string $readprefix The read prefix (optional). * @param array $context The context options (optional). * * @since 1.7.0 */ public function __construct($writeprefix = '', $readprefix = '', $context = array()) { $this->writeprefix = $writeprefix; $this->readprefix = $readprefix; $this->contextOptions = $context; $this->_buildContext(); } /** * Destructor * * @since 1.7.0 */ public function __destruct() { // Attempt to close on destruction if there is a file handle if ($this->fh) { @$this->close(); } } /** * Generic File Operations * * Open a stream with some lazy loading smarts * * @param string $filename Filename * @param string $mode Mode string to use * @param boolean $useIncludePath Use the PHP include path * @param resource $context Context to use when opening * @param boolean $usePrefix Use a prefix to open the file * @param boolean $relative Filename is a relative path (if false, strips JPATH_ROOT to make it relative) * @param boolean $detectProcessingMode Detect the processing method for the file and use the appropriate function * to handle output automatically * * @return boolean * * @since 1.7.0 */ public function open($filename, $mode = 'r', $useIncludePath = false, $context = null, $usePrefix = false, $relative = false, $detectProcessingMode = false) { $filename = $this->_getFilename($filename, $mode, $usePrefix, $relative); if (!$filename) { $this->setError(Text::_('JLIB_FILESYSTEM_ERROR_STREAMS_FILENAME')); return false; } $this->filename = $filename; $this->openmode = $mode; $url = parse_url($filename); $retval = false; if (isset($url['scheme'])) { // If we're dealing with a Joomla! stream, load it if (FilesystemHelper::isJoomlaStream($url['scheme'])) { require_once __DIR__ . '/streams/' . $url['scheme'] . '.php'; } // We have a scheme! force the method to be f $this->processingmethod = 'f'; } elseif ($detectProcessingMode) { $ext = strtolower(File::getExt($this->filename)); switch ($ext) { case 'tgz': case 'gz': case 'gzip': $this->processingmethod = 'gz'; break; case 'tbz2': case 'bz2': case 'bzip2': $this->processingmethod = 'bz'; break; default: $this->processingmethod = 'f'; break; } } // Capture PHP errors $php_errormsg = 'Error Unknown whilst opening a file'; $track_errors = ini_get('track_errors'); ini_set('track_errors', true); // Decide which context to use: switch ($this->processingmethod) { // Gzip doesn't support contexts or streams case 'gz': $this->fh = gzopen($filename, $mode, $useIncludePath); break; // Bzip2 is much like gzip except it doesn't use the include path case 'bz': $this->fh = bzopen($filename, $mode); break; // Fopen can handle streams case 'f': default: // One supplied at open; overrides everything if ($context) { $this->fh = fopen($filename, $mode, $useIncludePath, $context); } // One provided at initialisation elseif ($this->context) { $this->fh = fopen($filename, $mode, $useIncludePath, $this->context); } // No context; all defaults else { $this->fh = fopen($filename, $mode, $useIncludePath); } break; } if (!$this->fh) { $this->setError($php_errormsg); } else { $retval = true; } // Restore error tracking to what it was before ini_set('track_errors', $track_errors); // Return the result return $retval; } /** * Attempt to close a file handle * * Will return false if it failed and true on success * If the file is not open the system will return true, this function destroys the file handle as well * * @return boolean * * @since 1.7.0 */ public function close() { if (!$this->fh) { $this->setError(Text::_('JLIB_FILESYSTEM_ERROR_STREAMS_FILE_NOT_OPEN')); return true; } $retval = false; // Capture PHP errors $php_errormsg = 'Error Unknown'; $track_errors = ini_get('track_errors'); ini_set('track_errors', true); switch ($this->processingmethod) { case 'gz': $res = gzclose($this->fh); break; case 'bz': $res = bzclose($this->fh); break; case 'f': default: $res = fclose($this->fh); break; } if (!$res) { $this->setError($php_errormsg); } else { // Reset this $this->fh = null; $retval = true; } // If we wrote, chmod the file after it's closed if ($this->openmode[0] == 'w') { $this->chmod(); } // Restore error tracking to what it was before ini_set('track_errors', $track_errors); // Return the result return $retval; } /** * Work out if we're at the end of the file for a stream * * @return boolean * * @since 1.7.0 */ public function eof() { if (!$this->fh) { $this->setError(Text::_('JLIB_FILESYSTEM_ERROR_STREAMS_FILE_NOT_OPEN')); return false; } // Capture PHP errors $php_errormsg = ''; $track_errors = ini_get('track_errors'); ini_set('track_errors', true); switch ($this->processingmethod) { case 'gz': $res = gzeof($this->fh); break; case 'bz': case 'f': default: $res = feof($this->fh); break; } if ($php_errormsg) { $this->setError($php_errormsg); } // Restore error tracking to what it was before ini_set('track_errors', $track_errors); // Return the result return $res; } /** * Retrieve the file size of the path * * @return mixed * * @since 1.7.0 */ public function filesize() { if (!$this->filename) { $this->setError(Text::_('JLIB_FILESYSTEM_ERROR_STREAMS_FILE_NOT_OPEN')); return false; } $retval = false; // Capture PHP errors $php_errormsg = ''; $track_errors = ini_get('track_errors'); ini_set('track_errors', true); $res = @filesize($this->filename); if (!$res) { $tmp_error = ''; if ($php_errormsg) { // Something went wrong. // Store the error in case we need it. $tmp_error = $php_errormsg; } $res = FilesystemHelper::remotefsize($this->filename); if (!$res) { if ($tmp_error) { // Use the php_errormsg from before $this->setError($tmp_error); } else { // Error but nothing from php? How strange! Create our own $this->setError(Text::_('JLIB_FILESYSTEM_ERROR_STREAMS_FILE_SIZE')); } } else { $this->filesize = $res; $retval = $res; } } else { $this->filesize = $res; $retval = $res; } // Restore error tracking to what it was before. ini_set('track_errors', $track_errors); // Return the result return $retval; } /** * Get a line from the stream source. * * @param integer $length The number of bytes (optional) to read. * * @return mixed * * @since 1.7.0 */ public function gets($length = 0) { if (!$this->fh) { $this->setError(Text::_('JLIB_FILESYSTEM_ERROR_STREAMS_FILE_NOT_OPEN')); return false; } $retval = false; // Capture PHP errors $php_errormsg = 'Error Unknown'; $track_errors = ini_get('track_errors'); ini_set('track_errors', true); switch ($this->processingmethod) { case 'gz': $res = $length ? gzgets($this->fh, $length) : gzgets($this->fh); break; case 'bz': case 'f': default: $res = $length ? fgets($this->fh, $length) : fgets($this->fh); break; } if (!$res) { $this->setError($php_errormsg); } else { $retval = $res; } // Restore error tracking to what it was before ini_set('track_errors', $track_errors); // Return the result return $retval; } /** * Read a file * * Handles user space streams appropriately otherwise any read will return 8192 * * @param integer $length Length of data to read * * @return mixed * * @link https://www.php.net/manual/en/function.fread.php * @since 1.7.0 */ public function read($length = 0) { if (!$this->filesize && !$length) { // Get the filesize $this->filesize(); if (!$this->filesize) { // Set it to the biggest and then wait until eof $length = -1; } else { $length = $this->filesize; } } if (!$this->fh) { $this->setError(Text::_('JLIB_FILESYSTEM_ERROR_STREAMS_FILE_NOT_OPEN')); return false; } $retval = false; // Capture PHP errors $php_errormsg = 'Error Unknown'; $track_errors = ini_get('track_errors'); ini_set('track_errors', true); $remaining = $length; do { // Do chunked reads where relevant switch ($this->processingmethod) { case 'bz': $res = ($remaining > 0) ? bzread($this->fh, $remaining) : bzread($this->fh, $this->chunksize); break; case 'gz': $res = ($remaining > 0) ? gzread($this->fh, $remaining) : gzread($this->fh, $this->chunksize); break; case 'f': default: $res = ($remaining > 0) ? fread($this->fh, $remaining) : fread($this->fh, $this->chunksize); break; } if (!$res) { $this->setError($php_errormsg); // Jump from the loop $remaining = 0; } else { if (!$retval) { $retval = ''; } $retval .= $res; if (!$this->eof()) { $len = strlen($res); $remaining -= $len; } else { // If it's the end of the file then we've nothing left to read; reset remaining and len $remaining = 0; $length = strlen($retval); } } } while ($remaining || !$length); // Restore error tracking to what it was before ini_set('track_errors', $track_errors); // Return the result return $retval; } /** * Seek the file * * Note: the return value is different to that of fseek * * @param integer $offset Offset to use when seeking. * @param integer $whence Seek mode to use. * * @return boolean True on success, false on failure * * @link https://www.php.net/manual/en/function.fseek.php * @since 1.7.0 */ public function seek($offset, $whence = SEEK_SET) { if (!$this->fh) { $this->setError(Text::_('JLIB_FILESYSTEM_ERROR_STREAMS_FILE_NOT_OPEN')); return false; } $retval = false; // Capture PHP errors $php_errormsg = ''; $track_errors = ini_get('track_errors'); ini_set('track_errors', true); switch ($this->processingmethod) { case 'gz': $res = gzseek($this->fh, $offset, $whence); break; case 'bz': case 'f': default: $res = fseek($this->fh, $offset, $whence); break; } // Seek, interestingly, returns 0 on success or -1 on failure. if ($res == -1) { $this->setError($php_errormsg); } else { $retval = true; } // Restore error tracking to what it was before ini_set('track_errors', $track_errors); // Return the result return $retval; } /** * Returns the current position of the file read/write pointer. * * @return mixed * * @since 1.7.0 */ public function tell() { if (!$this->fh) { $this->setError(Text::_('JLIB_FILESYSTEM_ERROR_STREAMS_FILE_NOT_OPEN')); return false; } // Capture PHP errors $php_errormsg = ''; $track_errors = ini_get('track_errors'); ini_set('track_errors', true); switch ($this->processingmethod) { case 'gz': $res = gztell($this->fh); break; case 'bz': case 'f': default: $res = ftell($this->fh); break; } // May return 0 so check if it's really false if ($res === false) { $this->setError($php_errormsg); } // Restore error tracking to what it was before ini_set('track_errors', $track_errors); // Return the result return $res; } /** * File write * * Whilst this function accepts a reference, the underlying fwrite * will do a copy! This will roughly double the memory allocation for * any write you do. Specifying chunked will get around this by only * writing in specific chunk sizes. This defaults to 8192 which is a * sane number to use most of the time (change the default with * JStream::set('chunksize', newsize);) * Note: This doesn't support gzip/bzip2 writing like reading does * * @param string &$string Reference to the string to write. * @param integer $length Length of the string to write. * @param integer $chunk Size of chunks to write in. * * @return boolean * * @link https://www.php.net/manual/en/function.fwrite.php * @since 1.7.0 */ public function write(&$string, $length = 0, $chunk = 0) { if (!$this->fh) { $this->setError(Text::_('JLIB_FILESYSTEM_ERROR_STREAMS_FILE_NOT_OPEN')); return false; } // If the length isn't set, set it to the length of the string. if (!$length) { $length = strlen($string); } // If the chunk isn't set, set it to the default. if (!$chunk) { $chunk = $this->chunksize; } $retval = true; // Capture PHP errors $php_errormsg = ''; $track_errors = ini_get('track_errors'); ini_set('track_errors', true); $remaining = $length; $start = 0; do { // If the amount remaining is greater than the chunk size, then use the chunk $amount = ($remaining > $chunk) ? $chunk : $remaining; $res = fwrite($this->fh, substr($string, $start), $amount); // Returns false on error or the number of bytes written if ($res === false) { // Returned error $this->setError($php_errormsg); $retval = false; $remaining = 0; } elseif ($res === 0) { // Wrote nothing? $remaining = 0; $this->setError(Text::_('JLIB_FILESYSTEM_ERROR_NO_DATA_WRITTEN')); } else { // Wrote something $start += $amount; $remaining -= $res; } } while ($remaining); // Restore error tracking to what it was before. ini_set('track_errors', $track_errors); // Return the result return $retval; } /** * Chmod wrapper * * @param string $filename File name. * @param mixed $mode Mode to use. * * @return boolean * * @since 1.7.0 */ public function chmod($filename = '', $mode = 0) { if (!$filename) { if (!isset($this->filename) || !$this->filename) { $this->setError(Text::_('JLIB_FILESYSTEM_ERROR_STREAMS_FILENAME')); return false; } $filename = $this->filename; } // If no mode is set use the default if (!$mode) { $mode = $this->filemode; } $retval = false; // Capture PHP errors $php_errormsg = ''; $track_errors = ini_get('track_errors'); ini_set('track_errors', true); $sch = parse_url($filename, PHP_URL_SCHEME); // Scheme specific options; ftp's chmod support is fun. switch ($sch) { case 'ftp': case 'ftps': $res = FilesystemHelper::ftpChmod($filename, $mode); break; default: $res = chmod($filename, $mode); break; } // Seek, interestingly, returns 0 on success or -1 on failure if (!$res) { $this->setError($php_errormsg); } else { $retval = true; } // Restore error tracking to what it was before. ini_set('track_errors', $track_errors); // Return the result return $retval; } /** * Get the stream metadata * * @return array header/metadata * * @link https://www.php.net/manual/en/function.stream-get-meta-data.php * @since 1.7.0 */ public function get_meta_data() { if (!$this->fh) { $this->setError(Text::_('JLIB_FILESYSTEM_ERROR_STREAMS_FILE_NOT_OPEN')); return false; } return stream_get_meta_data($this->fh); } /** * Stream contexts * Builds the context from the array * * @return mixed * * @since 1.7.0 */ public function _buildContext() { // According to the manual this always works! if (count($this->contextOptions)) { $this->context = @stream_context_create($this->contextOptions); } else { $this->context = null; } } /** * Updates the context to the array * * Format is the same as the options for stream_context_create * * @param array $context Options to create the context with * * @return void * * @link https://www.php.net/stream_context_create * @since 1.7.0 */ public function setContextOptions($context) { $this->contextOptions = $context; $this->_buildContext(); } /** * Adds a particular options to the context * * @param string $wrapper The wrapper to use * @param string $name The option to set * @param string $value The value of the option * * @return void * * @link https://www.php.net/stream_context_create Stream Context Creation * @link https://www.php.net/manual/en/context.php Context Options for various streams * @since 1.7.0 */ public function addContextEntry($wrapper, $name, $value) { $this->contextOptions[$wrapper][$name] = $value; $this->_buildContext(); } /** * Deletes a particular setting from a context * * @param string $wrapper The wrapper to use * @param string $name The option to unset * * @return void * * @link https://www.php.net/stream_context_create * @since 1.7.0 */ public function deleteContextEntry($wrapper, $name) { // Check whether the wrapper is set if (isset($this->contextOptions[$wrapper])) { // Check that entry is set for that wrapper if (isset($this->contextOptions[$wrapper][$name])) { // Unset the item unset($this->contextOptions[$wrapper][$name]); // Check that there are still items there if (!count($this->contextOptions[$wrapper])) { // Clean up an empty wrapper context option unset($this->contextOptions[$wrapper]); } } } // Rebuild the context and apply it to the stream $this->_buildContext(); } /** * Applies the current context to the stream * * Use this to change the values of the context after you've opened a stream * * @return mixed * * @since 1.7.0 */ public function applyContextToStream() { $retval = false; if ($this->fh) { // Capture PHP errors $php_errormsg = 'Unknown error setting context option'; $track_errors = ini_get('track_errors'); ini_set('track_errors', true); $retval = @stream_context_set_option($this->fh, $this->contextOptions); if (!$retval) { $this->setError($php_errormsg); } // Restore error tracking to what it was before ini_set('track_errors', $track_errors); } return $retval; } /** * Stream filters * Append a filter to the chain * * @param string $filterName The key name of the filter. * @param integer $readWrite Optional. Defaults to STREAM_FILTER_READ. * @param array $params An array of params for the stream_filter_append call. * * @return mixed * * @link https://www.php.net/manual/en/function.stream-filter-append.php * @since 1.7.0 */ public function appendFilter($filterName, $readWrite = STREAM_FILTER_READ, $params = array()) { $res = false; if ($this->fh) { // Capture PHP errors $php_errormsg = ''; $track_errors = ini_get('track_errors'); ini_set('track_errors', true); $res = @stream_filter_append($this->fh, $filterName, $readWrite, $params); if (!$res && $php_errormsg) { $this->setError($php_errormsg); } else { $this->filters[] = &$res; } // Restore error tracking to what it was before. ini_set('track_errors', $track_errors); } return $res; } /** * Prepend a filter to the chain * * @param string $filterName The key name of the filter. * @param integer $readWrite Optional. Defaults to STREAM_FILTER_READ. * @param array $params An array of params for the stream_filter_prepend call. * * @return mixed * * @link https://www.php.net/manual/en/function.stream-filter-prepend.php * @since 1.7.0 */ public function prependFilter($filterName, $readWrite = STREAM_FILTER_READ, $params = array()) { $res = false; if ($this->fh) { // Capture PHP errors $php_errormsg = ''; $track_errors = ini_get('track_errors'); ini_set('track_errors', true); $res = @stream_filter_prepend($this->fh, $filterName, $readWrite, $params); if (!$res && $php_errormsg) { // Set the error msg $this->setError($php_errormsg); } else { array_unshift($res, ''); $res[0] = &$this->filters; } // Restore error tracking to what it was before. ini_set('track_errors', $track_errors); } return $res; } /** * Remove a filter, either by resource (handed out from the append or prepend function) * or via getting the filter list) * * @param resource &$resource The resource. * @param boolean $byindex The index of the filter. * * @return boolean Result of operation * * @since 1.7.0 */ public function removeFilter(&$resource, $byindex = false) { // Capture PHP errors $php_errormsg = ''; $track_errors = ini_get('track_errors'); ini_set('track_errors', true); if ($byindex) { $res = stream_filter_remove($this->filters[$resource]); } else { $res = stream_filter_remove($resource); } if ($res && $php_errormsg) { $this->setError($php_errormsg); } // Restore error tracking to what it was before. ini_set('track_errors', $track_errors); return $res; } /** * Copy a file from src to dest * * @param string $src The file path to copy from. * @param string $dest The file path to copy to. * @param resource $context A valid context resource (optional) created with stream_context_create. * @param boolean $usePrefix Controls the use of a prefix (optional). * @param boolean $relative Determines if the filename given is relative. Relative paths do not have JPATH_ROOT stripped. * * @return mixed * * @since 1.7.0 */ public function copy($src, $dest, $context = null, $usePrefix = true, $relative = false) { // Capture PHP errors $php_errormsg = ''; $track_errors = ini_get('track_errors'); ini_set('track_errors', true); $chmodDest = $this->_getFilename($dest, 'w', $usePrefix, $relative); // Since we're going to open the file directly we need to get the filename. // We need to use the same prefix so force everything to write. $src = $this->_getFilename($src, 'w', $usePrefix, $relative); $dest = $this->_getFilename($dest, 'w', $usePrefix, $relative); if ($context) { // Use the provided context $res = @copy($src, $dest, $context); } elseif ($this->context) { // Use the objects context $res = @copy($src, $dest, $this->context); } else { // Don't use any context $res = @copy($src, $dest); } if (!$res && $php_errormsg) { $this->setError($php_errormsg); } else { $this->chmod($chmodDest); } // Restore error tracking to what it was before ini_set('track_errors', $track_errors); return $res; } /** * Moves a file * * @param string $src The file path to move from. * @param string $dest The file path to move to. * @param resource $context A valid context resource (optional) created with stream_context_create. * @param boolean $usePrefix Controls the use of a prefix (optional). * @param boolean $relative Determines if the filename given is relative. Relative paths do not have JPATH_ROOT stripped. * * @return mixed * * @since 1.7.0 */ public function move($src, $dest, $context = null, $usePrefix = true, $relative = false) { // Capture PHP errors $php_errormsg = ''; $track_errors = ini_get('track_errors'); ini_set('track_errors', true); $src = $this->_getFilename($src, 'w', $usePrefix, $relative); $dest = $this->_getFilename($dest, 'w', $usePrefix, $relative); if ($context) { // Use the provided context $res = @rename($src, $dest, $context); } elseif ($this->context) { // Use the object's context $res = @rename($src, $dest, $this->context); } else { // Don't use any context $res = @rename($src, $dest); } if (!$res && $php_errormsg) { $this->setError($php_errormsg()); } $this->chmod($dest); // Restore error tracking to what it was before ini_set('track_errors', $track_errors); return $res; } /** * Delete a file * * @param string $filename The file path to delete. * @param resource $context A valid context resource (optional) created with stream_context_create. * @param boolean $usePrefix Controls the use of a prefix (optional). * @param boolean $relative Determines if the filename given is relative. Relative paths do not have JPATH_ROOT stripped. * * @return mixed * * @since 1.7.0 */ public function delete($filename, $context = null, $usePrefix = true, $relative = false) { // Capture PHP errors $php_errormsg = ''; $track_errors = ini_get('track_errors'); ini_set('track_errors', true); $filename = $this->_getFilename($filename, 'w', $usePrefix, $relative); if ($context) { // Use the provided context $res = @unlink($filename, $context); } elseif ($this->context) { // Use the object's context $res = @unlink($filename, $this->context); } else { // Don't use any context $res = @unlink($filename); } if (!$res && $php_errormsg) { $this->setError($php_errormsg()); } // Restore error tracking to what it was before. ini_set('track_errors', $track_errors); return $res; } /** * Upload a file * * @param string $src The file path to copy from (usually a temp folder). * @param string $dest The file path to copy to. * @param resource $context A valid context resource (optional) created with stream_context_create. * @param boolean $usePrefix Controls the use of a prefix (optional). * @param boolean $relative Determines if the filename given is relative. Relative paths do not have JPATH_ROOT stripped. * * @return mixed * * @since 1.7.0 */ public function upload($src, $dest, $context = null, $usePrefix = true, $relative = false) { if (is_uploaded_file($src)) { // Make sure it's an uploaded file return $this->copy($src, $dest, $context, $usePrefix, $relative); } else { $this->setError(Text::_('JLIB_FILESYSTEM_ERROR_STREAMS_NOT_UPLOADED_FILE')); return false; } } /** * Writes a chunk of data to a file. * * @param string $filename The file name. * @param string &$buffer The data to write to the file. * * @return boolean * * @since 1.7.0 */ public function writeFile($filename, &$buffer) { if ($this->open($filename, 'w')) { $result = $this->write($buffer); $this->chmod(); $this->close(); return $result; } return false; } /** * Determine the appropriate 'filename' of a file * * @param string $filename Original filename of the file * @param string $mode Mode string to retrieve the filename * @param boolean $usePrefix Controls the use of a prefix * @param boolean $relative Determines if the filename given is relative. Relative paths do not have JPATH_ROOT stripped. * * @return string * * @since 1.7.0 */ public function _getFilename($filename, $mode, $usePrefix, $relative) { if ($usePrefix) { // Get rid of binary or t, should be at the end of the string $tmode = trim($mode, 'btf123456789'); // Check if it's a write mode then add the appropriate prefix // Get rid of JPATH_ROOT (legacy compat) along the way if (in_array($tmode, FilesystemHelper::getWriteModes())) { if (!$relative && $this->writeprefix) { $filename = str_replace(JPATH_ROOT, '', $filename); } $filename = $this->writeprefix . $filename; } else { if (!$relative && $this->readprefix) { $filename = str_replace(JPATH_ROOT, '', $filename); } $filename = $this->readprefix . $filename; } } return $filename; } /** * Return the internal file handle * * @return resource File handler * * @since 1.7.0 */ public function getFileHandle() { return $this->fh; } } Streams/StreamString.php 0000644 00000012302 15117132553 0011316 0 ustar 00 <?php /** * Joomla! Content Management System * * @copyright (C) 2008 Open Source Matters, Inc. <https://www.joomla.org> * @license GNU General Public License version 2 or later; see LICENSE.txt */ namespace Joomla\CMS\Filesystem\Streams; defined('JPATH_PLATFORM') or die; use Joomla\CMS\Filesystem\Support\StringController; /** * String Stream Wrapper * * This class allows you to use a PHP string in the same way that * you would normally use a regular stream wrapper * * @since 1.7.0 */ class StreamString { /** * The current string * * @var string * @since 3.0.0 */ protected $currentString; /** * The path * * @var string * @since 3.0.0 */ protected $path; /** * The mode * * @var string * @since 3.0.0 */ protected $mode; /** * Enter description here ... * * @var string * @since 3.0.0 */ protected $options; /** * Enter description here ... * * @var string * @since 3.0.0 */ protected $openedPath; /** * Current position * * @var integer * @since 3.0.0 */ protected $pos; /** * Length of the string * * @var string * @since 3.0.0 */ protected $len; /** * Statistics for a file * * @var array * @since 3.0.0 * * @link http://us.php.net/manual/en/function.stat.php */ protected $stat; /** * Method to open a file or URL. * * @param string $path The stream path. * @param string $mode Not used. * @param integer $options Not used. * @param string &$openedPath Not used. * * @return boolean * * @since 1.7.0 */ public function stream_open($path, $mode, $options, &$openedPath) { $this->currentString = &StringController::getRef(str_replace('string://', '', $path)); if ($this->currentString) { $this->len = strlen($this->currentString); $this->pos = 0; $this->stat = $this->url_stat($path, 0); return true; } else { return false; } } /** * Method to retrieve information from a file resource * * @return array * * @link https://www.php.net/manual/en/streamwrapper.stream-stat.php * @since 1.7.0 */ public function stream_stat() { return $this->stat; } /** * Method to retrieve information about a file. * * @param string $path File path or URL to stat * @param integer $flags Additional flags set by the streams API * * @return array * * @link https://www.php.net/manual/en/streamwrapper.url-stat.php * @since 1.7.0 */ public function url_stat($path, $flags = 0) { $now = time(); $string = &StringController::getRef(str_replace('string://', '', $path)); $stat = array( 'dev' => 0, 'ino' => 0, 'mode' => 0, 'nlink' => 1, 'uid' => 0, 'gid' => 0, 'rdev' => 0, 'size' => strlen($string), 'atime' => $now, 'mtime' => $now, 'ctime' => $now, 'blksize' => '512', 'blocks' => ceil(strlen($string) / 512), ); return $stat; } /** * Method to read a given number of bytes starting at the current position * and moving to the end of the string defined by the current position plus the * given number. * * @param integer $count Bytes of data from the current position should be returned. * * @return void * * @since 1.7.0 * * @link https://www.php.net/manual/en/streamwrapper.stream-read.php */ public function stream_read($count) { $result = substr($this->currentString, $this->pos, $count); $this->pos += $count; return $result; } /** * Stream write, always returning false. * * @param string $data The data to write. * * @return boolean * * @since 1.7.0 * @note Updating the string is not supported. */ public function stream_write($data) { // We don't support updating the string. return false; } /** * Method to get the current position * * @return integer The position * * @since 1.7.0 */ public function stream_tell() { return $this->pos; } /** * End of field check * * @return boolean True if at end of field. * * @since 1.7.0 */ public function stream_eof() { if ($this->pos > $this->len) { return true; } return false; } /** * Stream offset * * @param integer $offset The starting offset. * @param integer $whence SEEK_SET, SEEK_CUR, SEEK_END * * @return boolean True on success. * * @since 1.7.0 */ public function stream_seek($offset, $whence) { // $whence: SEEK_SET, SEEK_CUR, SEEK_END if ($offset > $this->len) { // We can't seek beyond our len. return false; } switch ($whence) { case SEEK_SET: $this->pos = $offset; break; case SEEK_CUR: if (($this->pos + $offset) < $this->len) { $this->pos += $offset; } else { return false; } break; case SEEK_END: $this->pos = $this->len - $offset; break; } return true; } /** * Stream flush, always returns true. * * @return boolean * * @since 1.7.0 * @note Data storage is not supported */ public function stream_flush() { // We don't store data. return true; } } stream_wrapper_register('string', '\\Joomla\\CMS\\Filesystem\\Streams\\StreamString') or die('StreamString Wrapper Registration Failed'); Support/StringController.php 0000644 00000002223 15117132553 0012245 0 ustar 00 <?php /** * Joomla! Content Management System * * @copyright (C) 2008 Open Source Matters, Inc. <https://www.joomla.org> * @license GNU General Public License version 2 or later; see LICENSE.txt */ namespace Joomla\CMS\Filesystem\Support; defined('JPATH_PLATFORM') or die; /** * String Controller * * @since 1.7.0 */ class StringController { /** * Defines a variable as an array * * @return array * * @since 1.7.0 */ public function _getArray() { static $strings = array(); return $strings; } /** * Create a reference * * @param string $reference The key * @param string &$string The value * * @return void * * @since 1.7.0 */ public function createRef($reference, &$string) { $ref = &self::_getArray(); $ref[$reference] = & $string; } /** * Get reference * * @param string $reference The key for the reference. * * @return mixed False if not set, reference if it exists * * @since 1.7.0 */ public function getRef($reference) { $ref = &self::_getArray(); if (isset($ref[$reference])) { return $ref[$reference]; } else { return false; } } } Wrapper/FileWrapper.php 0000644 00000012467 15117132554 0011133 0 ustar 00 <?php /** * Joomla! Content Management System * * @copyright (C) 2014 Open Source Matters, Inc. <https://www.joomla.org> * @license GNU General Public License version 2 or later; see LICENSE.txt */ namespace Joomla\CMS\Filesystem\Wrapper; use Joomla\Filesystem\File; defined('JPATH_PLATFORM') or die; /** * Wrapper class for File * * @since 3.4 * @deprecated 4.0 Use \Joomla\CMS\Filesystem\File instead */ class FileWrapper { /** * Helper wrapper method for getExt * * @param string $file The file name. * * @return string The file extension. * * @see File::getExt() * @since 3.4 * @deprecated 4.0 Use \Joomla\CMS\Filesystem\File instead */ public function getExt($file) { return File::getExt($file); } /** * Helper wrapper method for stripExt * * @param string $file The file name. * * @return string The file name without the extension. * * @see File::stripExt() * @since 3.4 * @deprecated 4.0 Use \Joomla\CMS\Filesystem\File instead */ public function stripExt($file) { return File::stripExt($file); } /** * Helper wrapper method for makeSafe * * @param string $file The name of the file [not full path]. * * @return string The sanitised string. * * @see File::makeSafe() * @since 3.4 * @deprecated 4.0 Use \Joomla\CMS\Filesystem\File instead */ public function makeSafe($file) { return File::makeSafe($file); } /** * Helper wrapper method for copy * * @param string $src The path to the source file. * @param string $dest The path to the destination file. * @param string $path An optional base path to prefix to the file names. * @param boolean $useStreams True to use streams. * * @return boolean True on success. * * @see File::copy() * @since 3.4 * @deprecated 4.0 Use \Joomla\CMS\Filesystem\File instead */ public function copy($src, $dest, $path = null, $useStreams = false) { return File::copy($src, $dest, $path, $useStreams); } /** * Helper wrapper method for delete * * @param mixed $file The file name or an array of file names * * @return boolean True on success. * * @see File::delete() * @since 3.4 * @deprecated 4.0 Use \Joomla\CMS\Filesystem\File instead */ public function delete($file) { return File::delete($file); } /** * Helper wrapper method for move * * @param string $src The path to the source file. * @param string $dest The path to the destination file. * @param string $path An optional base path to prefix to the file names. * @param boolean $useStreams True to use streams. * * @return boolean True on success. * * @see File::move() * @since 3.4 * @deprecated 4.0 Use \Joomla\CMS\Filesystem\File instead */ public function move($src, $dest, $path = '', $useStreams = false) { return File::move($src, $dest, $path, $useStreams); } /** * Helper wrapper method for read * * @param string $filename The full file path. * @param boolean $incpath Use include path. * @param integer $amount Amount of file to read. * @param integer $chunksize Size of chunks to read. * @param integer $offset Offset of the file. * * @return mixed Returns file contents or boolean False if failed. * * @see File::read() * @since 3.4 * @deprecated 4.0 Use \Joomla\CMS\Filesystem\File instead */ public function read($filename, $incpath = false, $amount = 0, $chunksize = 8192, $offset = 0) { return File::read($filename, $incpath, $amount, $chunksize, $offset); } /** * Helper wrapper method for write * * @param string $file The full file path. * @param string &$buffer The buffer to write. * @param boolean $useStreams Use streams. * * @return boolean True on success. * * @see File::write() * @since 3.4 * @deprecated 4.0 Use \Joomla\CMS\Filesystem\File instead */ public function write($file, &$buffer, $useStreams = false) { return File::write($file, $buffer, $useStreams); } /** * Helper wrapper method for upload * * @param string $src The name of the php (temporary) uploaded file. * @param string $dest The path (including filename) to move the uploaded file to. * @param boolean $useStreams True to use streams. * * @return boolean True on success. * * @see File::upload() * @since 3.4 * @deprecated 4.0 Use \Joomla\CMS\Filesystem\File instead */ public function upload($src, $dest, $useStreams = false) { return File::upload($src, $dest, $useStreams); } /** * Helper wrapper method for exists * * @param string $file File path. * * @return boolean True if path is a file. * * @see File::exists() * @since 3.4 * @deprecated 4.0 Use \Joomla\CMS\Filesystem\File instead */ public function exists($file) { return File::exists($file); } /** * Helper wrapper method for getName * * @param string $file File path. * * @return string filename. * * @see File::getName() * @since 3.4 * @deprecated 4.0 Use \Joomla\CMS\Filesystem\File instead */ public function getName($file) { return File::getName($file); } } Wrapper/FolderWrapper.php 0000644 00000014421 15117132554 0011457 0 ustar 00 <?php /** * Joomla! Content Management System * * @copyright (C) 2014 Open Source Matters, Inc. <https://www.joomla.org> * @license GNU General Public License version 2 or later; see LICENSE.txt */ namespace Joomla\CMS\Filesystem\Wrapper; use Joomla\CMS\Filesystem\Folder; defined('JPATH_PLATFORM') or die; /** * Wrapper class for Folder * * @since 3.4 * @deprecated 4.0 Use \Joomla\CMS\Filesystem\Folder instead */ class FolderWrapper { /** * Helper wrapper method for copy * * @param string $src The path to the source folder. * @param string $dest The path to the destination folder. * @param string $path An optional base path to prefix to the file names. * @param boolean $force Force copy. * @param boolean $useStreams Optionally force folder/file overwrites. * * @return boolean True on success. * * @see Folder::copy() * @since 3.4 * @throws RuntimeException * @deprecated 4.0 Use \Joomla\CMS\Filesystem\Folder instead */ public function copy($src, $dest, $path = '', $force = false, $useStreams = false) { return Folder::copy($src, $dest, $path, $force, $useStreams); } /** * Helper wrapper method for create * * @param string $path A path to create from the base path. * @param integer $mode Directory permissions to set for folders created. 0755 by default. * * @return boolean True if successful. * * @see Folder::create() * @since 3.4 * @deprecated 4.0 Use \Joomla\CMS\Filesystem\Folder instead */ public function create($path = '', $mode = 493) { return Folder::create($path, $mode); } /** * Helper wrapper method for delete * * @param string $path The path to the folder to delete. * * @return boolean True on success. * * @see Folder::delete() * @since 3.4 * @throws UnexpectedValueException * @deprecated 4.0 Use \Joomla\CMS\Filesystem\Folder instead */ public function delete($path) { return Folder::delete($path); } /** * Helper wrapper method for move * * @param string $src The path to the source folder. * @param string $dest The path to the destination folder. * @param string $path An optional base path to prefix to the file names. * @param boolean $useStreams Optionally use streams. * * @return mixed Error message on false or boolean true on success. * * @see Folder::move() * @since 3.4 * @deprecated 4.0 Use \Joomla\CMS\Filesystem\Folder instead */ public function move($src, $dest, $path = '', $useStreams = false) { return Folder::move($src, $dest, $path, $useStreams); } /** * Helper wrapper method for exists * * @param string $path Folder name relative to installation dir. * * @return boolean True if path is a folder. * * @see Folder::exists() * @since 3.4 * @deprecated 4.0 Use \Joomla\CMS\Filesystem\Folder instead */ public function exists($path) { return Folder::exists($path); } /** * Helper wrapper method for files * * @param string $path The path of the folder to read. * @param string $filter A filter for file names. * @param mixed $recurse True to recursively search into sub-folders, or an integer to specify the maximum depth. * @param boolean $full True to return the full path to the file. * @param array $exclude Array with names of files which should not be shown in the result. * @param array $excludefilter Array of filter to exclude. * @param boolean $naturalSort False for asort, true for natsort. * * @return array Files in the given folder. * * @see Folder::files() * @since 3.4 * @deprecated 4.0 Use \Joomla\CMS\Filesystem\Folder instead */ public function files($path, $filter = '.', $recurse = false, $full = false, $exclude = array('.svn', 'CVS', '.DS_Store', '__MACOSX'), $excludefilter = array('^\..*', '.*~'), $naturalSort = false) { return Folder::files($path, $filter, $recurse, $full, $exclude, $excludefilter, $naturalSort); } /** * Helper wrapper method for folders * * @param string $path The path of the folder to read. * @param string $filter A filter for folder names. * @param mixed $recurse True to recursively search into sub-folders, or an integer to specify the maximum depth. * @param boolean $full True to return the full path to the folders. * @param array $exclude Array with names of folders which should not be shown in the result. * @param array $excludefilter Array with regular expressions matching folders which should not be shown in the result. * * @return array Folders in the given folder. * * @see Folder::folders() * @since 3.4 * @deprecated 4.0 Use \Joomla\CMS\Filesystem\Folder instead */ public function folders($path, $filter = '.', $recurse = false, $full = false, $exclude = array('.svn', 'CVS', '.DS_Store', '__MACOSX'), $excludefilter = array('^\..*')) { return Folder::folders($path, $filter, $recurse, $full, $exclude, $excludefilter); } /** * Helper wrapper method for listFolderTree * * @param string $path The path of the folder to read. * @param string $filter A filter for folder names. * @param integer $maxLevel The maximum number of levels to recursively read, defaults to three. * @param integer $level The current level, optional. * @param integer $parent Unique identifier of the parent folder, if any. * * @return array Folders in the given folder. * * @see Folder::listFolderTree() * @since 3.4 * @deprecated 4.0 Use \Joomla\CMS\Filesystem\Folder instead */ public function listFolderTree($path, $filter, $maxLevel = 3, $level = 0, $parent = 0) { return Folder::listFolderTree($path, $filter, $maxLevel, $level, $parent); } /** * Helper wrapper method for makeSafe * * @param string $path The full path to sanitise. * * @return string The sanitised string * * @see Folder::makeSafe() * @since 3.4 * @deprecated 4.0 Use \Joomla\CMS\Filesystem\Folder instead */ public function makeSafe($path) { return Folder::makeSafe($path); } } Wrapper/PathWrapper.php 0000644 00000007103 15117132554 0011137 0 ustar 00 <?php /** * Joomla! Content Management System * * @copyright (C) 2014 Open Source Matters, Inc. <https://www.joomla.org> * @license GNU General Public License version 2 or later; see LICENSE.txt */ namespace Joomla\CMS\Filesystem\Wrapper; use Joomla\CMS\Filesystem\Path; defined('JPATH_PLATFORM') or die; /** * Wrapper class for Path * * @since 3.4 * @deprecated 4.0 Use \Joomla\CMS\Filesystem\Path instead */ class PathWrapper { /** * Helper wrapper method for canChmod * * @param string $path Path to check. * * @return boolean True if path can have mode changed. * * @see Path::canChmod() * @since 3.4 * @deprecated 4.0 Use \Joomla\CMS\Filesystem\Path instead */ public function canChmod($path) { return Path::canChmod($path); } /** * Helper wrapper method for setPermissions * * @param string $path Root path to begin changing mode [without trailing slash]. * @param string $filemode Octal representation of the value to change file mode to [null = no change]. * @param string $foldermode Octal representation of the value to change folder mode to [null = no change]. * * @return boolean True if successful [one fail means the whole operation failed]. * * @see Path::setPermissions() * @since 3.4 * @deprecated 4.0 Use \Joomla\CMS\Filesystem\Path instead */ public function setPermissions($path, $filemode = '0644', $foldermode = '0755') { return Path::setPermissions($path, $filemode, $foldermode); } /** * Helper wrapper method for getPermissions * * @param string $path The path of a file/folder. * * @return string Filesystem permissions. * * @see Path::getPermissions() * @since 3.4 * @deprecated 4.0 Use \Joomla\CMS\Filesystem\Path instead */ public function getPermissions($path) { return Path::getPermissions($path); } /** * Helper wrapper method for check * * @param string $path A file system path to check. * * @return string A cleaned version of the path or exit on error. * * @see Path::check() * @since 3.4 * @throws Exception * @deprecated 4.0 Use \Joomla\CMS\Filesystem\Path instead */ public function check($path) { return Path::check($path); } /** * Helper wrapper method for clean * * @param string $path The path to clean. * @param string $ds Directory separator (optional). * * @return string The cleaned path. * * @see Path::clean() * @since 3.4 * @throws UnexpectedValueException * @deprecated 4.0 Use \Joomla\CMS\Filesystem\Path instead */ public function clean($path, $ds = DIRECTORY_SEPARATOR) { return Path::clean($path, $ds); } /** * Helper wrapper method for isOwner * * @param string $path Path to check ownership. * * @return boolean True if the php script owns the path passed. * * @see Path::isOwner() * @since 3.4 * @deprecated 4.0 Use \Joomla\CMS\Filesystem\Path instead */ public function isOwner($path) { return Path::isOwner($path); } /** * Helper wrapper method for find * * @param mixed $paths A path string or array of path strings to search in * @param string $file The file name to look for. * * @return mixed The full path and file name for the target file, or boolean false if the file is not found in any of the paths. * * @see Path::find() * @since 3.4 * @deprecated 4.0 Use \Joomla\CMS\Filesystem\Path instead */ public function find($paths, $file) { return Path::find($paths, $file); } }
| ver. 1.4 |
Github
|
.
| PHP 8.1.33 | Генерация страницы: 0 |
proxy
|
phpinfo
|
Настройка