mirror of
https://github.com/phpbb/phpbb.git
synced 2025-06-02 12:34:59 +02:00
[ticket/15253] Add storage abstraction
PHPBB3-15253
This commit is contained in:
parent
2482ec6897
commit
334b44057d
@ -25,6 +25,7 @@ imports:
|
||||
- { resource: services_profilefield.yml }
|
||||
- { resource: services_report.yml }
|
||||
- { resource: services_routing.yml }
|
||||
- { resource: services_storage.yml }
|
||||
- { resource: services_text_formatter.yml }
|
||||
- { resource: services_text_reparser.yml }
|
||||
- { resource: services_twig.yml }
|
||||
|
14
phpBB/config/default/container/services_storage.yml
Normal file
14
phpBB/config/default/container/services_storage.yml
Normal file
@ -0,0 +1,14 @@
|
||||
services:
|
||||
storage.adapter.avatar:
|
||||
class: phpbb\storage\adapter\local
|
||||
arguments:
|
||||
- '@filesystem'
|
||||
- '%core.root_path%'
|
||||
storage.avatar:
|
||||
class: phpbb\storage\storage
|
||||
arguments:
|
||||
- '@storage.adapter.avatar'
|
||||
storage.controller:
|
||||
class: phpbb\storage\controller
|
||||
arguments:
|
||||
- '@service_container'
|
78
phpBB/phpbb/storage/adapter/adapter_interface.php
Normal file
78
phpBB/phpbb/storage/adapter/adapter_interface.php
Normal file
@ -0,0 +1,78 @@
|
||||
<?php
|
||||
/**
|
||||
*
|
||||
* This file is part of the phpBB Forum Software package.
|
||||
*
|
||||
* @copyright (c) phpBB Limited <https://www.phpbb.com>
|
||||
* @license GNU General Public License, version 2 (GPL-2.0)
|
||||
*
|
||||
* For full copyright and license information, please see
|
||||
* the docs/CREDITS.txt file.
|
||||
*
|
||||
*/
|
||||
|
||||
namespace phpbb\storage\adapter;
|
||||
|
||||
interface adapter_interface
|
||||
{
|
||||
/**
|
||||
* Dumps content into a file.
|
||||
*
|
||||
* @param string path The file to be written to.
|
||||
* @param string content The data to write into the file.
|
||||
*
|
||||
* @throws \phpbb\storage\exception\exception When the file already exists
|
||||
* When the file cannot be written
|
||||
*/
|
||||
public function put_contents($path, $content);
|
||||
|
||||
/**
|
||||
* Read the contents of a file
|
||||
*
|
||||
* @param string $path The file to read
|
||||
*
|
||||
* @throws \phpbb\storage\exception\exception When the file dont exists
|
||||
* When cannot read file contents
|
||||
*/
|
||||
public function get_contents($path);
|
||||
|
||||
/**
|
||||
* Checks the existence of files or directories.
|
||||
*
|
||||
* @param string $path file/directory to check
|
||||
*
|
||||
* @return bool Returns true if all files/directories exist, false otherwise
|
||||
*/
|
||||
public function exists($path);
|
||||
|
||||
/**
|
||||
* Removes files or directories.
|
||||
*
|
||||
* @param string $path file/directory to remove
|
||||
*
|
||||
* @throws \phpbb\storage\exception\exception When removal fails.
|
||||
*/
|
||||
public function delete($path);
|
||||
|
||||
/**
|
||||
* Rename a file or a directory.
|
||||
*
|
||||
* @param string $path_orig The original file/direcotry
|
||||
* @param string $path_dest The target file/directory
|
||||
*
|
||||
* @throws \phpbb\storage\exception\exception When target exists
|
||||
* When file/directory cannot be renamed
|
||||
*/
|
||||
public function rename($path_orig, $path_dest);
|
||||
|
||||
/**
|
||||
* Copies a file.
|
||||
*
|
||||
* @param string $path_orig The original filename
|
||||
* @param string $path_dest The target filename
|
||||
*
|
||||
* @throws \phpbb\storage\exception\exception When target exists
|
||||
* When the file cannot be copied
|
||||
*/
|
||||
public function copy($path_orig, $path_dest);
|
||||
}
|
146
phpBB/phpbb/storage/adapter/local.php
Normal file
146
phpBB/phpbb/storage/adapter/local.php
Normal file
@ -0,0 +1,146 @@
|
||||
<?php
|
||||
/**
|
||||
*
|
||||
* This file is part of the phpBB Forum Software package.
|
||||
*
|
||||
* @copyright (c) phpBB Limited <https://www.phpbb.com>
|
||||
* @license GNU General Public License, version 2 (GPL-2.0)
|
||||
*
|
||||
* For full copyright and license information, please see
|
||||
* the docs/CREDITS.txt file.
|
||||
*
|
||||
*/
|
||||
|
||||
namespace phpbb\storage\adapter;
|
||||
|
||||
use phpbb\storage\exception\exception;
|
||||
use phpbb\filesystem\filesystem_exception;
|
||||
|
||||
class local implements adapter_interface
|
||||
{
|
||||
/**
|
||||
* Filesystem component
|
||||
*
|
||||
* @var \phpbb\filesystem\filesystem
|
||||
*/
|
||||
protected $filesystem;
|
||||
|
||||
/** @var string phpBB root path */
|
||||
protected $phpbb_root_path;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public function __construct($filesystem, $phpbb_root_path)
|
||||
{
|
||||
$this->filesystem = $filesystem;
|
||||
$this->phpbb_root_path = $phpbb_root_path;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function put_contents($path, $content)
|
||||
{
|
||||
if ($this->exists($this->phpbb_root_path.$path))
|
||||
{
|
||||
throw new exception('', $path); // FILE_EXISTS
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
$this->filesystem->dump_file($this->phpbb_root_path.$path, $content);
|
||||
}
|
||||
catch (filesystem_exception $e)
|
||||
{
|
||||
throw new exception('', $path, array(), $e); // CANNOT_DUMP_FILE
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function get_contents($path)
|
||||
{
|
||||
if (!$this->exists($this->phpbb_root_path.$path))
|
||||
{
|
||||
throw new exception('', $path); // FILE_DONT_EXIST
|
||||
}
|
||||
|
||||
if (($content = @file_get_contents($this->phpbb_root_path.$path)) === false)
|
||||
{
|
||||
throw new exception('', $path); // CANNOT READ FILE
|
||||
}
|
||||
|
||||
return $content;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function exists($path)
|
||||
{
|
||||
return $this->filesystem->exists($this->phpbb_root_path.$path);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function delete($path)
|
||||
{
|
||||
try
|
||||
{
|
||||
$this->filesystem->remove($this->phpbb_root_path.$path);
|
||||
}
|
||||
catch (filesystem_exception $e)
|
||||
{
|
||||
throw new exception('', $path, array(), $e); // CANNOT DELETE
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function rename($path_orig, $path_dest)
|
||||
{
|
||||
try
|
||||
{
|
||||
$this->filesystem->rename($this->phpbb_root_path.$path_orig, $this->phpbb_root_path.$path_dest, false);
|
||||
}
|
||||
catch (filesystem_exception $e)
|
||||
{
|
||||
throw new exception('', $path_orig, array(), $e); // CANNOT_RENAME
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function copy($path_orig, $path_dest)
|
||||
{
|
||||
try
|
||||
{
|
||||
$this->filesystem->copy($this->phpbb_root_path.$path_orig, $this->phpbb_root_path.$path_dest, false);
|
||||
}
|
||||
catch (filesystem_exception $e)
|
||||
{
|
||||
throw new exception('', '', array(), $e); // CANNOT_COPY_FILES
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function create_dir($path)
|
||||
{
|
||||
try
|
||||
{
|
||||
$this->filesystem->mkdir($this->phpbb_root_path.$path);
|
||||
}
|
||||
catch (filesystem_exception $e)
|
||||
{
|
||||
throw new exception('', $path, array(), $e); // CANNOT_CREATE_DIRECTORY
|
||||
}
|
||||
}
|
||||
|
||||
}
|
39
phpBB/phpbb/storage/controller.php
Normal file
39
phpBB/phpbb/storage/controller.php
Normal file
@ -0,0 +1,39 @@
|
||||
<?php
|
||||
/**
|
||||
*
|
||||
* This file is part of the phpBB Forum Software package.
|
||||
*
|
||||
* @copyright (c) phpBB Limited <https://www.phpbb.com>
|
||||
* @license GNU General Public License, version 2 (GPL-2.0)
|
||||
*
|
||||
* For full copyright and license information, please see
|
||||
* the docs/CREDITS.txt file.
|
||||
*
|
||||
*/
|
||||
|
||||
namespace phpbb\storage;
|
||||
|
||||
class controller
|
||||
{
|
||||
/**
|
||||
* @var ContainerInterface
|
||||
*/
|
||||
protected $container;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param ContainerInterface $container A ContainerInterface instance
|
||||
*/
|
||||
public function __construct(ContainerInterface $container)
|
||||
{
|
||||
$this->container = $container;
|
||||
}
|
||||
|
||||
public function get_file($storage, $file)
|
||||
{
|
||||
$storage = $this->container->get($storage);
|
||||
|
||||
return $storage->get_contents($file);
|
||||
}
|
||||
}
|
42
phpBB/phpbb/storage/exception/exception.php
Normal file
42
phpBB/phpbb/storage/exception/exception.php
Normal file
@ -0,0 +1,42 @@
|
||||
<?php
|
||||
/**
|
||||
*
|
||||
* This file is part of the phpBB Forum Software package.
|
||||
*
|
||||
* @copyright (c) phpBB Limited <https://www.phpbb.com>
|
||||
* @license GNU General Public License, version 2 (GPL-2.0)
|
||||
*
|
||||
* For full copyright and license information, please see
|
||||
* the docs/CREDITS.txt file.
|
||||
*
|
||||
*/
|
||||
|
||||
namespace phpbb\storage\exception;
|
||||
|
||||
class exception extends \phpbb\exception\runtime_exception
|
||||
{
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param string $message The Exception message to throw (must be a language variable).
|
||||
* @param string $filename The file that caused the error.
|
||||
* @param array $parameters The parameters to use with the language var.
|
||||
* @param \Exception $previous The previous runtime_exception used for the runtime_exception chaining.
|
||||
* @param integer $code The Exception code.
|
||||
*/
|
||||
public function __construct($message = "", $filename = '', $parameters = array(), \Exception $previous = null, $code = 0)
|
||||
{
|
||||
parent::__construct($message, array_merge(array('filename' => $filename), $parameters), $previous, $code);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the filename that triggered the error
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_filename()
|
||||
{
|
||||
$parameters = parent::get_parameters();
|
||||
return $parameters['filename'];
|
||||
}
|
||||
}
|
42
phpBB/phpbb/storage/exception/not_implemented.php
Normal file
42
phpBB/phpbb/storage/exception/not_implemented.php
Normal file
@ -0,0 +1,42 @@
|
||||
<?php
|
||||
/**
|
||||
*
|
||||
* This file is part of the phpBB Forum Software package.
|
||||
*
|
||||
* @copyright (c) phpBB Limited <https://www.phpbb.com>
|
||||
* @license GNU General Public License, version 2 (GPL-2.0)
|
||||
*
|
||||
* For full copyright and license information, please see
|
||||
* the docs/CREDITS.txt file.
|
||||
*
|
||||
*/
|
||||
|
||||
namespace phpbb\storage\exception;
|
||||
|
||||
class not_implemented extends \phpbb\exception\runtime_exception
|
||||
{
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param string $message The Exception message to throw (must be a language variable).
|
||||
* @param string $filename The file that caused the error.
|
||||
* @param array $parameters The parameters to use with the language var.
|
||||
* @param \Exception $previous The previous runtime_exception used for the runtime_exception chaining.
|
||||
* @param integer $code The Exception code.
|
||||
*/
|
||||
public function __construct($message = "", $filename = '', $parameters = array(), \Exception $previous = null, $code = 0)
|
||||
{
|
||||
parent::__construct($message, array_merge(array('filename' => $filename), $parameters), $previous, $code);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the filename that triggered the error
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_filename()
|
||||
{
|
||||
$parameters = parent::get_parameters();
|
||||
return $parameters['filename'];
|
||||
}
|
||||
}
|
365
phpBB/phpbb/storage/helper.php
Normal file
365
phpBB/phpbb/storage/helper.php
Normal file
@ -0,0 +1,365 @@
|
||||
<?php
|
||||
/**
|
||||
*
|
||||
* This file is part of the phpBB Forum Software package.
|
||||
*
|
||||
* @copyright (c) phpBB Limited <https://www.phpbb.com>
|
||||
* @license GNU General Public License, version 2 (GPL-2.0)
|
||||
*
|
||||
* For full copyright and license information, please see
|
||||
* the docs/CREDITS.txt file.
|
||||
*
|
||||
*/
|
||||
|
||||
namespace phpbb\storage;
|
||||
|
||||
class helper
|
||||
{
|
||||
/**
|
||||
* Eliminates useless . and .. components from specified path.
|
||||
*
|
||||
* @param string $path Path to clean
|
||||
*
|
||||
* @return string Cleaned path
|
||||
*/
|
||||
public static function clean_path($path)
|
||||
{
|
||||
$exploded = explode('/', $path);
|
||||
$filtered = array();
|
||||
foreach ($exploded as $part)
|
||||
{
|
||||
if ($part === '.' && !empty($filtered))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($part === '..' && !empty($filtered) && $filtered[sizeof($filtered) - 1] !== '.' && $filtered[sizeof($filtered) - 1] !== '..')
|
||||
{
|
||||
array_pop($filtered);
|
||||
}
|
||||
else
|
||||
{
|
||||
$filtered[] = $part;
|
||||
}
|
||||
}
|
||||
$path = implode('/', $filtered);
|
||||
return $path;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if a path is absolute or not
|
||||
*
|
||||
* @param string $path Path to check
|
||||
*
|
||||
* @return bool true if the path is absolute, false otherwise
|
||||
*/
|
||||
public static function is_absolute_path($path)
|
||||
{
|
||||
return (isset($path[0]) && $path[0] === '/' || preg_match('#^[a-z]:[/\\\]#i', $path)) ? true : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Try to resolve real path when PHP's realpath failes to do so
|
||||
*
|
||||
* @param string $path
|
||||
* @return bool|string
|
||||
*/
|
||||
protected static function phpbb_own_realpath($path)
|
||||
{
|
||||
|
||||
// Replace all directory separators with '/'
|
||||
$path = str_replace(DIRECTORY_SEPARATOR, '/', $path);
|
||||
|
||||
$is_absolute_path = false;
|
||||
$path_prefix = '';
|
||||
|
||||
if (self::is_absolute_path($path))
|
||||
{
|
||||
$is_absolute_path = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (function_exists('getcwd'))
|
||||
{
|
||||
$working_directory = str_replace(DIRECTORY_SEPARATOR, '/', getcwd());
|
||||
}
|
||||
|
||||
//
|
||||
// From this point on we really just guessing
|
||||
// If chdir were called we screwed
|
||||
//
|
||||
else if (function_exists('debug_backtrace'))
|
||||
{
|
||||
$call_stack = debug_backtrace(0);
|
||||
$working_directory = str_replace(DIRECTORY_SEPARATOR, '/', dirname($call_stack[sizeof($call_stack) - 1]['file']));
|
||||
}
|
||||
else
|
||||
{
|
||||
//
|
||||
// Assuming that the working directory is phpBB root
|
||||
// we could use this as a fallback, when phpBB will use controllers
|
||||
// everywhere this will be a safe assumption
|
||||
//
|
||||
//$dir_parts = explode(DIRECTORY_SEPARATOR, __DIR__);
|
||||
//$namespace_parts = explode('\\', trim(__NAMESPACE__, '\\'));
|
||||
|
||||
//$namespace_part_count = sizeof($namespace_parts);
|
||||
|
||||
// Check if we still loading from root
|
||||
//if (array_slice($dir_parts, -$namespace_part_count) === $namespace_parts)
|
||||
//{
|
||||
// $working_directory = implode('/', array_slice($dir_parts, 0, -$namespace_part_count));
|
||||
//}
|
||||
//else
|
||||
//{
|
||||
// $working_directory = false;
|
||||
//}
|
||||
|
||||
$working_directory = false;
|
||||
}
|
||||
|
||||
if ($working_directory !== false)
|
||||
{
|
||||
$is_absolute_path = true;
|
||||
$path = $working_directory . '/' . $path;
|
||||
}
|
||||
}
|
||||
|
||||
if ($is_absolute_path)
|
||||
{
|
||||
if (defined('PHP_WINDOWS_VERSION_MAJOR'))
|
||||
{
|
||||
$path_prefix = $path[0] . ':';
|
||||
$path = substr($path, 2);
|
||||
}
|
||||
else
|
||||
{
|
||||
$path_prefix = '';
|
||||
}
|
||||
}
|
||||
|
||||
$resolved_path = self::resolve_path($path, $path_prefix, $is_absolute_path);
|
||||
if ($resolved_path === false)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!@file_exists($resolved_path) || (!@is_dir($resolved_path . '/') && !is_file($resolved_path)))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Return OS specific directory separators
|
||||
$resolved = str_replace('/', DIRECTORY_SEPARATOR, $resolved_path);
|
||||
|
||||
// Check for DIRECTORY_SEPARATOR at the end (and remove it!)
|
||||
if (substr($resolved, -1) === DIRECTORY_SEPARATOR)
|
||||
{
|
||||
return substr($resolved, 0, -1);
|
||||
}
|
||||
|
||||
return $resolved;
|
||||
}
|
||||
|
||||
/**
|
||||
* A wrapper for PHP's realpath
|
||||
*
|
||||
* Try to resolve realpath when PHP's realpath is not available, or
|
||||
* known to be buggy.
|
||||
*
|
||||
* @param string $path Path to resolve
|
||||
*
|
||||
* @return string Resolved path
|
||||
*/
|
||||
public static function realpath($path)
|
||||
{
|
||||
if (!function_exists('realpath'))
|
||||
{
|
||||
return self::phpbb_own_realpath($path);
|
||||
}
|
||||
|
||||
$realpath = realpath($path);
|
||||
|
||||
// Strangely there are provider not disabling realpath but returning strange values. :o
|
||||
// We at least try to cope with them.
|
||||
if ((!self::is_absolute_path($path) && $realpath === $path) || $realpath === false)
|
||||
{
|
||||
return self::phpbb_own_realpath($path);
|
||||
}
|
||||
|
||||
// Check for DIRECTORY_SEPARATOR at the end (and remove it!)
|
||||
if (substr($realpath, -1) === DIRECTORY_SEPARATOR)
|
||||
{
|
||||
$realpath = substr($realpath, 0, -1);
|
||||
}
|
||||
|
||||
return $realpath;
|
||||
}
|
||||
|
||||
/**
|
||||
* Given an existing path, convert it to a path relative to a given starting path
|
||||
*
|
||||
* @param string $end_path Absolute path of target
|
||||
* @param string $start_path Absolute path where traversal begins
|
||||
*
|
||||
* @return string Path of target relative to starting path
|
||||
*/
|
||||
public static function make_path_relative($end_path, $start_path)
|
||||
{
|
||||
$symfony_filesystem = new \Symfony\Component\Filesystem\Filesystem();
|
||||
return $symfony_filesystem->makePathRelative($end_path, $start_path);
|
||||
}
|
||||
|
||||
/**
|
||||
* Try to resolve symlinks in path
|
||||
*
|
||||
* @param string $path The path to resolve
|
||||
* @param string $prefix The path prefix (on windows the drive letter)
|
||||
* @param bool $absolute Whether or not the path is absolute
|
||||
* @param bool $return_array Whether or not to return path parts
|
||||
*
|
||||
* @return string|array|bool returns the resolved path or an array of parts of the path if $return_array is true
|
||||
* or false if path cannot be resolved
|
||||
*/
|
||||
protected static function resolve_path($path, $prefix = '', $absolute = false, $return_array = false)
|
||||
{
|
||||
if ($return_array)
|
||||
{
|
||||
$path = str_replace(DIRECTORY_SEPARATOR, '/', $path);
|
||||
}
|
||||
|
||||
trim ($path, '/');
|
||||
$path_parts = explode('/', $path);
|
||||
$resolved = array();
|
||||
$resolved_path = $prefix;
|
||||
$file_found = false;
|
||||
|
||||
foreach ($path_parts as $path_part)
|
||||
{
|
||||
if ($file_found)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (empty($path_part) || ($path_part === '.' && ($absolute || !empty($resolved))))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
else if ($absolute && $path_part === '..')
|
||||
{
|
||||
if (empty($resolved))
|
||||
{
|
||||
// No directories above root
|
||||
return false;
|
||||
}
|
||||
|
||||
array_pop($resolved);
|
||||
$resolved_path = false;
|
||||
}
|
||||
else if ($path_part === '..' && !empty($resolved) && !in_array($resolved[sizeof($resolved) - 1], array('.', '..')))
|
||||
{
|
||||
array_pop($resolved);
|
||||
$resolved_path = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ($resolved_path === false)
|
||||
{
|
||||
if (empty($resolved))
|
||||
{
|
||||
$resolved_path = ($absolute) ? $prefix . '/' . $path_part : $path_part;
|
||||
}
|
||||
else
|
||||
{
|
||||
$tmp_array = $resolved;
|
||||
if ($absolute)
|
||||
{
|
||||
array_unshift($tmp_array, $prefix);
|
||||
}
|
||||
|
||||
$resolved_path = implode('/', $tmp_array);
|
||||
}
|
||||
}
|
||||
|
||||
$current_path = $resolved_path . '/' . $path_part;
|
||||
|
||||
// Resolve symlinks
|
||||
if (is_link($current_path))
|
||||
{
|
||||
if (!function_exists('readlink'))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
$link = readlink($current_path);
|
||||
|
||||
// Is link has an absolute path in it?
|
||||
if (self::is_absolute_path($link))
|
||||
{
|
||||
if (defined('PHP_WINDOWS_VERSION_MAJOR'))
|
||||
{
|
||||
$prefix = $link[0] . ':';
|
||||
$link = substr($link, 2);
|
||||
}
|
||||
else
|
||||
{
|
||||
$prefix = '';
|
||||
}
|
||||
|
||||
$resolved = self::resolve_path($link, $prefix, true, true);
|
||||
$absolute = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
$resolved = self::resolve_path($resolved_path . '/' . $link, $prefix, $absolute, true);
|
||||
}
|
||||
|
||||
if (!$resolved)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
$resolved_path = false;
|
||||
}
|
||||
else if (is_dir($current_path . '/'))
|
||||
{
|
||||
$resolved[] = $path_part;
|
||||
$resolved_path = $current_path;
|
||||
}
|
||||
else if (is_file($current_path))
|
||||
{
|
||||
$resolved[] = $path_part;
|
||||
$resolved_path = $current_path;
|
||||
$file_found = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If at the end of the path there were a .. or .
|
||||
// we need to build the path again.
|
||||
// Only doing this when a string is expected in return
|
||||
if ($resolved_path === false && $return_array === false)
|
||||
{
|
||||
if (empty($resolved))
|
||||
{
|
||||
$resolved_path = ($absolute) ? $prefix . '/' : './';
|
||||
}
|
||||
else
|
||||
{
|
||||
$tmp_array = $resolved;
|
||||
if ($absolute)
|
||||
{
|
||||
array_unshift($tmp_array, $prefix);
|
||||
}
|
||||
|
||||
$resolved_path = implode('/', $tmp_array);
|
||||
}
|
||||
}
|
||||
|
||||
return ($return_array) ? $resolved : $resolved_path;
|
||||
}
|
||||
}
|
66
phpBB/phpbb/storage/storage.php
Normal file
66
phpBB/phpbb/storage/storage.php
Normal file
@ -0,0 +1,66 @@
|
||||
<?php
|
||||
/**
|
||||
*
|
||||
* This file is part of the phpBB Forum Software package.
|
||||
*
|
||||
* @copyright (c) phpBB Limited <https://www.phpbb.com>
|
||||
* @license GNU General Public License, version 2 (GPL-2.0)
|
||||
*
|
||||
* For full copyright and license information, please see
|
||||
* the docs/CREDITS.txt file.
|
||||
*
|
||||
*/
|
||||
|
||||
namespace phpbb\storage;
|
||||
|
||||
use phpbb\storage\exception\exception;
|
||||
|
||||
class storage
|
||||
{
|
||||
protected $adapter;
|
||||
|
||||
public function __construct($adapter)
|
||||
{
|
||||
$this->adapter = $adapter;
|
||||
}
|
||||
|
||||
public function put_contents($path, $content)
|
||||
{
|
||||
$this->adapter->put_contents($path, $content);
|
||||
}
|
||||
|
||||
public function get_contents($path)
|
||||
{
|
||||
$this->adapter->put_contents($path);
|
||||
}
|
||||
|
||||
public function exists($path)
|
||||
{
|
||||
return $this->adapter->exists($path);
|
||||
}
|
||||
|
||||
public function delete($path)
|
||||
{
|
||||
$this->adapter->delete($path);
|
||||
}
|
||||
|
||||
public function rename($path_orig, $path_dest)
|
||||
{
|
||||
$this->adapter->rename($path_orig, $path_dest);
|
||||
}
|
||||
|
||||
public function copy($path_orig, $path_dest)
|
||||
{
|
||||
$this->adapter->copy($path_orig, $path_dest);
|
||||
}
|
||||
|
||||
public function create_dir($path)
|
||||
{
|
||||
$this->adapter->create_dir($path);
|
||||
}
|
||||
|
||||
public function delete_dir($path)
|
||||
{
|
||||
$this->adapter->delete_dir($path);
|
||||
}
|
||||
}
|
86
tests/storage/adapter/local_test.php
Normal file
86
tests/storage/adapter/local_test.php
Normal file
@ -0,0 +1,86 @@
|
||||
<?php
|
||||
/**
|
||||
*
|
||||
* This file is part of the phpBB Forum Software package.
|
||||
*
|
||||
* @copyright (c) phpBB Limited <https://www.phpbb.com>
|
||||
* @license GNU General Public License, version 2 (GPL-2.0)
|
||||
*
|
||||
* For full copyright and license information, please see
|
||||
* the docs/CREDITS.txt file.
|
||||
*
|
||||
*/
|
||||
|
||||
class phpbb_storage_adapter_local_test extends phpbb_test_case
|
||||
{
|
||||
protected $adapter;
|
||||
|
||||
public function setUp()
|
||||
{
|
||||
parent::setUp();
|
||||
$this->adapter = new \phpbb\storage\adapter\local();
|
||||
}
|
||||
|
||||
public function tearDown()
|
||||
{
|
||||
$this->adapter = null;
|
||||
}
|
||||
|
||||
public function test_put_contents()
|
||||
{
|
||||
$this->adapter->put_contents('file.txt', 'abc');
|
||||
$this->assertTrue(file_exists('file.txt'));
|
||||
$this->assertEquals(file_get_contents('file.txt'), 'abc');
|
||||
unlink('file.txt');
|
||||
}
|
||||
|
||||
public function test_get_contents()
|
||||
{
|
||||
file_put_contents('file.txt', 'abc');
|
||||
$this->assertEquals($this->adapter->get_contents('file.txt'), 'abc');
|
||||
unlink('file.txt');
|
||||
}
|
||||
|
||||
public function test_exists()
|
||||
{
|
||||
// Exists with files
|
||||
$this->assertTrue($this->adapter->exists(__DIR__.'/local_test.php'));
|
||||
$this->assertFalse($this->adapter->exists(__DIR__.'/nonexistent_file.php'));
|
||||
// exists with directory
|
||||
$this->assertTrue($this->adapter->exists(__DIR__.'/../adapter'));
|
||||
$this->assertFalse($this->adapter->exists(__DIR__.'/../nonexistet_folder'));
|
||||
}
|
||||
|
||||
public function test_delete()
|
||||
{
|
||||
// Delete with files
|
||||
file_put_contents('file.txt', '');
|
||||
$this->assertTrue(file_exists('file.txt'));
|
||||
$this->adapter->delete('file.txt');
|
||||
$this->assertFalse(file_exists('file.txt'));
|
||||
// Delete with directories
|
||||
mkdir('path/to/dir', 0777, true);
|
||||
$this->assertTrue(file_exists('path/to/dir'));
|
||||
$this->adapter->delete('path');
|
||||
$this->assertFalse(file_exists('path/to/dir'));
|
||||
}
|
||||
|
||||
public function test_rename()
|
||||
{
|
||||
file_put_contents('file.txt', '');
|
||||
$this->adapter->rename('file.txt', 'file2.txt');
|
||||
$this->assertFalse(file_exists('file.txt'));
|
||||
$this->assertTrue(file_exists('file2.txt'));
|
||||
unlink('file2.txt');
|
||||
}
|
||||
|
||||
public function test_copy()
|
||||
{
|
||||
file_put_contents('file.txt', 'abc');
|
||||
$this->adapter->copy('file.txt', 'file2.txt');
|
||||
$this->assertEquals(file_get_contents('file.txt'), 'abc');
|
||||
$this->assertEquals(file_get_contents('file.txt'), 'abc');
|
||||
unlink('file.txt');
|
||||
unlink('file2.txt');
|
||||
}
|
||||
}
|
52
tests/storage/helper_clean_path_test.php
Normal file
52
tests/storage/helper_clean_path_test.php
Normal file
@ -0,0 +1,52 @@
|
||||
<?php
|
||||
/**
|
||||
*
|
||||
* This file is part of the phpBB Forum Software package.
|
||||
*
|
||||
* @copyright (c) phpBB Limited <https://www.phpbb.com>
|
||||
* @license GNU General Public License, version 2 (GPL-2.0)
|
||||
*
|
||||
* For full copyright and license information, please see
|
||||
* the docs/CREDITS.txt file.
|
||||
*
|
||||
*/
|
||||
|
||||
class phpbb_storage_helper_clean_path_test extends phpbb_test_case
|
||||
{
|
||||
|
||||
public function setUp()
|
||||
{
|
||||
parent::setUp();
|
||||
}
|
||||
|
||||
public function clean_path_data()
|
||||
{
|
||||
return array(
|
||||
array('foo', 'foo'),
|
||||
array('foo/bar', 'foo/bar'),
|
||||
array('foo/bar/', 'foo/bar/'),
|
||||
array('foo/./bar', 'foo/bar'),
|
||||
array('foo/./././bar', 'foo/bar'),
|
||||
array('foo/bar/.', 'foo/bar'),
|
||||
array('./foo/bar', './foo/bar'),
|
||||
array('../foo/bar', '../foo/bar'),
|
||||
array('./../foo/bar', './../foo/bar'),
|
||||
array('././../foo/bar', './../foo/bar'),
|
||||
array('one/two/three', 'one/two/three'),
|
||||
array('one/two/../three', 'one/three'),
|
||||
array('one/../two/three', 'two/three'),
|
||||
array('one/two/..', 'one'),
|
||||
array('one/two/../', 'one/'),
|
||||
array('one/two/../three/../four', 'one/four'),
|
||||
array('one/two/three/../../four', 'one/four'),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider clean_path_data
|
||||
*/
|
||||
public function test_clean_path($input, $expected)
|
||||
{
|
||||
$this->assertEquals($expected, \phpbb\storage\helper::clean_path($input));
|
||||
}
|
||||
}
|
64
tests/storage/helper_is_absolute_test.php
Normal file
64
tests/storage/helper_is_absolute_test.php
Normal file
@ -0,0 +1,64 @@
|
||||
<?php
|
||||
/**
|
||||
*
|
||||
* This file is part of the phpBB Forum Software package.
|
||||
*
|
||||
* @copyright (c) phpBB Limited <https://www.phpbb.com>
|
||||
* @license GNU General Public License, version 2 (GPL-2.0)
|
||||
*
|
||||
* For full copyright and license information, please see
|
||||
* the docs/CREDITS.txt file.
|
||||
*
|
||||
*/
|
||||
|
||||
class phpbb_storage_helper_is_absolute_test extends phpbb_test_case
|
||||
{
|
||||
|
||||
public function setUp()
|
||||
{
|
||||
parent::setUp();
|
||||
}
|
||||
|
||||
static public function is_absolute_data()
|
||||
{
|
||||
return array(
|
||||
// Empty
|
||||
array('', false),
|
||||
|
||||
// Absolute unix style
|
||||
array('/etc/phpbb', true),
|
||||
// Unix does not support \ so that is not an absolute path
|
||||
array('\etc\phpbb', false),
|
||||
|
||||
// Absolute windows style
|
||||
array('c:\windows', true),
|
||||
array('C:\Windows', true),
|
||||
array('c:/windows', true),
|
||||
array('C:/Windows', true),
|
||||
|
||||
// Executable
|
||||
array('etc/phpbb', false),
|
||||
array('explorer.exe', false),
|
||||
|
||||
// Relative subdir
|
||||
array('Windows\System32', false),
|
||||
array('Windows\System32\explorer.exe', false),
|
||||
array('Windows/System32', false),
|
||||
array('Windows/System32/explorer.exe', false),
|
||||
|
||||
// Relative updir
|
||||
array('..\Windows\System32', false),
|
||||
array('..\Windows\System32\explorer.exe', false),
|
||||
array('../Windows/System32', false),
|
||||
array('../Windows/System32/explorer.exe', false),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider is_absolute_data
|
||||
*/
|
||||
public function test_is_absolute($path, $expected)
|
||||
{
|
||||
$this->assertEquals($expected, \phpbb\storage\helper::is_absolute_path($path));
|
||||
}
|
||||
}
|
83
tests/storage/helper_realpath_test.php
Normal file
83
tests/storage/helper_realpath_test.php
Normal file
@ -0,0 +1,83 @@
|
||||
<?php
|
||||
/**
|
||||
*
|
||||
* This file is part of the phpBB Forum Software package.
|
||||
*
|
||||
* @copyright (c) phpBB Limited <https://www.phpbb.com>
|
||||
* @license GNU General Public License, version 2 (GPL-2.0)
|
||||
*
|
||||
* For full copyright and license information, please see
|
||||
* the docs/CREDITS.txt file.
|
||||
*
|
||||
*/
|
||||
|
||||
class phpbb_storage_helper_realpath_test extends phpbb_test_case
|
||||
{
|
||||
protected static $storage_helper_phpbb_own_realpath;
|
||||
|
||||
static public function setUpBeforeClass()
|
||||
{
|
||||
parent::setUpBeforeClass();
|
||||
|
||||
self::$storage_helper_phpbb_own_realpath = new ReflectionMethod('\phpbb\storage\helper', 'phpbb_own_realpath');
|
||||
self::$storage_helper_phpbb_own_realpath->setAccessible(true);
|
||||
}
|
||||
|
||||
public function setUp()
|
||||
{
|
||||
parent::setUp();
|
||||
}
|
||||
|
||||
public function realpath_resolve_absolute_without_symlinks_data()
|
||||
{
|
||||
return array(
|
||||
// Constant data
|
||||
array(__DIR__, __DIR__),
|
||||
array(__DIR__ . '/../storage/../storage', __DIR__),
|
||||
array(__DIR__ . '/././', __DIR__),
|
||||
array(__DIR__ . '/non_existent', false),
|
||||
|
||||
array(__FILE__, __FILE__),
|
||||
array(__FILE__ . '../', false),
|
||||
);
|
||||
}
|
||||
|
||||
public function realpath_resolve_relative_without_symlinks_data()
|
||||
{
|
||||
if (!function_exists('getcwd'))
|
||||
{
|
||||
return array();
|
||||
}
|
||||
|
||||
$relative_path = \phpbb\storage\helper::make_path_relative(__DIR__, getcwd());
|
||||
|
||||
return array(
|
||||
array($relative_path, __DIR__),
|
||||
array($relative_path . '../storage/../storage', __DIR__),
|
||||
array($relative_path . '././', __DIR__),
|
||||
|
||||
array($relative_path . 'helper_realpath_test.php', __FILE__),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider realpath_resolve_absolute_without_symlinks_data
|
||||
*/
|
||||
public function test_realpath_absolute_without_links($path, $expected)
|
||||
{
|
||||
$this->assertEquals($expected, self::$storage_helper_phpbb_own_realpath->invoke(null, $path));
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider realpath_resolve_relative_without_symlinks_data
|
||||
*/
|
||||
public function test_realpath_relative_without_links($path, $expected)
|
||||
{
|
||||
if (!function_exists('getcwd'))
|
||||
{
|
||||
$this->markTestSkipped('phpbb_own_realpath() cannot be tested with relative paths: getcwd is not available.');
|
||||
}
|
||||
|
||||
$this->assertEquals($expected, self::$storage_helper_phpbb_own_realpath->invoke(null, $path));
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user