Completed
Push — master ( cc47d7...1bf541 )
by Jeremy
34s queued 13s
created

CleanDownloadedImagesCommand::configure()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 10
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 3
Bugs 0 Features 1
Metric Value
cc 1
eloc 8
c 3
b 0
f 1
nc 1
nop 0
dl 0
loc 10
rs 10
1
<?php
2
3
namespace Wallabag\CoreBundle\Command;
4
5
use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand;
6
use Symfony\Component\Console\Input\InputInterface;
7
use Symfony\Component\Console\Input\InputOption;
8
use Symfony\Component\Console\Output\OutputInterface;
9
use Symfony\Component\Console\Style\SymfonyStyle;
10
use Symfony\Component\Finder\Finder;
11
12
class CleanDownloadedImagesCommand extends ContainerAwareCommand
13
{
14
    protected function configure()
15
    {
16
        $this
17
            ->setName('wallabag:clean-downloaded-images')
18
            ->setDescription('Cleans downloaded images which are no more associated to an entry')
19
            ->addOption(
20
               'dry-run',
21
               null,
22
               InputOption::VALUE_NONE,
23
               'Do not remove images, just dump counters'
24
            );
25
    }
26
27
    protected function execute(InputInterface $input, OutputInterface $output)
28
    {
29
        $io = new SymfonyStyle($input, $output);
30
31
        $dryRun = (bool) $input->getOption('dry-run');
32
33
        if ($dryRun) {
34
            $io->text('Dry run mode <info>enabled</info> (no images will be removed)');
35
        }
36
37
        $downloadImages = $this->getContainer()->get('wallabag_core.entry.download_images');
38
        $baseFolder = $downloadImages->getBaseFolder();
39
40
        $io->text('Retrieve existing images');
41
42
        // retrieve _existing_ folders in the image folder
43
        $finder = new Finder();
44
        $finder
45
            ->directories()
46
            ->ignoreDotFiles(true)
47
            ->depth(2)
48
            ->in($baseFolder);
49
50
        $existingPaths = [];
51
        foreach ($finder as $file) {
52
            $existingPaths[] = $file->getFilename();
53
        }
54
55
        $io->text(sprintf('  -> <info>%d</info> images found', \count($existingPaths)));
56
57
        $io->text('Retrieve valid folders attached to a user');
58
59
        $entries = $this->getContainer()->get('wallabag_core.entry_repository')->findAllEntriesIdByUserId();
60
61
        // retrieve _valid_ folders from existing entries
62
        $validPaths = [];
63
        foreach ($entries as $entry) {
64
            $path = $downloadImages->getRelativePath($entry['id']);
65
66
            if (!file_exists($baseFolder . '/' . $path)) {
67
                continue;
68
            }
69
70
            // only store the hash, not the full path
71
            $validPaths[] = explode('/', $path)[2];
72
        }
73
74
        $io->text(sprintf('  -> <info>%d</info> folders found', \count($validPaths)));
75
76
        $deletedCount = 0;
77
78
        $io->text('Remove images');
79
80
        // check if existing path are valid, if not, remove all images and the folder
81
        foreach ($existingPaths as $existingPath) {
82
            if (!\in_array($existingPath, $validPaths, true)) {
83
                $fullPath = $baseFolder . '/' . $existingPath[0] . '/' . $existingPath[1] . '/' . $existingPath;
84
                $files = glob($fullPath . '/*.*');
85
86
                if (!$dryRun) {
87
                    array_map('unlink', $files);
0 ignored issues
show
Bug introduced by
It seems like $files can also be of type false; however, parameter $arr1 of array_map() does only seem to accept array, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

87
                    array_map('unlink', /** @scrutinizer ignore-type */ $files);
Loading history...
88
                    rmdir($fullPath);
89
                }
90
91
                $deletedCount += \count($files);
0 ignored issues
show
Bug introduced by
It seems like $files can also be of type false; however, parameter $var of count() does only seem to accept Countable|array, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

91
                $deletedCount += \count(/** @scrutinizer ignore-type */ $files);
Loading history...
92
93
                $io->text(sprintf('Deleted images in <info>%s</info>: <info>%d</info>', $existingPath, \count($files)));
94
            }
95
        }
96
97
        $io->success(sprintf('Finished cleaning. %d deleted images', $deletedCount));
98
99
        return 0;
100
    }
101
}
102