Issue #2050759 by tim.plunkett, fietserwin: Move drupal_chmod and other code in file.inc to a Drupal\Core\File\FileSystem class
parent
7736ba085e
commit
fc63f5e0c4
|
@ -189,6 +189,9 @@ services:
|
||||||
factory_class: Drupal\Core\Database\Database
|
factory_class: Drupal\Core\Database\Database
|
||||||
factory_method: getConnection
|
factory_method: getConnection
|
||||||
arguments: [default]
|
arguments: [default]
|
||||||
|
file_system:
|
||||||
|
class: Drupal\Core\File\FileSystem
|
||||||
|
arguments: ['@stream_wrapper_manager', '@settings', '@logger.channel.file']
|
||||||
form_builder:
|
form_builder:
|
||||||
class: Drupal\Core\Form\FormBuilder
|
class: Drupal\Core\Form\FormBuilder
|
||||||
arguments: ['@form_validator', '@form_submitter', '@form_cache', '@module_handler', '@event_dispatcher', '@request_stack', '@class_resolver', '@theme.manager', '@?csrf_token']
|
arguments: ['@form_validator', '@form_submitter', '@form_cache', '@module_handler', '@event_dispatcher', '@request_stack', '@class_resolver', '@theme.manager', '@?csrf_token']
|
||||||
|
@ -236,6 +239,11 @@ services:
|
||||||
logger.channel.cron:
|
logger.channel.cron:
|
||||||
parent: logger.channel_base
|
parent: logger.channel_base
|
||||||
arguments: ['cron']
|
arguments: ['cron']
|
||||||
|
logger.channel.file:
|
||||||
|
class: Drupal\Core\Logger\LoggerChannel
|
||||||
|
factory_method: get
|
||||||
|
factory_service: logger.factory
|
||||||
|
arguments: ['file']
|
||||||
logger.channel.form:
|
logger.channel.form:
|
||||||
parent: logger.channel_base
|
parent: logger.channel_base
|
||||||
arguments: ['form']
|
arguments: ['form']
|
||||||
|
|
|
@ -10,20 +10,26 @@ use Drupal\Component\Utility\UrlHelper;
|
||||||
use Drupal\Component\PhpStorage\FileStorage;
|
use Drupal\Component\PhpStorage\FileStorage;
|
||||||
use Drupal\Component\Utility\Bytes;
|
use Drupal\Component\Utility\Bytes;
|
||||||
use Drupal\Component\Utility\String;
|
use Drupal\Component\Utility\String;
|
||||||
use Drupal\Core\Site\Settings;
|
use Drupal\Core\File\FileSystem;
|
||||||
use Drupal\Core\StreamWrapper\PublicStream;
|
use Drupal\Core\StreamWrapper\PublicStream;
|
||||||
use Drupal\Core\StreamWrapper\StreamWrapperInterface;
|
use Drupal\Core\StreamWrapper\StreamWrapperInterface;
|
||||||
use Drupal\Core\StreamWrapper\PrivateStream;
|
use Drupal\Core\StreamWrapper\PrivateStream;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Default mode for new directories. See drupal_chmod().
|
* Default mode for new directories. See drupal_chmod().
|
||||||
|
*
|
||||||
|
* @deprecated in Drupal 8.0.x-dev, will be removed before Drupal 9.0.0.
|
||||||
|
* Use \Drupal\Core\File\FileSystem::CHMOD_DIRECTORY.
|
||||||
*/
|
*/
|
||||||
const FILE_CHMOD_DIRECTORY = 0775;
|
const FILE_CHMOD_DIRECTORY = FileSystem::CHMOD_DIRECTORY;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Default mode for new files. See drupal_chmod().
|
* Default mode for new files. See drupal_chmod().
|
||||||
|
*
|
||||||
|
* @deprecated in Drupal 8.0.x-dev, will be removed before Drupal 9.0.0.
|
||||||
|
* Use \Drupal\Core\File\FileSystem::CHMOD_FILE.
|
||||||
*/
|
*/
|
||||||
const FILE_CHMOD_FILE = 0664;
|
const FILE_CHMOD_FILE = FileSystem::CHMOD_FILE;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @defgroup file File interface
|
* @defgroup file File interface
|
||||||
|
@ -129,40 +135,21 @@ function file_stream_wrapper_get_class($scheme) {
|
||||||
/**
|
/**
|
||||||
* Returns the scheme of a URI (e.g. a stream).
|
* Returns the scheme of a URI (e.g. a stream).
|
||||||
*
|
*
|
||||||
* @param string $uri
|
* @deprecated in Drupal 8.0.x-dev, will be removed before Drupal 9.0.0.
|
||||||
* A stream, referenced as "scheme://target" or "data:target".
|
* Use \Drupal\Core\File\FileSystem::uriScheme().
|
||||||
*
|
|
||||||
* @return string
|
|
||||||
* A string containing the name of the scheme, or FALSE if none. For example,
|
|
||||||
* the URI "public://example.txt" would return "public".
|
|
||||||
*
|
|
||||||
* @see file_uri_target()
|
|
||||||
*/
|
*/
|
||||||
function file_uri_scheme($uri) {
|
function file_uri_scheme($uri) {
|
||||||
if (preg_match('/^([\w\-]+):\/\/|^(data):/', $uri, $matches)) {
|
return \Drupal::service('file_system')->uriScheme($uri);
|
||||||
// The scheme will always be the last element in the matches array.
|
|
||||||
return array_pop($matches);
|
|
||||||
}
|
|
||||||
|
|
||||||
return FALSE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks that the scheme of a stream URI is valid.
|
* Checks that the scheme of a stream URI is valid.
|
||||||
*
|
*
|
||||||
* Confirms that there is a registered stream handler for the provided scheme
|
* @deprecated in Drupal 8.0.x-dev, will be removed before Drupal 9.0.0.
|
||||||
* and that it is callable. This is useful if you want to confirm a valid
|
* Use \Drupal\Core\File\FileSystem::validScheme().
|
||||||
* scheme without creating a new instance of the registered handler.
|
|
||||||
*
|
|
||||||
* @param string $scheme
|
|
||||||
* A URI scheme, a stream is referenced as "scheme://target".
|
|
||||||
*
|
|
||||||
* @return bool
|
|
||||||
* Returns TRUE if the string is the name of a validated stream,
|
|
||||||
* or FALSE if the scheme does not have a registered handler.
|
|
||||||
*/
|
*/
|
||||||
function file_stream_wrapper_valid_scheme($scheme) {
|
function file_stream_wrapper_valid_scheme($scheme) {
|
||||||
return $scheme && class_exists(file_stream_wrapper_get_class($scheme));
|
return \Drupal::service('file_system')->validScheme($scheme);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -957,38 +944,11 @@ function file_unmanaged_delete_recursive($path, $callback = NULL) {
|
||||||
/**
|
/**
|
||||||
* Moves an uploaded file to a new location.
|
* Moves an uploaded file to a new location.
|
||||||
*
|
*
|
||||||
* PHP's move_uploaded_file() does not properly support streams if open_basedir
|
* @deprecated in Drupal 8.0.x-dev, will be removed before Drupal 9.0.0.
|
||||||
* is enabled, so this function fills that gap.
|
* Use \Drupal\Core\File\FileSystem::moveUploadedFile().
|
||||||
*
|
|
||||||
* Compatibility: normal paths and stream wrappers.
|
|
||||||
*
|
|
||||||
* @param $filename
|
|
||||||
* The filename of the uploaded file.
|
|
||||||
* @param $uri
|
|
||||||
* A string containing the destination URI of the file.
|
|
||||||
*
|
|
||||||
* @return
|
|
||||||
* TRUE on success, or FALSE on failure.
|
|
||||||
*
|
|
||||||
* @see move_uploaded_file()
|
|
||||||
* @see http://drupal.org/node/515192
|
|
||||||
* @ingroup php_wrappers
|
|
||||||
*/
|
*/
|
||||||
function drupal_move_uploaded_file($filename, $uri) {
|
function drupal_move_uploaded_file($filename, $uri) {
|
||||||
$result = @move_uploaded_file($filename, $uri);
|
return \Drupal::service('file_system')->moveUploadedFile($filename, $uri);
|
||||||
// PHP's move_uploaded_file() does not properly support streams if
|
|
||||||
// open_basedir is enabled so if the move failed, try finding a real path and
|
|
||||||
// retry the move operation.
|
|
||||||
if (!$result) {
|
|
||||||
if ($realpath = drupal_realpath($uri)) {
|
|
||||||
$result = move_uploaded_file($filename, $realpath);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
$result = move_uploaded_file($filename, $uri);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return $result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1179,338 +1139,82 @@ function file_get_mimetype($uri, $mapping = NULL) {
|
||||||
/**
|
/**
|
||||||
* Sets the permissions on a file or directory.
|
* Sets the permissions on a file or directory.
|
||||||
*
|
*
|
||||||
* This function will use the file_chmod_directory and
|
* @deprecated in Drupal 8.0.x-dev, will be removed before Drupal 9.0.0.
|
||||||
* file_chmod_file settings for the default modes for directories
|
* Use \Drupal\Core\File\FileSystem::chmod().
|
||||||
* and uploaded/generated files. By default these will give everyone read access
|
|
||||||
* so that users accessing the files with a user account without the webserver
|
|
||||||
* group (e.g. via FTP) can read these files, and give group write permissions
|
|
||||||
* so webserver group members (e.g. a vhost account) can alter files uploaded
|
|
||||||
* and owned by the webserver.
|
|
||||||
*
|
|
||||||
* PHP's chmod does not support stream wrappers so we use our wrapper
|
|
||||||
* implementation which interfaces with chmod() by default. Contrib wrappers
|
|
||||||
* may override this behavior in their implementations as needed.
|
|
||||||
*
|
|
||||||
* @param $uri
|
|
||||||
* A string containing a URI file, or directory path.
|
|
||||||
* @param $mode
|
|
||||||
* Integer value for the permissions. Consult PHP chmod() documentation for
|
|
||||||
* more information.
|
|
||||||
*
|
|
||||||
* @return bool
|
|
||||||
* TRUE for success, FALSE in the event of an error.
|
|
||||||
*
|
|
||||||
* @ingroup php_wrappers
|
|
||||||
*/
|
*/
|
||||||
function drupal_chmod($uri, $mode = NULL) {
|
function drupal_chmod($uri, $mode = NULL) {
|
||||||
if (!isset($mode)) {
|
return \Drupal::service('file_system')->chmod($uri, $mode);
|
||||||
if (is_dir($uri)) {
|
|
||||||
$mode = Settings::get('file_chmod_directory', FILE_CHMOD_DIRECTORY);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
$mode = Settings::get('file_chmod_file', FILE_CHMOD_FILE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (@chmod($uri, $mode)) {
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
\Drupal::logger('file')->error('The file permissions could not be set on %uri.', array('%uri' => $uri));
|
|
||||||
return FALSE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Deletes a file.
|
* Deletes a file.
|
||||||
*
|
*
|
||||||
* PHP's unlink() is broken on Windows, as it can fail to remove a file
|
* @deprecated in Drupal 8.0.x-dev, will be removed before Drupal 9.0.0.
|
||||||
* when it has a read-only flag set.
|
* Use \Drupal\Core\File\FileSystem::unlink().
|
||||||
*
|
|
||||||
* @param $uri
|
|
||||||
* A URI or pathname.
|
|
||||||
* @param $context
|
|
||||||
* Refer to http://php.net/manual/ref.stream.php
|
|
||||||
*
|
|
||||||
* @return
|
|
||||||
* Boolean TRUE on success, or FALSE on failure.
|
|
||||||
*
|
|
||||||
* @see unlink()
|
|
||||||
* @ingroup php_wrappers
|
|
||||||
*/
|
*/
|
||||||
function drupal_unlink($uri, $context = NULL) {
|
function drupal_unlink($uri, $context = NULL) {
|
||||||
$scheme = file_uri_scheme($uri);
|
return \Drupal::service('file_system')->unlink($uri, $context);
|
||||||
if (!file_stream_wrapper_valid_scheme($scheme) && (substr(PHP_OS, 0, 3) == 'WIN')) {
|
|
||||||
chmod($uri, 0600);
|
|
||||||
}
|
|
||||||
if ($context) {
|
|
||||||
return unlink($uri, $context);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return unlink($uri);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Resolves the absolute filepath of a local URI or filepath.
|
* Resolves the absolute filepath of a local URI or filepath.
|
||||||
*
|
*
|
||||||
* The use of drupal_realpath() is discouraged, because it does not work for
|
* @deprecated in Drupal 8.0.x-dev, will be removed before Drupal 9.0.0.
|
||||||
* remote URIs. Except in rare cases, URIs should not be manually resolved.
|
* Use \Drupal\Core\File\FileSystem::realpath().
|
||||||
*
|
|
||||||
* Only use this function if you know that the stream wrapper in the URI uses
|
|
||||||
* the local file system, and you need to pass an absolute path to a function
|
|
||||||
* that is incompatible with stream URIs.
|
|
||||||
*
|
|
||||||
* @param string $uri
|
|
||||||
* A stream wrapper URI or a filepath, possibly including one or more symbolic
|
|
||||||
* links.
|
|
||||||
*
|
|
||||||
* @return string|false
|
|
||||||
* The absolute local filepath (with no symbolic links), or FALSE on failure.
|
|
||||||
*
|
|
||||||
* @see \Drupal\Core\StreamWrapper\StreamWrapperInterface::realpath()
|
|
||||||
* @see http://php.net/manual/function.realpath.php
|
|
||||||
* @ingroup php_wrappers
|
|
||||||
*/
|
*/
|
||||||
function drupal_realpath($uri) {
|
function drupal_realpath($uri) {
|
||||||
// If this URI is a stream, pass it off to the appropriate stream wrapper.
|
return \Drupal::service('file_system')->realpath($uri);
|
||||||
// Otherwise, attempt PHP's realpath. This allows use of drupal_realpath even
|
|
||||||
// for unmanaged files outside of the stream wrapper interface.
|
|
||||||
if ($wrapper = file_stream_wrapper_get_instance_by_uri($uri)) {
|
|
||||||
return $wrapper->realpath();
|
|
||||||
}
|
|
||||||
|
|
||||||
return realpath($uri);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the name of the directory from a given path.
|
* Gets the name of the directory from a given path.
|
||||||
*
|
*
|
||||||
* PHP's dirname() does not properly pass streams, so this function fills
|
* @deprecated in Drupal 8.0.x-dev, will be removed before Drupal 9.0.0.
|
||||||
* that gap. It is backwards compatible with normal paths and will use
|
* Use \Drupal\Core\File\FileSystem::dirname().
|
||||||
* PHP's dirname() as a fallback.
|
|
||||||
*
|
|
||||||
* Compatibility: normal paths and stream wrappers.
|
|
||||||
*
|
|
||||||
* @param $uri
|
|
||||||
* A URI or path.
|
|
||||||
*
|
|
||||||
* @return
|
|
||||||
* A string containing the directory name.
|
|
||||||
*
|
|
||||||
* @see dirname()
|
|
||||||
* @see http://drupal.org/node/515192
|
|
||||||
* @ingroup php_wrappers
|
|
||||||
*/
|
*/
|
||||||
function drupal_dirname($uri) {
|
function drupal_dirname($uri) {
|
||||||
$scheme = file_uri_scheme($uri);
|
return \Drupal::service('file_system')->dirname($uri);
|
||||||
|
|
||||||
if (file_stream_wrapper_valid_scheme($scheme)) {
|
|
||||||
return file_stream_wrapper_get_instance_by_scheme($scheme)->dirname($uri);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return dirname($uri);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the filename from a given path.
|
* Gets the filename from a given path.
|
||||||
*
|
*
|
||||||
* PHP's basename() does not properly support streams or filenames beginning
|
* @deprecated in Drupal 8.0.x-dev, will be removed before Drupal 9.0.0.
|
||||||
* with a non-US-ASCII character.
|
* Use \Drupal\Core\File\FileSystem::basename().
|
||||||
*
|
|
||||||
* @see http://bugs.php.net/bug.php?id=37738
|
|
||||||
* @see basename()
|
|
||||||
*
|
|
||||||
* @ingroup php_wrappers
|
|
||||||
*/
|
*/
|
||||||
function drupal_basename($uri, $suffix = NULL) {
|
function drupal_basename($uri, $suffix = NULL) {
|
||||||
$separators = '/';
|
return \Drupal::service('file_system')->basename($uri, $suffix);
|
||||||
if (DIRECTORY_SEPARATOR != '/') {
|
|
||||||
// For Windows OS add special separator.
|
|
||||||
$separators .= DIRECTORY_SEPARATOR;
|
|
||||||
}
|
|
||||||
// Remove right-most slashes when $uri points to directory.
|
|
||||||
$uri = rtrim($uri, $separators);
|
|
||||||
// Returns the trailing part of the $uri starting after one of the directory
|
|
||||||
// separators.
|
|
||||||
$filename = preg_match('@[^' . preg_quote($separators, '@') . ']+$@', $uri, $matches) ? $matches[0] : '';
|
|
||||||
// Cuts off a suffix from the filename.
|
|
||||||
if ($suffix) {
|
|
||||||
$filename = preg_replace('@' . preg_quote($suffix, '@') . '$@', '', $filename);
|
|
||||||
}
|
|
||||||
return $filename;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a directory, optionally creating missing components in the path to
|
* Creates a directory, optionally creating missing components in the path to
|
||||||
* the directory.
|
* the directory.
|
||||||
*
|
*
|
||||||
* When PHP's mkdir() creates a directory, the requested mode is affected by the
|
* @deprecated in Drupal 8.0.x-dev, will be removed before Drupal 9.0.0.
|
||||||
* process's umask. This function overrides the umask and sets the mode
|
* Use \Drupal\Core\File\FileSystem::mkdir().
|
||||||
* explicitly for all directory components created.
|
|
||||||
*
|
|
||||||
* @param $uri
|
|
||||||
* A URI or pathname.
|
|
||||||
* @param $mode
|
|
||||||
* Mode given to created directories. Defaults to the directory mode
|
|
||||||
* configured in the Drupal installation. It must have a leading zero.
|
|
||||||
* @param $recursive
|
|
||||||
* Create directories recursively, defaults to FALSE. Cannot work with a mode
|
|
||||||
* which denies writing or execution to the owner of the process.
|
|
||||||
* @param $context
|
|
||||||
* Refer to http://php.net/manual/ref.stream.php
|
|
||||||
*
|
|
||||||
* @return
|
|
||||||
* Boolean TRUE on success, or FALSE on failure.
|
|
||||||
*
|
|
||||||
* @see mkdir()
|
|
||||||
* @see http://drupal.org/node/515192
|
|
||||||
* @ingroup php_wrappers
|
|
||||||
*
|
|
||||||
* @todo Update with open_basedir compatible recursion logic from
|
|
||||||
* \Drupal\Component\PhpStorage\FileStorage::ensureDirectory().
|
|
||||||
*/
|
*/
|
||||||
function drupal_mkdir($uri, $mode = NULL, $recursive = FALSE, $context = NULL) {
|
function drupal_mkdir($uri, $mode = NULL, $recursive = FALSE, $context = NULL) {
|
||||||
if (!isset($mode)) {
|
return \Drupal::service('file_system')->mkdir($uri, $mode, $recursive, $context);
|
||||||
$mode = Settings::get('file_chmod_directory', FILE_CHMOD_DIRECTORY);
|
|
||||||
}
|
|
||||||
|
|
||||||
// If the URI has a scheme, don't override the umask - schemes can handle this
|
|
||||||
// issue in their own implementation.
|
|
||||||
if (file_uri_scheme($uri)) {
|
|
||||||
return _drupal_mkdir_call($uri, $mode, $recursive, $context);
|
|
||||||
}
|
|
||||||
|
|
||||||
// If recursive, create each missing component of the parent directory
|
|
||||||
// individually and set the mode explicitly to override the umask.
|
|
||||||
if ($recursive) {
|
|
||||||
// Ensure the path is using DIRECTORY_SEPARATOR.
|
|
||||||
$uri = str_replace('/', DIRECTORY_SEPARATOR, $uri);
|
|
||||||
// Determine the components of the path.
|
|
||||||
$components = explode(DIRECTORY_SEPARATOR, $uri);
|
|
||||||
// If the filepath is absolute the first component will be empty as there
|
|
||||||
// will be nothing before the first slash.
|
|
||||||
if ($components[0] == '') {
|
|
||||||
$recursive_path = DIRECTORY_SEPARATOR;
|
|
||||||
// Get rid of the empty first component.
|
|
||||||
array_shift($components);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
$recursive_path = '';
|
|
||||||
}
|
|
||||||
// Don't handle the top-level directory in this loop.
|
|
||||||
array_pop($components);
|
|
||||||
// Create each component if necessary.
|
|
||||||
foreach ($components as $component) {
|
|
||||||
$recursive_path .= $component;
|
|
||||||
|
|
||||||
if (!file_exists($recursive_path)) {
|
|
||||||
if (!_drupal_mkdir_call($recursive_path, $mode, FALSE, $context)) {
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
// Not necessary to use drupal_chmod() as there is no scheme.
|
|
||||||
if (!chmod($recursive_path, $mode)) {
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$recursive_path .= DIRECTORY_SEPARATOR;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Do not check if the top-level directory already exists, as this condition
|
|
||||||
// must cause this function to fail.
|
|
||||||
if (!_drupal_mkdir_call($uri, $mode, FALSE, $context)) {
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
// Not necessary to use drupal_chmod() as there is no scheme.
|
|
||||||
return chmod($uri, $mode);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Helper function. Ensures we don't pass a NULL as a context resource to
|
|
||||||
* mkdir().
|
|
||||||
*
|
|
||||||
* @see drupal_mkdir()
|
|
||||||
*/
|
|
||||||
function _drupal_mkdir_call($uri, $mode, $recursive, $context) {
|
|
||||||
if (is_null($context)) {
|
|
||||||
return mkdir($uri, $mode, $recursive);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return mkdir($uri, $mode, $recursive, $context);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Removes a directory.
|
* Removes a directory.
|
||||||
*
|
*
|
||||||
* PHP's rmdir() is broken on Windows, as it can fail to remove a directory
|
* @deprecated in Drupal 8.0.x-dev, will be removed before Drupal 9.0.0.
|
||||||
* when it has a read-only flag set.
|
* Use \Drupal\Core\File\FileSystem::rmdir().
|
||||||
*
|
|
||||||
* @param $uri
|
|
||||||
* A URI or pathname.
|
|
||||||
* @param $context
|
|
||||||
* Refer to http://php.net/manual/ref.stream.php
|
|
||||||
*
|
|
||||||
* @return
|
|
||||||
* Boolean TRUE on success, or FALSE on failure.
|
|
||||||
*
|
|
||||||
* @see rmdir()
|
|
||||||
* @ingroup php_wrappers
|
|
||||||
*/
|
*/
|
||||||
function drupal_rmdir($uri, $context = NULL) {
|
function drupal_rmdir($uri, $context = NULL) {
|
||||||
$scheme = file_uri_scheme($uri);
|
return \Drupal::service('file_system')->rmdir($uri, $context);
|
||||||
if (!file_stream_wrapper_valid_scheme($scheme) && (substr(PHP_OS, 0, 3) == 'WIN')) {
|
|
||||||
chmod($uri, 0700);
|
|
||||||
}
|
|
||||||
if ($context) {
|
|
||||||
return rmdir($uri, $context);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return rmdir($uri);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a file with a unique filename in the specified directory.
|
* Creates a file with a unique filename in the specified directory.
|
||||||
*
|
*
|
||||||
* PHP's tempnam() does not return a URI like we want. This function
|
* @deprecated in Drupal 8.0.x-dev, will be removed before Drupal 9.0.0.
|
||||||
* will return a URI if given a URI, or it will return a filepath if
|
* Use \Drupal\Core\File\FileSystem::tempnam().
|
||||||
* given a filepath.
|
|
||||||
*
|
|
||||||
* Compatibility: normal paths and stream wrappers.
|
|
||||||
*
|
|
||||||
* @param $directory
|
|
||||||
* The directory where the temporary filename will be created.
|
|
||||||
* @param $prefix
|
|
||||||
* The prefix of the generated temporary filename.
|
|
||||||
* Note: Windows uses only the first three characters of prefix.
|
|
||||||
*
|
|
||||||
* @return
|
|
||||||
* The new temporary filename, or FALSE on failure.
|
|
||||||
*
|
|
||||||
* @see tempnam()
|
|
||||||
* @see http://drupal.org/node/515192
|
|
||||||
* @ingroup php_wrappers
|
|
||||||
*/
|
*/
|
||||||
function drupal_tempnam($directory, $prefix) {
|
function drupal_tempnam($directory, $prefix) {
|
||||||
$scheme = file_uri_scheme($directory);
|
return \Drupal::service('file_system')->tempnam($directory, $prefix);
|
||||||
|
|
||||||
if (file_stream_wrapper_valid_scheme($scheme)) {
|
|
||||||
$wrapper = file_stream_wrapper_get_instance_by_scheme($scheme);
|
|
||||||
|
|
||||||
if ($filename = tempnam($wrapper->getDirectoryPath(), $prefix)) {
|
|
||||||
return $scheme . '://' . drupal_basename($filename);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// Handle as a normal tempnam() call.
|
|
||||||
return tempnam($directory, $prefix);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -14,6 +14,7 @@ use Drupal\Core\Installer\Exception\NoProfilesException;
|
||||||
use Drupal\Core\Installer\InstallerKernel;
|
use Drupal\Core\Installer\InstallerKernel;
|
||||||
use Drupal\Core\Language\Language;
|
use Drupal\Core\Language\Language;
|
||||||
use Drupal\Core\Language\LanguageManager;
|
use Drupal\Core\Language\LanguageManager;
|
||||||
|
use Drupal\Core\Logger\LoggerChannelFactory;
|
||||||
use Drupal\Core\Site\Settings;
|
use Drupal\Core\Site\Settings;
|
||||||
use Drupal\Core\StringTranslation\Translator\FileTranslation;
|
use Drupal\Core\StringTranslation\Translator\FileTranslation;
|
||||||
use Drupal\Core\Extension\ExtensionDiscovery;
|
use Drupal\Core\Extension\ExtensionDiscovery;
|
||||||
|
@ -343,8 +344,12 @@ function install_begin_request($class_loader, &$install_state) {
|
||||||
// Register the stream wrapper manager.
|
// Register the stream wrapper manager.
|
||||||
$container
|
$container
|
||||||
->register('stream_wrapper_manager', 'Drupal\Core\StreamWrapper\StreamWrapperManager')
|
->register('stream_wrapper_manager', 'Drupal\Core\StreamWrapper\StreamWrapperManager')
|
||||||
->addArgument(new Reference('module_handler'))
|
|
||||||
->addMethodCall('setContainer', array(new Reference('service_container')));
|
->addMethodCall('setContainer', array(new Reference('service_container')));
|
||||||
|
$container
|
||||||
|
->register('file_system', 'Drupal\Core\File\FileSystem')
|
||||||
|
->addArgument(new Reference('stream_wrapper_manager'))
|
||||||
|
->addArgument(Settings::getInstance())
|
||||||
|
->addArgument((new LoggerChannelFactory())->get('file'));
|
||||||
|
|
||||||
\Drupal::setContainer($container);
|
\Drupal::setContainer($container);
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,307 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @file
|
||||||
|
* Contains \Drupal\Core\File\FileSystem.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Drupal\Core\File;
|
||||||
|
|
||||||
|
use Drupal\Core\Site\Settings;
|
||||||
|
use Drupal\Core\StreamWrapper\StreamWrapperManagerInterface;
|
||||||
|
use Psr\Log\LoggerInterface;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides helpers to operate on files and stream wrappers.
|
||||||
|
*/
|
||||||
|
class FileSystem implements FileSystemInterface {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Default mode for new directories. See self::chmod().
|
||||||
|
*/
|
||||||
|
const CHMOD_DIRECTORY = 0775;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Default mode for new files. See self::chmod().
|
||||||
|
*/
|
||||||
|
const CHMOD_FILE = 0664;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The site settings.
|
||||||
|
*
|
||||||
|
* @var \Drupal\Core\Site\Settings
|
||||||
|
*/
|
||||||
|
protected $settings;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The file logger channel.
|
||||||
|
*
|
||||||
|
* @var \Psr\Log\LoggerInterface
|
||||||
|
*/
|
||||||
|
protected $logger;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The stream wrapper manager.
|
||||||
|
*
|
||||||
|
* @var \Drupal\Core\StreamWrapper\StreamWrapperManagerInterface
|
||||||
|
*/
|
||||||
|
protected $streamWrapperManager;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs a new FileSystem.
|
||||||
|
*
|
||||||
|
* @param \Drupal\Core\StreamWrapper\StreamWrapperManagerInterface $stream_wrapper_manager
|
||||||
|
* The stream wrapper manager.
|
||||||
|
* @param \Drupal\Core\Site\Settings $settings
|
||||||
|
* The site settings.
|
||||||
|
* @param \Psr\Log\LoggerInterface $logger
|
||||||
|
* The file logger channel.
|
||||||
|
*/
|
||||||
|
public function __construct(StreamWrapperManagerInterface $stream_wrapper_manager, Settings $settings, LoggerInterface $logger) {
|
||||||
|
$this->streamWrapperManager = $stream_wrapper_manager;
|
||||||
|
$this->settings = $settings;
|
||||||
|
$this->logger = $logger;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function moveUploadedFile($filename, $uri) {
|
||||||
|
$result = @move_uploaded_file($filename, $uri);
|
||||||
|
// PHP's move_uploaded_file() does not properly support streams if
|
||||||
|
// open_basedir is enabled so if the move failed, try finding a real path
|
||||||
|
// and retry the move operation.
|
||||||
|
if (!$result) {
|
||||||
|
if ($realpath = $this->realpath($uri)) {
|
||||||
|
$result = move_uploaded_file($filename, $realpath);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$result = move_uploaded_file($filename, $uri);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function chmod($uri, $mode = NULL) {
|
||||||
|
if (!isset($mode)) {
|
||||||
|
if (is_dir($uri)) {
|
||||||
|
$mode = $this->settings->get('file_chmod_directory', static::CHMOD_DIRECTORY);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$mode = $this->settings->get('file_chmod_file', static::CHMOD_FILE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (@chmod($uri, $mode)) {
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->logger->error('The file permissions could not be set on %uri.', array('%uri' => $uri));
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function unlink($uri, $context = NULL) {
|
||||||
|
$scheme = $this->uriScheme($uri);
|
||||||
|
if (!$this->validScheme($scheme) && (substr(PHP_OS, 0, 3) == 'WIN')) {
|
||||||
|
chmod($uri, 0600);
|
||||||
|
}
|
||||||
|
if ($context) {
|
||||||
|
return unlink($uri, $context);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return unlink($uri);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function realpath($uri) {
|
||||||
|
// If this URI is a stream, pass it off to the appropriate stream wrapper.
|
||||||
|
// Otherwise, attempt PHP's realpath. This allows use of this method even
|
||||||
|
// for unmanaged files outside of the stream wrapper interface.
|
||||||
|
if ($wrapper = $this->streamWrapperManager->getViaUri($uri)) {
|
||||||
|
return $wrapper->realpath();
|
||||||
|
}
|
||||||
|
|
||||||
|
return realpath($uri);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function dirname($uri) {
|
||||||
|
$scheme = $this->uriScheme($uri);
|
||||||
|
|
||||||
|
if ($this->validScheme($scheme)) {
|
||||||
|
return $this->streamWrapperManager->getViaScheme($scheme)->dirname($uri);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return dirname($uri);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function basename($uri, $suffix = NULL) {
|
||||||
|
$separators = '/';
|
||||||
|
if (DIRECTORY_SEPARATOR != '/') {
|
||||||
|
// For Windows OS add special separator.
|
||||||
|
$separators .= DIRECTORY_SEPARATOR;
|
||||||
|
}
|
||||||
|
// Remove right-most slashes when $uri points to directory.
|
||||||
|
$uri = rtrim($uri, $separators);
|
||||||
|
// Returns the trailing part of the $uri starting after one of the directory
|
||||||
|
// separators.
|
||||||
|
$filename = preg_match('@[^' . preg_quote($separators, '@') . ']+$@', $uri, $matches) ? $matches[0] : '';
|
||||||
|
// Cuts off a suffix from the filename.
|
||||||
|
if ($suffix) {
|
||||||
|
$filename = preg_replace('@' . preg_quote($suffix, '@') . '$@', '', $filename);
|
||||||
|
}
|
||||||
|
return $filename;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function mkdir($uri, $mode = NULL, $recursive = FALSE, $context = NULL) {
|
||||||
|
if (!isset($mode)) {
|
||||||
|
$mode = $this->settings->get('file_chmod_directory', static::CHMOD_DIRECTORY);
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the URI has a scheme, don't override the umask - schemes can handle
|
||||||
|
// this issue in their own implementation.
|
||||||
|
if ($this->uriScheme($uri)) {
|
||||||
|
return $this->mkdirCall($uri, $mode, $recursive, $context);
|
||||||
|
}
|
||||||
|
|
||||||
|
// If recursive, create each missing component of the parent directory
|
||||||
|
// individually and set the mode explicitly to override the umask.
|
||||||
|
if ($recursive) {
|
||||||
|
// Ensure the path is using DIRECTORY_SEPARATOR.
|
||||||
|
$uri = str_replace('/', DIRECTORY_SEPARATOR, $uri);
|
||||||
|
// Determine the components of the path.
|
||||||
|
$components = explode(DIRECTORY_SEPARATOR, $uri);
|
||||||
|
// If the filepath is absolute the first component will be empty as there
|
||||||
|
// will be nothing before the first slash.
|
||||||
|
if ($components[0] == '') {
|
||||||
|
$recursive_path = DIRECTORY_SEPARATOR;
|
||||||
|
// Get rid of the empty first component.
|
||||||
|
array_shift($components);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$recursive_path = '';
|
||||||
|
}
|
||||||
|
// Don't handle the top-level directory in this loop.
|
||||||
|
array_pop($components);
|
||||||
|
// Create each component if necessary.
|
||||||
|
foreach ($components as $component) {
|
||||||
|
$recursive_path .= $component;
|
||||||
|
|
||||||
|
if (!file_exists($recursive_path)) {
|
||||||
|
if (!$this->mkdirCall($recursive_path, $mode, FALSE, $context)) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
// Not necessary to use self::chmod() as there is no scheme.
|
||||||
|
if (!chmod($recursive_path, $mode)) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$recursive_path .= DIRECTORY_SEPARATOR;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Do not check if the top-level directory already exists, as this condition
|
||||||
|
// must cause this function to fail.
|
||||||
|
if (!$this->mkdirCall($uri, $mode, FALSE, $context)) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
// Not necessary to use self::chmod() as there is no scheme.
|
||||||
|
return chmod($uri, $mode);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper function. Ensures we don't pass a NULL as a context resource to
|
||||||
|
* mkdir().
|
||||||
|
*
|
||||||
|
* @see self::mkdir()
|
||||||
|
*/
|
||||||
|
protected function mkdirCall($uri, $mode, $recursive, $context) {
|
||||||
|
if (is_null($context)) {
|
||||||
|
return mkdir($uri, $mode, $recursive);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return mkdir($uri, $mode, $recursive, $context);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function rmdir($uri, $context = NULL) {
|
||||||
|
$scheme = $this->uriScheme($uri);
|
||||||
|
if (!$this->validScheme($scheme) && (substr(PHP_OS, 0, 3) == 'WIN')) {
|
||||||
|
chmod($uri, 0700);
|
||||||
|
}
|
||||||
|
if ($context) {
|
||||||
|
return rmdir($uri, $context);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return rmdir($uri);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function tempnam($directory, $prefix) {
|
||||||
|
$scheme = $this->uriScheme($directory);
|
||||||
|
|
||||||
|
if ($this->validScheme($scheme)) {
|
||||||
|
$wrapper = $this->streamWrapperManager->getViaScheme($scheme);
|
||||||
|
|
||||||
|
if ($filename = tempnam($wrapper->getDirectoryPath(), $prefix)) {
|
||||||
|
return $scheme . '://' . static::basename($filename);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// Handle as a normal tempnam() call.
|
||||||
|
return tempnam($directory, $prefix);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function uriScheme($uri) {
|
||||||
|
if (preg_match('/^([\w\-]+):\/\/|^(data):/', $uri, $matches)) {
|
||||||
|
// The scheme will always be the last element in the matches array.
|
||||||
|
return array_pop($matches);
|
||||||
|
}
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function validScheme($scheme) {
|
||||||
|
if (!$scheme) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
return class_exists($this->streamWrapperManager->getClass($scheme));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,245 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @file
|
||||||
|
* Contains \Drupal\Core\File\FileSystemInterface.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Drupal\Core\File;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides an interface for helpers that operate on files and stream wrappers.
|
||||||
|
*/
|
||||||
|
interface FileSystemInterface {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Moves an uploaded file to a new location.
|
||||||
|
*
|
||||||
|
* PHP's move_uploaded_file() does not properly support streams if
|
||||||
|
* open_basedir is enabled, so this function fills that gap.
|
||||||
|
*
|
||||||
|
* Compatibility: normal paths and stream wrappers.
|
||||||
|
*
|
||||||
|
* @param string $filename
|
||||||
|
* The filename of the uploaded file.
|
||||||
|
* @param string $uri
|
||||||
|
* A string containing the destination URI of the file.
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
* TRUE on success, or FALSE on failure.
|
||||||
|
*
|
||||||
|
* @see move_uploaded_file()
|
||||||
|
* @see http://drupal.org/node/515192
|
||||||
|
* @ingroup php_wrappers
|
||||||
|
*/
|
||||||
|
public function moveUploadedFile($filename, $uri);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the permissions on a file or directory.
|
||||||
|
*
|
||||||
|
* This function will use the file_chmod_directory and
|
||||||
|
* file_chmod_file settings for the default modes for directories
|
||||||
|
* and uploaded/generated files. By default these will give everyone read
|
||||||
|
* access so that users accessing the files with a user account without the
|
||||||
|
* webserver group (e.g. via FTP) can read these files, and give group write
|
||||||
|
* permissions so webserver group members (e.g. a vhost account) can alter
|
||||||
|
* files uploaded and owned by the webserver.
|
||||||
|
*
|
||||||
|
* PHP's chmod does not support stream wrappers so we use our wrapper
|
||||||
|
* implementation which interfaces with chmod() by default. Contrib wrappers
|
||||||
|
* may override this behavior in their implementations as needed.
|
||||||
|
*
|
||||||
|
* @param string $uri
|
||||||
|
* A string containing a URI file, or directory path.
|
||||||
|
* @param int $mode
|
||||||
|
* Integer value for the permissions. Consult PHP chmod() documentation for
|
||||||
|
* more information.
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
* TRUE for success, FALSE in the event of an error.
|
||||||
|
*
|
||||||
|
* @ingroup php_wrappers
|
||||||
|
*/
|
||||||
|
public function chmod($uri, $mode = NULL);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deletes a file.
|
||||||
|
*
|
||||||
|
* PHP's unlink() is broken on Windows, as it can fail to remove a file when
|
||||||
|
* it has a read-only flag set.
|
||||||
|
*
|
||||||
|
* @param string $uri
|
||||||
|
* A URI or pathname.
|
||||||
|
* @param resource $context
|
||||||
|
* Refer to http://php.net/manual/ref.stream.php
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
* Boolean TRUE on success, or FALSE on failure.
|
||||||
|
*
|
||||||
|
* @see unlink()
|
||||||
|
* @ingroup php_wrappers
|
||||||
|
*/
|
||||||
|
public function unlink($uri, $context = NULL);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Resolves the absolute filepath of a local URI or filepath.
|
||||||
|
*
|
||||||
|
* The use of this method is discouraged, because it does not work for
|
||||||
|
* remote URIs. Except in rare cases, URIs should not be manually resolved.
|
||||||
|
*
|
||||||
|
* Only use this function if you know that the stream wrapper in the URI uses
|
||||||
|
* the local file system, and you need to pass an absolute path to a function
|
||||||
|
* that is incompatible with stream URIs.
|
||||||
|
*
|
||||||
|
* @param string $uri
|
||||||
|
* A stream wrapper URI or a filepath, possibly including one or more
|
||||||
|
* symbolic links.
|
||||||
|
*
|
||||||
|
* @return string|false
|
||||||
|
* The absolute local filepath (with no symbolic links) or FALSE on failure.
|
||||||
|
*
|
||||||
|
* @see \Drupal\Core\StreamWrapper\StreamWrapperInterface::realpath()
|
||||||
|
* @see http://php.net/manual/function.realpath.php
|
||||||
|
* @ingroup php_wrappers
|
||||||
|
*/
|
||||||
|
public function realpath($uri);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the name of the directory from a given path.
|
||||||
|
*
|
||||||
|
* PHP's dirname() does not properly pass streams, so this function fills that
|
||||||
|
* gap. It is backwards compatible with normal paths and will use PHP's
|
||||||
|
* dirname() as a fallback.
|
||||||
|
*
|
||||||
|
* Compatibility: normal paths and stream wrappers.
|
||||||
|
*
|
||||||
|
* @param string $uri
|
||||||
|
* A URI or path.
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
* A string containing the directory name.
|
||||||
|
*
|
||||||
|
* @see dirname()
|
||||||
|
* @see http://drupal.org/node/515192
|
||||||
|
* @ingroup php_wrappers
|
||||||
|
*/
|
||||||
|
public function dirname($uri);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the filename from a given path.
|
||||||
|
*
|
||||||
|
* PHP's basename() does not properly support streams or filenames beginning
|
||||||
|
* with a non-US-ASCII character.
|
||||||
|
*
|
||||||
|
* @see http://bugs.php.net/bug.php?id=37738
|
||||||
|
* @see basename()
|
||||||
|
*
|
||||||
|
* @ingroup php_wrappers
|
||||||
|
*/
|
||||||
|
public function basename($uri, $suffix = NULL);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a directory, optionally creating missing components in the path to
|
||||||
|
* the directory.
|
||||||
|
*
|
||||||
|
* When PHP's mkdir() creates a directory, the requested mode is affected by
|
||||||
|
* the process's umask. This function overrides the umask and sets the mode
|
||||||
|
* explicitly for all directory components created.
|
||||||
|
*
|
||||||
|
* @param string $uri
|
||||||
|
* A URI or pathname.
|
||||||
|
* @param int $mode
|
||||||
|
* Mode given to created directories. Defaults to the directory mode
|
||||||
|
* configured in the Drupal installation. It must have a leading zero.
|
||||||
|
* @param bool $recursive
|
||||||
|
* Create directories recursively, defaults to FALSE. Cannot work with a
|
||||||
|
* mode which denies writing or execution to the owner of the process.
|
||||||
|
* @param resource $context
|
||||||
|
* Refer to http://php.net/manual/ref.stream.php
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
* Boolean TRUE on success, or FALSE on failure.
|
||||||
|
*
|
||||||
|
* @see mkdir()
|
||||||
|
* @see http://drupal.org/node/515192
|
||||||
|
* @ingroup php_wrappers
|
||||||
|
*
|
||||||
|
* @todo Update with open_basedir compatible recursion logic from
|
||||||
|
* \Drupal\Component\PhpStorage\FileStorage::ensureDirectory().
|
||||||
|
*/
|
||||||
|
public function mkdir($uri, $mode = NULL, $recursive = FALSE, $context = NULL);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes a directory.
|
||||||
|
*
|
||||||
|
* PHP's rmdir() is broken on Windows, as it can fail to remove a directory
|
||||||
|
* when it has a read-only flag set.
|
||||||
|
*
|
||||||
|
* @param string $uri
|
||||||
|
* A URI or pathname.
|
||||||
|
* @param resource $context
|
||||||
|
* Refer to http://php.net/manual/ref.stream.php
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
* Boolean TRUE on success, or FALSE on failure.
|
||||||
|
*
|
||||||
|
* @see rmdir()
|
||||||
|
* @ingroup php_wrappers
|
||||||
|
*/
|
||||||
|
public function rmdir($uri, $context = NULL);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a file with a unique filename in the specified directory.
|
||||||
|
*
|
||||||
|
* PHP's tempnam() does not return a URI like we want. This function will
|
||||||
|
* return a URI if given a URI, or it will return a filepath if given a
|
||||||
|
* filepath.
|
||||||
|
*
|
||||||
|
* Compatibility: normal paths and stream wrappers.
|
||||||
|
*
|
||||||
|
* @param string $directory
|
||||||
|
* The directory where the temporary filename will be created.
|
||||||
|
* @param string $prefix
|
||||||
|
* The prefix of the generated temporary filename.
|
||||||
|
* Note: Windows uses only the first three characters of prefix.
|
||||||
|
*
|
||||||
|
* @return string|bool
|
||||||
|
* The new temporary filename, or FALSE on failure.
|
||||||
|
*
|
||||||
|
* @see tempnam()
|
||||||
|
* @see http://drupal.org/node/515192
|
||||||
|
* @ingroup php_wrappers
|
||||||
|
*/
|
||||||
|
public function tempnam($directory, $prefix);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the scheme of a URI (e.g. a stream).
|
||||||
|
*
|
||||||
|
* @param string $uri
|
||||||
|
* A stream, referenced as "scheme://target" or "data:target".
|
||||||
|
*
|
||||||
|
* @return string|bool
|
||||||
|
* A string containing the name of the scheme, or FALSE if none. For
|
||||||
|
* example, the URI "public://example.txt" would return "public".
|
||||||
|
*
|
||||||
|
* @see file_uri_target()
|
||||||
|
*/
|
||||||
|
public function uriScheme($uri);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks that the scheme of a stream URI is valid.
|
||||||
|
*
|
||||||
|
* Confirms that there is a registered stream handler for the provided scheme
|
||||||
|
* and that it is callable. This is useful if you want to confirm a valid
|
||||||
|
* scheme without creating a new instance of the registered handler.
|
||||||
|
*
|
||||||
|
* @param string $scheme
|
||||||
|
* A URI scheme, a stream is referenced as "scheme://target".
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
* Returns TRUE if the string is the name of a validated stream, or FALSE if
|
||||||
|
* the scheme does not have a registered handler.
|
||||||
|
*/
|
||||||
|
public function validScheme($scheme);
|
||||||
|
|
||||||
|
}
|
|
@ -7,7 +7,6 @@
|
||||||
|
|
||||||
namespace Drupal\Core\StreamWrapper;
|
namespace Drupal\Core\StreamWrapper;
|
||||||
|
|
||||||
use Drupal\Core\Extension\ModuleHandlerInterface;
|
|
||||||
use Symfony\Component\DependencyInjection\ContainerAware;
|
use Symfony\Component\DependencyInjection\ContainerAware;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -16,7 +15,7 @@ use Symfony\Component\DependencyInjection\ContainerAware;
|
||||||
* @see file_get_stream_wrappers()
|
* @see file_get_stream_wrappers()
|
||||||
* @see \Drupal\Core\StreamWrapper\StreamWrapperInterface
|
* @see \Drupal\Core\StreamWrapper\StreamWrapperInterface
|
||||||
*/
|
*/
|
||||||
class StreamWrapperManager extends ContainerAware {
|
class StreamWrapperManager extends ContainerAware implements StreamWrapperManagerInterface {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Contains stream wrapper info.
|
* Contains stream wrapper info.
|
||||||
|
@ -48,57 +47,7 @@ class StreamWrapperManager extends ContainerAware {
|
||||||
protected $wrappers = array();
|
protected $wrappers = array();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides Drupal stream wrapper registry.
|
* {@inheritdoc}
|
||||||
*
|
|
||||||
* A stream wrapper is an abstraction of a file system that allows Drupal to
|
|
||||||
* use the same set of methods to access both local files and remote
|
|
||||||
* resources.
|
|
||||||
*
|
|
||||||
* Provide a facility for managing and querying user-defined stream wrappers
|
|
||||||
* in PHP. PHP's internal stream_get_wrappers() doesn't return the class
|
|
||||||
* registered to handle a stream, which we need to be able to find the handler
|
|
||||||
* for class instantiation.
|
|
||||||
*
|
|
||||||
* If a module registers a scheme that is already registered with PHP, the
|
|
||||||
* existing scheme will be unregistered and replaced with the specified class.
|
|
||||||
*
|
|
||||||
* A stream is referenced as "scheme://target".
|
|
||||||
*
|
|
||||||
* The optional $filter parameter can be used to retrieve only the stream
|
|
||||||
* wrappers that are appropriate for particular usage. For example, this
|
|
||||||
* returns only stream wrappers that use local file storage:
|
|
||||||
*
|
|
||||||
* @code
|
|
||||||
* $local_stream_wrappers = file_get_stream_wrappers(StreamWrapperInterface::LOCAL);
|
|
||||||
* @endcode
|
|
||||||
*
|
|
||||||
* The $filter parameter can only filter to types containing a particular
|
|
||||||
* flag. In some cases, you may want to filter to types that do not contain a
|
|
||||||
* particular flag. For example, you may want to retrieve all stream wrappers
|
|
||||||
* that are not writable, or all stream wrappers that are not local. PHP's
|
|
||||||
* array_diff_key() function can be used to help with this. For example, this
|
|
||||||
* returns only stream wrappers that do not use local file storage:
|
|
||||||
* @code
|
|
||||||
* $remote_stream_wrappers = array_diff_key(file_get_stream_wrappers(StreamWrapperInterface::ALL), file_get_stream_wrappers(StreamWrapperInterface::LOCAL));
|
|
||||||
* @endcode
|
|
||||||
*
|
|
||||||
* @param int $filter
|
|
||||||
* (Optional) Filters out all types except those with an on bit for each on
|
|
||||||
* bit in $filter. For example, if $filter is
|
|
||||||
* StreamWrapperInterface::WRITE_VISIBLE, which is equal to
|
|
||||||
* (StreamWrapperInterface::READ | StreamWrapperInterface::WRITE |
|
|
||||||
* StreamWrapperInterface::VISIBLE), then only stream wrappers with all
|
|
||||||
* three of these bits set are returned. Defaults to
|
|
||||||
* StreamWrapperInterface::ALL, which returns all registered stream
|
|
||||||
* wrappers.
|
|
||||||
*
|
|
||||||
* @return array
|
|
||||||
* An array keyed by scheme, with values containing an array of information
|
|
||||||
* about the stream wrapper, as returned by hook_stream_wrappers(). If
|
|
||||||
* $filter is omitted or set to StreamWrapperInterface::ALL, the entire
|
|
||||||
* Drupal stream wrapper registry is returned. Otherwise only the stream
|
|
||||||
* wrappers whose 'type' bitmask has an on bit for each bit specified in
|
|
||||||
* $filter are returned.
|
|
||||||
*/
|
*/
|
||||||
public function getWrappers($filter = StreamWrapperInterface::ALL) {
|
public function getWrappers($filter = StreamWrapperInterface::ALL) {
|
||||||
if (isset($this->wrappers[$filter])) {
|
if (isset($this->wrappers[$filter])) {
|
||||||
|
@ -120,20 +69,7 @@ class StreamWrapperManager extends ContainerAware {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns registered stream wrapper names.
|
* {@inheritdoc}
|
||||||
*
|
|
||||||
* @param int $filter
|
|
||||||
* (Optional) Filters out all types except those with an on bit for each on
|
|
||||||
* bit in $filter. For example, if $filter is
|
|
||||||
* StreamWrapperInterface::WRITE_VISIBLE, which is equal to
|
|
||||||
* (StreamWrapperInterface::READ | StreamWrapperInterface::WRITE |
|
|
||||||
* StreamWrapperInterface::VISIBLE), then only stream wrappers with all
|
|
||||||
* three of these bits set are returned. Defaults to
|
|
||||||
* StreamWrapperInterface::ALL, which returns all registered stream
|
|
||||||
* wrappers.
|
|
||||||
*
|
|
||||||
* @return array
|
|
||||||
* Stream wrapper names, keyed by scheme.
|
|
||||||
*/
|
*/
|
||||||
public function getNames($filter = StreamWrapperInterface::ALL) {
|
public function getNames($filter = StreamWrapperInterface::ALL) {
|
||||||
$names = array();
|
$names = array();
|
||||||
|
@ -145,20 +81,7 @@ class StreamWrapperManager extends ContainerAware {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns registered stream wrapper descriptions.
|
* {@inheritdoc}
|
||||||
*
|
|
||||||
* @param int $filter
|
|
||||||
* (Optional) Filters out all types except those with an on bit for each on
|
|
||||||
* bit in $filter. For example, if $filter is
|
|
||||||
* StreamWrapperInterface::WRITE_VISIBLE, which is equal to
|
|
||||||
* (StreamWrapperInterface::READ | StreamWrapperInterface::WRITE |
|
|
||||||
* StreamWrapperInterface::VISIBLE), then only stream wrappers with all
|
|
||||||
* three of these bits set are returned. Defaults to
|
|
||||||
* StreamWrapperInterface::ALL, which returns all registered stream
|
|
||||||
* wrappers.
|
|
||||||
*
|
|
||||||
* @return array
|
|
||||||
* Stream wrapper descriptions, keyed by scheme.
|
|
||||||
*/
|
*/
|
||||||
public function getDescriptions($filter = StreamWrapperInterface::ALL) {
|
public function getDescriptions($filter = StreamWrapperInterface::ALL) {
|
||||||
$descriptions = array();
|
$descriptions = array();
|
||||||
|
@ -170,26 +93,14 @@ class StreamWrapperManager extends ContainerAware {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a stream wrapper via scheme.
|
* {@inheritdoc}
|
||||||
*
|
|
||||||
* @param string $scheme
|
|
||||||
* The scheme of the stream wrapper.
|
|
||||||
*
|
|
||||||
* @return \Drupal\Core\StreamWrapper\StreamWrapperInterface|bool
|
|
||||||
* A stream wrapper object, or false if the scheme is not available.
|
|
||||||
*/
|
*/
|
||||||
public function getViaScheme($scheme) {
|
public function getViaScheme($scheme) {
|
||||||
return $this->getWrapper($scheme, $scheme . '://');
|
return $this->getWrapper($scheme, $scheme . '://');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a stream wrapper via URI.
|
* {@inheritdoc}
|
||||||
*
|
|
||||||
* @param string $uri
|
|
||||||
* The URI of the stream wrapper.
|
|
||||||
*
|
|
||||||
* @return \Drupal\Core\StreamWrapper\StreamWrapperInterface|bool
|
|
||||||
* A stream wrapper object, or false if the scheme is not available.
|
|
||||||
*/
|
*/
|
||||||
public function getViaUri($uri) {
|
public function getViaUri($uri) {
|
||||||
$scheme = file_uri_scheme($uri);
|
$scheme = file_uri_scheme($uri);
|
||||||
|
@ -197,13 +108,7 @@ class StreamWrapperManager extends ContainerAware {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the stream wrapper class.
|
* {@inheritdoc}
|
||||||
*
|
|
||||||
* @param string $scheme
|
|
||||||
* The stream wrapper scheme.
|
|
||||||
*
|
|
||||||
* @return string|bool
|
|
||||||
* The stream wrapper class, or false if the scheme does not exist.
|
|
||||||
*/
|
*/
|
||||||
public function getClass($scheme) {
|
public function getClass($scheme) {
|
||||||
if (isset($this->info[$scheme])) {
|
if (isset($this->info[$scheme])) {
|
||||||
|
@ -283,14 +188,7 @@ class StreamWrapperManager extends ContainerAware {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Registers stream wrapper with PHP.
|
* {@inheritdoc}
|
||||||
*
|
|
||||||
* @param string $scheme
|
|
||||||
* The scheme of the stream wrapper.
|
|
||||||
* @param string $class
|
|
||||||
* The class of the stream wrapper.
|
|
||||||
* @param int $type
|
|
||||||
* The type of the stream wrapper.
|
|
||||||
*/
|
*/
|
||||||
public function registerWrapper($scheme, $class, $type) {
|
public function registerWrapper($scheme, $class, $type) {
|
||||||
if (in_array($scheme, stream_get_wrappers(), TRUE)) {
|
if (in_array($scheme, stream_get_wrappers(), TRUE)) {
|
||||||
|
|
|
@ -0,0 +1,159 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @file
|
||||||
|
* Contains \Drupal\Core\StreamWrapper\StreamWrapperManagerInterface.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Drupal\Core\StreamWrapper;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides a StreamWrapper manager.
|
||||||
|
*
|
||||||
|
* @see file_get_stream_wrappers()
|
||||||
|
* @see \Drupal\Core\StreamWrapper\StreamWrapperInterface
|
||||||
|
*/
|
||||||
|
interface StreamWrapperManagerInterface {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides Drupal stream wrapper registry.
|
||||||
|
*
|
||||||
|
* A stream wrapper is an abstraction of a file system that allows Drupal to
|
||||||
|
* use the same set of methods to access both local files and remote
|
||||||
|
* resources.
|
||||||
|
*
|
||||||
|
* Provide a facility for managing and querying user-defined stream wrappers
|
||||||
|
* in PHP. PHP's internal stream_get_wrappers() doesn't return the class
|
||||||
|
* registered to handle a stream, which we need to be able to find the
|
||||||
|
* handler
|
||||||
|
* for class instantiation.
|
||||||
|
*
|
||||||
|
* If a module registers a scheme that is already registered with PHP, the
|
||||||
|
* existing scheme will be unregistered and replaced with the specified
|
||||||
|
* class.
|
||||||
|
*
|
||||||
|
* A stream is referenced as "scheme://target".
|
||||||
|
*
|
||||||
|
* The optional $filter parameter can be used to retrieve only the stream
|
||||||
|
* wrappers that are appropriate for particular usage. For example, this
|
||||||
|
* returns only stream wrappers that use local file storage:
|
||||||
|
*
|
||||||
|
* @code
|
||||||
|
* $local_stream_wrappers =
|
||||||
|
* file_get_stream_wrappers(StreamWrapperInterface::LOCAL);
|
||||||
|
* @endcode
|
||||||
|
*
|
||||||
|
* The $filter parameter can only filter to types containing a particular
|
||||||
|
* flag. In some cases, you may want to filter to types that do not contain a
|
||||||
|
* particular flag. For example, you may want to retrieve all stream wrappers
|
||||||
|
* that are not writable, or all stream wrappers that are not local. PHP's
|
||||||
|
* array_diff_key() function can be used to help with this. For example, this
|
||||||
|
* returns only stream wrappers that do not use local file storage:
|
||||||
|
* @code
|
||||||
|
* $remote_stream_wrappers =
|
||||||
|
* array_diff_key(file_get_stream_wrappers(StreamWrapperInterface::ALL),
|
||||||
|
* file_get_stream_wrappers(StreamWrapperInterface::LOCAL));
|
||||||
|
* @endcode
|
||||||
|
*
|
||||||
|
* @param int $filter
|
||||||
|
* (Optional) Filters out all types except those with an on bit for each on
|
||||||
|
* bit in $filter. For example, if $filter is
|
||||||
|
* StreamWrapperInterface::WRITE_VISIBLE, which is equal to
|
||||||
|
* (StreamWrapperInterface::READ | StreamWrapperInterface::WRITE |
|
||||||
|
* StreamWrapperInterface::VISIBLE), then only stream wrappers with all
|
||||||
|
* three of these bits set are returned. Defaults to
|
||||||
|
* StreamWrapperInterface::ALL, which returns all registered stream
|
||||||
|
* wrappers.
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
* An array keyed by scheme, with values containing an array of information
|
||||||
|
* about the stream wrapper, as returned by hook_stream_wrappers(). If
|
||||||
|
* $filter is omitted or set to StreamWrapperInterface::ALL, the entire
|
||||||
|
* Drupal stream wrapper registry is returned. Otherwise only the stream
|
||||||
|
* wrappers whose 'type' bitmask has an on bit for each bit specified in
|
||||||
|
* $filter are returned.
|
||||||
|
*/
|
||||||
|
public function getWrappers($filter = StreamWrapperInterface::ALL);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns registered stream wrapper names.
|
||||||
|
*
|
||||||
|
* @param int $filter
|
||||||
|
* (Optional) Filters out all types except those with an on bit for each on
|
||||||
|
* bit in $filter. For example, if $filter is
|
||||||
|
* StreamWrapperInterface::WRITE_VISIBLE, which is equal to
|
||||||
|
* (StreamWrapperInterface::READ | StreamWrapperInterface::WRITE |
|
||||||
|
* StreamWrapperInterface::VISIBLE), then only stream wrappers with all
|
||||||
|
* three of these bits set are returned. Defaults to
|
||||||
|
* StreamWrapperInterface::ALL, which returns all registered stream
|
||||||
|
* wrappers.
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
* Stream wrapper names, keyed by scheme.
|
||||||
|
*/
|
||||||
|
public function getNames($filter = StreamWrapperInterface::ALL);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns registered stream wrapper descriptions.
|
||||||
|
*
|
||||||
|
* @param int $filter
|
||||||
|
* (Optional) Filters out all types except those with an on bit for each on
|
||||||
|
* bit in $filter. For example, if $filter is
|
||||||
|
* StreamWrapperInterface::WRITE_VISIBLE, which is equal to
|
||||||
|
* (StreamWrapperInterface::READ | StreamWrapperInterface::WRITE |
|
||||||
|
* StreamWrapperInterface::VISIBLE), then only stream wrappers with all
|
||||||
|
* three of these bits set are returned. Defaults to
|
||||||
|
* StreamWrapperInterface::ALL, which returns all registered stream
|
||||||
|
* wrappers.
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
* Stream wrapper descriptions, keyed by scheme.
|
||||||
|
*/
|
||||||
|
public function getDescriptions($filter = StreamWrapperInterface::ALL);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a stream wrapper via scheme.
|
||||||
|
*
|
||||||
|
* @param string $scheme
|
||||||
|
* The scheme of the stream wrapper.
|
||||||
|
*
|
||||||
|
* @return \Drupal\Core\StreamWrapper\StreamWrapperInterface|bool
|
||||||
|
* A stream wrapper object, or false if the scheme is not available.
|
||||||
|
*/
|
||||||
|
public function getViaScheme($scheme);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a stream wrapper via URI.
|
||||||
|
*
|
||||||
|
* @param string $uri
|
||||||
|
* The URI of the stream wrapper.
|
||||||
|
*
|
||||||
|
* @return \Drupal\Core\StreamWrapper\StreamWrapperInterface|bool
|
||||||
|
* A stream wrapper object, or false if the scheme is not available.
|
||||||
|
*/
|
||||||
|
public function getViaUri($uri);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the stream wrapper class.
|
||||||
|
*
|
||||||
|
* @param string $scheme
|
||||||
|
* The stream wrapper scheme.
|
||||||
|
*
|
||||||
|
* @return string|bool
|
||||||
|
* The stream wrapper class, or false if the scheme does not exist.
|
||||||
|
*/
|
||||||
|
public function getClass($scheme);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Registers stream wrapper with PHP.
|
||||||
|
*
|
||||||
|
* @param string $scheme
|
||||||
|
* The scheme of the stream wrapper.
|
||||||
|
* @param string $class
|
||||||
|
* The class of the stream wrapper.
|
||||||
|
* @param int $type
|
||||||
|
* The type of the stream wrapper.
|
||||||
|
*/
|
||||||
|
public function registerWrapper($scheme, $class, $type);
|
||||||
|
|
||||||
|
}
|
|
@ -147,9 +147,6 @@ abstract class KernelTestBase extends TestBase {
|
||||||
$this->settingsSet('container_yamls', [$testing_services_file]);
|
$this->settingsSet('container_yamls', [$testing_services_file]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create and set new configuration directories.
|
|
||||||
$this->prepareConfigDirectories();
|
|
||||||
|
|
||||||
// Add this test class as a service provider.
|
// Add this test class as a service provider.
|
||||||
// @todo Remove the indirection; implement ServiceProviderInterface instead.
|
// @todo Remove the indirection; implement ServiceProviderInterface instead.
|
||||||
$GLOBALS['conf']['container_service_providers']['TestServiceProvider'] = 'Drupal\simpletest\TestServiceProvider';
|
$GLOBALS['conf']['container_service_providers']['TestServiceProvider'] = 'Drupal\simpletest\TestServiceProvider';
|
||||||
|
@ -172,6 +169,9 @@ abstract class KernelTestBase extends TestBase {
|
||||||
// method sets additional settings.
|
// method sets additional settings.
|
||||||
new Settings($settings + Settings::getAll());
|
new Settings($settings + Settings::getAll());
|
||||||
|
|
||||||
|
// Create and set new configuration directories.
|
||||||
|
$this->prepareConfigDirectories();
|
||||||
|
|
||||||
// Set the request scope.
|
// Set the request scope.
|
||||||
$this->container = $this->kernel->getContainer();
|
$this->container = $this->kernel->getContainer();
|
||||||
$this->container->get('request_stack')->push($request);
|
$this->container->get('request_stack')->push($request);
|
||||||
|
|
|
@ -1282,6 +1282,10 @@ abstract class TestBase {
|
||||||
// log to pick up any fatal errors.
|
// log to pick up any fatal errors.
|
||||||
simpletest_log_read($this->testId, $this->databasePrefix, get_class($this));
|
simpletest_log_read($this->testId, $this->databasePrefix, get_class($this));
|
||||||
|
|
||||||
|
// Restore original dependency injection container.
|
||||||
|
$this->container = $this->originalContainer;
|
||||||
|
\Drupal::setContainer($this->originalContainer);
|
||||||
|
|
||||||
// Delete test site directory.
|
// Delete test site directory.
|
||||||
file_unmanaged_delete_recursive($this->siteDirectory, array($this, 'filePreDeleteCallback'));
|
file_unmanaged_delete_recursive($this->siteDirectory, array($this, 'filePreDeleteCallback'));
|
||||||
|
|
||||||
|
@ -1300,7 +1304,6 @@ abstract class TestBase {
|
||||||
new Settings($this->originalSettings);
|
new Settings($this->originalSettings);
|
||||||
|
|
||||||
// Restore original statics and globals.
|
// Restore original statics and globals.
|
||||||
\Drupal::setContainer($this->originalContainer);
|
|
||||||
$GLOBALS['config_directories'] = $this->originalConfigDirectories;
|
$GLOBALS['config_directories'] = $this->originalConfigDirectories;
|
||||||
|
|
||||||
// Re-initialize original stream wrappers of the parent site.
|
// Re-initialize original stream wrappers of the parent site.
|
||||||
|
|
|
@ -1005,12 +1005,27 @@ abstract class WebTestBase extends TestBase {
|
||||||
|
|
||||||
// If we only have one db driver available, we cannot set the driver.
|
// If we only have one db driver available, we cannot set the driver.
|
||||||
include_once DRUPAL_ROOT . '/core/includes/install.inc';
|
include_once DRUPAL_ROOT . '/core/includes/install.inc';
|
||||||
if (count(drupal_get_database_types()) == 1) {
|
if (count($this->getDatabaseTypes()) == 1) {
|
||||||
unset($parameters['forms']['install_settings_form']['driver']);
|
unset($parameters['forms']['install_settings_form']['driver']);
|
||||||
}
|
}
|
||||||
return $parameters;
|
return $parameters;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns all supported database driver installer objects.
|
||||||
|
*
|
||||||
|
* This wraps drupal_get_database_types() for use without a current container.
|
||||||
|
*
|
||||||
|
* @return \Drupal\Core\Database\Install\Tasks[]
|
||||||
|
* An array of available database driver installer objects.
|
||||||
|
*/
|
||||||
|
protected function getDatabaseTypes() {
|
||||||
|
\Drupal::setContainer($this->originalContainer);
|
||||||
|
$database_types = drupal_get_database_types();
|
||||||
|
\Drupal::setContainer(NULL);
|
||||||
|
return $database_types;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Rewrites the settings.php file of the test site.
|
* Rewrites the settings.php file of the test site.
|
||||||
*
|
*
|
||||||
|
|
|
@ -15,7 +15,7 @@ use Drupal\Core\StreamWrapper\PrivateStream;
|
||||||
use Drupal\Core\StreamWrapper\PublicStream;
|
use Drupal\Core\StreamWrapper\PublicStream;
|
||||||
use Drupal\Core\Form\ConfigFormBase;
|
use Drupal\Core\Form\ConfigFormBase;
|
||||||
use Drupal\Core\StreamWrapper\StreamWrapperInterface;
|
use Drupal\Core\StreamWrapper\StreamWrapperInterface;
|
||||||
use Drupal\Core\StreamWrapper\StreamWrapperManager;
|
use Drupal\Core\StreamWrapper\StreamWrapperManagerInterface;
|
||||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -33,7 +33,7 @@ class FileSystemForm extends ConfigFormBase {
|
||||||
/**
|
/**
|
||||||
* The stream wrapper manager.
|
* The stream wrapper manager.
|
||||||
*
|
*
|
||||||
* @var \Drupal\Core\StreamWrapper\StreamWrapperManager
|
* @var \Drupal\Core\StreamWrapper\StreamWrapperManagerInterface
|
||||||
*/
|
*/
|
||||||
protected $streamWrapperManager;
|
protected $streamWrapperManager;
|
||||||
|
|
||||||
|
@ -44,10 +44,10 @@ class FileSystemForm extends ConfigFormBase {
|
||||||
* The factory for configuration objects.
|
* The factory for configuration objects.
|
||||||
* @param \Drupal\Core\Datetime\DateFormatter $date_formatter
|
* @param \Drupal\Core\Datetime\DateFormatter $date_formatter
|
||||||
* The date formatter service.
|
* The date formatter service.
|
||||||
* @param \Drupal\Core\StreamWrapper\StreamWrapperManager $stream_wrapper_manager
|
* @param \Drupal\Core\StreamWrapper\StreamWrapperManagerInterface $stream_wrapper_manager
|
||||||
* The stream wrapper manager.
|
* The stream wrapper manager.
|
||||||
*/
|
*/
|
||||||
public function __construct(ConfigFactoryInterface $config_factory, DateFormatter $date_formatter, StreamWrapperManager $stream_wrapper_manager) {
|
public function __construct(ConfigFactoryInterface $config_factory, DateFormatter $date_formatter, StreamWrapperManagerInterface $stream_wrapper_manager) {
|
||||||
parent::__construct($config_factory);
|
parent::__construct($config_factory);
|
||||||
$this->dateFormatter = $date_formatter;
|
$this->dateFormatter = $date_formatter;
|
||||||
$this->streamWrapperManager = $stream_wrapper_manager;
|
$this->streamWrapperManager = $stream_wrapper_manager;
|
||||||
|
|
|
@ -16,12 +16,34 @@ use Drupal\simpletest\KernelTestBase;
|
||||||
*/
|
*/
|
||||||
class GetFilenameUnitTest extends KernelTestBase {
|
class GetFilenameUnitTest extends KernelTestBase {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The container used by the test, moved out of the way.
|
||||||
|
*
|
||||||
|
* @var \Symfony\Component\DependencyInjection\ContainerInterface
|
||||||
|
*/
|
||||||
|
protected $previousContainer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
protected function setUp() {
|
protected function setUp() {
|
||||||
parent::setUp();
|
parent::setUp();
|
||||||
|
// Store the previous container.
|
||||||
|
$this->previousContainer = $this->container;
|
||||||
$this->container = NULL;
|
$this->container = NULL;
|
||||||
\Drupal::setContainer(NULL);
|
\Drupal::setContainer(NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
protected function tearDown() {
|
||||||
|
parent::tearDown();
|
||||||
|
// Restore the previous container.
|
||||||
|
$this->container = $this->previousContainer;
|
||||||
|
\Drupal::setContainer($this->previousContainer);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests that drupal_get_filename() works when the file is not in database.
|
* Tests that drupal_get_filename() works when the file is not in database.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -35,6 +35,15 @@ class DrupalKernelTest extends KernelTestBase {
|
||||||
)));
|
)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
protected function prepareConfigDirectories() {
|
||||||
|
\Drupal::setContainer($this->originalContainer);
|
||||||
|
parent::prepareConfigDirectories();
|
||||||
|
\Drupal::setContainer(NULL);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Build a kernel for testings.
|
* Build a kernel for testings.
|
||||||
*
|
*
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
namespace Drupal\system\Tests\File;
|
namespace Drupal\system\Tests\File;
|
||||||
|
|
||||||
use Drupal\Core\Site\Settings;
|
use Drupal\Core\Site\Settings;
|
||||||
|
use Drupal\Core\File\FileSystem;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests the unmanaged file copy function.
|
* Tests the unmanaged file copy function.
|
||||||
|
@ -29,7 +30,7 @@ class UnmanagedCopyTest extends FileTestBase {
|
||||||
$this->assertEqual($new_filepath, $desired_filepath, 'Returned expected filepath.');
|
$this->assertEqual($new_filepath, $desired_filepath, 'Returned expected filepath.');
|
||||||
$this->assertTrue(file_exists($uri), 'Original file remains.');
|
$this->assertTrue(file_exists($uri), 'Original file remains.');
|
||||||
$this->assertTrue(file_exists($new_filepath), 'New file exists.');
|
$this->assertTrue(file_exists($new_filepath), 'New file exists.');
|
||||||
$this->assertFilePermissions($new_filepath, Settings::get('file_chmod_file', FILE_CHMOD_FILE));
|
$this->assertFilePermissions($new_filepath, Settings::get('file_chmod_file', FileSystem::CHMOD_FILE));
|
||||||
|
|
||||||
// Copying with rename.
|
// Copying with rename.
|
||||||
$desired_filepath = 'public://' . $this->randomMachineName();
|
$desired_filepath = 'public://' . $this->randomMachineName();
|
||||||
|
@ -39,7 +40,7 @@ class UnmanagedCopyTest extends FileTestBase {
|
||||||
$this->assertNotEqual($newer_filepath, $desired_filepath, 'Returned expected filepath.');
|
$this->assertNotEqual($newer_filepath, $desired_filepath, 'Returned expected filepath.');
|
||||||
$this->assertTrue(file_exists($uri), 'Original file remains.');
|
$this->assertTrue(file_exists($uri), 'Original file remains.');
|
||||||
$this->assertTrue(file_exists($newer_filepath), 'New file exists.');
|
$this->assertTrue(file_exists($newer_filepath), 'New file exists.');
|
||||||
$this->assertFilePermissions($newer_filepath, Settings::get('file_chmod_file', FILE_CHMOD_FILE));
|
$this->assertFilePermissions($newer_filepath, Settings::get('file_chmod_file', FileSystem::CHMOD_FILE));
|
||||||
|
|
||||||
// TODO: test copying to a directory (rather than full directory/file path)
|
// TODO: test copying to a directory (rather than full directory/file path)
|
||||||
// TODO: test copying normal files using normal paths (rather than only streams)
|
// TODO: test copying normal files using normal paths (rather than only streams)
|
||||||
|
@ -69,7 +70,7 @@ class UnmanagedCopyTest extends FileTestBase {
|
||||||
$this->assertNotEqual($new_filepath, $uri, 'Copied file has a new name.');
|
$this->assertNotEqual($new_filepath, $uri, 'Copied file has a new name.');
|
||||||
$this->assertTrue(file_exists($uri), 'Original file exists after copying onto itself.');
|
$this->assertTrue(file_exists($uri), 'Original file exists after copying onto itself.');
|
||||||
$this->assertTrue(file_exists($new_filepath), 'Copied file exists after copying onto itself.');
|
$this->assertTrue(file_exists($new_filepath), 'Copied file exists after copying onto itself.');
|
||||||
$this->assertFilePermissions($new_filepath, Settings::get('file_chmod_file', FILE_CHMOD_FILE));
|
$this->assertFilePermissions($new_filepath, Settings::get('file_chmod_file', FileSystem::CHMOD_FILE));
|
||||||
|
|
||||||
// Copy the file onto itself without renaming fails.
|
// Copy the file onto itself without renaming fails.
|
||||||
$new_filepath = file_unmanaged_copy($uri, $uri, FILE_EXISTS_ERROR);
|
$new_filepath = file_unmanaged_copy($uri, $uri, FILE_EXISTS_ERROR);
|
||||||
|
@ -87,6 +88,6 @@ class UnmanagedCopyTest extends FileTestBase {
|
||||||
$this->assertNotEqual($new_filepath, $uri, 'Copied file has a new name.');
|
$this->assertNotEqual($new_filepath, $uri, 'Copied file has a new name.');
|
||||||
$this->assertTrue(file_exists($uri), 'Original file exists after copying onto itself.');
|
$this->assertTrue(file_exists($uri), 'Original file exists after copying onto itself.');
|
||||||
$this->assertTrue(file_exists($new_filepath), 'Copied file exists after copying onto itself.');
|
$this->assertTrue(file_exists($new_filepath), 'Copied file exists after copying onto itself.');
|
||||||
$this->assertFilePermissions($new_filepath, Settings::get('file_chmod_file', FILE_CHMOD_FILE));
|
$this->assertFilePermissions($new_filepath, Settings::get('file_chmod_file', FileSystem::CHMOD_FILE));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
namespace Drupal\system\Tests\File;
|
namespace Drupal\system\Tests\File;
|
||||||
|
|
||||||
use Drupal\Core\Site\Settings;
|
use Drupal\Core\Site\Settings;
|
||||||
|
use Drupal\Core\File\FileSystem;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests the unmanaged file move function.
|
* Tests the unmanaged file move function.
|
||||||
|
@ -29,7 +30,7 @@ class UnmanagedMoveTest extends FileTestBase {
|
||||||
$this->assertEqual($new_filepath, $desired_filepath, 'Returned expected filepath.');
|
$this->assertEqual($new_filepath, $desired_filepath, 'Returned expected filepath.');
|
||||||
$this->assertTrue(file_exists($new_filepath), 'File exists at the new location.');
|
$this->assertTrue(file_exists($new_filepath), 'File exists at the new location.');
|
||||||
$this->assertFalse(file_exists($uri), 'No file remains at the old location.');
|
$this->assertFalse(file_exists($uri), 'No file remains at the old location.');
|
||||||
$this->assertFilePermissions($new_filepath, Settings::get('file_chmod_file', FILE_CHMOD_FILE));
|
$this->assertFilePermissions($new_filepath, Settings::get('file_chmod_file', FileSystem::CHMOD_FILE));
|
||||||
|
|
||||||
// Moving with rename.
|
// Moving with rename.
|
||||||
$desired_filepath = 'public://' . $this->randomMachineName();
|
$desired_filepath = 'public://' . $this->randomMachineName();
|
||||||
|
@ -40,7 +41,7 @@ class UnmanagedMoveTest extends FileTestBase {
|
||||||
$this->assertNotEqual($newer_filepath, $desired_filepath, 'Returned expected filepath.');
|
$this->assertNotEqual($newer_filepath, $desired_filepath, 'Returned expected filepath.');
|
||||||
$this->assertTrue(file_exists($newer_filepath), 'File exists at the new location.');
|
$this->assertTrue(file_exists($newer_filepath), 'File exists at the new location.');
|
||||||
$this->assertFalse(file_exists($new_filepath), 'No file remains at the old location.');
|
$this->assertFalse(file_exists($new_filepath), 'No file remains at the old location.');
|
||||||
$this->assertFilePermissions($newer_filepath, Settings::get('file_chmod_file', FILE_CHMOD_FILE));
|
$this->assertFilePermissions($newer_filepath, Settings::get('file_chmod_file', FileSystem::CHMOD_FILE));
|
||||||
|
|
||||||
// TODO: test moving to a directory (rather than full directory/file path)
|
// TODO: test moving to a directory (rather than full directory/file path)
|
||||||
// TODO: test creating and moving normal files (rather than streams)
|
// TODO: test creating and moving normal files (rather than streams)
|
||||||
|
|
|
@ -50,6 +50,7 @@ class RouteProviderTest extends KernelTestBase {
|
||||||
protected $state;
|
protected $state;
|
||||||
|
|
||||||
protected function setUp() {
|
protected function setUp() {
|
||||||
|
parent::setUp();
|
||||||
$this->fixtures = new RoutingFixtures();
|
$this->fixtures = new RoutingFixtures();
|
||||||
$this->routeBuilder = new NullRouteBuilder();
|
$this->routeBuilder = new NullRouteBuilder();
|
||||||
$this->state = new State(new KeyValueMemoryFactory());
|
$this->state = new State(new KeyValueMemoryFactory());
|
||||||
|
|
|
@ -0,0 +1,183 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @file
|
||||||
|
* Contains \Drupal\Tests\Core\File\FileSystemTest.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Drupal\Tests\Core\File;
|
||||||
|
|
||||||
|
use Drupal\Core\File\FileSystem;
|
||||||
|
use Drupal\Core\Site\Settings;
|
||||||
|
use Drupal\Tests\UnitTestCase;
|
||||||
|
use org\bovigo\vfs\vfsStream;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @coversDefaultClass \Drupal\Core\File\FileSystem
|
||||||
|
*
|
||||||
|
* @group File
|
||||||
|
*/
|
||||||
|
class FileSystemTest extends UnitTestCase {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var \Drupal\Core\File\FileSystem
|
||||||
|
*/
|
||||||
|
protected $fileSystem;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The file logger channel.
|
||||||
|
*
|
||||||
|
* @var \Psr\Log\LoggerInterface|\PHPUnit_Framework_MockObject_MockObject
|
||||||
|
*/
|
||||||
|
protected $logger;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
protected function setUp() {
|
||||||
|
parent::setUp();
|
||||||
|
|
||||||
|
$settings = new Settings([]);
|
||||||
|
$stream_wrapper_manager = $this->getMock('Drupal\Core\StreamWrapper\StreamWrapperManagerInterface');
|
||||||
|
$this->logger = $this->getMock('Psr\Log\LoggerInterface');
|
||||||
|
$this->fileSystem = new FileSystem($stream_wrapper_manager, $settings, $this->logger);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @covers ::chmod
|
||||||
|
*/
|
||||||
|
public function testChmodFile() {
|
||||||
|
vfsStream::setup('dir');
|
||||||
|
vfsStream::create(['test.txt' => 'asdf']);
|
||||||
|
$uri = 'vfs://dir/test.txt';
|
||||||
|
|
||||||
|
$this->assertTrue($this->fileSystem->chmod($uri));
|
||||||
|
$this->assertFilePermissions(FileSystem::CHMOD_FILE, $uri);
|
||||||
|
$this->assertTrue($this->fileSystem->chmod($uri, 0444));
|
||||||
|
$this->assertFilePermissions(0444, $uri);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @covers ::chmod
|
||||||
|
*/
|
||||||
|
public function testChmodDir() {
|
||||||
|
vfsStream::setup('dir');
|
||||||
|
vfsStream::create(['nested_dir' => []]);
|
||||||
|
$uri = 'vfs://dir/nested_dir';
|
||||||
|
|
||||||
|
$this->assertTrue($this->fileSystem->chmod($uri));
|
||||||
|
$this->assertFilePermissions(FileSystem::CHMOD_DIRECTORY, $uri);
|
||||||
|
$this->assertTrue($this->fileSystem->chmod($uri, 0444));
|
||||||
|
$this->assertFilePermissions(0444, $uri);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @covers ::chmod
|
||||||
|
*/
|
||||||
|
public function testChmodUnsuccessful() {
|
||||||
|
vfsStream::setup('dir');
|
||||||
|
$this->logger->expects($this->once())
|
||||||
|
->method('error');
|
||||||
|
$this->assertFalse($this->fileSystem->chmod('vfs://dir/test.txt'));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @covers ::unlink
|
||||||
|
*/
|
||||||
|
public function testUnlink() {
|
||||||
|
vfsStream::setup('dir');
|
||||||
|
vfsStream::create(['test.txt' => 'asdf']);
|
||||||
|
$uri = 'vfs://dir/test.txt';
|
||||||
|
|
||||||
|
$this->fileSystem = $this->getMockBuilder('Drupal\Core\File\FileSystem')
|
||||||
|
->disableOriginalConstructor()
|
||||||
|
->setMethods(['validScheme'])
|
||||||
|
->getMock();
|
||||||
|
$this->fileSystem->expects($this->once())
|
||||||
|
->method('validScheme')
|
||||||
|
->willReturn(TRUE);
|
||||||
|
|
||||||
|
$this->assertFileExists($uri);
|
||||||
|
$this->fileSystem->unlink($uri);
|
||||||
|
$this->assertFileNotExists($uri);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @covers ::basename
|
||||||
|
*
|
||||||
|
* @dataProvider providerTestBasename
|
||||||
|
*/
|
||||||
|
public function testBasename($uri, $expected, $suffix = NULL) {
|
||||||
|
$this->assertSame($expected, $this->fileSystem->basename($uri, $suffix));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function providerTestBasename() {
|
||||||
|
$data = [];
|
||||||
|
$data[] = [
|
||||||
|
'public://nested/dir',
|
||||||
|
'dir',
|
||||||
|
];
|
||||||
|
$data[] = [
|
||||||
|
'public://dir/test.txt',
|
||||||
|
'test.txt',
|
||||||
|
];
|
||||||
|
$data[] = [
|
||||||
|
'public://dir/test.txt',
|
||||||
|
'test',
|
||||||
|
'.txt'
|
||||||
|
];
|
||||||
|
return $data;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @covers ::uriScheme
|
||||||
|
*
|
||||||
|
* @dataProvider providerTestUriScheme
|
||||||
|
*/
|
||||||
|
public function testUriScheme($uri, $expected) {
|
||||||
|
$this->assertSame($expected, $this->fileSystem->uriScheme($uri));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function providerTestUriScheme() {
|
||||||
|
$data = [];
|
||||||
|
$data[] = [
|
||||||
|
'public://filename',
|
||||||
|
'public',
|
||||||
|
];
|
||||||
|
$data[] = [
|
||||||
|
'public://extra://',
|
||||||
|
'public',
|
||||||
|
];
|
||||||
|
$data[] = [
|
||||||
|
'invalid',
|
||||||
|
FALSE,
|
||||||
|
];
|
||||||
|
return $data;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Asserts that the file permissions of a given URI matches.
|
||||||
|
*
|
||||||
|
* @param int $expected_mode
|
||||||
|
* @param string $uri
|
||||||
|
* @param string $message
|
||||||
|
*/
|
||||||
|
protected function assertFilePermissions($expected_mode, $uri, $message = '') {
|
||||||
|
// Mask out all but the last three octets.
|
||||||
|
$actual_mode = fileperms($uri) & 0777;
|
||||||
|
|
||||||
|
// PHP on Windows has limited support for file permissions. Usually each of
|
||||||
|
// "user", "group" and "other" use one octal digit (3 bits) to represent the
|
||||||
|
// read/write/execute bits. On Windows, chmod() ignores the "group" and
|
||||||
|
// "other" bits, and fileperms() returns the "user" bits in all three
|
||||||
|
// positions. $expected_mode is updated to reflect this.
|
||||||
|
if (substr(PHP_OS, 0, 3) == 'WIN') {
|
||||||
|
// Reset the "group" and "other" bits.
|
||||||
|
$expected_mode = $expected_mode & 0700;
|
||||||
|
// Shift the "user" bits to the "group" and "other" positions also.
|
||||||
|
$expected_mode = $expected_mode | $expected_mode >> 3 | $expected_mode >> 6;
|
||||||
|
}
|
||||||
|
$this->assertSame($expected_mode, $actual_mode, $message);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in New Issue