primo commit
This commit is contained in:
		
							
								
								
									
										186
									
								
								libraries/vendor/joomla/filesystem/src/Buffer.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										186
									
								
								libraries/vendor/joomla/filesystem/src/Buffer.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,186 @@ | ||||
| <?php | ||||
|  | ||||
| /** | ||||
|  * Part of the Joomla Framework Filesystem Package | ||||
|  * | ||||
|  * @copyright  Copyright (C) 2005 - 2021 Open Source Matters, Inc. All rights reserved. | ||||
|  * @license    GNU General Public License version 2 or later; see LICENSE | ||||
|  */ | ||||
|  | ||||
| namespace Joomla\Filesystem; | ||||
|  | ||||
| /** | ||||
|  * Generic Buffer stream handler | ||||
|  * | ||||
|  * This class provides a generic buffer stream.  It can be used to store/retrieve/manipulate | ||||
|  * string buffers with the standard PHP filesystem I/O methods. | ||||
|  * | ||||
|  * @since  1.0 | ||||
|  */ | ||||
| class Buffer | ||||
| { | ||||
|     /** | ||||
|      * Stream position | ||||
|      * | ||||
|      * @var    integer | ||||
|      * @since  1.0 | ||||
|      */ | ||||
|     public $position = 0; | ||||
|  | ||||
|     /** | ||||
|      * Buffer name | ||||
|      * | ||||
|      * @var    string | ||||
|      * @since  1.0 | ||||
|      */ | ||||
|     public $name; | ||||
|  | ||||
|     /** | ||||
|      * Buffer hash | ||||
|      * | ||||
|      * @var    array | ||||
|      * @since  1.0 | ||||
|      */ | ||||
|     public $buffers = []; | ||||
|  | ||||
|     /** | ||||
|      * Function to open file or url | ||||
|      * | ||||
|      * @param   string   $path        The URL that was passed | ||||
|      * @param   string   $mode        Mode used to open the file @see fopen | ||||
|      * @param   integer  $options     Flags used by the API, may be STREAM_USE_PATH and STREAM_REPORT_ERRORS | ||||
|      * @param   string   $openedPath  Full path of the resource. Used with STREAN_USE_PATH option | ||||
|      * | ||||
|      * @return  boolean | ||||
|      * | ||||
|      * @since   1.0 | ||||
|      * @see     streamWrapper::stream_open | ||||
|      */ | ||||
|     public function stream_open($path, $mode, $options, &$openedPath) | ||||
|     { | ||||
|         $url                        = parse_url($path); | ||||
|         $this->name                 = $url['host']; | ||||
|         $this->buffers[$this->name] = null; | ||||
|         $this->position             = 0; | ||||
|  | ||||
|         return true; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Read stream | ||||
|      * | ||||
|      * @param   integer  $count  How many bytes of data from the current position should be returned. | ||||
|      * | ||||
|      * @return  mixed    The data from the stream up to the specified number of bytes (all data if | ||||
|      *                   the total number of bytes in the stream is less than $count. Null if | ||||
|      *                   the stream is empty. | ||||
|      * | ||||
|      * @see     streamWrapper::stream_read | ||||
|      * @since   1.0 | ||||
|      */ | ||||
|     public function stream_read($count) | ||||
|     { | ||||
|         $ret = substr($this->buffers[$this->name], $this->position, $count); | ||||
|         $this->position += \strlen($ret); | ||||
|  | ||||
|         return $ret; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Write stream | ||||
|      * | ||||
|      * @param   string  $data  The data to write to the stream. | ||||
|      * | ||||
|      * @return  integer | ||||
|      * | ||||
|      * @see     streamWrapper::stream_write | ||||
|      * @since   1.0 | ||||
|      */ | ||||
|     public function stream_write($data) | ||||
|     { | ||||
|         $left                       = substr($this->buffers[$this->name], 0, $this->position); | ||||
|         $right                      = substr($this->buffers[$this->name], $this->position + \strlen($data)); | ||||
|         $this->buffers[$this->name] = $left . $data . $right; | ||||
|         $this->position += \strlen($data); | ||||
|  | ||||
|         return \strlen($data); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Function to get the current position of the stream | ||||
|      * | ||||
|      * @return  integer | ||||
|      * | ||||
|      * @see     streamWrapper::stream_tell | ||||
|      * @since   1.0 | ||||
|      */ | ||||
|     public function stream_tell() | ||||
|     { | ||||
|         return $this->position; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Function to test for end of file pointer | ||||
|      * | ||||
|      * @return  boolean  True if the pointer is at the end of the stream | ||||
|      * | ||||
|      * @see     streamWrapper::stream_eof | ||||
|      * @since   1.0 | ||||
|      */ | ||||
|     public function stream_eof() | ||||
|     { | ||||
|         return $this->position >= \strlen($this->buffers[$this->name]); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * The read write position updates in response to $offset and $whence | ||||
|      * | ||||
|      * @param   integer  $offset  The offset in bytes | ||||
|      * @param   integer  $whence  Position the offset is added to | ||||
|      *                            Options are SEEK_SET, SEEK_CUR, and SEEK_END | ||||
|      * | ||||
|      * @return  boolean  True if updated | ||||
|      * | ||||
|      * @see     streamWrapper::stream_seek | ||||
|      * @since   1.0 | ||||
|      */ | ||||
|     public function stream_seek($offset, $whence) | ||||
|     { | ||||
|         switch ($whence) { | ||||
|             case \SEEK_SET: | ||||
|                 if ($offset < \strlen($this->buffers[$this->name]) && $offset >= 0) { | ||||
|                     $this->position = $offset; | ||||
|  | ||||
|                     return true; | ||||
|                 } | ||||
|  | ||||
|                 return false; | ||||
|  | ||||
|             case \SEEK_CUR: | ||||
|                 if ($offset >= 0) { | ||||
|                     $this->position += $offset; | ||||
|  | ||||
|                     return true; | ||||
|                 } | ||||
|  | ||||
|                 return false; | ||||
|  | ||||
|             case \SEEK_END: | ||||
|                 if (\strlen($this->buffers[$this->name]) + $offset >= 0) { | ||||
|                     $this->position = \strlen($this->buffers[$this->name]) + $offset; | ||||
|  | ||||
|                     return true; | ||||
|                 } | ||||
|  | ||||
|                 return false; | ||||
|  | ||||
|             default: | ||||
|                 return false; | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| // Register the stream | ||||
| // phpcs:disable PSR1.Files.SideEffects | ||||
| stream_wrapper_register('buffer', 'Joomla\\Filesystem\\Buffer'); | ||||
| // phpcs:enable PSR1.Files.SideEffects | ||||
							
								
								
									
										1635
									
								
								libraries/vendor/joomla/filesystem/src/Clients/FtpClient.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1635
									
								
								libraries/vendor/joomla/filesystem/src/Clients/FtpClient.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										38
									
								
								libraries/vendor/joomla/filesystem/src/Exception/FilesystemException.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										38
									
								
								libraries/vendor/joomla/filesystem/src/Exception/FilesystemException.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,38 @@ | ||||
| <?php | ||||
|  | ||||
| /** | ||||
|  * Part of the Joomla Framework Filesystem Package | ||||
|  * | ||||
|  * @copyright  Copyright (C) 2005 - 2021 Open Source Matters, Inc. All rights reserved. | ||||
|  * @license    GNU General Public License version 2 or later; see LICENSE | ||||
|  */ | ||||
|  | ||||
| namespace Joomla\Filesystem\Exception; | ||||
|  | ||||
| use Joomla\Filesystem\Path; | ||||
|  | ||||
| /** | ||||
|  * Exception class for handling errors in the Filesystem package | ||||
|  * | ||||
|  * @since   1.2.0 | ||||
|  * @change  2.0.1  If the message contains a full path, the root path (JPATH_ROOT) is removed from it | ||||
|  *          to avoid any full path disclosure. Before 2.0.1, the path was propagated as provided. | ||||
|  */ | ||||
| class FilesystemException extends \RuntimeException | ||||
| { | ||||
|     /** | ||||
|      * Constructor. | ||||
|      * | ||||
|      * @param   string           $message   The message | ||||
|      * @param   integer          $code      The code | ||||
|      * @param   \Throwable|null  $previous  A previous exception | ||||
|      */ | ||||
|     public function __construct($message = "", $code = 0, ?\Throwable $previous = null) | ||||
|     { | ||||
|         parent::__construct( | ||||
|             Path::removeRoot($message), | ||||
|             $code, | ||||
|             $previous | ||||
|         ); | ||||
|     } | ||||
| } | ||||
							
								
								
									
										341
									
								
								libraries/vendor/joomla/filesystem/src/File.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										341
									
								
								libraries/vendor/joomla/filesystem/src/File.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,341 @@ | ||||
| <?php | ||||
|  | ||||
| /** | ||||
|  * Part of the Joomla Framework Filesystem Package | ||||
|  * | ||||
|  * @copyright  Copyright (C) 2005 - 2021 Open Source Matters, Inc. All rights reserved. | ||||
|  * @license    GNU General Public License version 2 or later; see LICENSE | ||||
|  */ | ||||
|  | ||||
| namespace Joomla\Filesystem; | ||||
|  | ||||
| use Joomla\Filesystem\Exception\FilesystemException; | ||||
|  | ||||
| /** | ||||
|  * A File handling class | ||||
|  * | ||||
|  * @since  1.0 | ||||
|  */ | ||||
| class File | ||||
| { | ||||
|     /** | ||||
|      * Gets the extension of a file name | ||||
|      * | ||||
|      * @param   string  $file  The file name | ||||
|      * | ||||
|      * @return  string  The file extension | ||||
|      * | ||||
|      * @since   3.0.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.0 | ||||
|      */ | ||||
|     public static function stripExt($file) | ||||
|     { | ||||
|         return preg_replace('#\.[^.]*$#', '', $file); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Makes the file name safe to use | ||||
|      * | ||||
|      * @param   string  $file        The name of the file [not full path] | ||||
|      * @param   array   $stripChars  Array of regex (by default will remove any leading periods) | ||||
|      * | ||||
|      * @return  string  The sanitised string | ||||
|      * | ||||
|      * @since   1.0 | ||||
|      */ | ||||
|     public static function makeSafe($file, array $stripChars = ['#^\.#']) | ||||
|     { | ||||
|         // Try transliterating the file name using the native php function | ||||
|         if (function_exists('transliterator_transliterate') && function_exists('iconv')) { | ||||
|             // Using iconv to ignore characters that can't be transliterated | ||||
|             $file = iconv("UTF-8", "ASCII//TRANSLIT//IGNORE", transliterator_transliterate('Any-Latin; Latin-ASCII', $file)); | ||||
|         } | ||||
|  | ||||
|         $regex = array_merge(['#(\.){2,}#', '#[^A-Za-z0-9\.\_\- ]#'], $stripChars); | ||||
|         $file  = preg_replace($regex, '', $file); | ||||
|  | ||||
|         // Remove any trailing dots, as those aren't ever valid file names. | ||||
|         $file = rtrim($file, '.'); | ||||
|  | ||||
|         return trim($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.0 | ||||
|      * @throws  FilesystemException | ||||
|      * @throws  \UnexpectedValueException | ||||
|      */ | ||||
|     public static function copy($src, $dest, $path = null, $useStreams = false) | ||||
|     { | ||||
|         // Prepend a base path if it exists | ||||
|         if ($path) { | ||||
|             $src  = Path::clean($path . '/' . $src); | ||||
|             $dest = Path::clean($path . '/' . $dest); | ||||
|         } | ||||
|  | ||||
|         // Check src path | ||||
|         if (!is_readable($src)) { | ||||
|             throw new \UnexpectedValueException( | ||||
|                 sprintf( | ||||
|                     "%s: Cannot find or read file: %s", | ||||
|                     __METHOD__, | ||||
|                     Path::removeRoot($src) | ||||
|                 ) | ||||
|             ); | ||||
|         } | ||||
|  | ||||
|         if ($useStreams) { | ||||
|             $stream = Stream::getStream(); | ||||
|  | ||||
|             if (!$stream->copy($src, $dest, null, false)) { | ||||
|                 throw new FilesystemException(sprintf('%1$s(%2$s, %3$s): %4$s', __METHOD__, $src, $dest, $stream->getError())); | ||||
|             } | ||||
|  | ||||
|             self::invalidateFileCache($dest); | ||||
|  | ||||
|             return true; | ||||
|         } | ||||
|  | ||||
|         if (!@ copy($src, $dest)) { | ||||
|             throw new FilesystemException(__METHOD__ . ': Copy failed.'); | ||||
|         } | ||||
|  | ||||
|         self::invalidateFileCache($dest); | ||||
|  | ||||
|         return true; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 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.0 | ||||
|      * @throws  FilesystemException | ||||
|      */ | ||||
|     public static function delete($file) | ||||
|     { | ||||
|         $files = (array) $file; | ||||
|  | ||||
|         foreach ($files as $file) { | ||||
|             $file     = Path::clean($file); | ||||
|             $filename = basename($file); | ||||
|  | ||||
|             // 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)) { | ||||
|                 throw new FilesystemException(__METHOD__ . ': Failed deleting ' . $filename); | ||||
|             } | ||||
|  | ||||
|             self::invalidateFileCache($file); | ||||
|         } | ||||
|  | ||||
|         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.0 | ||||
|      * @throws  FilesystemException | ||||
|      */ | ||||
|     public static function move($src, $dest, $path = '', $useStreams = false) | ||||
|     { | ||||
|         if ($path) { | ||||
|             $src  = Path::clean($path . '/' . $src); | ||||
|             $dest = Path::clean($path . '/' . $dest); | ||||
|         } | ||||
|  | ||||
|         // Check src path | ||||
|         if (!is_readable($src)) { | ||||
|             return 'Cannot find source file.'; | ||||
|         } | ||||
|  | ||||
|         if ($useStreams) { | ||||
|             $stream = Stream::getStream(); | ||||
|  | ||||
|             if (!$stream->move($src, $dest, null, false)) { | ||||
|                 throw new FilesystemException(__METHOD__ . ': ' . $stream->getError()); | ||||
|             } | ||||
|  | ||||
|             self::invalidateFileCache($dest); | ||||
|  | ||||
|             return true; | ||||
|         } | ||||
|  | ||||
|         if (!@ rename($src, $dest)) { | ||||
|             throw new FilesystemException(__METHOD__ . ': Rename failed.'); | ||||
|         } | ||||
|  | ||||
|         self::invalidateFileCache($dest); | ||||
|  | ||||
|         return true; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Write contents to a file | ||||
|      * | ||||
|      * @param   string   $file          The full file path | ||||
|      * @param   string   $buffer        The buffer to write | ||||
|      * @param   boolean  $useStreams    Use streams | ||||
|      * @param   boolean  $appendToFile  Append to the file and not overwrite it. | ||||
|      * | ||||
|      * @return  boolean  True on success | ||||
|      * | ||||
|      * @since   1.0 | ||||
|      */ | ||||
|     public static function write($file, $buffer, $useStreams = false, $appendToFile = false) | ||||
|     { | ||||
|         if (\function_exists('set_time_limit')) { | ||||
|             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))) { | ||||
|             Folder::create(\dirname($file)); | ||||
|         } | ||||
|  | ||||
|         if ($useStreams) { | ||||
|             $stream = Stream::getStream(); | ||||
|  | ||||
|             // Beef up the chunk size to a meg | ||||
|             $stream->set('chunksize', (1024 * 1024)); | ||||
|             $stream->writeFile($file, $buffer, $appendToFile); | ||||
|  | ||||
|             self::invalidateFileCache($file); | ||||
|  | ||||
|             return true; | ||||
|         } | ||||
|  | ||||
|         $file = Path::clean($file); | ||||
|  | ||||
|         // Set the required flag to only append to the file and not overwrite it | ||||
|         if ($appendToFile === true) { | ||||
|             $res = \is_int(file_put_contents($file, $buffer, \FILE_APPEND)); | ||||
|         } else { | ||||
|             $res = \is_int(file_put_contents($file, $buffer)); | ||||
|         } | ||||
|  | ||||
|         self::invalidateFileCache($file); | ||||
|  | ||||
|         return $res; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 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 | ||||
|      * | ||||
|      * @return  boolean  True on success | ||||
|      * | ||||
|      * @since   1.0 | ||||
|      * @throws  FilesystemException | ||||
|      */ | ||||
|     public static function upload($src, $dest, $useStreams = false) | ||||
|     { | ||||
|         // Ensure that the path is valid and clean | ||||
|         $dest = Path::clean($dest); | ||||
|  | ||||
|         // Create the destination directory if it does not exist | ||||
|         $baseDir = \dirname($dest); | ||||
|  | ||||
|         if (!is_dir($baseDir)) { | ||||
|             Folder::create($baseDir); | ||||
|         } | ||||
|  | ||||
|         if ($useStreams) { | ||||
|             $stream = Stream::getStream(); | ||||
|  | ||||
|             if (!$stream->upload($src, $dest, null, false)) { | ||||
|                 throw new FilesystemException(sprintf('%1$s(%2$s, %3$s): %4$s', __METHOD__, $src, $dest, $stream->getError())); | ||||
|             } | ||||
|  | ||||
|             self::invalidateFileCache($dest); | ||||
|  | ||||
|             return true; | ||||
|         } | ||||
|  | ||||
|         if (is_writable($baseDir) && move_uploaded_file($src, $dest)) { | ||||
|             // Short circuit to prevent file permission errors | ||||
|             if (Path::setPermissions($dest)) { | ||||
|                 self::invalidateFileCache($dest); | ||||
|  | ||||
|                 return true; | ||||
|             } | ||||
|  | ||||
|             throw new FilesystemException(__METHOD__ . ': Failed to change file permissions.'); | ||||
|         } | ||||
|  | ||||
|         throw new FilesystemException(__METHOD__ . ': Failed to move file.'); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Invalidate any opcache for a newly written file immediately, if opcache* functions exist and if this was a PHP file. | ||||
|      * | ||||
|      * @param   string  $file  The path to the file just written to, to flush from opcache | ||||
|      * | ||||
|      * @return void | ||||
|      */ | ||||
|     public static function invalidateFileCache($file) | ||||
|     { | ||||
|         if (function_exists('opcache_invalidate')) { | ||||
|             $info = pathinfo($file); | ||||
|  | ||||
|             if (isset($info['extension']) && $info['extension'] === 'php') { | ||||
|                 // Force invalidation to be absolutely sure the opcache is cleared for this file. | ||||
|                 opcache_invalidate($file, true); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| } | ||||
							
								
								
									
										548
									
								
								libraries/vendor/joomla/filesystem/src/Folder.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										548
									
								
								libraries/vendor/joomla/filesystem/src/Folder.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,548 @@ | ||||
| <?php | ||||
|  | ||||
| /** | ||||
|  * Part of the Joomla Framework Filesystem Package | ||||
|  * | ||||
|  * @copyright  Copyright (C) 2005 - 2021 Open Source Matters, Inc. All rights reserved. | ||||
|  * @license    GNU General Public License version 2 or later; see LICENSE | ||||
|  */ | ||||
|  | ||||
| namespace Joomla\Filesystem; | ||||
|  | ||||
| use Joomla\Filesystem\Exception\FilesystemException; | ||||
|  | ||||
| /** | ||||
|  * A Folder handling class | ||||
|  * | ||||
|  * @since  1.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.0 | ||||
|      * @throws  FilesystemException | ||||
|      */ | ||||
|     public static function copy($src, $dest, $path = '', $force = false, $useStreams = false) | ||||
|     { | ||||
|         if (\function_exists('set_time_limit')) { | ||||
|             set_time_limit(ini_get('max_execution_time')); | ||||
|         } | ||||
|  | ||||
|         if ($path) { | ||||
|             $src  = Path::clean($path . '/' . $src); | ||||
|             $dest = Path::clean($path . '/' . $dest); | ||||
|         } | ||||
|  | ||||
|         // Eliminate trailing directory separators, if any | ||||
|         $src  = rtrim($src, \DIRECTORY_SEPARATOR); | ||||
|         $dest = rtrim($dest, \DIRECTORY_SEPARATOR); | ||||
|  | ||||
|         if (!is_dir(Path::clean($src))) { | ||||
|             throw new FilesystemException('Source folder not found', -1); | ||||
|         } | ||||
|  | ||||
|         if (is_dir(Path::clean($dest)) && !$force) { | ||||
|             throw new FilesystemException('Destination folder not found', -1); | ||||
|         } | ||||
|  | ||||
|         // Make sure the destination exists | ||||
|         if (!self::create($dest)) { | ||||
|             throw new FilesystemException('Cannot create destination folder', -1); | ||||
|         } | ||||
|  | ||||
|         if (!($dh = @opendir($src))) { | ||||
|             throw new FilesystemException('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::getStream()->copy($sfid, $dfid); | ||||
|                     } else { | ||||
|                         if (!@copy($sfid, $dfid)) { | ||||
|                             throw new FilesystemException('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.0 | ||||
|      * @throws  FilesystemException | ||||
|      */ | ||||
|     public static function create($path = '', $mode = 0755) | ||||
|     { | ||||
|         static $nested = 0; | ||||
|  | ||||
|         // Check to make sure the path valid and clean | ||||
|         $path = Path::clean($path); | ||||
|  | ||||
|         // Check if parent dir exists | ||||
|         $parent = \dirname($path); | ||||
|  | ||||
|         if (!is_dir(Path::clean($parent))) { | ||||
|             // Prevent infinite loops! | ||||
|             $nested++; | ||||
|  | ||||
|             if (($nested > 20) || ($parent == $path)) { | ||||
|                 throw new FilesystemException(__METHOD__ . ': Infinite loop detected'); | ||||
|             } | ||||
|  | ||||
|             try { | ||||
|                 // Create the parent directory | ||||
|                 if (self::create($parent, $mode) !== true) { | ||||
|                     // Folder::create throws an error | ||||
|                     $nested--; | ||||
|  | ||||
|                     return false; | ||||
|                 } | ||||
|             } catch (FilesystemException $exception) { | ||||
|                 $nested--; | ||||
|  | ||||
|                 throw $exception; | ||||
|             } | ||||
|  | ||||
|             // OK, parent directory has been created | ||||
|             $nested--; | ||||
|         } | ||||
|  | ||||
|         // Check if dir already exists | ||||
|         if (is_dir(Path::clean($path))) { | ||||
|             return true; | ||||
|         } | ||||
|  | ||||
|         // 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 (\defined('PHP_WINDOWS_VERSION_MAJOR')) { | ||||
|                 $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 = Path::clean($test); | ||||
|  | ||||
|                 if (strpos($path, $test) === 0 || strpos($path, realpath($test)) === 0) { | ||||
|                     $inBaseDir = true; | ||||
|  | ||||
|                     break; | ||||
|                 } | ||||
|             } | ||||
|  | ||||
|             if ($inBaseDir == false) { | ||||
|                 // Throw a FilesystemException because the path to be created is not in open_basedir | ||||
|                 throw new FilesystemException(__METHOD__ . ': Path not in open_basedir paths'); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         // First set umask | ||||
|         $origmask = @umask(0); | ||||
|  | ||||
|         // Create the path | ||||
|         if (!$ret = @mkdir($path, $mode)) { | ||||
|             @umask($origmask); | ||||
|  | ||||
|             throw new FilesystemException(__METHOD__ . ': Could not create directory.  Path: ' . $path); | ||||
|         } | ||||
|  | ||||
|         // 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.0 | ||||
|      * @throws  FilesystemException | ||||
|      * @throws  \UnexpectedValueException | ||||
|      */ | ||||
|     public static function delete($path) | ||||
|     { | ||||
|         if (\function_exists('set_time_limit')) { | ||||
|             set_time_limit(ini_get('max_execution_time')); | ||||
|         } | ||||
|  | ||||
|         // Sanity check | ||||
|         if (!$path) { | ||||
|             // Bad programmer! Bad Bad programmer! | ||||
|             throw new FilesystemException(__METHOD__ . ': You can not delete a base directory.'); | ||||
|         } | ||||
|  | ||||
|         // Check to make sure the path valid and clean | ||||
|         $path = Path::clean($path); | ||||
|  | ||||
|         // Is this really a folder? | ||||
|         if (!is_dir($path)) { | ||||
|             throw new \UnexpectedValueException( | ||||
|                 sprintf( | ||||
|                     '%1$s: Path is not a folder. Path: %2$s', | ||||
|                     __METHOD__, | ||||
|                     Path::removeRoot($path) | ||||
|                 ) | ||||
|             ); | ||||
|         } | ||||
|  | ||||
|         // Remove all the files in folder if they exist; disable all filtering | ||||
|         $files = self::files($path, '.', false, true, [], []); | ||||
|  | ||||
|         if (!empty($files)) { | ||||
|             if (File::delete($files) !== true) { | ||||
|                 // File::delete throws an error | ||||
|                 return false; | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         // Remove sub-folders of folder; disable all filtering | ||||
|         $folders = self::folders($path, '.', false, true, [], []); | ||||
|  | ||||
|         foreach ($folders as $folder) { | ||||
|             if (is_link($folder)) { | ||||
|                 // Don't descend into linked directories, just delete the link. | ||||
|                 if (File::delete($folder) !== true) { | ||||
|                     // File::delete throws an error | ||||
|                     return false; | ||||
|                 } | ||||
|             } elseif (self::delete($folder) !== true) { | ||||
|                 // Folder::delete throws an error | ||||
|                 return false; | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         // 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)) { | ||||
|             return true; | ||||
|         } | ||||
|  | ||||
|         throw new FilesystemException(sprintf('%1$s: Could not delete folder. Path: %2$s', __METHOD__, $path)); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 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  string|boolean  Error message on false or boolean true on success. | ||||
|      * | ||||
|      * @since   1.0 | ||||
|      */ | ||||
|     public static function move($src, $dest, $path = '', $useStreams = false) | ||||
|     { | ||||
|         if ($path) { | ||||
|             $src  = Path::clean($path . '/' . $src); | ||||
|             $dest = Path::clean($path . '/' . $dest); | ||||
|         } | ||||
|  | ||||
|         if (!is_dir(Path::clean($src))) { | ||||
|             return 'Cannot find source folder'; | ||||
|         } | ||||
|  | ||||
|         if (is_dir(Path::clean($dest))) { | ||||
|             return 'Folder already exists'; | ||||
|         } | ||||
|  | ||||
|         if ($useStreams) { | ||||
|             Stream::getStream()->move($src, $dest); | ||||
|  | ||||
|             return true; | ||||
|         } | ||||
|  | ||||
|         if (!@rename($src, $dest)) { | ||||
|             return 'Rename failed'; | ||||
|         } | ||||
|  | ||||
|         return true; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 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.0 | ||||
|      * @throws  \UnexpectedValueException | ||||
|      */ | ||||
|     public static function files( | ||||
|         $path, | ||||
|         $filter = '.', | ||||
|         $recurse = false, | ||||
|         $full = false, | ||||
|         $exclude = ['.svn', 'CVS', '.DS_Store', '__MACOSX'], | ||||
|         $excludeFilter = ['^\..*', '.*~'], | ||||
|         $naturalSort = false | ||||
|     ) { | ||||
|         // Check to make sure the path valid and clean | ||||
|         $path = Path::clean($path); | ||||
|  | ||||
|         // Is the path a folder? | ||||
|         if (!is_dir($path)) { | ||||
|             throw new \UnexpectedValueException( | ||||
|                 sprintf( | ||||
|                     '%1$s: Path is not a folder. Path: %2$s', | ||||
|                     __METHOD__, | ||||
|                     Path::removeRoot($path) | ||||
|                 ) | ||||
|             ); | ||||
|         } | ||||
|  | ||||
|         // Compute the excludefilter string | ||||
|         if (\count($excludeFilter)) { | ||||
|             $excludeFilterString = '/(' . implode('|', $excludeFilter) . ')/'; | ||||
|         } else { | ||||
|             $excludeFilterString = ''; | ||||
|         } | ||||
|  | ||||
|         // Get the files | ||||
|         $arr = self::_items($path, $filter, $recurse, $full, $exclude, $excludeFilterString, 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.0 | ||||
|      * @throws  \UnexpectedValueException | ||||
|      */ | ||||
|     public static function folders( | ||||
|         $path, | ||||
|         $filter = '.', | ||||
|         $recurse = false, | ||||
|         $full = false, | ||||
|         $exclude = ['.svn', 'CVS', '.DS_Store', '__MACOSX'], | ||||
|         $excludeFilter = ['^\..*'] | ||||
|     ) { | ||||
|         // Check to make sure the path valid and clean | ||||
|         $path = Path::clean($path); | ||||
|  | ||||
|         // Is the path a folder? | ||||
|         if (!is_dir($path)) { | ||||
|             throw new \UnexpectedValueException( | ||||
|                 sprintf( | ||||
|                     '%1$s: Path is not a folder. Path: %2$s', | ||||
|                     __METHOD__, | ||||
|                     Path::removeRoot($path) | ||||
|                 ) | ||||
|             ); | ||||
|         } | ||||
|  | ||||
|         // Compute the excludefilter string | ||||
|         if (\count($excludeFilter)) { | ||||
|             $excludeFilterString = '/(' . implode('|', $excludeFilter) . ')/'; | ||||
|         } else { | ||||
|             $excludeFilterString = ''; | ||||
|         } | ||||
|  | ||||
|         // Get the folders | ||||
|         $arr = self::_items($path, $filter, $recurse, $full, $exclude, $excludeFilterString, 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.0 | ||||
|      */ | ||||
|     protected static function _items($path, $filter, $recurse, $full, $exclude, $excludeFilterString, $findfiles) | ||||
|     { | ||||
|         if (\function_exists('set_time_limit')) { | ||||
|             set_time_limit(ini_get('max_execution_time')); | ||||
|         } | ||||
|  | ||||
|         $arr = []; | ||||
|  | ||||
|         // 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::clean($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.0 | ||||
|      */ | ||||
|     public static function listFolderTree($path, $filter, $maxLevel = 3, $level = 0, $parent = 0) | ||||
|     { | ||||
|         $dirs = []; | ||||
|  | ||||
|         if ($level == 0) { | ||||
|             $GLOBALS['_JFolder_folder_tree_index'] = 0; | ||||
|         } | ||||
|  | ||||
|         if ($level < $maxLevel) { | ||||
|             $folders = self::folders($path, $filter); | ||||
|  | ||||
|             // First path, index foldernames | ||||
|             foreach ($folders as $name) { | ||||
|                 $id       = ++$GLOBALS['_JFolder_folder_tree_index']; | ||||
|                 $fullName = Path::clean($path . '/' . $name); | ||||
|                 $dirs[]   = [ | ||||
|                     '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.0 | ||||
|      */ | ||||
|     public static function makeSafe($path) | ||||
|     { | ||||
|         $regex = ['#[^A-Za-z0-9_\\\/\(\)\[\]\{\}\#\$\^\+\.\'~`!@&=;,-]#']; | ||||
|  | ||||
|         return preg_replace($regex, '', $path); | ||||
|     } | ||||
| } | ||||
							
								
								
									
										280
									
								
								libraries/vendor/joomla/filesystem/src/Helper.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										280
									
								
								libraries/vendor/joomla/filesystem/src/Helper.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,280 @@ | ||||
| <?php | ||||
|  | ||||
| /** | ||||
|  * Part of the Joomla Framework Filesystem Package | ||||
|  * | ||||
|  * @copyright  Copyright (C) 2005 - 2021 Open Source Matters, Inc. All rights reserved. | ||||
|  * @license    GNU General Public License version 2 or later; see LICENSE | ||||
|  */ | ||||
|  | ||||
| namespace Joomla\Filesystem; | ||||
|  | ||||
| /** | ||||
|  * File system helper | ||||
|  * | ||||
|  * Holds support functions for the filesystem, particularly the stream | ||||
|  * | ||||
|  * @since  1.0 | ||||
|  */ | ||||
| class Helper | ||||
| { | ||||
|     /** | ||||
|      * 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#71098 | ||||
|      * @since   1.0 | ||||
|      */ | ||||
|     public static function remotefsize($url) | ||||
|     { | ||||
|         $sch = parse_url($url, \PHP_URL_SCHEME); | ||||
|  | ||||
|         if (!\in_array($sch, ['http', 'https', 'ftp', 'ftps'], true)) { | ||||
|             return false; | ||||
|         } | ||||
|  | ||||
|         if (\in_array($sch, ['http', 'https'], true)) { | ||||
|             $headers = @ get_headers($url, 1); | ||||
|  | ||||
|             if (!$headers || (!\array_key_exists('Content-Length', $headers))) { | ||||
|                 return false; | ||||
|             } | ||||
|  | ||||
|             return $headers['Content-Length']; | ||||
|         } | ||||
|  | ||||
|         if (\in_array($sch, ['ftp', 'ftps'], true)) { | ||||
|             $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 = ''; | ||||
|             } | ||||
|  | ||||
|             $ftpid = null; | ||||
|  | ||||
|             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  integer|boolean | ||||
|      * | ||||
|      * @link    https://www.php.net/manual/en/function.ftp-chmod.php | ||||
|      * @since   1.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 = ''; | ||||
|         } | ||||
|  | ||||
|         $ftpid = null; | ||||
|  | ||||
|         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.0 | ||||
|      */ | ||||
|     public static function getWriteModes() | ||||
|     { | ||||
|         return ['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.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.0 | ||||
|      */ | ||||
|     public static function getTransports() | ||||
|     { | ||||
|         // Is this overkill? | ||||
|         return stream_get_transports(); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Returns a list of filters | ||||
|      * | ||||
|      * @return  array | ||||
|      * | ||||
|      * @since   1.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.0 | ||||
|      */ | ||||
|     public static function getJStreams() | ||||
|     { | ||||
|         static $streams = []; | ||||
|  | ||||
|         if (!$streams) { | ||||
|             $files = new \DirectoryIterator(__DIR__ . '/Stream'); | ||||
|  | ||||
|             /** @var \DirectoryIterator $file */ | ||||
|             foreach ($files as $file) { | ||||
|                 // Only load for php files. | ||||
|                 if (!$file->isFile() || $file->getExtension() != 'php') { | ||||
|                     continue; | ||||
|                 } | ||||
|  | ||||
|                 $streams[] = $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.0 | ||||
|      */ | ||||
|     public static function isJoomlaStream($streamname) | ||||
|     { | ||||
|         return \in_array($streamname, self::getJStreams()); | ||||
|     } | ||||
| } | ||||
							
								
								
									
										516
									
								
								libraries/vendor/joomla/filesystem/src/Patcher.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										516
									
								
								libraries/vendor/joomla/filesystem/src/Patcher.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,516 @@ | ||||
| <?php | ||||
|  | ||||
| /** | ||||
|  * Part of the Joomla Framework Filesystem Package | ||||
|  * | ||||
|  * @copyright  Copyright (C) 2005 - 2021 Open Source Matters, Inc. All rights reserved. | ||||
|  * @license    GNU General Public License version 2 or later; see LICENSE | ||||
|  */ | ||||
|  | ||||
| namespace Joomla\Filesystem; | ||||
|  | ||||
| /** | ||||
|  * 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  1.0 | ||||
|  */ | ||||
| class Patcher | ||||
| { | ||||
|     /** | ||||
|      * Regular expression for searching source files | ||||
|      * | ||||
|      * @var    string | ||||
|      * @since  1.0 | ||||
|      */ | ||||
|     public 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 | ||||
|      * | ||||
|      * @var    string | ||||
|      * @since  1.0 | ||||
|      */ | ||||
|     public 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 | ||||
|      * | ||||
|      * @var    string | ||||
|      * @since  1.0 | ||||
|      */ | ||||
|     public const HUNK = '/@@ -(\\d+)(,(\\d+))?\\s+\\+(\\d+)(,(\\d+))?\\s+@@($)/A'; | ||||
|  | ||||
|     /** | ||||
|      * Regular expression for splitting lines | ||||
|      * | ||||
|      * @var    string | ||||
|      * @since  1.0 | ||||
|      */ | ||||
|     public const SPLIT = '/(\r\n)|(\r)|(\n)/'; | ||||
|  | ||||
|     /** | ||||
|      * Source files | ||||
|      * | ||||
|      * @var    array | ||||
|      * @since  1.0 | ||||
|      */ | ||||
|     protected $sources = []; | ||||
|  | ||||
|     /** | ||||
|      * Destination files | ||||
|      * | ||||
|      * @var    array | ||||
|      * @since  1.0 | ||||
|      */ | ||||
|     protected $destinations = []; | ||||
|  | ||||
|     /** | ||||
|      * Removal files | ||||
|      * | ||||
|      * @var    array | ||||
|      * @since  1.0 | ||||
|      */ | ||||
|     protected $removals = []; | ||||
|  | ||||
|     /** | ||||
|      * Patches | ||||
|      * | ||||
|      * @var    array | ||||
|      * @since  1.0 | ||||
|      */ | ||||
|     protected $patches = []; | ||||
|  | ||||
|     /** | ||||
|      * Singleton instance of this class | ||||
|      * | ||||
|      * @var    Patcher | ||||
|      * @since  1.0 | ||||
|      */ | ||||
|     protected static $instance; | ||||
|  | ||||
|     /** | ||||
|      * Constructor | ||||
|      * | ||||
|      * The constructor is protected to force the use of Patcher::getInstance() | ||||
|      * | ||||
|      * @since   1.0 | ||||
|      */ | ||||
|     protected function __construct() | ||||
|     { | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Method to get a patcher | ||||
|      * | ||||
|      * @return  Patcher  an instance of the patcher | ||||
|      * | ||||
|      * @since   1.0 | ||||
|      */ | ||||
|     public static function getInstance() | ||||
|     { | ||||
|         if (!isset(static::$instance)) { | ||||
|             static::$instance = new static(); | ||||
|         } | ||||
|  | ||||
|         return static::$instance; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Reset the pacher | ||||
|      * | ||||
|      * @return  Patcher  This object for chaining | ||||
|      * | ||||
|      * @since   1.0 | ||||
|      */ | ||||
|     public function reset() | ||||
|     { | ||||
|         $this->sources      = []; | ||||
|         $this->destinations = []; | ||||
|         $this->removals     = []; | ||||
|         $this->patches      = []; | ||||
|  | ||||
|         return $this; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Apply the patches | ||||
|      * | ||||
|      * @return  integer  The number of files patched | ||||
|      * | ||||
|      * @since   1.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; | ||||
|  | ||||
|                 if ($patch['strip'] === null) { | ||||
|                     $src = $patch['root'] . preg_replace('#^([^/]*/)*#', '', $src); | ||||
|                     $dst = $patch['root'] . preg_replace('#^([^/]*/)*#', '', $dst); | ||||
|                 } else { | ||||
|                     $src = $patch['root'] . preg_replace('#^([^/]*/){' . (int) $patch['strip'] . '}#', '', $src); | ||||
|                     $dst = $patch['root'] . preg_replace('#^([^/]*/){' . (int) $patch['strip'] . '}#', '', $dst); | ||||
|                 } | ||||
|  | ||||
|                 // Loop for each hunk of differences | ||||
|                 while (self::findHunk($lines, $srcLine, $srcSize, $dstLine, $dstSize)) { | ||||
|                     $done = true; | ||||
|  | ||||
|                     // Apply the hunk of differences | ||||
|                     $this->applyHunk($lines, $src, $dst, $srcLine, $srcSize, $dstLine, $dstSize); | ||||
|                 } | ||||
|  | ||||
|                 // 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) { | ||||
|             $content = implode("\n", $content); | ||||
|  | ||||
|             if (File::write($file, $content)) { | ||||
|                 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 = []; | ||||
|  | ||||
|         // Clear the removals | ||||
|         $this->removals = []; | ||||
|  | ||||
|         // Clear the patches | ||||
|         $this->patches = []; | ||||
|  | ||||
|         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   integer  $strip     The number of '/' to strip | ||||
|      * | ||||
|      * @return  Patcher  $this for chaining | ||||
|      * | ||||
|      * @since   1.0 | ||||
|      */ | ||||
|     public function addFile($filename, $root, $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   integer  $strip  The number of '/' to strip | ||||
|      * | ||||
|      * @return  Patcher  $this for chaining | ||||
|      * | ||||
|      * @since   1.0 | ||||
|      */ | ||||
|     public function add($udiff, $root, $strip = 0) | ||||
|     { | ||||
|         $this->patches[] = [ | ||||
|             '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 input destination file | ||||
|      * | ||||
|      * @since   1.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   1.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   1.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]; | ||||
|  | ||||
|             if ($m[3] === '') { | ||||
|                 $srcSize = 1; | ||||
|             } else { | ||||
|                 $srcSize = (int) $m[3]; | ||||
|             } | ||||
|  | ||||
|             $dstLine = (int) $m[4]; | ||||
|  | ||||
|             if ($m[6] === '') { | ||||
|                 $dstSize = 1; | ||||
|             } else { | ||||
|                 $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   1.0 | ||||
|      * @throws  \RuntimeException | ||||
|      */ | ||||
|     protected function applyHunk(&$lines, $src, $dst, $srcLine, $srcSize, $dstLine, $dstSize) | ||||
|     { | ||||
|         $srcLine--; | ||||
|         $dstLine--; | ||||
|         $line = current($lines); | ||||
|  | ||||
|         // Source lines (old file) | ||||
|         $source = []; | ||||
|  | ||||
|         // New lines (new file) | ||||
|         $destin  = []; | ||||
|         $srcLeft = $srcSize; | ||||
|         $dstLeft = $dstSize; | ||||
|  | ||||
|         do { | ||||
|             if (!isset($line[0])) { | ||||
|                 $source[] = ''; | ||||
|                 $destin[] = ''; | ||||
|                 $srcLeft--; | ||||
|                 $dstLeft--; | ||||
|             } elseif ($line[0] == '-') { | ||||
|                 if ($srcLeft == 0) { | ||||
|                     throw new \RuntimeException('Unexpected remove line at line ' . key($lines)); | ||||
|                 } | ||||
|  | ||||
|                 $source[] = substr($line, 1); | ||||
|                 $srcLeft--; | ||||
|             } elseif ($line[0] == '+') { | ||||
|                 if ($dstLeft == 0) { | ||||
|                     throw new \RuntimeException('Unexpected add line at line ' . key($lines)); | ||||
|                 } | ||||
|  | ||||
|                 $destin[] = substr($line, 1); | ||||
|                 $dstLeft--; | ||||
|             } elseif ($line != '\\ No newline at end of file') { | ||||
|                 $line     = substr($line, 1); | ||||
|                 $source[] = $line; | ||||
|                 $destin[] = $line; | ||||
|                 $srcLeft--; | ||||
|                 $dstLeft--; | ||||
|             } | ||||
|  | ||||
|             if ($srcLeft == 0 && $dstLeft == 0) { | ||||
|                 // Now apply the patch, finally! | ||||
|                 if ($srcSize > 0) { | ||||
|                     $srcLines = & $this->getSource($src); | ||||
|  | ||||
|                     if (!isset($srcLines)) { | ||||
|                         throw new \RuntimeException( | ||||
|                             'Unexisting source file: ' . Path::removeRoot($src) | ||||
|                         ); | ||||
|                     } | ||||
|                 } | ||||
|  | ||||
|                 if ($dstSize > 0) { | ||||
|                     if ($srcSize > 0) { | ||||
|                         $dstLines  = & $this->getDestination($dst, $src); | ||||
|                         $srcBottom = $srcLine + \count($source); | ||||
|  | ||||
|                         for ($l = $srcLine; $l < $srcBottom; $l++) { | ||||
|                             if ($srcLines[$l] != $source[$l - $srcLine]) { | ||||
|                                 throw new \RuntimeException( | ||||
|                                     sprintf( | ||||
|                                         'Failed source verification of file %1$s at line %2$s', | ||||
|                                         Path::removeRoot($src), | ||||
|                                         $l | ||||
|                                     ) | ||||
|                                 ); | ||||
|                             } | ||||
|                         } | ||||
|  | ||||
|                         array_splice($dstLines, $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   1.0 | ||||
|      */ | ||||
|     protected function &getSource($src) | ||||
|     { | ||||
|         if (!isset($this->sources[$src])) { | ||||
|             if (is_readable($src)) { | ||||
|                 $this->sources[$src] = self::splitLines(file_get_contents($src)); | ||||
|             } else { | ||||
|                 $this->sources[$src] = null; | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         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   1.0 | ||||
|      */ | ||||
|     protected function &getDestination($dst, $src) | ||||
|     { | ||||
|         if (!isset($this->destinations[$dst])) { | ||||
|             $this->destinations[$dst] = $this->getSource($src); | ||||
|         } | ||||
|  | ||||
|         return $this->destinations[$dst]; | ||||
|     } | ||||
| } | ||||
							
								
								
									
										376
									
								
								libraries/vendor/joomla/filesystem/src/Path.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										376
									
								
								libraries/vendor/joomla/filesystem/src/Path.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,376 @@ | ||||
| <?php | ||||
|  | ||||
| /** | ||||
|  * Part of the Joomla Framework Filesystem Package | ||||
|  * | ||||
|  * @copyright  Copyright (C) 2005 - 2021 Open Source Matters, Inc. All rights reserved. | ||||
|  * @license    GNU General Public License version 2 or later; see LICENSE | ||||
|  */ | ||||
|  | ||||
| namespace Joomla\Filesystem; | ||||
|  | ||||
| use Joomla\Filesystem\Exception\FilesystemException; | ||||
|  | ||||
| /** | ||||
|  * A Path handling class | ||||
|  * | ||||
|  * @since  1.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.0 | ||||
|      */ | ||||
|     public static function canChmod($path) | ||||
|     { | ||||
|         if (!file_exists($path)) { | ||||
|             return false; | ||||
|         } | ||||
|  | ||||
|         $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.0 | ||||
|      */ | ||||
|     public static function setPermissions($path, $filemode = '0644', $foldermode = '0755') | ||||
|     { | ||||
|         // Initialise return value | ||||
|         $ret = true; | ||||
|  | ||||
|         if (is_dir($path)) { | ||||
|             $dh = @opendir($path); | ||||
|  | ||||
|             if ($dh) { | ||||
|                 while ($file = readdir($dh)) { | ||||
|                     if ($file != '.' && $file != '..') { | ||||
|                         $fullpath = $path . '/' . $file; | ||||
|  | ||||
|                         if (is_dir($fullpath)) { | ||||
|                             if (!static::setPermissions($fullpath, $filemode, $foldermode)) { | ||||
|                                 $ret = false; | ||||
|                             } | ||||
|                         } else { | ||||
|                             if (isset($filemode)) { | ||||
|                                 if (!static::canChmod($fullpath) || !@ chmod($fullpath, octdec($filemode))) { | ||||
|                                     $ret = false; | ||||
|                                 } | ||||
|                             } | ||||
|                         } | ||||
|                     } | ||||
|                 } | ||||
|  | ||||
|                 closedir($dh); | ||||
|             } | ||||
|  | ||||
|             if (isset($foldermode)) { | ||||
|                 if (!static::canChmod($path) || !@ chmod($path, octdec($foldermode))) { | ||||
|                     $ret = false; | ||||
|                 } | ||||
|             } | ||||
|         } else { | ||||
|             if (isset($filemode)) { | ||||
|                 if (!static::canChmod($path) || !@ chmod($path, octdec($filemode))) { | ||||
|                     $ret = false; | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         return $ret; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Get the permissions of the file/folder at a give path. | ||||
|      * | ||||
|      * @param   string  $path  The path of a file/folder. | ||||
|      * | ||||
|      * @return  string  Filesystem permissions. | ||||
|      * | ||||
|      * @since   1.0 | ||||
|      */ | ||||
|     public static function getPermissions($path) | ||||
|     { | ||||
|         $path = self::clean($path); | ||||
|         $mode = @ decoct(@ fileperms($path) & 0777); | ||||
|  | ||||
|         if (\strlen($mode) < 3) { | ||||
|             return '---------'; | ||||
|         } | ||||
|  | ||||
|         $parsedMode = ''; | ||||
|  | ||||
|         for ($i = 0; $i < 3; $i++) { | ||||
|             // Read | ||||
|             $parsedMode .= ($mode[$i] & 04) ? 'r' : '-'; | ||||
|  | ||||
|             // Write | ||||
|             $parsedMode .= ($mode[$i] & 02) ? 'w' : '-'; | ||||
|  | ||||
|             // Execute | ||||
|             $parsedMode .= ($mode[$i] & 01) ? 'x' : '-'; | ||||
|         } | ||||
|  | ||||
|         return $parsedMode; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Checks for snooping outside of the file system root. | ||||
|      * | ||||
|      * @param   string  $path      A file system path to check. | ||||
|      * @param   string  $basePath  The base path of the system | ||||
|      * | ||||
|      * @return  string  A cleaned version of the path or exit on error. | ||||
|      * | ||||
|      * @since   1.0 | ||||
|      * @throws  FilesystemException | ||||
|      */ | ||||
|     public static function check($path, $basePath = '') | ||||
|     { | ||||
|         if (strpos($path, '..') !== false) { | ||||
|             throw new FilesystemException( | ||||
|                 sprintf( | ||||
|                     '%s() - Use of relative paths not permitted', | ||||
|                     __METHOD__ | ||||
|                 ), | ||||
|                 20 | ||||
|             ); | ||||
|         } | ||||
|  | ||||
|         $path = static::clean($path); | ||||
|  | ||||
|         // If a base path is defined then check the cleaned path is not outside of root | ||||
|         if (($basePath != '') && strpos($path, static::clean($basePath)) !== 0) { | ||||
|             throw new FilesystemException( | ||||
|                 sprintf( | ||||
|                     '%1$s() - Snooping out of bounds @ %2$s', | ||||
|                     __METHOD__, | ||||
|                     $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.0 | ||||
|      * @throws  \UnexpectedValueException If $path is not a string. | ||||
|      */ | ||||
|     public static function clean($path, $ds = \DIRECTORY_SEPARATOR) | ||||
|     { | ||||
|         if ($path === '') { | ||||
|             return ''; | ||||
|         } | ||||
|  | ||||
|         if (!\is_string($path)) { | ||||
|             throw new \InvalidArgumentException('You must specify a non-empty path to clean'); | ||||
|         } | ||||
|  | ||||
|         $stream = explode('://', $path, 2); | ||||
|         $scheme = ''; | ||||
|         $path   = $stream[0]; | ||||
|  | ||||
|         if (\count($stream) >= 2) { | ||||
|             $scheme = $stream[0] . '://'; | ||||
|             $path   = $stream[1]; | ||||
|         } | ||||
|  | ||||
|         $path = trim($path); | ||||
|  | ||||
|         // 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. | ||||
|         if (($ds == '\\') && ($path[0] == '\\') && ($path[1] == '\\')) { | ||||
|             $path = '\\' . preg_replace('#[/\\\\]+#', $ds, $path); | ||||
|         } else { | ||||
|             $path = preg_replace('#[/\\\\]+#', $ds, $path); | ||||
|         } | ||||
|  | ||||
|         return $scheme . $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.0 | ||||
|      */ | ||||
|     public static function isOwner($path) | ||||
|     { | ||||
|         $tmp = md5(random_bytes(16)); | ||||
|         $ssp = ini_get('session.save_path'); | ||||
|  | ||||
|         // Try to find a writable directory | ||||
|         $dir = is_writable('/tmp') ? '/tmp' : false; | ||||
|         $dir = !$dir && is_writable('.') ? '.' : $dir; | ||||
|         $dir = !$dir && is_writable($ssp) ? $ssp : $dir; | ||||
|  | ||||
|         if ($dir) { | ||||
|             $test = $dir . '/' . $tmp; | ||||
|  | ||||
|             // Create the test file | ||||
|             $blank = ''; | ||||
|             File::write($test, $blank, false); | ||||
|  | ||||
|             // Test ownership | ||||
|             $return = fileowner($test) === fileowner($path); | ||||
|  | ||||
|             // Delete the test file | ||||
|             File::delete($test); | ||||
|  | ||||
|             return $return; | ||||
|         } | ||||
|  | ||||
|         return false; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Searches the directory paths for a given file. | ||||
|      * | ||||
|      * @param   mixed   $paths  A path string or array of path strings to search in | ||||
|      * @param   string  $file   The file name to look for. | ||||
|      * | ||||
|      * @return  string|boolean   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.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   1.6.0 | ||||
|      */ | ||||
|     public static function resolve($path) | ||||
|     { | ||||
|         $path = static::clean($path); | ||||
|  | ||||
|         // Save start character for absolute path | ||||
|         $startCharacter = ($path[0] === DIRECTORY_SEPARATOR) ? DIRECTORY_SEPARATOR : ''; | ||||
|  | ||||
|         $parts = []; | ||||
|  | ||||
|         foreach (explode(DIRECTORY_SEPARATOR, $path) as $part) { | ||||
|             switch ($part) { | ||||
|                 case '': | ||||
|                 case '.': | ||||
|                     break; | ||||
|  | ||||
|                 case '..': | ||||
|                     if (empty($parts)) { | ||||
|                         throw new FilesystemException('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   2.0.1 | ||||
|      */ | ||||
|     public static function removeRoot($message, $rootDirectory = null) | ||||
|     { | ||||
|         if (empty($rootDirectory)) { | ||||
|             $rootDirectory = JPATH_ROOT; | ||||
|         } | ||||
|  | ||||
|         $makePattern = static function ($dir) { | ||||
|             return '~' . str_replace('~', '\\~', preg_replace('~[/\\\\]+~', '.', $dir)) . '~'; | ||||
|         }; | ||||
|  | ||||
|         $replacements = [ | ||||
|             $makePattern(static::clean($rootDirectory)) => '[ROOT]', | ||||
|             $makePattern(sys_get_temp_dir())            => '[TMP]', | ||||
|         ]; | ||||
|  | ||||
|         return preg_replace(array_keys($replacements), array_values($replacements), $message); | ||||
|     } | ||||
| } | ||||
							
								
								
									
										1418
									
								
								libraries/vendor/joomla/filesystem/src/Stream.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1418
									
								
								libraries/vendor/joomla/filesystem/src/Stream.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										290
									
								
								libraries/vendor/joomla/filesystem/src/Stream/StringWrapper.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										290
									
								
								libraries/vendor/joomla/filesystem/src/Stream/StringWrapper.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,290 @@ | ||||
| <?php | ||||
|  | ||||
| /** | ||||
|  * Part of the Joomla Framework Filesystem Package | ||||
|  * | ||||
|  * @copyright  Copyright (C) 2005 - 2021 Open Source Matters, Inc. All rights reserved. | ||||
|  * @license    GNU General Public License version 2 or later; see LICENSE | ||||
|  */ | ||||
|  | ||||
| namespace Joomla\Filesystem\Stream; | ||||
|  | ||||
| use Joomla\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.3.0 | ||||
|  */ | ||||
| class StringWrapper | ||||
| { | ||||
|     /** | ||||
|      * The current string | ||||
|      * | ||||
|      * @var   string | ||||
|      * @since  1.3.0 | ||||
|      */ | ||||
|     protected $currentString; | ||||
|  | ||||
|     /** | ||||
|      * The path | ||||
|      * | ||||
|      * @var   string | ||||
|      * @since  1.3.0 | ||||
|      */ | ||||
|     protected $path; | ||||
|  | ||||
|     /** | ||||
|      * The mode | ||||
|      * | ||||
|      * @var   string | ||||
|      * @since  1.3.0 | ||||
|      */ | ||||
|     protected $mode; | ||||
|  | ||||
|     /** | ||||
|      * Enter description here ... | ||||
|      * | ||||
|      * @var   string | ||||
|      * @since  1.3.0 | ||||
|      */ | ||||
|     protected $options; | ||||
|  | ||||
|     /** | ||||
|      * Enter description here ... | ||||
|      * | ||||
|      * @var   string | ||||
|      * @since  1.3.0 | ||||
|      */ | ||||
|     protected $openedPath; | ||||
|  | ||||
|     /** | ||||
|      * Current position | ||||
|      * | ||||
|      * @var   integer | ||||
|      * @since  1.3.0 | ||||
|      */ | ||||
|     protected $pos; | ||||
|  | ||||
|     /** | ||||
|      * Length of the string | ||||
|      * | ||||
|      * @var   string | ||||
|      * @since  1.3.0 | ||||
|      */ | ||||
|     protected $len; | ||||
|  | ||||
|     /** | ||||
|      * Statistics for a file | ||||
|      * | ||||
|      * @var    array | ||||
|      * @since  1.3.0 | ||||
|      * @link   https://www.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.3.0 | ||||
|      */ | ||||
|     public function stream_open($path, $mode, $options, &$openedPath) | ||||
|     { | ||||
|         $refPath = StringController::getRef(str_replace('string://', '', $path)); | ||||
|  | ||||
|         $this->currentString = &$refPath; | ||||
|  | ||||
|         if ($this->currentString) { | ||||
|             $this->len  = \strlen($this->currentString); | ||||
|             $this->pos  = 0; | ||||
|             $this->stat = $this->url_stat($path, 0); | ||||
|  | ||||
|             return true; | ||||
|         } | ||||
|  | ||||
|         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.3.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.3.0 | ||||
|      */ | ||||
|     public function url_stat($path, $flags = 0) | ||||
|     { | ||||
|         $now     = time(); | ||||
|         $refPath = StringController::getRef(str_replace('string://', '', $path)); | ||||
|         $string  = &$refPath; | ||||
|         $stat    = [ | ||||
|             '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  string | ||||
|      * | ||||
|      * @link    https://www.php.net/manual/en/streamwrapper.stream-read.php | ||||
|      * @since   1.3.0 | ||||
|      */ | ||||
|     public function stream_read($count) | ||||
|     { | ||||
|         $result = substr($this->currentString, $this->pos ?? 0, $count); | ||||
|         $this->pos += $count; | ||||
|  | ||||
|         return $result; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Stream write, always returning false. | ||||
|      * | ||||
|      * @param   string  $data  The data to write. | ||||
|      * | ||||
|      * @return  boolean | ||||
|      * | ||||
|      * @since   1.3.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.3.0 | ||||
|      */ | ||||
|     public function stream_tell() | ||||
|     { | ||||
|         return $this->pos; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * End of field check | ||||
|      * | ||||
|      * @return  boolean  True if at end of field. | ||||
|      * | ||||
|      * @since   1.3.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.3.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) { | ||||
|                     return false; | ||||
|                 } | ||||
|  | ||||
|                 $this->pos += $offset; | ||||
|  | ||||
|                 break; | ||||
|  | ||||
|             case \SEEK_END: | ||||
|                 $this->pos = $this->len - $offset; | ||||
|  | ||||
|                 break; | ||||
|         } | ||||
|  | ||||
|         return true; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Stream flush, always returns true. | ||||
|      * | ||||
|      * @return  boolean | ||||
|      * | ||||
|      * @since   1.3.0 | ||||
|      * @note    Data storage is not supported | ||||
|      */ | ||||
|     public function stream_flush() | ||||
|     { | ||||
|         // We don't store data. | ||||
|         return true; | ||||
|     } | ||||
| } | ||||
|  | ||||
| // phpcs:disable PSR1.Files.SideEffects | ||||
| if (!stream_wrapper_register('string', '\\Joomla\\Filesystem\\Stream\\StringWrapper')) { | ||||
|     die('\\Joomla\\Filesystem\\Stream\\StringWrapper Wrapper Registration Failed'); | ||||
| } | ||||
| // phpcs:enable PSR1.Files.SideEffects | ||||
							
								
								
									
										84
									
								
								libraries/vendor/joomla/filesystem/src/Support/StringController.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										84
									
								
								libraries/vendor/joomla/filesystem/src/Support/StringController.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,84 @@ | ||||
| <?php | ||||
|  | ||||
| /** | ||||
|  * Part of the Joomla Framework Filesystem Package | ||||
|  * | ||||
|  * @copyright  Copyright (C) 2005 - 2021 Open Source Matters, Inc. All rights reserved. | ||||
|  * @license    GNU General Public License version 2 or later; see LICENSE | ||||
|  */ | ||||
|  | ||||
| namespace Joomla\Filesystem\Support; | ||||
|  | ||||
| /** | ||||
|  * String Controller | ||||
|  * | ||||
|  * @since  1.0 | ||||
|  */ | ||||
| class StringController | ||||
| { | ||||
|     /** | ||||
|      * Internal string references | ||||
|      * | ||||
|      * @var     array | ||||
|      * @ssince  1.4.0 | ||||
|      */ | ||||
|     private static $strings = []; | ||||
|  | ||||
|     /** | ||||
|      * Defines a variable as an array | ||||
|      * | ||||
|      * @return  array | ||||
|      * | ||||
|      * @since   1.0 | ||||
|      * @deprecated  2.0  Use `getArray` instead. | ||||
|      */ | ||||
|     public static function _getArray() | ||||
|     { | ||||
|         return self::getArray(); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Defines a variable as an array | ||||
|      * | ||||
|      * @return  array | ||||
|      * | ||||
|      * @since   1.4.0 | ||||
|      */ | ||||
|     public static function getArray() | ||||
|     { | ||||
|         return self::$strings; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Create a reference | ||||
|      * | ||||
|      * @param   string  $reference  The key | ||||
|      * @param   string  $string     The value | ||||
|      * | ||||
|      * @return  void | ||||
|      * | ||||
|      * @since   1.0 | ||||
|      */ | ||||
|     public static function createRef($reference, &$string) | ||||
|     { | ||||
|         self::$strings[$reference] = & $string; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Get reference | ||||
|      * | ||||
|      * @param   string  $reference  The key for the reference. | ||||
|      * | ||||
|      * @return  mixed  False if not set, reference if it exists | ||||
|      * | ||||
|      * @since   1.0 | ||||
|      */ | ||||
|     public static function getRef($reference) | ||||
|     { | ||||
|         if (isset(self::$strings[$reference])) { | ||||
|             return self::$strings[$reference]; | ||||
|         } | ||||
|  | ||||
|         return false; | ||||
|     } | ||||
| } | ||||
		Reference in New Issue
	
	Block a user