Completed
Push — master ( ba95f5...ac295e )
by
unknown
03:55
created

CleanMediaCommand::execute()   C

Complexity

Conditions 8
Paths 3

Size

Total Lines 44
Code Lines 28

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 44
rs 5.3846
cc 8
eloc 28
nc 3
nop 2
1
<?php
2
3
/*
4
 * This file is part of the Sonata Project package.
5
 *
6
 * (c) Thomas Rabaix <[email protected]>
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
namespace Sonata\MediaBundle\Command;
13
14
use Sonata\MediaBundle\Provider\FileProvider;
15
use Sonata\MediaBundle\Provider\MediaProviderInterface;
16
use Sonata\MediaBundle\Provider\Pool;
17
use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand;
18
use Symfony\Component\Console\Input\InputInterface;
19
use Symfony\Component\Console\Input\InputOption;
20
use Symfony\Component\Console\Output\OutputInterface;
21
use Symfony\Component\Filesystem\Exception\IOException;
22
use Symfony\Component\Filesystem\Filesystem;
23
use Symfony\Component\Finder\Finder;
24
25
class CleanMediaCommand extends ContainerAwareCommand
26
{
27
    /**
28
     * @var MediaProviderInterface[]|false
29
     */
30
    private $providers = false;
31
32
    /**
33
     * {@inheritdoc}
34
     */
35
    public function configure()
36
    {
37
        $this->setName('sonata:media:clean-uploads')
38
            ->setDescription('Find orphaned files in media upload directory')
39
            ->addOption('dry-run', null, InputOption::VALUE_NONE, 'Execute the cleanup as a dry run. This doesn\'t remove any files');
40
    }
41
42
    /**
43
     * {@inheritdoc}
44
     */
45
    protected function execute(InputInterface $input, OutputInterface $output)
46
    {
47
        $dryRun = (bool) $input->getOption('dry-run');
48
        $verbose  = (bool) $input->getOption('verbose');
49
50
        $pool = $this->getContainer()->get('sonata.media.pool');
51
        $finder = Finder::create();
52
        $filesystem    = new Filesystem();
53
        $baseDirectory = $this->getContainer()->get('sonata.media.adapter.filesystem.local')->getDirectory();
54
55
        $output->writeln(sprintf('<info>Scanning upload directory: %s</info>', $baseDirectory));
56
57
        foreach ($pool->getContexts() as $contextName => $context) {
58
            if (!$filesystem->exists($baseDirectory.'/'.$contextName)) {
59
                $output->writeln(sprintf("<info>'%s' does not exist</info>", $baseDirectory.'/'.$contextName));
60
                continue;
61
            }
62
63
            $output->writeln(sprintf('<info>Context: %s</info>', $contextName));
64
65
            $files = $finder->files()->in($baseDirectory.'/'.$contextName);
66
67
            foreach ($files as $file) {
68
                $filename = $file->getFilename();
69
70
                if (!$this->mediaExists($filename, $contextName)) {
71
                    if ($dryRun) {
72
                        $output->writeln(sprintf("<info>'%s' is orphanend</info>", $filename));
73
                    } else {
74
                        try {
75
                            $filesystem->remove($file->getRealPath());
76
                            $output->writeln(sprintf("<info>'%s' was successfully removed</info>", $filename));
77
                        } catch (IOException $ioe) {
78
                            $output->writeln(sprintf('<error>%s</error>', $ioe->getMessage()));
79
                        }
80
                    }
81
                } elseif ($verbose) {
82
                    $output->writeln(sprintf("'%s' found", $filename));
83
                }
84
            }
85
        }
86
87
        $output->writeln('<info>done!</info>');
88
    }
89
90
    /**
91
     * @return string[]
92
     */
93
    private function getProviders()
94
    {
95
        if (!$this->providers) {
96
            $this->providers = array();
97
98
            $pool = $this->getContainer()->get('sonata.media.pool');
99
100
            foreach ($pool->getProviders() as $provider) {
101
                if ($provider instanceof FileProvider) {
102
                    $this->providers[] = $provider->getName();
103
                }
104
            }
105
        }
106
107
        return $this->providers;
108
    }
109
110
    /**
111
     * @param $filename
112
     * @param $context
113
     *
114
     * @return bool
115
     */
116
    private function mediaExists($filename, $context = null)
117
    {
118
        $mediaManager = $this->getContainer()->get('sonata.media.manager.media');
119
120
        $fileParts = explode('_', $filename);
121
122
        if (count($fileParts) > 1 && $fileParts[0] == 'thumb') {
123
            return $mediaManager->findOneBy(array(
124
                    'id'      => $fileParts[1],
125
                    'context' => $context,
126
                )) != null;
127
        }
128
129
        return count($mediaManager->findBy(array(
130
                'providerReference' => $filename,
131
                'providers'         => $this->getProviders(),
132
            ))) > 0;
133
    }
134
}
135