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