Passed
Push — master ( 73bfc2...a878a7 )
by Adrien
13:45 queued 10:48
created

FileChecker::readDisk()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 18
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 12

Importance

Changes 2
Bugs 0 Features 0
Metric Value
cc 3
eloc 9
c 2
b 0
f 0
nc 3
nop 1
dl 0
loc 18
ccs 0
cts 10
cp 0
crap 12
rs 9.9666
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Ecodev\Felix\Service;
6
7
use Doctrine\DBAL\Connection;
8
use Exception;
9
10
/**
11
 * Check missing files on disk and non-needed files on disk.
12
 *
13
 * It is up to the user to then take appropriate action based on that information.
14
 */
15
class FileChecker
16
{
17
    public function __construct(private readonly Connection $connection)
18
    {
19
    }
20
21
    /**
22
     * Print the result.
23
     *
24
     * @param array $config must be $table => $basePath
25
     */
26
    public function check(array $config): void
27
    {
28
        $filesInDb = $this->fetchFromDb($config);
29
        $filesOnDisk = $this->readDisk($config);
30
31
        $missingFiles = array_diff($filesInDb, $filesOnDisk);
32
        $unneededFiles = array_diff($filesOnDisk, $filesInDb);
33
34
        $this->printFiles('List of missing files on disk:', $missingFiles);
35
        $this->printFiles('List of unneeded files on disk:', $unneededFiles);
36
37
        echo '
38
Total files in DB     : ' . count($filesInDb) . '
39
Total files on disk   : ' . count($filesOnDisk) . '
40
Missing files on disk : ' . count($missingFiles) . '
41
Unneeded files on disk: ' . count($unneededFiles) . '
42
';
43
    }
44
45
    private function fetchFromDb(array $config): array
46
    {
47
        $queries = [];
48
        foreach ($config as $table => $basePath) {
49
            $q = 'SELECT DISTINCT CONCAT(' . $this->connection->quote($basePath) . ', filename) FROM ' . $this->connection->quoteIdentifier($table) . ' WHERE filename != "" ORDER BY filename';
50
            $queries[] = '(' . $q . ')';
51
        }
52
53
        $query = implode(' UNION ', $queries);
54
55
        return $this->connection->executeQuery($query)->fetchFirstColumn();
56
    }
57
58
    private function readDisk(array $config): array
59
    {
60
        $files = [];
61
62
        foreach ($config as $basePath) {
63
            $filesFound = glob($basePath . '*');
64
            if ($filesFound === false) {
65
                throw new Exception('Could not glob path: ' . $basePath);
66
            }
67
68
            $filesFound = array_filter($filesFound, 'is_file');
69
70
            $files = [...$files, ...$filesFound];
71
        }
72
73
        sort($files);
74
75
        return $files;
76
    }
77
78
    /**
79
     * Print a list of files if non empty.
80
     */
81
    private function printFiles(string $title, array $files): void
82
    {
83
        if (!$files) {
84
            return;
85
        }
86
87
        echo $title . PHP_EOL . PHP_EOL;
88
89
        foreach ($files as $file) {
90
            echo '    ' . escapeshellarg($file) . PHP_EOL;
91
        }
92
        echo PHP_EOL;
93
    }
94
}
95