PluginProbe
Disk Usage Insights / trunk
Disk Usage Insights vtrunk
trunk 1.0 1.10 1.11 1.2 1.3 1.4 1.5 1.6 1.7 1.8 1.9
disk-usage-insights / src / Domain / DiskUsage.php

DiskUsage.php in Disk Usage Insights trunk, at src/Domain/DiskUsage.php

227 lines 6.4 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace Mgleis\DiskUsageInsights\Domain;
4
5 class DiskUsage {
6
7 private /** @var string */ $rootDirectory;
8
9 public function __construct(string $rootDirectory) {
10 $this->rootDirectory = $rootDirectory;
11 }
12
13 public function scan(string $directory = null, bool $first = true): array {
14
15 if ($directory == null) {
16 $directory = $this->rootDirectory;
17 }
18
19 $retval = [];
20
21 $files = scandir($directory);
22 if ($files !== false) {
23
24 foreach ($files as $file) {
25 if ($file == '.') {
26 continue;
27 }
28 if ($file == '..') {
29 continue;
30 }
31
32 $absName = $directory . '/' . $file;
33 $isDir = is_dir($absName);
34 $size = ($isDir ? 0 : filesize($absName));
35
36 $entry = [
37 'name' => $file,
38 'abs' => substr($absName, strlen($this->rootDirectory)),
39 'file' => !$isDir,
40 'size' => $size
41 ];
42
43 if ($isDir) {
44 $entry['entries'] =$this->scan($absName, false);
45 }
46 $retval[] = $entry;
47
48 }
49 }
50
51 if ($first) {
52 $root = [
53 'name' => basename($directory),
54 'abs' => substr($directory, strlen($this->rootDirectory)),
55 'file' => false,
56 'size' => 0
57 ];
58 $root['entries'] = $retval;
59 $retval = [$root];
60 }
61
62 return $retval;
63 }
64
65 public function calculateDirTotalSizes(array &$arr): int {
66 $totalSize = 0;
67 foreach ($arr as &$entry) {
68 if (!$entry['file']) {
69 $subdirSize = $this->calculateDirTotalSizes($entry['entries']);
70 $entry['totalSize'] = $subdirSize;
71 $totalSize += $subdirSize;
72 } else {
73 $totalSize += $entry['size'];
74 }
75 }
76
77 return $totalSize;
78 }
79
80 public function calculateDirFileSizes(array &$arr, array &$parentFolder = null) {
81 $fileSizes = 0;
82 foreach ($arr as &$entry) {
83 if (!$entry['file']) {
84 $this->calculateDirFileSizes($entry['entries'], $entry);
85 } else {
86 $fileSizes += $entry['size'];
87 }
88 }
89 if ($parentFolder !== null) {
90 $parentFolder['fileSizes'] = $fileSizes;
91 }
92 }
93
94 public function calculateDirFileCount(array &$arr, array &$parentFolder = null) {
95 $fileCount = 0;
96 foreach ($arr as &$entry) {
97 if (!$entry['file']) {
98 $this->calculateDirFileCount($entry['entries'], $entry);
99 } else {
100 $fileCount++;
101 }
102 }
103 if ($parentFolder !== null) {
104 $parentFolder['fileCount'] = $fileCount;
105 }
106 }
107
108 public function calculateLargestFiles(int $n, array $arr) : array {
109 $files = $this->flatten($arr);
110
111 uasort($files, function($a, $b) {
112 return $b['size'] <=> $a['size'];
113 });
114
115 return array_slice($files, 0, $n);
116 }
117
118 public function flatten(array $arr): array {
119 $flattened = [];
120 foreach ($arr as $entry) {
121 if ($entry['file']) {
122 $flattened[] = $entry;
123 } else {
124 $entries = $entry['entries'];
125 unset($entry['entries']);
126 $flattened[] = $entry;
127
128 $flattenedEntries = $this->flatten($entries);
129 foreach ($flattenedEntries as $flattenedEntry) {
130 $flattened[] = $flattenedEntry;
131 }
132
133 }
134 }
135
136 return $flattened;
137 }
138
139 public function calculateLargestFoldersRecursive(int $n, array $arr) : array {
140 $files = $this->flatten($arr);
141 $files = array_filter($files, function($entry) {
142 return !$entry['file'];
143 });
144
145 uasort($files, function($a, $b) {
146 return $b['totalSize'] <=> $a['totalSize'];
147 });
148
149 return array_slice($files, 0, $n);
150 }
151
152 public function calculateLargestFolders(int $n, array $arr) : array {
153 $files = $this->flatten($arr);
154 $files = array_filter($files, function($entry) {
155 return !$entry['file'];
156 });
157
158 uasort($files, function($a, $b) {
159 return $b['fileSizes'] <=> $a['fileSizes'];
160 });
161
162 return array_slice($files, 0, $n);
163 }
164
165 public function calculateFoldersWithMostFiles(int $n, array $arr) : array {
166 $files = $this->flatten($arr);
167 $files = array_filter($files, function($entry) {
168 return !$entry['file'];
169 });
170
171 uasort($files, function($a, $b) {
172 return $b['fileCount'] <=> $a['fileCount'];
173 });
174
175 return array_slice($files, 0, $n);
176 }
177
178 public function calculateLargestFilesFoldersFirstLevel(int $n, array $arr) : array {
179 $ret = [];
180 foreach ($arr[0]['entries'] as $entry) {
181 $ret[] = [
182 'name' => $entry['name'],
183 'size' => $entry['totalSize'] ?? $entry['size']
184 ];
185 }
186
187 uasort($ret, function($a, $b) {
188 return $b['size'] <=> $a['size'];
189 });
190
191 return array_slice($ret, 0, $n);
192 }
193
194 public function findSubDir(array $arr, $subdir) {
195 // TODO parse $subdir with PHP function to get each folder
196 $folders = explode('/', trim($subdir, '/'));
197 $ret = $arr[0]['entries'];
198 for ($i = 0; $i < sizeof($folders); $i++) {
199 $folder = $folders[$i];
200 // TODO sanity checks
201 foreach ($ret as $entry) {
202 if ($entry['name'] == $folder) {
203 if ($i != sizeof($folders)-1) {
204 $ret = $entry['entries'];
205 } else {
206 return [$entry];
207 }
208 }
209 }
210 }
211
212 return $ret;
213 }
214
215 public function doMore() {
216 // TODO: Remove "Largest Folders (incl. sub folders)"? Does not make sense
217 // TODO: Are "file links" a problem? Loop?
218 // Change Hot Spots: Folders which have most recent changes
219 // Oldest Files ? Für was?
220 // Newest Files: Recently Created, Recently Modified, ...
221 //
222 // Grouped by (Mime) Type: Images, Videos, Documents, ...
223 // Grouped by Plugin / Theme
224 }
225
226 }
227