annotate core/lib/Drupal/Core/StreamWrapper/StreamWrapperManager.php @ 19:fa3358dc1485 tip

Add ndrum files
author Chris Cannam
date Wed, 28 Aug 2019 13:14:47 +0100
parents 4c8ae668cc8c
children
rev   line source
Chris@0 1 <?php
Chris@0 2
Chris@0 3 namespace Drupal\Core\StreamWrapper;
Chris@0 4
Chris@0 5 use Symfony\Component\DependencyInjection\ContainerAwareInterface;
Chris@0 6 use Symfony\Component\DependencyInjection\ContainerAwareTrait;
Chris@0 7
Chris@0 8 /**
Chris@0 9 * Provides a StreamWrapper manager.
Chris@0 10 *
Chris@0 11 * @see \Drupal\Core\StreamWrapper\StreamWrapperInterface
Chris@0 12 */
Chris@0 13 class StreamWrapperManager implements ContainerAwareInterface, StreamWrapperManagerInterface {
Chris@0 14
Chris@0 15 use ContainerAwareTrait;
Chris@0 16
Chris@0 17 /**
Chris@0 18 * Contains stream wrapper info.
Chris@0 19 *
Chris@0 20 * An associative array where keys are scheme names and values are themselves
Chris@0 21 * associative arrays with the keys class, type and (optionally) service_id,
Chris@0 22 * and string values.
Chris@0 23 *
Chris@0 24 * @var array
Chris@0 25 */
Chris@0 26 protected $info = [];
Chris@0 27
Chris@0 28 /**
Chris@0 29 * Contains collected stream wrappers.
Chris@0 30 *
Chris@0 31 * Keyed by filter, each value is itself an associative array keyed by scheme.
Chris@0 32 * Each of those values is an array representing a stream wrapper, with the
Chris@0 33 * following keys and values:
Chris@0 34 * - class: stream wrapper class name
Chris@0 35 * - type: a bitmask corresponding to the type constants in
Chris@0 36 * StreamWrapperInterface
Chris@0 37 * - service_id: name of service
Chris@0 38 *
Chris@0 39 * The array on key StreamWrapperInterface::ALL contains representations of
Chris@0 40 * all schemes and corresponding wrappers.
Chris@0 41 *
Chris@0 42 * @var array
Chris@0 43 */
Chris@0 44 protected $wrappers = [];
Chris@0 45
Chris@0 46 /**
Chris@0 47 * {@inheritdoc}
Chris@0 48 */
Chris@0 49 public function getWrappers($filter = StreamWrapperInterface::ALL) {
Chris@0 50 if (isset($this->wrappers[$filter])) {
Chris@0 51 return $this->wrappers[$filter];
Chris@0 52 }
Chris@0 53 elseif (isset($this->wrappers[StreamWrapperInterface::ALL])) {
Chris@0 54 $this->wrappers[$filter] = [];
Chris@0 55 foreach ($this->wrappers[StreamWrapperInterface::ALL] as $scheme => $info) {
Chris@0 56 // Bit-wise filter.
Chris@0 57 if (($info['type'] & $filter) == $filter) {
Chris@0 58 $this->wrappers[$filter][$scheme] = $info;
Chris@0 59 }
Chris@0 60 }
Chris@0 61 return $this->wrappers[$filter];
Chris@0 62 }
Chris@0 63 else {
Chris@0 64 return [];
Chris@0 65 }
Chris@0 66 }
Chris@0 67
Chris@0 68 /**
Chris@0 69 * {@inheritdoc}
Chris@0 70 */
Chris@0 71 public function getNames($filter = StreamWrapperInterface::ALL) {
Chris@0 72 $names = [];
Chris@0 73 foreach (array_keys($this->getWrappers($filter)) as $scheme) {
Chris@0 74 $names[$scheme] = $this->getViaScheme($scheme)->getName();
Chris@0 75 }
Chris@0 76
Chris@0 77 return $names;
Chris@0 78 }
Chris@0 79
Chris@0 80 /**
Chris@0 81 * {@inheritdoc}
Chris@0 82 */
Chris@0 83 public function getDescriptions($filter = StreamWrapperInterface::ALL) {
Chris@0 84 $descriptions = [];
Chris@0 85 foreach (array_keys($this->getWrappers($filter)) as $scheme) {
Chris@0 86 $descriptions[$scheme] = $this->getViaScheme($scheme)->getDescription();
Chris@0 87 }
Chris@0 88
Chris@0 89 return $descriptions;
Chris@0 90 }
Chris@0 91
Chris@0 92 /**
Chris@0 93 * {@inheritdoc}
Chris@0 94 */
Chris@0 95 public function getViaScheme($scheme) {
Chris@0 96 return $this->getWrapper($scheme, $scheme . '://');
Chris@0 97 }
Chris@0 98
Chris@0 99 /**
Chris@0 100 * {@inheritdoc}
Chris@0 101 */
Chris@0 102 public function getViaUri($uri) {
Chris@0 103 $scheme = file_uri_scheme($uri);
Chris@0 104 return $this->getWrapper($scheme, $uri);
Chris@0 105 }
Chris@0 106
Chris@0 107 /**
Chris@0 108 * {@inheritdoc}
Chris@0 109 */
Chris@0 110 public function getClass($scheme) {
Chris@0 111 if (isset($this->info[$scheme])) {
Chris@0 112 return $this->info[$scheme]['class'];
Chris@0 113 }
Chris@0 114
Chris@0 115 return FALSE;
Chris@0 116 }
Chris@0 117
Chris@0 118 /**
Chris@0 119 * Returns a stream wrapper instance.
Chris@0 120 *
Chris@0 121 * @param string $scheme
Chris@0 122 * The scheme of the desired stream wrapper.
Chris@0 123 * @param string $uri
Chris@0 124 * The URI of the stream.
Chris@0 125 *
Chris@0 126 * @return \Drupal\Core\StreamWrapper\StreamWrapperInterface|bool
Chris@0 127 * A stream wrapper object, or false if the scheme is not available.
Chris@0 128 */
Chris@0 129 protected function getWrapper($scheme, $uri) {
Chris@0 130 if (isset($this->info[$scheme]['service_id'])) {
Chris@0 131 $instance = $this->container->get($this->info[$scheme]['service_id']);
Chris@0 132 $instance->setUri($uri);
Chris@0 133 return $instance;
Chris@0 134 }
Chris@0 135
Chris@0 136 return FALSE;
Chris@0 137 }
Chris@0 138
Chris@0 139 /**
Chris@0 140 * Adds a stream wrapper.
Chris@0 141 *
Chris@0 142 * Internal use only.
Chris@0 143 *
Chris@0 144 * @param string $service_id
Chris@0 145 * The service id.
Chris@0 146 * @param string $class
Chris@0 147 * The stream wrapper class.
Chris@0 148 * @param string $scheme
Chris@0 149 * The scheme for which the wrapper should be registered.
Chris@0 150 */
Chris@0 151 public function addStreamWrapper($service_id, $class, $scheme) {
Chris@0 152 $this->info[$scheme] = [
Chris@0 153 'class' => $class,
Chris@0 154 'type' => $class::getType(),
Chris@0 155 'service_id' => $service_id,
Chris@0 156 ];
Chris@0 157 }
Chris@0 158
Chris@0 159 /**
Chris@0 160 * Registers the tagged stream wrappers.
Chris@0 161 *
Chris@0 162 * Internal use only.
Chris@0 163 */
Chris@0 164 public function register() {
Chris@0 165 foreach ($this->info as $scheme => $info) {
Chris@0 166 $this->registerWrapper($scheme, $info['class'], $info['type']);
Chris@0 167 }
Chris@0 168 }
Chris@0 169
Chris@0 170 /**
Chris@0 171 * Unregisters the tagged stream wrappers.
Chris@0 172 *
Chris@0 173 * Internal use only.
Chris@0 174 */
Chris@0 175 public function unregister() {
Chris@0 176 // Normally, there are definitely wrappers set for the ALL filter. However,
Chris@0 177 // in some cases involving many container rebuilds (e.g. WebTestBase),
Chris@0 178 // $this->wrappers may be empty although wrappers are still registered
Chris@0 179 // globally. Thus an isset() check is needed before iterating.
Chris@0 180 if (isset($this->wrappers[StreamWrapperInterface::ALL])) {
Chris@0 181 foreach (array_keys($this->wrappers[StreamWrapperInterface::ALL]) as $scheme) {
Chris@0 182 stream_wrapper_unregister($scheme);
Chris@0 183 }
Chris@0 184 }
Chris@0 185 }
Chris@0 186
Chris@0 187 /**
Chris@0 188 * {@inheritdoc}
Chris@0 189 */
Chris@0 190 public function registerWrapper($scheme, $class, $type) {
Chris@0 191 if (in_array($scheme, stream_get_wrappers(), TRUE)) {
Chris@0 192 stream_wrapper_unregister($scheme);
Chris@0 193 }
Chris@0 194
Chris@0 195 if (($type & StreamWrapperInterface::LOCAL) == StreamWrapperInterface::LOCAL) {
Chris@0 196 stream_wrapper_register($scheme, $class);
Chris@0 197 }
Chris@0 198 else {
Chris@0 199 stream_wrapper_register($scheme, $class, STREAM_IS_URL);
Chris@0 200 }
Chris@0 201
Chris@0 202 // Pre-populate the static cache with the filters most typically used.
Chris@0 203 $info = ['type' => $type, 'class' => $class];
Chris@0 204 $this->wrappers[StreamWrapperInterface::ALL][$scheme] = $info;
Chris@0 205
Chris@0 206 if (($type & StreamWrapperInterface::WRITE_VISIBLE) == StreamWrapperInterface::WRITE_VISIBLE) {
Chris@0 207 $this->wrappers[StreamWrapperInterface::WRITE_VISIBLE][$scheme] = $info;
Chris@0 208 }
Chris@0 209 }
Chris@0 210
Chris@0 211 }