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 }
|