Issues (98)

src/Checks/Files/WhatFiles.php (4 issues)

1
<?php
2
3
namespace Sunnysideup\HealthCheckProvider\Checks\Files;
4
5
use RecursiveDirectoryIterator;
6
use RecursiveIteratorIterator;
7
use SilverStripe\Assets\File;
8
use SilverStripe\Core\Config\Config;
9
10
use Sunnysideup\HealthCheckProvider\Checks\HealthCheckItemRunner;
11
12
class WhatFiles extends HealthCheckItemRunner
13
{
14
    protected $allowedExtension = [];
15
16
    private static $not_real_file_substrings = [
0 ignored issues
show
The private property $not_real_file_substrings is not used, and could be removed.
Loading history...
17
        DIRECTORY_SEPARATOR . '_resampled',
18
        DIRECTORY_SEPARATOR . '__',
19
        DIRECTORY_SEPARATOR . '.',
20
    ];
21
22
    private static $excluded_folders = [
0 ignored issues
show
The private property $excluded_folders is not used, and could be removed.
Loading history...
23
        '.protected',
24
    ];
25
26
    private static $excluded_files = [
0 ignored issues
show
The private property $excluded_files is not used, and could be removed.
Loading history...
27
        'error-500.html',
28
        'error-404.html',
29
        '.gitignore',
30
        '.htaccess',
31
        // DIRECTORY_SEPARATOR . '_resampled',
32
        // DIRECTORY_SEPARATOR . '__',
33
        // DIRECTORY_SEPARATOR . '.',
34
    ];
35
36
    // anything over half a megabyte may needs attention...
37
    private static $min_size_in_bytes = ((1024 * 1024) / 2);
0 ignored issues
show
The private property $min_size_in_bytes is not used, and could be removed.
Loading history...
38
39
    /**
40
     * get a list of files in the asset path
41
     * @return array
42
     */
43
    public function getCalculatedAnswer()
44
    {
45
        $this->allowedExtension = Config::inst()->get(File::class, 'allowed_extensions');
46
        $finalArray = [];
47
        $arrayRaw = new RecursiveIteratorIterator(
48
            new RecursiveDirectoryIterator($this->getAssetPath()),
49
            RecursiveIteratorIterator::SELF_FIRST
50
        );
51
        $count = 0;
52
        $sizeSum = 0;
53
        foreach ($arrayRaw as $src) {
54
            $path = $src->getPathName();
55
            if ($this->excludeFileTest($path)) {
56
                continue;
57
            }
58
            if (is_dir($path)) {
59
                continue;
60
            }
61
            if ($this->excludeFolderTest($path)) {
62
                continue;
63
            }
64
            if ($this->isCountableFile($path)) {
65
                ++$count;
66
            }
67
            $size = filesize($path);
68
            $sizeSum += $size;
69
            if ($size > $this->Config()->get('min_size_in_bytes') || $this->invalidExtension($path)) {
70
                if (strpos($path, $this->getAssetPath()) === 0) {
71
                    $shortPath = str_replace($this->getAssetPath(), '', $path);
72
                    $finalArray[(string) $shortPath] = $size;
73
                } else {
74
                    $finalArray[(string) $path] = $size;
75
                }
76
            }
77
        }
78
79
        return [
80
            'Path' => ASSETS_DIR,
81
            'Files' => $finalArray,
82
            'Count' => [
83
                'FileSystem' => $count,
84
                'DB' => File::get()->count(),
85
            ],
86
            'Size' => $sizeSum,
87
        ];
88
    }
89
90
    /**
91
     * return the location for assets
92
     */
93
    protected function getAssetPath(): string
94
    {
95
        $path = realpath(ASSETS_PATH);
96
        if ($path) {
97
            return $path;
98
        }
99
        user_error('Could not find asset path');
100
        return 'error';
101
    }
102
103
    /**
104
     * get an extension of a file
105
     */
106
    protected function fileExtension(string $s): string
107
    {
108
        $n = strrpos($s, '.');
109
110
        return $n === false ? '' : substr($s, $n + 1);
111
    }
112
113
    /**
114
     * should the file be ignored
115
     */
116
    protected function excludeFileTest(string $path): bool
117
    {
118
        $listOfItemsToSearchFor = $this->Config()->get('excluded_files');
119
        foreach ($listOfItemsToSearchFor as $test) {
120
            $pos = strpos($path, $test);
121
            if ($pos !== false) {
122
                if (substr($path, $pos) === $test) {
123
                    return true;
124
                }
125
            }
126
        }
127
128
        return false;
129
    }
130
131
    /**
132
     * should the folder be ignored
133
     */
134
    protected function excludeFolderTest(string $path): bool
135
    {
136
        $listOfItemsToSearchFor = $this->Config()->get('excluded_folders');
137
        foreach ($listOfItemsToSearchFor as $test) {
138
            $folder = DIRECTORY_SEPARATOR . trim($test, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR;
139
            $pathExtra = DIRECTORY_SEPARATOR . trim($path, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR;
140
            if (stripos($pathExtra, $folder) !== false) {
141
                return true;
142
            }
143
        }
144
145
        return false;
146
    }
147
148
    protected function invalidExtension(string $path): bool
149
    {
150
        return !$this->validExtension($path);
151
    }
152
153
    protected function validExtension(string $path): bool
154
    {
155
        $extension = $this->fileExtension($path);
156
        return $extension && in_array($extension, $this->allowedExtension, true);
157
    }
158
159
    protected function isCountableFile($path): bool
160
    {
161
        $listOfItemsToSearchFor = $this->Config()->get('not_real_file_substrings');
162
        foreach ($listOfItemsToSearchFor as $test) {
163
            if (strpos(DIRECTORY_SEPARATOR . $path, $test)) {
164
                return false;
165
            }
166
        }
167
168
        return true;
169
    }
170
}
171