1 | <?php |
||
2 | |||
3 | namespace SilverStripe\EnvironmentCheck\Checks; |
||
4 | |||
5 | use SilverStripe\EnvironmentCheck\EnvironmentCheck; |
||
6 | use SilverStripe\Versioned\Versioned; |
||
7 | |||
8 | /** |
||
9 | * Checks for the accessibility and file type validation of one or more files or folders. |
||
10 | * |
||
11 | * Examples: |
||
12 | * // Checks /assets/calculator_files has .json files and all files are valid json files. |
||
13 | * EnvironmentCheckSuite::register( |
||
14 | * 'check', |
||
15 | * 'FileAccessibilityAndValidationCheck( |
||
16 | * "' . BASE_PATH . '/assets/calculator_files/*.json", |
||
17 | * "jsonValidate", |
||
18 | * '.FileAccessibilityAndValidationCheck::CHECK_ALL.' |
||
19 | * )', |
||
20 | * 'Check a json file exist and are all valid json files' |
||
21 | * ); |
||
22 | * |
||
23 | * // Checks /assets/calculator_files/calculator.json exists and is valid json file. |
||
24 | * EnvironmentCheckSuite::register( |
||
25 | * 'check', |
||
26 | * 'FileAccessibilityAndValidationCheck( |
||
27 | * "' . BASE_PATH . '/assets/calculator_files/calculator.json", |
||
28 | * "jsonValidate", |
||
29 | * '.FileAccessibilityAndValidationCheck::CHECK_SINGLE.' |
||
30 | * )', |
||
31 | * 'Check a calculator.json exists and is valid json file' |
||
32 | * ); |
||
33 | * |
||
34 | * // Check only existence |
||
35 | * EnvironmentCheckSuite::register( |
||
36 | * 'check', |
||
37 | * 'FileAccessibilityAndValidationCheck("' . BASE_PATH . '/assets/calculator_files/calculator.json")', |
||
38 | * 'Check a calculator.json exists only' |
||
39 | * ); |
||
40 | */ |
||
41 | class FileAccessibilityAndValidationCheck implements EnvironmentCheck |
||
42 | { |
||
43 | /** |
||
44 | * @var int |
||
45 | */ |
||
46 | const CHECK_SINGLE = 1; |
||
47 | |||
48 | /** |
||
49 | * @var int |
||
50 | */ |
||
51 | const CHECK_ALL = 2; |
||
52 | |||
53 | /** |
||
54 | * Absolute path to a file or folder, compatible with glob(). |
||
55 | * |
||
56 | * @var string |
||
57 | */ |
||
58 | protected $path; |
||
59 | |||
60 | /** |
||
61 | * Constant, check for a single file to match age criteria, or all of them. |
||
62 | * |
||
63 | * @var int |
||
64 | */ |
||
65 | protected $fileTypeValidateFunc; |
||
66 | |||
67 | /** |
||
68 | * Constant, check for a single file to match age criteria, or all of them. |
||
69 | * |
||
70 | * @var int |
||
71 | */ |
||
72 | protected $checkType; |
||
73 | |||
74 | /** |
||
75 | * @param string $path |
||
76 | * @param string $fileTypeValidateFunc |
||
77 | * @param null|int $checkType |
||
78 | */ |
||
79 | public function __construct($path, $fileTypeValidateFunc = 'noVidation', $checkType = null) |
||
80 | { |
||
81 | $this->path = $path; |
||
82 | $this->fileTypeValidateFunc = ($fileTypeValidateFunc)? $fileTypeValidateFunc : 'noVidation'; |
||
0 ignored issues
–
show
|
|||
83 | $this->checkType = ($checkType) ? $checkType : self::CHECK_SINGLE; |
||
84 | } |
||
85 | |||
86 | /** |
||
87 | * {@inheritDoc} |
||
88 | * |
||
89 | * @return array |
||
90 | */ |
||
91 | public function check() |
||
92 | { |
||
93 | $origStage = Versioned::get_reading_mode(); |
||
94 | Versioned::set_reading_mode(Versioned::LIVE); |
||
95 | |||
96 | $files = $this->getFiles(); |
||
97 | if ($files) { |
||
0 ignored issues
–
show
The expression
$files of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.
This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent. Consider making the comparison explicit by using ![]() |
|||
98 | $fileTypeValidateFunc = $this->fileTypeValidateFunc; |
||
99 | if (method_exists($this, $fileTypeValidateFunc)) { |
||
100 | $invalidFiles = []; |
||
101 | $validFiles = []; |
||
102 | |||
103 | foreach ($files as $file) { |
||
104 | if ($this->$fileTypeValidateFunc($file)) { |
||
105 | $validFiles[] = $file; |
||
106 | } else { |
||
107 | $invalidFiles[] = $file; |
||
108 | } |
||
109 | } |
||
110 | |||
111 | // If at least one file was valid, count as passed |
||
112 | if ($this->checkType == self::CHECK_SINGLE && count($invalidFiles) < count($files)) { |
||
113 | $validFileList = PHP_EOL; |
||
114 | foreach ($validFiles as $vf) { |
||
115 | $validFileList .= $vf . PHP_EOL; |
||
116 | } |
||
117 | if ($fileTypeValidateFunc == 'noVidation') { |
||
118 | $checkReturn = [ |
||
119 | EnvironmentCheck::OK, |
||
120 | sprintf('At least these file(s) accessible: %s', $validFileList) |
||
121 | ]; |
||
122 | } else { |
||
123 | $checkReturn = [ |
||
124 | EnvironmentCheck::OK, |
||
125 | sprintf( |
||
126 | 'At least these file(s) passed file type validate function "%s": %s', |
||
127 | $fileTypeValidateFunc, |
||
128 | $validFileList |
||
129 | ) |
||
130 | ]; |
||
131 | } |
||
132 | } else { |
||
133 | if (count($invalidFiles) == 0) { |
||
134 | $checkReturn = [EnvironmentCheck::OK, 'All files valideted']; |
||
135 | } else { |
||
136 | $invalidFileList = PHP_EOL; |
||
137 | foreach ($invalidFiles as $vf) { |
||
138 | $invalidFileList .= $vf . PHP_EOL; |
||
139 | } |
||
140 | |||
141 | if ($fileTypeValidateFunc == 'noVidation') { |
||
142 | $checkReturn = [ |
||
143 | EnvironmentCheck::ERROR, |
||
144 | sprintf('File(s) not accessible: %s', $invalidFileList) |
||
145 | ]; |
||
146 | } else { |
||
147 | $checkReturn = [ |
||
148 | EnvironmentCheck::ERROR, |
||
149 | sprintf( |
||
150 | 'File(s) not passing the file type validate function "%s": %s', |
||
151 | $fileTypeValidateFunc, |
||
152 | $invalidFileList |
||
153 | ) |
||
154 | ]; |
||
155 | } |
||
156 | } |
||
157 | } |
||
158 | } else { |
||
159 | $checkReturn = array( |
||
160 | EnvironmentCheck::ERROR, |
||
161 | sprintf("Invalid file type validation method name passed: %s ", $fileTypeValidateFunc) |
||
162 | ); |
||
163 | } |
||
164 | } else { |
||
165 | $checkReturn = array( |
||
166 | EnvironmentCheck::ERROR, |
||
167 | sprintf("No files accessible at path %s", $this->path) |
||
168 | ); |
||
169 | } |
||
170 | |||
171 | Versioned::set_reading_mode($origStage); |
||
172 | |||
173 | return $checkReturn; |
||
174 | } |
||
175 | |||
176 | /** |
||
177 | * @param string $file |
||
178 | * |
||
179 | * @return bool |
||
180 | */ |
||
181 | private function jsonValidate($file) |
||
182 | { |
||
183 | $json = json_decode(file_get_contents($file)); |
||
184 | if (!$json) { |
||
185 | return false; |
||
186 | } |
||
187 | return true; |
||
188 | } |
||
189 | |||
190 | /** |
||
191 | * @param string $file |
||
192 | * |
||
193 | * @return bool |
||
194 | */ |
||
195 | protected function noVidation($file) |
||
196 | { |
||
197 | return true; |
||
198 | } |
||
199 | |||
200 | /** |
||
201 | * Gets a list of absolute file paths. |
||
202 | * |
||
203 | * @return array |
||
204 | */ |
||
205 | protected function getFiles() |
||
206 | { |
||
207 | return glob($this->path); |
||
0 ignored issues
–
show
The expression
return glob($this->path) could also return false which is incompatible with the documented return type array . Did you maybe forget to handle an error condition?
If the returned type also contains false, it is an indicator that maybe an error condition leading to the specific return statement remains unhandled. ![]() |
|||
208 | } |
||
209 | } |
||
210 |
This check looks for assignments to scalar types that may be of the wrong type.
To ensure the code behaves as expected, it may be a good idea to add an explicit type cast.