PluginProbe
WPFunnels – Funnel Builder for WooCommerce with Checkout & One Click Upsell / 3.12.4
WPFunnels – Funnel Builder for WooCommerce with Checkout & One Click Upsell v3.12.4
3.13.3 3.13.2 3.13.1 3.13.0 3.12.13 3.12.12 3.12.11 3.12.10 3.12.9 3.12.8 3.12.7 3.12.6 3.12.5 3.12.4 3.12.3 3.12.1 3.12.2 3.12.0 3.11.1 3.11.0 3.10.9 3.10.8 3.10.7 3.10.6 2.8.16 All 261 releases
wpfunnels / vendor / league / flysystem / src / Filesystem.php

Filesystem.php in WPFunnels – Funnel Builder for WooCommerce with Checkout & One Click Upsell 3.12.4, at vendor/league/flysystem/src/Filesystem.php

291 lines 9.6 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 declare(strict_types=1);
4
5 namespace League\Flysystem;
6
7 use DateTimeInterface;
8 use Generator;
9 use League\Flysystem\UrlGeneration\PrefixPublicUrlGenerator;
10 use League\Flysystem\UrlGeneration\PublicUrlGenerator;
11 use League\Flysystem\UrlGeneration\ShardedPrefixPublicUrlGenerator;
12 use League\Flysystem\UrlGeneration\TemporaryUrlGenerator;
13 use Throwable;
14
15 use function array_key_exists;
16 use function is_array;
17
18 class Filesystem implements FilesystemOperator
19 {
20 use CalculateChecksumFromStream;
21
22 private Config $config;
23 private PathNormalizer $pathNormalizer;
24
25 public function __construct(
26 private FilesystemAdapter $adapter,
27 array $config = [],
28 ?PathNormalizer $pathNormalizer = null,
29 private ?PublicUrlGenerator $publicUrlGenerator = null,
30 private ?TemporaryUrlGenerator $temporaryUrlGenerator = null,
31 ) {
32 $this->config = new Config($config);
33 $this->pathNormalizer = $pathNormalizer ?? new WhitespacePathNormalizer();
34 }
35
36 public function fileExists(string $location): bool
37 {
38 return $this->adapter->fileExists($this->pathNormalizer->normalizePath($location));
39 }
40
41 public function directoryExists(string $location): bool
42 {
43 return $this->adapter->directoryExists($this->pathNormalizer->normalizePath($location));
44 }
45
46 public function has(string $location): bool
47 {
48 $path = $this->pathNormalizer->normalizePath($location);
49
50 return $this->adapter->fileExists($path) || $this->adapter->directoryExists($path);
51 }
52
53 public function write(string $location, string $contents, array $config = []): void
54 {
55 $this->adapter->write(
56 $this->pathNormalizer->normalizePath($location),
57 $contents,
58 $this->config->extend($config)
59 );
60 }
61
62 public function writeStream(string $location, $contents, array $config = []): void
63 {
64 /* @var resource $contents */
65 $this->assertIsResource($contents);
66 $this->rewindStream($contents);
67 $this->adapter->writeStream(
68 $this->pathNormalizer->normalizePath($location),
69 $contents,
70 $this->config->extend($config)
71 );
72 }
73
74 public function read(string $location): string
75 {
76 return $this->adapter->read($this->pathNormalizer->normalizePath($location));
77 }
78
79 public function readStream(string $location)
80 {
81 return $this->adapter->readStream($this->pathNormalizer->normalizePath($location));
82 }
83
84 public function delete(string $location): void
85 {
86 $this->adapter->delete($this->pathNormalizer->normalizePath($location));
87 }
88
89 public function deleteDirectory(string $location): void
90 {
91 $this->adapter->deleteDirectory($this->pathNormalizer->normalizePath($location));
92 }
93
94 public function createDirectory(string $location, array $config = []): void
95 {
96 $this->adapter->createDirectory(
97 $this->pathNormalizer->normalizePath($location),
98 $this->config->extend($config)
99 );
100 }
101
102 public function listContents(string $location, bool $deep = self::LIST_SHALLOW): DirectoryListing
103 {
104 $path = $this->pathNormalizer->normalizePath($location);
105 $listing = $this->adapter->listContents($path, $deep);
106
107 return new DirectoryListing($this->pipeListing($location, $deep, $listing));
108 }
109
110 private function pipeListing(string $location, bool $deep, iterable $listing): Generator
111 {
112 try {
113 foreach ($listing as $item) {
114 yield $item;
115 }
116 } catch (Throwable $exception) {
117 throw UnableToListContents::atLocation($location, $deep, $exception);
118 }
119 }
120
121 public function move(string $source, string $destination, array $config = []): void
122 {
123 $config = $this->resolveConfigForMoveAndCopy($config);
124 $from = $this->pathNormalizer->normalizePath($source);
125 $to = $this->pathNormalizer->normalizePath($destination);
126
127 if ($from === $to) {
128 $resolutionStrategy = $config->get(Config::OPTION_MOVE_IDENTICAL_PATH, ResolveIdenticalPathConflict::TRY);
129
130 if ($resolutionStrategy === ResolveIdenticalPathConflict::FAIL) {
131 throw UnableToMoveFile::sourceAndDestinationAreTheSame($source, $destination);
132 } elseif ($resolutionStrategy === ResolveIdenticalPathConflict::IGNORE) {
133 return;
134 }
135 }
136
137 $this->adapter->move($from, $to, $config);
138 }
139
140 public function copy(string $source, string $destination, array $config = []): void
141 {
142 $config = $this->resolveConfigForMoveAndCopy($config);
143 $from = $this->pathNormalizer->normalizePath($source);
144 $to = $this->pathNormalizer->normalizePath($destination);
145
146 if ($from === $to) {
147 $resolutionStrategy = $config->get(Config::OPTION_COPY_IDENTICAL_PATH, ResolveIdenticalPathConflict::TRY);
148
149 if ($resolutionStrategy === ResolveIdenticalPathConflict::FAIL) {
150 throw UnableToCopyFile::sourceAndDestinationAreTheSame($source, $destination);
151 } elseif ($resolutionStrategy === ResolveIdenticalPathConflict::IGNORE) {
152 return;
153 }
154 }
155
156 $this->adapter->copy($from, $to, $config);
157 }
158
159 public function lastModified(string $path): int
160 {
161 return $this->adapter->lastModified($this->pathNormalizer->normalizePath($path))->lastModified();
162 }
163
164 public function fileSize(string $path): int
165 {
166 return $this->adapter->fileSize($this->pathNormalizer->normalizePath($path))->fileSize();
167 }
168
169 public function mimeType(string $path): string
170 {
171 return $this->adapter->mimeType($this->pathNormalizer->normalizePath($path))->mimeType();
172 }
173
174 public function setVisibility(string $path, string $visibility): void
175 {
176 $this->adapter->setVisibility($this->pathNormalizer->normalizePath($path), $visibility);
177 }
178
179 public function visibility(string $path): string
180 {
181 return $this->adapter->visibility($this->pathNormalizer->normalizePath($path))->visibility();
182 }
183
184 public function publicUrl(string $path, array $config = []): string
185 {
186 $this->publicUrlGenerator ??= $this->resolvePublicUrlGenerator()
187 ?? throw UnableToGeneratePublicUrl::noGeneratorConfigured($path);
188 $config = $this->config->extend($config);
189
190 return $this->publicUrlGenerator->publicUrl(
191 $this->pathNormalizer->normalizePath($path),
192 $config,
193 );
194 }
195
196 public function temporaryUrl(string $path, DateTimeInterface $expiresAt, array $config = []): string
197 {
198 $generator = $this->temporaryUrlGenerator ?? $this->adapter;
199
200 if ($generator instanceof TemporaryUrlGenerator) {
201 return $generator->temporaryUrl(
202 $this->pathNormalizer->normalizePath($path),
203 $expiresAt,
204 $this->config->extend($config)
205 );
206 }
207
208 throw UnableToGenerateTemporaryUrl::noGeneratorConfigured($path);
209 }
210
211 public function checksum(string $path, array $config = []): string
212 {
213 $config = $this->config->extend($config);
214
215 if ( ! $this->adapter instanceof ChecksumProvider) {
216 return $this->calculateChecksumFromStream($path, $config);
217 }
218
219 try {
220 return $this->adapter->checksum(
221 $this->pathNormalizer->normalizePath($path),
222 $config,
223 );
224 } catch (ChecksumAlgoIsNotSupported) {
225 return $this->calculateChecksumFromStream(
226 $this->pathNormalizer->normalizePath($path),
227 $config,
228 );
229 }
230 }
231
232 private function resolvePublicUrlGenerator(): ?PublicUrlGenerator
233 {
234 if ($publicUrl = $this->config->get('public_url')) {
235 return match (true) {
236 is_array($publicUrl) => new ShardedPrefixPublicUrlGenerator($publicUrl),
237 default => new PrefixPublicUrlGenerator($publicUrl),
238 };
239 }
240
241 if ($this->adapter instanceof PublicUrlGenerator) {
242 return $this->adapter;
243 }
244
245 return null;
246 }
247
248 /**
249 * @param mixed $contents
250 */
251 private function assertIsResource($contents): void
252 {
253 if (is_resource($contents) === false) {
254 throw new InvalidStreamProvided(
255 "Invalid stream provided, expected stream resource, received " . gettype($contents)
256 );
257 } elseif ($type = get_resource_type($contents) !== 'stream') {
258 throw new InvalidStreamProvided(
259 "Invalid stream provided, expected stream resource, received resource of type " . $type
260 );
261 }
262 }
263
264 /**
265 * @param resource $resource
266 */
267 private function rewindStream($resource): void
268 {
269 if (ftell($resource) !== 0 && stream_get_meta_data($resource)['seekable']) {
270 rewind($resource);
271 }
272 }
273
274 private function resolveConfigForMoveAndCopy(array $config): Config
275 {
276 $retainVisibility = $this->config->get(Config::OPTION_RETAIN_VISIBILITY, $config[Config::OPTION_RETAIN_VISIBILITY] ?? true);
277 $fullConfig = $this->config->extend($config);
278
279 /*
280 * By default, we retain visibility. When we do not retain visibility, the visibility setting
281 * from the default configuration is ignored. Only when it is set explicitly, we propagate the
282 * setting.
283 */
284 if ($retainVisibility && ! array_key_exists(Config::OPTION_VISIBILITY, $config)) {
285 $fullConfig = $fullConfig->withoutSettings(Config::OPTION_VISIBILITY)->extend($config);
286 }
287
288 return $fullConfig;
289 }
290 }
291