FileChecker::printFiles()   A
last analyzed

Complexity

Conditions 3
Paths 3

Size

Total Lines 12
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 12

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 3
eloc 6
c 1
b 0
f 0
nc 3
nop 2
dl 0
loc 12
ccs 0
cts 7
cp 0
crap 12
rs 10
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(
18
        private readonly Connection $connection,
19
    ) {}
20
21
    /**
22
     * Print the result.
23
     *
24
     * @param array<string, string> $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
    /**
46
     * @param array<string, string> $config
47
     */
48
    private function fetchFromDb(array $config): array
49
    {
50
        $queries = [];
51
        foreach ($config as $table => $basePath) {
52
            $q = 'SELECT DISTINCT CONCAT(' . $this->connection->quote($basePath) . ', filename) FROM ' . $this->connection->quoteIdentifier($table) . ' WHERE filename != "" ORDER BY filename';
53
            $queries[] = '(' . $q . ')';
54
        }
55
56
        $query = implode(' UNION ', $queries);
57
58
        return $this->connection->executeQuery($query)->fetchFirstColumn();
59
    }
60
61
    /**
62
     * @param array<string, string> $config
63
     */
64
    private function readDisk(array $config): array
65
    {
66
        $files = [];
67
68
        foreach ($config as $basePath) {
69
            $filesFound = glob($basePath . '*');
70
            if ($filesFound === false) {
71
                throw new Exception('Could not glob path: ' . $basePath);
72
            }
73
74
            $filesFound = array_filter($filesFound, 'is_file');
75
76
            $files = [...$files, ...$filesFound];
77
        }
78
79
        sort($files);
80
81
        return $files;
82
    }
83
84
    /**
85
     * Print a list of files if non-empty.
86
     */
87
    private function printFiles(string $title, array $files): void
88
    {
89
        if (!$files) {
90
            return;
91
        }
92
93
        echo $title . PHP_EOL . PHP_EOL;
94
95
        foreach ($files as $file) {
96
            echo '    ' . escapeshellarg($file) . PHP_EOL;
97
        }
98
        echo PHP_EOL;
99
    }
100
}
101