FileAccessibilityAndValidationCheck::check()   C
last analyzed

Complexity

Conditions 12
Paths 7

Size

Total Lines 83
Code Lines 56

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 12
eloc 56
nc 7
nop 0
dl 0
loc 83
rs 6.5333
c 0
b 0
f 0

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

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
Documentation Bug introduced by
The property $fileTypeValidateFunc was declared of type integer, but $fileTypeValidateFunc ? ...dateFunc : 'noVidation' is of type string. Maybe add a type cast?

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.

$answer = 42;

$correct = false;

$correct = (bool) $answer;
Loading history...
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
Bug Best Practice introduced by
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 empty(..) or ! empty(...) instead.

Loading history...
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
Bug Best Practice introduced by
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.

Loading history...
208
    }
209
}
210