1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
/* |
4
|
|
|
* This file is part of the `liip/LiipImagineBundle` project. |
5
|
|
|
* |
6
|
|
|
* (c) https://github.com/liip/LiipImagineBundle/graphs/contributors |
7
|
|
|
* |
8
|
|
|
* For the full copyright and license information, please view the LICENSE.md |
9
|
|
|
* file that was distributed with this source code. |
10
|
|
|
*/ |
11
|
|
|
|
12
|
|
|
namespace Liip\ImagineBundle\Imagine\Cache\Resolver; |
13
|
|
|
|
14
|
|
|
use League\Flysystem\Config; |
15
|
|
|
use League\Flysystem\FilesystemOperator; |
16
|
|
|
use League\Flysystem\Visibility; |
17
|
|
|
use Liip\ImagineBundle\Binary\BinaryInterface; |
18
|
|
|
use Liip\ImagineBundle\Exception\Imagine\Cache\Resolver\NotResolvableException; |
19
|
|
|
use Symfony\Component\Routing\RequestContext; |
20
|
|
|
|
21
|
|
View Code Duplication |
class FlysystemV2Resolver implements ResolverInterface |
|
|
|
|
22
|
|
|
{ |
23
|
|
|
/** |
24
|
|
|
* @var FilesystemOperator |
25
|
|
|
*/ |
26
|
|
|
protected $flysystem; |
27
|
|
|
|
28
|
|
|
/** |
29
|
|
|
* @var RequestContext |
30
|
|
|
*/ |
31
|
|
|
protected $requestContext; |
32
|
|
|
|
33
|
|
|
/** |
34
|
|
|
* @var string |
35
|
|
|
*/ |
36
|
|
|
protected $webRoot; |
37
|
|
|
|
38
|
|
|
/** |
39
|
|
|
* @var string |
40
|
|
|
*/ |
41
|
|
|
protected $cachePrefix; |
42
|
|
|
|
43
|
|
|
/** |
44
|
|
|
* @var string |
45
|
|
|
*/ |
46
|
|
|
protected $cacheRoot; |
47
|
|
|
|
48
|
|
|
/** |
49
|
|
|
* Flysystem specific visibility. |
50
|
|
|
* |
51
|
|
|
* @see Visibility |
52
|
|
|
* |
53
|
|
|
* @var string |
54
|
|
|
*/ |
55
|
|
|
protected $visibility; |
56
|
|
|
|
57
|
|
|
/** |
58
|
|
|
* FlysystemResolver constructor. |
59
|
|
|
* |
60
|
|
|
* @param string $rootUrl |
61
|
|
|
* @param string $cachePrefix |
62
|
|
|
* @param string $visibility |
63
|
|
|
*/ |
64
|
|
|
public function __construct( |
65
|
|
|
FilesystemOperator $flysystem, |
66
|
|
|
RequestContext $requestContext, |
67
|
|
|
$rootUrl, |
68
|
|
|
$cachePrefix = 'media/cache', |
69
|
|
|
$visibility = Visibility::PUBLIC |
70
|
|
|
) { |
71
|
|
|
$this->flysystem = $flysystem; |
72
|
|
|
$this->requestContext = $requestContext; |
73
|
|
|
|
74
|
|
|
$this->webRoot = rtrim($rootUrl, '/'); |
75
|
|
|
$this->cachePrefix = ltrim(str_replace('//', '/', $cachePrefix), '/'); |
76
|
|
|
$this->cacheRoot = $this->cachePrefix; |
77
|
|
|
$this->visibility = $visibility; |
78
|
|
|
} |
79
|
|
|
|
80
|
|
|
/** |
81
|
|
|
* Checks whether the given path is stored within this Resolver. |
82
|
|
|
* |
83
|
|
|
* @param string $path |
84
|
|
|
* @param string $filter |
85
|
|
|
* |
86
|
|
|
* @return bool |
87
|
|
|
*/ |
88
|
|
|
public function isStored($path, $filter) |
89
|
|
|
{ |
90
|
|
|
return $this->flysystem->fileExists($this->getFilePath($path, $filter)); |
91
|
|
|
} |
92
|
|
|
|
93
|
|
|
/** |
94
|
|
|
* Resolves filtered path for rendering in the browser. |
95
|
|
|
* |
96
|
|
|
* @param string $path The path where the original file is expected to be |
97
|
|
|
* @param string $filter The name of the imagine filter in effect |
98
|
|
|
* |
99
|
|
|
* @throws NotResolvableException |
100
|
|
|
* |
101
|
|
|
* @return string The absolute URL of the cached image |
102
|
|
|
*/ |
103
|
|
|
public function resolve($path, $filter) |
104
|
|
|
{ |
105
|
|
|
return sprintf( |
106
|
|
|
'%s/%s', |
107
|
|
|
rtrim($this->webRoot, '/'), |
108
|
|
|
ltrim($this->getFileUrl($path, $filter), '/') |
109
|
|
|
); |
110
|
|
|
} |
111
|
|
|
|
112
|
|
|
/** |
113
|
|
|
* Stores the content of the given binary. |
114
|
|
|
* |
115
|
|
|
* @param BinaryInterface $binary The image binary to store |
116
|
|
|
* @param string $path The path where the original file is expected to be |
117
|
|
|
* @param string $filter The name of the imagine filter in effect |
118
|
|
|
*/ |
119
|
|
|
public function store(BinaryInterface $binary, $path, $filter) |
120
|
|
|
{ |
121
|
|
|
$this->flysystem->write( |
122
|
|
|
$this->getFilePath($path, $filter), |
123
|
|
|
$binary->getContent(), |
124
|
|
|
[Config::OPTION_VISIBILITY => $this->visibility, 'mimetype' => $binary->getMimeType()] |
125
|
|
|
); |
126
|
|
|
} |
127
|
|
|
|
128
|
|
|
/** |
129
|
|
|
* @param string[] $paths The paths where the original files are expected to be |
130
|
|
|
* @param string[] $filters The imagine filters in effect |
131
|
|
|
*/ |
132
|
|
|
public function remove(array $paths, array $filters) |
133
|
|
|
{ |
134
|
|
|
if (empty($paths) && empty($filters)) { |
135
|
|
|
return; |
136
|
|
|
} |
137
|
|
|
|
138
|
|
|
if (empty($paths)) { |
139
|
|
|
foreach ($filters as $filter) { |
140
|
|
|
$filterCacheDir = $this->cacheRoot.'/'.$filter; |
141
|
|
|
$this->flysystem->deleteDirectory($filterCacheDir); |
142
|
|
|
} |
143
|
|
|
|
144
|
|
|
return; |
145
|
|
|
} |
146
|
|
|
|
147
|
|
|
foreach ($paths as $path) { |
148
|
|
|
foreach ($filters as $filter) { |
149
|
|
|
if ($this->flysystem->fileExists($this->getFilePath($path, $filter))) { |
150
|
|
|
$this->flysystem->delete($this->getFilePath($path, $filter)); |
151
|
|
|
} |
152
|
|
|
} |
153
|
|
|
} |
154
|
|
|
} |
155
|
|
|
|
156
|
|
|
/** |
157
|
|
|
* {@inheritdoc} |
158
|
|
|
*/ |
159
|
|
|
protected function getFilePath($path, $filter) |
160
|
|
|
{ |
161
|
|
|
return $this->getFileUrl($path, $filter); |
162
|
|
|
} |
163
|
|
|
|
164
|
|
|
/** |
165
|
|
|
* {@inheritdoc} |
166
|
|
|
*/ |
167
|
|
|
protected function getFileUrl($path, $filter) |
168
|
|
|
{ |
169
|
|
|
// crude way of sanitizing URL scheme ("protocol") part |
170
|
|
|
$path = str_replace('://', '---', $path); |
171
|
|
|
|
172
|
|
|
return $this->cachePrefix.'/'.$filter.'/'.ltrim($path, '/'); |
173
|
|
|
} |
174
|
|
|
} |
175
|
|
|
|
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.