diff --git a/core/core.services.yml b/core/core.services.yml index 20b8651..e3eaa28 100644 --- a/core/core.services.yml +++ b/core/core.services.yml @@ -549,6 +549,10 @@ services: plugin.manager.condition: class: Drupal\Core\Condition\ConditionManager parent: default_plugin_manager + arguments: ['@container.namespaces', '@cache.cache', '@language_manager', '@module_handler'] + plugin.manager.stream_wrapper: + class: Drupal\Core\StreamWrapper\StreamWrapperManager + arguments: ['@container.namespaces', '@module_handler'] kernel_destruct_subscriber: class: Drupal\Core\EventSubscriber\KernelDestructionSubscriber tags: diff --git a/core/includes/file.inc b/core/includes/file.inc index 037d195..61b650e 100644 --- a/core/includes/file.inc +++ b/core/includes/file.inc @@ -139,37 +139,8 @@ /** * 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(STREAM_WRAPPERS_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(STREAM_WRAPPERS_ALL), file_get_stream_wrappers(STREAM_WRAPPERS_LOCAL)); - * @endcode - * - * @param $filter + * @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 STREAM_WRAPPERS_WRITE_VISIBLE, * which is equal to (STREAM_WRAPPERS_READ | STREAM_WRAPPERS_WRITE | @@ -177,7 +148,7 @@ * bits set are returned. Defaults to STREAM_WRAPPERS_ALL, which returns all * registered stream wrappers. * - * @return + * @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 STREAM_WRAPPERS_ALL, the entire Drupal stream wrapper @@ -186,78 +157,35 @@ * * @see hook_stream_wrappers() * @see hook_stream_wrappers_alter() + * @see \Drupal\Core\StreamWrapper\StreamWrapperManager + * + * @deprecated Use \Drupal::service('plugin.manager.stream_wrapper')->getWrappers() */ function file_get_stream_wrappers($filter = STREAM_WRAPPERS_ALL) { - $wrappers_storage = &drupal_static(__FUNCTION__); - - if (!isset($wrappers_storage)) { - $wrappers = \Drupal::moduleHandler()->invokeAll('stream_wrappers'); - foreach ($wrappers as $scheme => $info) { - // Add defaults. - $wrappers[$scheme] += array('type' => STREAM_WRAPPERS_NORMAL); - } - drupal_alter('stream_wrappers', $wrappers); - $existing = stream_get_wrappers(); - foreach ($wrappers as $scheme => $info) { - // We only register classes that implement our interface. - if (in_array('Drupal\Core\StreamWrapper\StreamWrapperInterface', class_implements($info['class']), TRUE)) { - // Record whether we are overriding an existing scheme. - if (in_array($scheme, $existing, TRUE)) { - $wrappers[$scheme]['override'] = TRUE; - stream_wrapper_unregister($scheme); - } - else { - $wrappers[$scheme]['override'] = FALSE; - } - if (($info['type'] & STREAM_WRAPPERS_LOCAL) == STREAM_WRAPPERS_LOCAL) { - stream_wrapper_register($scheme, $info['class']); - } - else { - stream_wrapper_register($scheme, $info['class'], STREAM_IS_URL); - } - } - // Pre-populate the static cache with the filters most typically used. - $wrappers_storage[STREAM_WRAPPERS_ALL][$scheme] = $wrappers[$scheme]; - if (($info['type'] & STREAM_WRAPPERS_WRITE_VISIBLE) == STREAM_WRAPPERS_WRITE_VISIBLE) { - $wrappers_storage[STREAM_WRAPPERS_WRITE_VISIBLE][$scheme] = $wrappers[$scheme]; - } - } - } - - if (!isset($wrappers_storage[$filter])) { - $wrappers_storage[$filter] = array(); - foreach ($wrappers_storage[STREAM_WRAPPERS_ALL] as $scheme => $info) { - // Bit-wise filter. - if (($info['type'] & $filter) == $filter) { - $wrappers_storage[$filter][$scheme] = $info; - } - } - } - - return $wrappers_storage[$filter]; + return \Drupal::service('plugin.manager.stream_wrapper')->getWrappers($filter); } /** * Returns the stream wrapper class name for a given scheme. * - * @param $scheme + * @param string $scheme * Stream scheme. * - * @return + * @return string|bool * Return string if a scheme has a registered handler, or FALSE. */ function file_stream_wrapper_get_class($scheme) { - $wrappers = file_get_stream_wrappers(); - return empty($wrappers[$scheme]) ? FALSE : $wrappers[$scheme]['class']; + $wrapper = \Drupal::service('plugin.manager.stream_wrapper')->getDefinition($scheme); + return !empty($wrapper) ? $wrapper['class'] : FALSE; } /** * Returns the scheme of a URI (e.g. a stream). * - * @param $uri + * @param string $uri * A stream, referenced as "scheme://target". * - * @return + * @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". * @@ -275,10 +203,10 @@ function file_uri_scheme($uri) { * 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 $scheme + * @param string $scheme * A URI scheme, a stream is referenced as "scheme://target". * - * @return + * @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. */ @@ -286,14 +214,13 @@ function file_stream_wrapper_valid_scheme($scheme) { return $scheme && class_exists(file_stream_wrapper_get_class($scheme)); } - /** * Returns the part of a URI after the schema. * - * @param $uri + * @param string $uri * A stream, referenced as "scheme://target". * - * @return + * @return string|bool * A string containing the target (path), or FALSE if none. * For example, the URI "public://sample/test.txt" would return * "sample/test.txt". @@ -310,7 +237,7 @@ function file_uri_target($uri) { /** * Gets the default file stream implementation. * - * @return + * @return string * 'public', 'private' or any other file scheme defined as the default. */ function file_default_scheme() { @@ -326,10 +253,10 @@ function file_default_scheme() { * - Remove trailing slashes from target * - Trim erroneous leading slashes from target. e.g. ":///" becomes "://". * - * @param $uri + * @param string $uri * String reference containing the URI to normalize. * - * @return + * @return string * The normalized URI. */ function file_stream_wrapper_uri_normalize($uri) { @@ -352,25 +279,19 @@ function file_stream_wrapper_uri_normalize($uri) { * The scheme determines the stream wrapper class that should be * used by consulting the stream wrapper registry. * - * @param $uri + * @param string $uri * A stream, referenced as "scheme://target". * - * @return + * @return \Drupal\Core\StreamWrapper\StreamWrapperInterface|bool * Returns a new stream wrapper object appropriate for the given URI or FALSE * if no registered handler could be found. For example, a URI of * "private://example.txt" would return a new private stream wrapper object * (Drupal\Core\StreamWrapper\PrivateStream). + * + * @deprecated Use \Drupal::service('plugin.manager.stream_wrapper')->getInstance() */ function file_stream_wrapper_get_instance_by_uri($uri) { - if ($scheme = file_uri_scheme($uri)) { - $class = file_stream_wrapper_get_class($scheme); - if (class_exists($class)) { - $instance = new $class(); - $instance->setUri($uri); - return $instance; - } - } - return FALSE; + return \Drupal::service('plugin.manager.stream_wrapper')->getInstance(array('uri' => $uri)); } /** @@ -384,25 +305,19 @@ function file_stream_wrapper_get_instance_by_uri($uri) { * Note: the instance URI will be initialized to "scheme://" so that you can * make the customary method calls as if you had retrieved an instance by URI. * - * @param $scheme + * @param string $scheme * If the stream was "public://target", "public" would be the scheme. * - * @return \Drupal\Core\StreamWrapper\StreamWrapperInterface + * @return \Drupal\Core\StreamWrapper\StreamWrapperInterface|bool * Returns a new stream wrapper object appropriate for the given $scheme. * For example, for the public scheme a stream wrapper object * (Drupal\Core\StreamWrapper\PublicStream). * FALSE is returned if no registered handler could be found. + * + * @deprecated Use \Drupal::service('plugin.manager.stream_wrapper')->getInstance() */ function file_stream_wrapper_get_instance_by_scheme($scheme) { - $class = file_stream_wrapper_get_class($scheme); - if (class_exists($class)) { - $instance = new $class(); - $instance->setUri($scheme . '://'); - return $instance; - } - else { - return FALSE; - } + return \Drupal::service('plugin.manager.stream_wrapper')->getInstance(array('scheme' => $scheme)); } /** @@ -1057,8 +972,6 @@ function file_unmanaged_delete_recursive($path, $callback = NULL) { return file_unmanaged_delete($path); } - - /** * Moves an uploaded file to a new location. * diff --git a/core/includes/install.core.inc b/core/includes/install.core.inc index 22d2cff..e606c04 100644 --- a/core/includes/install.core.inc +++ b/core/includes/install.core.inc @@ -421,6 +421,12 @@ function install_begin_request(&$install_state) { $container ->register('module_handler', 'Drupal\Core\Extension\ModuleHandler'); + // Register the stream wrapper manager with an empty set of namespaces. + $container + ->register('plugin.manager.stream_wrapper', 'Drupal\Core\StreamWrapper\StreamWrapperManager') + ->addArgument(new ArrayObject()) + ->addArgument(new Reference('module_handler')); + // Register the Guzzle HTTP client for fetching translation files from a // remote translation server such as localization.drupal.org. $container->register('http_default_client', 'Guzzle\Http\Client') diff --git a/core/lib/Drupal/Core/Extension/UpdateModuleHandler.php b/core/lib/Drupal/Core/Extension/UpdateModuleHandler.php index 7d7ac9c..2bf5e2a 100644 --- a/core/lib/Drupal/Core/Extension/UpdateModuleHandler.php +++ b/core/lib/Drupal/Core/Extension/UpdateModuleHandler.php @@ -35,6 +35,7 @@ public function getImplementations($hook) { // Allow logging. case 'watchdog': return parent::getImplementations($hook); + // Forms and pages do not render without the basic elements defined in // system_element_info(). case 'element_info': @@ -44,6 +45,7 @@ public function getImplementations($hook) { // user_update_8011() uses public:// to create the image style directory. case 'stream_wrappers': return array('system'); + // This is called during rebuild to find testing themes. case 'system_theme_info': // Those are needed by user_access() to check access on update.php. @@ -51,10 +53,12 @@ public function getImplementations($hook) { case 'entity_load': case 'user_role_load': return array(); - // t() in system_stream_wrappers() needs this. Other schema calls aren't - // supported. + + // t() (called indirectly by \Drupal\Core\StreamWrapper\PublicStream) + // needs this. Other schema calls aren't supported. case 'schema': return array('locale'); + default: throw new \LogicException("Invoking hooks $hook is not supported during updates"); } diff --git a/core/lib/Drupal/Core/StreamWrapper/PrivateStream.php b/core/lib/Drupal/Core/StreamWrapper/PrivateStream.php index 39b3f28..9ec822b 100644 --- a/core/lib/Drupal/Core/StreamWrapper/PrivateStream.php +++ b/core/lib/Drupal/Core/StreamWrapper/PrivateStream.php @@ -2,7 +2,7 @@ /** * @file - * Definition of Drupal\Core\StreamWrapper\PrivateStream. + * Contains \Drupal\Core\StreamWrapper\PrivateStream. */ namespace Drupal\Core\StreamWrapper; @@ -16,20 +16,18 @@ class PrivateStream extends LocalStream { /** - * Implements Drupal\Core\StreamWrapper\LocalStream::getDirectoryPath() + * {@inheritdoc} */ public function getDirectoryPath() { return \Drupal::config('system.file')->get('path.private'); } /** - * Implements Drupal\Core\StreamWrapper\StreamWrapperInterface::getExternalUrl(). - * - * @return string - * Returns the HTML URI of a private file. + * {@inheritdoc} */ function getExternalUrl() { $path = str_replace('\\', '/', $this->getTarget()); return url('system/files/' . $path, array('absolute' => TRUE)); } + } diff --git a/core/lib/Drupal/Core/StreamWrapper/PublicStream.php b/core/lib/Drupal/Core/StreamWrapper/PublicStream.php index 90f17b3..c5a6c3b 100644 --- a/core/lib/Drupal/Core/StreamWrapper/PublicStream.php +++ b/core/lib/Drupal/Core/StreamWrapper/PublicStream.php @@ -2,7 +2,7 @@ /** * @file - * Definition of Drupal\Core\StreamWrapper\PublicStream. + * Contains \Drupal\Core\StreamWrapper\PublicStream. */ namespace Drupal\Core\StreamWrapper; diff --git a/core/lib/Drupal/Core/StreamWrapper/StreamWrapperManager.php b/core/lib/Drupal/Core/StreamWrapper/StreamWrapperManager.php new file mode 100644 index 0000000..5154e5c --- /dev/null +++ b/core/lib/Drupal/Core/StreamWrapper/StreamWrapperManager.php @@ -0,0 +1,172 @@ + STREAM_WRAPPERS_NORMAL, + ); + + /** + * Constructs a new StreamWrapperManager object. + * + * @param \Traversable $namespaces + * An object that implements \Traversable which contains the root paths + * keyed by the corresponding namespace to look for plugin implementations. + * @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler + * The module handler to invoke the alter hook with. + */ + public function __construct(\Traversable $namespaces, ModuleHandlerInterface $module_handler) { + $this->discovery = new HookDiscovery($module_handler, 'stream_wrappers'); + $this->discovery = new ContainerDerivativeDiscoveryDecorator($this->discovery); + $this->factory = new ContainerFactory($this); + $this->alterInfo($module_handler, 'stream_wrappers'); + } + + /** + * Provides Drupal stream wrapper registry. + * + * 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(STREAM_WRAPPERS_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(STREAM_WRAPPERS_ALL), file_get_stream_wrappers(STREAM_WRAPPERS_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 STREAM_WRAPPERS_WRITE_VISIBLE, + * which is equal to (STREAM_WRAPPERS_READ | STREAM_WRAPPERS_WRITE | + * STREAM_WRAPPERS_VISIBLE), then only stream wrappers with all three of + * these bits set are returned. Defaults to STREAM_WRAPPERS_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 STREAM_WRAPPERS_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 = STREAM_WRAPPERS_ALL) { + if (!$this->wrappers) { + $wrappers = $this->getDefinitions(); + foreach ($wrappers as $scheme => $info) { + // Pre-populate the static cache with the filters most typically used. + $this->wrappers[STREAM_WRAPPERS_ALL][$scheme] = $info; + if (($info['type'] & STREAM_WRAPPERS_WRITE_VISIBLE) == STREAM_WRAPPERS_WRITE_VISIBLE) { + $this->wrappers[STREAM_WRAPPERS_WRITE_VISIBLE][$scheme] = $info; + } + } + } + + if (!isset($this->wrappers[$filter])) { + $this->wrappers[$filter] = array(); + foreach ($this->wrappers[STREAM_WRAPPERS_ALL] as $scheme => $info) { + // Bit-wise filter. + if (($info['type'] & $filter) == $filter) { + $this->wrappers[$filter][$scheme] = $info; + } + } + } + + return $this->wrappers[$filter]; + } + + /** + * {@inheritdoc} + */ + public function processDefinition(&$definition, $plugin_id) { + parent::processDefinition($definition, $plugin_id); + + // Record whether we are overriding an existing scheme. + if (in_array($plugin_id, stream_get_wrappers(), TRUE)) { + $definition['override'] = TRUE; + stream_wrapper_unregister($plugin_id); + } + else { + $definition['override'] = FALSE; + } + + if (($definition['type'] & STREAM_WRAPPERS_LOCAL) == STREAM_WRAPPERS_LOCAL) { + stream_wrapper_register($plugin_id, $definition['class']); + } + else { + stream_wrapper_register($plugin_id, $definition['class'], STREAM_IS_URL); + } + } + + /** + * {@inheritdoc} + */ + public function getInstance(array $options) { + if (isset($options['scheme'])) { + $scheme = $options['scheme']; + $uri = $scheme . '://'; + } + elseif (isset($options['uri'])) { + $uri = $options['uri']; + $scheme = file_uri_scheme($uri); + } + else { + return FALSE; + } + + // Attempt to instantiate a stream wrapper. + try { + $instance = $this->createInstance($scheme); + $instance->setUri($uri); + return $instance; + } + catch (PluginException $e) { + return FALSE; + } + } + +} diff --git a/core/lib/Drupal/Core/StreamWrapper/TemporaryStream.php b/core/lib/Drupal/Core/StreamWrapper/TemporaryStream.php index 42dd4fd..ca4d133 100644 --- a/core/lib/Drupal/Core/StreamWrapper/TemporaryStream.php +++ b/core/lib/Drupal/Core/StreamWrapper/TemporaryStream.php @@ -2,7 +2,7 @@ /** * @file - * Definition of Drupal\Core\StreamWrapper\TemporaryStream. + * Contains \Drupal\Core\StreamWrapper\TemporaryStream. */ namespace Drupal\Core\StreamWrapper; @@ -16,17 +16,18 @@ class TemporaryStream extends LocalStream { /** - * Implements Drupal\Core\StreamWrapper\LocalStream::getDirectoryPath() + * {@inheritdoc} */ public function getDirectoryPath() { return file_directory_temp(); } /** - * Implements Drupal\Core\StreamWrapper\StreamWrapperInterface::getExternalUrl(). + * {@inheritdoc} */ public function getExternalUrl() { $path = str_replace('\\', '/', $this->getTarget()); return url('system/temporary/' . $path, array('absolute' => TRUE)); } + } diff --git a/core/modules/file/tests/file_test/lib/Drupal/file_test/DummyReadOnlyStreamWrapper.php b/core/modules/file/tests/file_test/lib/Drupal/file_test/DummyReadOnlyStreamWrapper.php index b427d3f..f594669 100644 --- a/core/modules/file/tests/file_test/lib/Drupal/file_test/DummyReadOnlyStreamWrapper.php +++ b/core/modules/file/tests/file_test/lib/Drupal/file_test/DummyReadOnlyStreamWrapper.php @@ -2,7 +2,7 @@ /** * @file - * Definition of Drupal\file_test\DummyReadOnlyStreamWrapper. + * Contains \Drupal\file_test\DummyReadOnlyStreamWrapper. */ namespace Drupal\file_test; @@ -15,25 +15,26 @@ * Dummy stream wrapper implementation (dummy-readonly://). */ class DummyReadOnlyStreamWrapper extends LocalReadOnlyStream { + + /** + * {@inheritdoc} + */ function getDirectoryPath() { return 'sites/default/files'; } /** - * Override getInternalUri(). - * - * Return a dummy path for testing. + * {@inheritdoc} */ function getInternalUri() { return '/dummy/example.txt'; } /** - * Override getExternalUrl(). - * - * Return the HTML URI of a public file. + * {@inheritdoc} */ function getExternalUrl() { return '/dummy/example.txt'; } + } diff --git a/core/modules/file/tests/file_test/lib/Drupal/file_test/DummyRemoteStreamWrapper.php b/core/modules/file/tests/file_test/lib/Drupal/file_test/DummyRemoteStreamWrapper.php index 2741196..0e5ba66 100644 --- a/core/modules/file/tests/file_test/lib/Drupal/file_test/DummyRemoteStreamWrapper.php +++ b/core/modules/file/tests/file_test/lib/Drupal/file_test/DummyRemoteStreamWrapper.php @@ -2,7 +2,7 @@ /** * @file - * Definition of Drupal\file_test\DummyRemoteStreamWrapper. + * Contains \Drupal\file_test\DummyRemoteStreamWrapper. */ namespace Drupal\file_test; @@ -17,7 +17,12 @@ * Basically just the public scheme but not returning a local file for realpath. */ class DummyRemoteStreamWrapper extends PublicStream { + + /** + * {@inheritdoc} + */ function realpath() { return FALSE; } + } diff --git a/core/modules/file/tests/file_test/lib/Drupal/file_test/DummyStreamWrapper.php b/core/modules/file/tests/file_test/lib/Drupal/file_test/DummyStreamWrapper.php index 4836f09..54f33f3 100644 --- a/core/modules/file/tests/file_test/lib/Drupal/file_test/DummyStreamWrapper.php +++ b/core/modules/file/tests/file_test/lib/Drupal/file_test/DummyStreamWrapper.php @@ -2,7 +2,7 @@ /** * @file - * Definition of Drupal\file_test\DummyStreamWrapper. + * Contains \Drupal\file_test\DummyStreamWrapper. */ namespace Drupal\file_test; @@ -20,20 +20,17 @@ function getDirectoryPath() { } /** - * Override getInternalUri(). - * - * Return a dummy path for testing. + * {@inheritdoc} */ function getInternalUri() { return '/dummy/example.txt'; } /** - * Override getExternalUrl(). - * - * Return the HTML URI of a public file. + * {@inheritdoc} */ function getExternalUrl() { return '/dummy/example.txt'; } + } diff --git a/core/modules/image/lib/Drupal/image/Entity/ImageStyle.php b/core/modules/image/lib/Drupal/image/Entity/ImageStyle.php index d67bcad..b706b52 100644 --- a/core/modules/image/lib/Drupal/image/Entity/ImageStyle.php +++ b/core/modules/image/lib/Drupal/image/Entity/ImageStyle.php @@ -254,7 +254,7 @@ public function flush($path = NULL) { } // Delete the style directory in each registered wrapper. - $wrappers = file_get_stream_wrappers(STREAM_WRAPPERS_WRITE_VISIBLE); + $wrappers = \Drupal::service('plugin.manager.stream_wrapper')->getWrappers(STREAM_WRAPPERS_WRITE_VISIBLE); foreach ($wrappers as $wrapper => $wrapper_data) { if (file_exists($directory = $wrapper . '://styles/' . $this->id())) { file_unmanaged_delete_recursive($directory); diff --git a/core/modules/locale/lib/Drupal/locale/TranslationsStream.php b/core/modules/locale/lib/Drupal/locale/TranslationsStream.php index 5245bd4..cc59708 100644 --- a/core/modules/locale/lib/Drupal/locale/TranslationsStream.php +++ b/core/modules/locale/lib/Drupal/locale/TranslationsStream.php @@ -2,7 +2,7 @@ /** * @file - * Definition of Drupal\locale\TranslationStream. + * Contains \Drupal\locale\TranslationStream. */ namespace Drupal\locale; @@ -17,17 +17,19 @@ class TranslationsStream extends LocalStream { /** - * Implements Drupal\Core\StreamWrapper\LocalStream::getDirectoryPath() + * {@inheritdoc} */ function getDirectoryPath() { return \Drupal::config('locale.settings')->get('translation.path'); } /** - * Implements Drupal\Core\StreamWrapper\StreamWrapperInterface::getExternalUrl(). + * {@inheritdoc} + * * @throws \LogicException PO files URL should not be public. */ function getExternalUrl() { throw new \LogicException('PO files URL should not be public.'); } + } diff --git a/core/modules/system/lib/Drupal/system/Form/FileSystemForm.php b/core/modules/system/lib/Drupal/system/Form/FileSystemForm.php index 2d51684..f15c700 100644 --- a/core/modules/system/lib/Drupal/system/Form/FileSystemForm.php +++ b/core/modules/system/lib/Drupal/system/Form/FileSystemForm.php @@ -7,8 +7,14 @@ namespace Drupal\system\Form; +use Drupal\Component\Utility\String; +use Drupal\Core\Config\ConfigFactory; +use Drupal\Core\Config\Context\ContextInterface; use Drupal\Core\StreamWrapper\PublicStream; use Drupal\Core\Form\ConfigFormBase; +use Drupal\Core\StreamWrapper\StreamWrapperManager; +use Drupal\system\SystemConfigFormBase; +use Symfony\Component\DependencyInjection\ContainerInterface; /** * Configure file system settings for this site. @@ -16,6 +22,40 @@ class FileSystemForm extends ConfigFormBase { /** + * The stream wrapper manager. + * + * @var \Drupal\Core\StreamWrapper\StreamWrapperManager + */ + protected $streamWrapperManager; + + /** + * Constructs a FileSystemForm object. + * + * @param \Drupal\Core\Config\ConfigFactory $config_factory + * The factory for configuration objects. + * @param \Drupal\Core\Config\Context\ContextInterface $context + * The configuration context to use. + * @param \Drupal\Core\StreamWrapper\StreamWrapperManager $stream_wrapper_manager + * The stream wrapper manager. + */ + public function __construct(ConfigFactory $config_factory, ContextInterface $context, StreamWrapperManager $stream_wrapper_manager) { + parent::__construct($config_factory, $context); + + $this->streamWrapperManager = $stream_wrapper_manager; + } + + /** + * {@inheritdoc} + */ + public static function create(ContainerInterface $container) { + return new static( + $container->get('config.factory'), + $container->get('config.context.free'), + $container->get('plugin.manager.stream_wrapper') + ); + } + + /** * {@inheritdoc} */ public function getFormId() { @@ -54,9 +94,9 @@ public function buildForm(array $form, array &$form_state) { ); // Any visible, writeable wrapper can potentially be used for the files // directory, including a remote file system that integrates with a CDN. - foreach (file_get_stream_wrappers(STREAM_WRAPPERS_WRITE_VISIBLE) as $scheme => $info) { - $options[$scheme] = check_plain($info['description']); - } + $options = array_map(function ($wrapper) { + return String::checkPlain($wrapper['description']); + }, $this->streamWrapperManager->getWrappers(STREAM_WRAPPERS_WRITE_VISIBLE)); if (!empty($options)) { $form['file_default_scheme'] = array( diff --git a/core/modules/system/system.api.php b/core/modules/system/system.api.php index 2bff21f..e080b57 100644 --- a/core/modules/system/system.api.php +++ b/core/modules/system/system.api.php @@ -1801,7 +1801,7 @@ function hook_stream_wrappers() { * Alters the list of PHP stream wrapper implementations. * * @see file_get_stream_wrappers() - * @see hook_stream_wrappers() + * @see \Drupal\Core\StreamWrapper\StreamWrapperManager */ function hook_stream_wrappers_alter(&$wrappers) { // Change the name of private files to reflect the performance.