Completed
Push — master ( d66330...eb9ee0 )
by Grégoire
02:15
created

src/Command/SyncThumbsCommand.php (1 issue)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
3
declare(strict_types=1);
4
5
/*
6
 * This file is part of the Sonata Project package.
7
 *
8
 * (c) Thomas Rabaix <[email protected]>
9
 *
10
 * For the full copyright and license information, please view the LICENSE
11
 * file that was distributed with this source code.
12
 */
13
14
namespace Sonata\MediaBundle\Command;
15
16
use Sonata\MediaBundle\Model\MediaInterface;
17
use Sonata\MediaBundle\Provider\MediaProviderInterface;
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
use Symfony\Component\Console\Question\ChoiceQuestion;
23
24
/**
25
 * This command can be used to re-generate the thumbnails for all uploaded medias.
26
 *
27
 * Useful if you have existing media content and added new formats.
28
 *
29
 * @final since sonata-project/media-bundle 3.21.0
30
 */
31
class SyncThumbsCommand extends BaseCommand
0 ignored issues
show
Deprecated Code introduced by
The class Sonata\MediaBundle\Command\BaseCommand has been deprecated with message: since sonata-project/media-bundle 3.x, to be removed in 4.0.

This class, trait or interface has been deprecated. The supplier of the file has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the type will be removed from the class and what other constant to use instead.

Loading history...
32
{
33
    /**
34
     * @var bool
35
     */
36
    protected $quiet = false;
37
38
    /**
39
     * @var OutputInterface
40
     */
41
    protected $output;
42
43
    public function configure(): void
44
    {
45
        $this->setName('sonata:media:sync-thumbnails')
46
            ->setDescription('Sync uploaded image thumbs with new media formats')
47
            ->setDefinition(
48
                [
49
                new InputArgument('providerName', InputArgument::OPTIONAL, 'The provider'),
50
                new InputArgument('context', InputArgument::OPTIONAL, 'The context'),
51
                new InputOption('batchSize', null, InputOption::VALUE_REQUIRED, 'Media batch size (100 by default)', 100),
52
                new InputOption('batchesLimit', null, InputOption::VALUE_REQUIRED, 'Media batches limit (0 by default)', 0),
53
                new InputOption('startOffset', null, InputOption::VALUE_REQUIRED, 'Medias start offset (0 by default)', 0),
54
            ]
55
            );
56
    }
57
58
    public function execute(InputInterface $input, OutputInterface $output): int
59
    {
60
        $helper = $this->getHelper('question');
61
62
        $providerName = $input->getArgument('providerName');
63
        if (null === $providerName) {
64
            $providers = array_keys($this->getMediaPool()->getProviders());
65
            $question = new ChoiceQuestion('Please select the provider', $providers, 0);
66
            $question->setErrorMessage('Provider %s is invalid.');
67
68
            $providerName = $helper->ask($input, $output, $question);
69
        }
70
71
        $context = $input->getArgument('context');
72
        if (null === $context) {
73
            $contexts = array_keys($this->getMediaPool()->getContexts());
74
            $question = new ChoiceQuestion('Please select the context', $contexts, 0);
75
            $question->setErrorMessage('Context %s is invalid.');
76
77
            $context = $helper->ask($input, $output, $question);
78
        }
79
80
        $this->quiet = $input->getOption('quiet');
81
        $this->output = $output;
82
83
        $provider = $this->getMediaPool()->getProvider($providerName);
84
85
        $filesystem = $provider->getFilesystem();
86
        $fsReflection = new \ReflectionClass($filesystem);
87
        $fsRegister = $fsReflection->getProperty('fileRegister');
88
        $fsRegister->setAccessible(true);
89
90
        $batchCounter = 0;
91
        $batchSize = (int) $input->getOption('batchSize');
92
        $batchesLimit = (int) $input->getOption('batchesLimit');
93
        $startOffset = (int) $input->getOption('startOffset');
94
        $totalMediasCount = 0;
95
        do {
96
            ++$batchCounter;
97
98
            try {
99
                $batchOffset = $startOffset + ($batchCounter - 1) * $batchSize;
100
                $medias = $this->getMediaManager()->findBy(
101
                    [
102
                        'providerName' => $providerName,
103
                        'context' => $context,
104
                    ],
105
                    [
106
                        'id' => 'ASC',
107
                    ],
108
                    $batchSize,
109
                    $batchOffset
110
                );
111
            } catch (\Exception $e) {
112
                $this->log('Error: '.$e->getMessage());
113
114
                break;
115
            }
116
117
            $batchMediasCount = \count($medias);
118
            if (0 === $batchMediasCount) {
119
                break;
120
            }
121
122
            $totalMediasCount += $batchMediasCount;
123
            $this->log(
124
                sprintf(
125
                    'Loaded %s medias (batch #%d, offset %d) for generating thumbs (provider: %s, context: %s)',
126
                    $batchMediasCount,
127
                    $batchCounter,
128
                    $batchOffset,
129
                    $providerName,
130
                    $context
131
                )
132
            );
133
134
            foreach ($medias as $media) {
135
                if (!$this->processMedia($media, $provider)) {
136
                    continue;
137
                }
138
                //clean filesystem registry for saving memory
139
                $fsRegister->setValue($filesystem, []);
140
            }
141
142
            //clear entity manager for saving memory
143
            $this->getMediaManager()->getObjectManager()->clear();
144
145
            if ($batchesLimit > 0 && $batchCounter === $batchesLimit) {
146
                break;
147
            }
148
        } while (true);
149
150
        $this->log("Done (total medias processed: {$totalMediasCount}).");
151
152
        return 0;
153
    }
154
155
    /**
156
     * @param MediaInterface         $media
157
     * @param MediaProviderInterface $provider
158
     */
159
    protected function processMedia($media, $provider): bool
160
    {
161
        $this->log('Generating thumbs for '.$media->getName().' - '.$media->getId());
162
163
        try {
164
            $provider->removeThumbnails($media);
165
        } catch (\Exception $e) {
166
            $this->log(sprintf(
167
                '<error>Unable to remove old thumbnails, media: %s - %s </error>',
168
                $media->getId(),
169
                $e->getMessage()
170
            ));
171
172
            return false;
173
        }
174
175
        try {
176
            $provider->generateThumbnails($media);
177
        } catch (\Exception $e) {
178
            $this->log(sprintf(
179
                '<error>Unable to generate new thumbnails, media: %s - %s </error>',
180
                $media->getId(),
181
                $e->getMessage()
182
            ));
183
184
            return false;
185
        }
186
187
        return true;
188
    }
189
190
    /**
191
     * Write a message to the output.
192
     *
193
     * @param string $message
194
     */
195
    protected function log($message): void
196
    {
197
        if (false === $this->quiet) {
198
            $this->output->writeln($message);
199
        }
200
    }
201
}
202