/
FileAgeCheck.php
151 lines (138 loc) · 4.26 KB
/
FileAgeCheck.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
<?php
namespace SilverStripe\EnvironmentCheck\Checks;
use SilverStripe\EnvironmentCheck\EnvironmentCheck;
use SilverStripe\ORM\FieldType\DBDatetime;
/**
* Checks for the maximum age of one or more files or folders.
* Useful for files which should be frequently auto-generated,
* like static caches, as well as for backup files and folders.
* Does NOT check for existence of a file (will silently fail).
*
* Examples:
* // Checks that Requirements::combine_files() has regenerated files in the last 24h
* EnvironmentCheckSuite::register(
* 'check',
* 'FileAgeCheck("' . ASSETS_PATH . '/_combined_files/*.js' . '", "-1 day", '>', " . FileAgeCheck::CHECK_ALL) . "'
* );
*
* // Checks that at least one backup folder has been created in the last 24h
* EnvironmentCheckSuite::register(
* 'check',
* 'FileAgeCheck("' . BASE_PATH . '/../backups/*' . '", "-1 day", '>', " . FileAgeCheck::CHECK_SINGLE) . "'
* );
*
* @package environmentcheck
*/
class FileAgeCheck implements EnvironmentCheck
{
/**
* @var int
*/
const CHECK_SINGLE = 1;
/**
* @var int
*/
const CHECK_ALL = 2;
/**
* Absolute path to a file or folder, compatible with glob().
*
* @var string
*/
protected $path;
/**
* Relative date specification, compatible with strtotime().
*
* @var string
*/
protected $relativeAge;
/**
* The function to use for checking file age: so filemtime(), filectime(), or fileatime().
*
* @var string
*/
protected $checkFn;
/**
* Constant, check for a single file to match age criteria, or all of them.
*
* @var int
*/
protected $checkType;
/**
* Type of comparison (either > or <).
*
* @var string
*/
protected $compareOperand;
/**
* @param string $path
* @param string $relativeAge
* @param string $compareOperand
* @param null|int $checkType
* @param string $checkFn
*/
public function __construct($path, $relativeAge, $compareOperand = '>', $checkType = null, $checkFn = 'filemtime')
{
$this->path = $path;
$this->relativeAge = $relativeAge;
$this->checkFn = $checkFn;
$this->checkType = ($checkType) ? $checkType : self::CHECK_SINGLE;
$this->compareOperand = $compareOperand;
}
/**
* {@inheritDoc}
*
* @return array
*/
public function check()
{
$cutoffTime = strtotime($this->relativeAge ?? '', DBDatetime::now()->Format('U'));
$files = $this->getFiles();
$invalidFiles = [];
$validFiles = [];
$checkFn = $this->checkFn;
$allValid = true;
if ($files) {
foreach ($files as $file) {
$fileTime = $checkFn($file);
$valid = ($this->compareOperand == '>') ? ($fileTime >= $cutoffTime) : ($fileTime <= $cutoffTime);
if ($valid) {
$validFiles[] = $file;
} else {
$invalidFiles[] = $file;
if ($this->checkType == self::CHECK_ALL) {
return [
EnvironmentCheck::ERROR,
sprintf(
'File "%s" doesn\'t match age check (compare %s: %s, actual: %s)',
$file,
$this->compareOperand,
date('c', $cutoffTime),
date('c', $fileTime)
)
];
}
}
}
}
// If at least one file was valid, count as passed
if ($this->checkType == self::CHECK_SINGLE && count($invalidFiles ?? []) < count($files ?? [])) {
return [EnvironmentCheck::OK, ''];
}
if (count($invalidFiles ?? []) == 0) {
return [EnvironmentCheck::OK, ''];
}
return [
EnvironmentCheck::ERROR,
sprintf('No files matched criteria (%s %s)', $this->compareOperand, date('c', $cutoffTime))
];
}
/**
* Gets a list of absolute file paths.
*
* @return array
*/
protected function getFiles()
{
return glob($this->path ?? '');
}
}