Mercurial > hg > isophonics-drupal-site
diff core/lib/Drupal/Core/StreamWrapper/StreamWrapperManager.php @ 0:4c8ae668cc8c
Initial import (non-working)
author | Chris Cannam |
---|---|
date | Wed, 29 Nov 2017 16:09:58 +0000 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/core/lib/Drupal/Core/StreamWrapper/StreamWrapperManager.php Wed Nov 29 16:09:58 2017 +0000 @@ -0,0 +1,211 @@ +<?php + +namespace Drupal\Core\StreamWrapper; + +use Symfony\Component\DependencyInjection\ContainerAwareInterface; +use Symfony\Component\DependencyInjection\ContainerAwareTrait; + +/** + * Provides a StreamWrapper manager. + * + * @see \Drupal\Core\StreamWrapper\StreamWrapperInterface + */ +class StreamWrapperManager implements ContainerAwareInterface, StreamWrapperManagerInterface { + + use ContainerAwareTrait; + + /** + * Contains stream wrapper info. + * + * An associative array where keys are scheme names and values are themselves + * associative arrays with the keys class, type and (optionally) service_id, + * and string values. + * + * @var array + */ + protected $info = []; + + /** + * Contains collected stream wrappers. + * + * Keyed by filter, each value is itself an associative array keyed by scheme. + * Each of those values is an array representing a stream wrapper, with the + * following keys and values: + * - class: stream wrapper class name + * - type: a bitmask corresponding to the type constants in + * StreamWrapperInterface + * - service_id: name of service + * + * The array on key StreamWrapperInterface::ALL contains representations of + * all schemes and corresponding wrappers. + * + * @var array + */ + protected $wrappers = []; + + /** + * {@inheritdoc} + */ + public function getWrappers($filter = StreamWrapperInterface::ALL) { + if (isset($this->wrappers[$filter])) { + return $this->wrappers[$filter]; + } + elseif (isset($this->wrappers[StreamWrapperInterface::ALL])) { + $this->wrappers[$filter] = []; + foreach ($this->wrappers[StreamWrapperInterface::ALL] as $scheme => $info) { + // Bit-wise filter. + if (($info['type'] & $filter) == $filter) { + $this->wrappers[$filter][$scheme] = $info; + } + } + return $this->wrappers[$filter]; + } + else { + return []; + } + } + + /** + * {@inheritdoc} + */ + public function getNames($filter = StreamWrapperInterface::ALL) { + $names = []; + foreach (array_keys($this->getWrappers($filter)) as $scheme) { + $names[$scheme] = $this->getViaScheme($scheme)->getName(); + } + + return $names; + } + + /** + * {@inheritdoc} + */ + public function getDescriptions($filter = StreamWrapperInterface::ALL) { + $descriptions = []; + foreach (array_keys($this->getWrappers($filter)) as $scheme) { + $descriptions[$scheme] = $this->getViaScheme($scheme)->getDescription(); + } + + return $descriptions; + } + + /** + * {@inheritdoc} + */ + public function getViaScheme($scheme) { + return $this->getWrapper($scheme, $scheme . '://'); + } + + /** + * {@inheritdoc} + */ + public function getViaUri($uri) { + $scheme = file_uri_scheme($uri); + return $this->getWrapper($scheme, $uri); + } + + /** + * {@inheritdoc} + */ + public function getClass($scheme) { + if (isset($this->info[$scheme])) { + return $this->info[$scheme]['class']; + } + + return FALSE; + } + + /** + * Returns a stream wrapper instance. + * + * @param string $scheme + * The scheme of the desired stream wrapper. + * @param string $uri + * The URI of the stream. + * + * @return \Drupal\Core\StreamWrapper\StreamWrapperInterface|bool + * A stream wrapper object, or false if the scheme is not available. + */ + protected function getWrapper($scheme, $uri) { + if (isset($this->info[$scheme]['service_id'])) { + $instance = $this->container->get($this->info[$scheme]['service_id']); + $instance->setUri($uri); + return $instance; + } + + return FALSE; + } + + /** + * Adds a stream wrapper. + * + * Internal use only. + * + * @param string $service_id + * The service id. + * @param string $class + * The stream wrapper class. + * @param string $scheme + * The scheme for which the wrapper should be registered. + */ + public function addStreamWrapper($service_id, $class, $scheme) { + $this->info[$scheme] = [ + 'class' => $class, + 'type' => $class::getType(), + 'service_id' => $service_id, + ]; + } + + /** + * Registers the tagged stream wrappers. + * + * Internal use only. + */ + public function register() { + foreach ($this->info as $scheme => $info) { + $this->registerWrapper($scheme, $info['class'], $info['type']); + } + } + + /** + * Unregisters the tagged stream wrappers. + * + * Internal use only. + */ + public function unregister() { + // Normally, there are definitely wrappers set for the ALL filter. However, + // in some cases involving many container rebuilds (e.g. WebTestBase), + // $this->wrappers may be empty although wrappers are still registered + // globally. Thus an isset() check is needed before iterating. + if (isset($this->wrappers[StreamWrapperInterface::ALL])) { + foreach (array_keys($this->wrappers[StreamWrapperInterface::ALL]) as $scheme) { + stream_wrapper_unregister($scheme); + } + } + } + + /** + * {@inheritdoc} + */ + public function registerWrapper($scheme, $class, $type) { + if (in_array($scheme, stream_get_wrappers(), TRUE)) { + stream_wrapper_unregister($scheme); + } + + if (($type & StreamWrapperInterface::LOCAL) == StreamWrapperInterface::LOCAL) { + stream_wrapper_register($scheme, $class); + } + else { + stream_wrapper_register($scheme, $class, STREAM_IS_URL); + } + + // Pre-populate the static cache with the filters most typically used. + $info = ['type' => $type, 'class' => $class]; + $this->wrappers[StreamWrapperInterface::ALL][$scheme] = $info; + + if (($type & StreamWrapperInterface::WRITE_VISIBLE) == StreamWrapperInterface::WRITE_VISIBLE) { + $this->wrappers[StreamWrapperInterface::WRITE_VISIBLE][$scheme] = $info; + } + } + +}