-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathfile_finder.php
216 lines (175 loc) · 5.98 KB
/
file_finder.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
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
<?php
/** @noinspection UseStaticReturnTypeInsteadOfSelfInspection */
/*
Завдання: необхідно написати клас для пошуку файлів і директорій.
Клас має реалізовувати інтерфейс FileFinderInterface.
На виході клас має повертати масив строк - повних шляхів до папок/файлів, які відповідають заданим умовам.
Нижче в файлі є приклади використання класу.
Можна використовувати тільки вбудований функціонал PHP.
Завдання розраховане на 1-2 години роботи, просимо не витрачати більше.
Краще додайте до реалізації список доробок/покращень, які ви б зробили в коді, якби працювали б над ним далі.
*/
interface FileFinderInterface
{
/**
* Search in directory $directory.
* If called multiple times, the result must include paths from all provided directories.
*/
public function inDir(string $directory): self;
/** Filter: only files, ignore directories */
public function onlyFiles(): self;
/** Filter: only directories, ignore files */
public function onlyDirectories(): self;
/**
* Filter by regular expression on full path.
* If called multiple times, the result must include paths that match at least one of the provided expressions.
*/
public function match(string $regularExpression): self;
/**
* Returns array of all found files/directories (full path)
* @return string[]
*/
public function find(): array;
}
/** @noinspection PhpHierarchyChecksInspection */
class FileFinderImplementation implements FileFinderInterface
{
protected $dirsArr = [];
protected $mode = [];
protected $matchMode;
protected $inDir = false;
public function inDir(string $directory): self
{
if (is_dir($directory)) {
$this->inDir = true;
$this->dirsArr[$directory] = $this->getFiles($directory);
foreach ($this->mode as $mode) {
if ($mode === 'onlyFiles') {
$this->onlyFiles();
}
if ($mode === 'onlyDirectories') {
$this->onlyDirectories();
}
}
if ($this->matchMode) {
$this->match($this->matchMode);
}
return $this;
} else {
try {
throw new \Exception("The directory: $directory does not exist");
} catch (\Exception $e) {
exit($e->getMessage());
}
}
}
public function onlyFiles(): self
{
$this->mode[] = 'onlyFiles';
$resArr = [];
foreach ($this->dirsArr as $path => $files) {
foreach ($files as $file) {
if (is_file($file)) {
$resArr[$path][] = $file;
}
}
}
$this->dirsArr = $resArr;
return $this;
}
public function onlyDirectories(): self
{
$this->mode[] = 'onlyDirectories';
$resArr = [];
foreach ($this->dirsArr as $path => $files) {
foreach ($files as $file) {
if (is_dir($file)) {
$resArr[$path][] = $file;
}
}
}
$this->dirsArr = $resArr;
return $this;
}
public function match(string $regularExpression): self
{
$this->matchMode = $regularExpression;
$resArr = [];
foreach ($this->dirsArr as $path => $files) {
foreach ($files as $file) {
if (preg_match($regularExpression, $file, $matches)) {
$resArr[$path][] = $file;
}
}
}
$this->dirsArr = $resArr;
return $this;
}
public function find(): array
{
$resArr = [];
foreach ($this->dirsArr as $path => $value) {
foreach ($value as $file) {
$resArr[] = $file;
}
}
if (!$this->inDir) throw new \Exception('You need to specify the directory!');
return $resArr;
}
public function getFiles($dir)
{
$dir .= substr($dir, -1) == '/' ? '' : '/';
$dirInfo = array();
foreach (glob($dir . '*') as $v) {
$dirInfo[] = $v;
if (is_dir($v)) {
$dirInfo = array_merge($dirInfo, $this->getFiles($v));
}
}
return $dirInfo;
}
}
// $finder
// ->onlyFiles()
// ->inDir('/etc/')
// ->inDir('/var/log/')
// ->match('/.*\.conf$/');
// foreach ($finder->find() as $file) {
// print $file . "\n";
// }
// print "\n\n";
// // # search for all files in /tmp
// $finder = (new FileFinderImplementation())
// ->onlyFiles()
// ->inDir('/tmp');
// foreach ($finder->find() as $file) {
// print $file . "\n";
// }
// print "\n\n";
// // # search for .doc files in /tmp
// $finder = (new FileFinderImplementation())
// ->match('/.*\.doc$/')
// ->onlyFiles()
// ->inDir('/tmp');
// foreach ($finder->find() as $file) {
// print $file . "\n";
// }
// print "\n\n";
// // # list all directories in /var
// $finder = (new FileFinderImplementation())
// ->onlyDirectories()
// ->inDir('/var/log/');
// foreach ($finder->find() as $file) {
// print $file . "\n";
// }
// print "\n\n";
// # should throw an exception if no directories were provided
// try {
// $files = (new FileFinderImplementation())
// ->onlyFiles()
// ->match('/.*\.ini$/')
// ->find(); # -> exception
// print "When no dir were provided: exception was not thrown, something does not work correctly\n";
// } catch (\Exception $exception) {
// print "When no dir were provided: exception was thrown with message \"" . $exception->getMessage() . "\"\n";
// }