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\Command; |
13
|
|
|
|
14
|
|
|
use Liip\ImagineBundle\Imagine\Cache\CacheManager; |
15
|
|
|
use Liip\ImagineBundle\Imagine\Data\DataManager; |
16
|
|
|
use Liip\ImagineBundle\Imagine\Filter\FilterManager; |
17
|
|
|
use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand; |
18
|
|
|
use Symfony\Component\Console\Input\InputArgument; |
19
|
|
|
use Symfony\Component\Console\Input\InputInterface; |
20
|
|
|
use Symfony\Component\Console\Input\InputOption; |
21
|
|
|
use Symfony\Component\Console\Output\OutputInterface; |
22
|
|
|
|
23
|
|
|
class ResolveCacheCommand extends ContainerAwareCommand |
24
|
|
|
{ |
25
|
|
|
protected function configure() |
26
|
|
|
{ |
27
|
|
|
$this |
28
|
|
|
->setName('liip:imagine:cache:resolve') |
29
|
|
|
->setDescription('Resolve cache for given path and set of filters.') |
30
|
|
|
->addArgument('paths', InputArgument::REQUIRED | InputArgument::IS_ARRAY, |
31
|
|
|
'Any number of image paths to act on.') |
32
|
|
|
->addOption('filters', null, InputOption::VALUE_OPTIONAL | InputOption::VALUE_IS_ARRAY, |
33
|
|
|
'List of filters to apply to passed images (Deprecated, use "filter").') |
34
|
|
|
->addOption('filter', 'f', InputOption::VALUE_OPTIONAL | InputOption::VALUE_IS_ARRAY, |
35
|
|
|
'List of filters to apply to passed images.') |
36
|
|
|
->addOption('force', 'F', InputOption::VALUE_NONE, |
37
|
|
|
'Force image resolution regardless of cache.') |
38
|
|
|
->addOption('as-script', 's', InputOption::VALUE_NONE, |
39
|
|
|
'Only print machine-parseable results.') |
40
|
|
|
->setHelp(<<<'EOF' |
41
|
|
|
The <comment>%command.name%</comment> command resolves the passed image(s) for the resolved |
42
|
|
|
filter(s), outputting results using the following basic format: |
43
|
|
|
<info>- "image.ext[filter]" (resolved|cached|failed) as "path/to/cached/image.ext"</> |
44
|
|
|
|
45
|
|
|
<comment># bin/console %command.name% --filter=thumb1 foo.ext bar.ext</comment> |
46
|
|
|
Resolve <options=bold>both</> <comment>foo.ext</comment> and <comment>bar.ext</comment> using <comment>thumb1</comment> filter, outputting: |
47
|
|
|
<info>- "foo.ext[thumb1]" resolved as "http://localhost/media/cache/thumb1/foo.ext"</> |
48
|
|
|
<info>- "bar.ext[thumb1]" resolved as "http://localhost/media/cache/thumb1/bar.ext"</> |
49
|
|
|
|
50
|
|
|
<comment># bin/console %command.name% --filter=thumb1 --filter=thumb2 foo.ext</comment> |
51
|
|
|
Resolve <comment>foo.ext</comment> using <options=bold>both</> <comment>thumb1</comment> and <comment>thumb2</comment> filters, outputting: |
52
|
|
|
<info>- "foo.ext[thumb1]" resolved as "http://localhost/media/cache/thumb1/foo.ext"</> |
53
|
|
|
<info>- "foo.ext[thumb2]" resolved as "http://localhost/media/cache/thumb2/foo.ext"</> |
54
|
|
|
|
55
|
|
|
<comment># bin/console %command.name% foo.ext</comment> |
56
|
|
|
Resolve <comment>foo.ext</comment> using <options=bold>all configured filters</> (as none are specified), outputting: |
57
|
|
|
<info>- "foo.ext[thumb1]" resolved as "http://localhost/media/cache/thumb1/foo.ext"</> |
58
|
|
|
<info>- "foo.ext[thumb2]" resolved as "http://localhost/media/cache/thumb2/foo.ext"</> |
59
|
|
|
|
60
|
|
|
<comment># bin/console %command.name% --force --filter=thumb1 foo.ext</comment> |
61
|
|
|
Resolve <comment>foo.ext</comment> using <comment>thumb1</comment> and <options=bold>force creation</> regardless of cache, outputting: |
62
|
|
|
<info>- "foo.ext[thumb1]" resolved as "http://localhost/media/cache/thumb1/foo.ext"</> |
63
|
|
|
|
64
|
|
|
EOF |
65
|
|
|
); |
66
|
|
|
} |
67
|
|
|
|
68
|
|
|
protected function execute(InputInterface $input, OutputInterface $output) |
69
|
|
|
{ |
70
|
|
|
$force = $input->getOption('force'); |
71
|
|
|
$paths = $input->getArgument('paths'); |
72
|
|
|
$filters = $this->resolveInputFilters($input); |
73
|
|
|
$machine = $input->getOption('as-script'); |
74
|
|
|
$failed = 0; |
75
|
|
|
|
76
|
|
|
$filterManager = $this->getFilterManager(); |
77
|
|
|
$dataManager = $this->getDataManager(); |
78
|
|
|
$cacheManager = $this->getCacheManager(); |
79
|
|
|
|
80
|
|
|
if (0 === count($filters)) { |
81
|
|
|
$filters = array_keys($filterManager->getFilterConfiguration()->all()); |
82
|
|
|
} |
83
|
|
|
|
84
|
|
|
$this->outputTitle($output, $machine); |
85
|
|
|
|
86
|
|
|
foreach ($paths as $path) { |
87
|
|
|
foreach ($filters as $filter) { |
88
|
|
|
$output->write(sprintf('- %s[%s] ', $path, $filter)); |
89
|
|
|
|
90
|
|
|
try { |
91
|
|
|
if ($force || !$cacheManager->isStored($path, $filter)) { |
92
|
|
|
$cacheManager->store($filterManager->applyFilter($dataManager->find($filter, $path), $filter), $path, $filter); |
93
|
|
|
$output->write('resolved: '); |
94
|
|
|
} else { |
95
|
|
|
$output->write('cached: '); |
96
|
|
|
} |
97
|
|
|
|
98
|
|
|
$output->writeln($cacheManager->resolve($path, $filter)); |
99
|
|
|
} catch (\Exception $e) { |
100
|
|
|
$output->writeln(sprintf('failed: %s', $e->getMessage())); |
101
|
|
|
++$failed; |
102
|
|
|
} |
103
|
|
|
} |
104
|
|
|
} |
105
|
|
|
|
106
|
|
|
$this->outputSummary($output, $machine, count($filters), count($paths), $failed); |
107
|
|
|
|
108
|
|
|
return 0 === $failed ? 0 : 255; |
109
|
|
|
} |
110
|
|
|
|
111
|
|
|
/** |
112
|
|
|
* @param OutputInterface $output |
113
|
|
|
* @param bool $machine |
114
|
|
|
*/ |
115
|
|
|
private function outputTitle(OutputInterface $output, $machine) |
116
|
|
|
{ |
117
|
|
|
if (!$machine) { |
118
|
|
|
$title = '[liip/imagine-bundle] Image Resolver'; |
119
|
|
|
|
120
|
|
|
$output->writeln(sprintf('<info>%s</info>', $title)); |
121
|
|
|
$output->writeln(str_repeat('=', strlen($title))); |
122
|
|
|
$output->writeln(''); |
123
|
|
|
} |
124
|
|
|
} |
125
|
|
|
|
126
|
|
|
/** |
127
|
|
|
* @param OutputInterface $output |
128
|
|
|
* @param bool $machine |
129
|
|
|
* @param int $filters |
130
|
|
|
* @param int $paths |
131
|
|
|
* @param int $failed |
132
|
|
|
*/ |
133
|
|
|
private function outputSummary(OutputInterface $output, $machine, $filters, $paths, $failed) |
134
|
|
|
{ |
135
|
|
|
if (!$machine) { |
136
|
|
|
$operations = ($filters * $paths) - $failed; |
137
|
|
|
|
138
|
|
|
$output->writeln(''); |
139
|
|
|
$output->writeln(vsprintf('Completed %d %s (%d %s on %d %s) <fg=red;options=bold>%s</>', array( |
140
|
|
|
$operations, |
141
|
|
|
$this->pluralizeWord($operations, 'operation'), |
142
|
|
|
$filters, |
143
|
|
|
$this->pluralizeWord($filters, 'filter'), |
144
|
|
|
$paths, |
145
|
|
|
$this->pluralizeWord($paths, 'image'), |
146
|
|
|
0 === $failed ? '' : sprintf('[encountered %d %s]', $failed, $this->pluralizeWord($failed, 'failure')), |
147
|
|
|
))); |
148
|
|
|
} |
149
|
|
|
} |
150
|
|
|
|
151
|
|
|
/** |
152
|
|
|
* @param int $count |
153
|
|
|
* @param string $singular |
154
|
|
|
* @param string $pluralEnding |
155
|
|
|
* |
156
|
|
|
* @return string |
157
|
|
|
*/ |
158
|
|
|
private function pluralizeWord($count, $singular, $pluralEnding = 's') |
159
|
|
|
{ |
160
|
|
|
return 1 === $count ? $singular : $singular.$pluralEnding; |
161
|
|
|
} |
162
|
|
|
|
163
|
|
|
/** |
164
|
|
|
* @param InputInterface $input |
165
|
|
|
* |
166
|
|
|
* @return array|mixed |
167
|
|
|
*/ |
168
|
|
View Code Duplication |
private function resolveInputFilters(InputInterface $input) |
|
|
|
|
169
|
|
|
{ |
170
|
|
|
$filters = $input->getOption('filter'); |
171
|
|
|
|
172
|
|
|
if (count($filtersDeprecated = $input->getOption('filters'))) { |
173
|
|
|
$filters = array_merge($filters, $filtersDeprecated); |
174
|
|
|
@trigger_error('As of 1.9, use of the "--filters" option has been deprecated in favor of "--filter" and will be removed in 2.0.', E_USER_DEPRECATED); |
|
|
|
|
175
|
|
|
} |
176
|
|
|
|
177
|
|
|
return $filters; |
178
|
|
|
} |
179
|
|
|
|
180
|
|
|
/** |
181
|
|
|
* @return FilterManager |
182
|
|
|
*/ |
183
|
|
|
private function getFilterManager() |
184
|
|
|
{ |
185
|
|
|
return $this->getContainer()->get('liip_imagine.filter.manager'); |
186
|
|
|
} |
187
|
|
|
|
188
|
|
|
/** |
189
|
|
|
* @return DataManager |
190
|
|
|
*/ |
191
|
|
|
private function getDataManager() |
192
|
|
|
{ |
193
|
|
|
return $this->getContainer()->get('liip_imagine.data.manager'); |
194
|
|
|
} |
195
|
|
|
|
196
|
|
|
/** |
197
|
|
|
* @return CacheManager |
198
|
|
|
*/ |
199
|
|
|
private function getCacheManager() |
200
|
|
|
{ |
201
|
|
|
return $this->getContainer()->get('liip_imagine.cache.manager'); |
202
|
|
|
} |
203
|
|
|
} |
204
|
|
|
|
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.