Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
92.16% covered (success)
92.16%
47 / 51
40.00% covered (danger)
40.00%
2 / 5
CRAP
0.00% covered (danger)
0.00%
0 / 1
Folder
92.16% covered (success)
92.16%
47 / 51
40.00% covered (danger)
40.00%
2 / 5
36.63
0.00% covered (danger)
0.00%
0 / 1
 glob
90.00% covered (success)
90.00%
9 / 10
0.00% covered (danger)
0.00%
0 / 1
8.06
 getContentsRecursive
100.00% covered (success)
100.00%
10 / 10
100.00% covered (success)
100.00%
1 / 1
7
 getContentsFlat
100.00% covered (success)
100.00%
11 / 11
100.00% covered (success)
100.00%
1 / 1
8
 deleteContentsRecursive
81.82% covered (warning)
81.82%
9 / 11
0.00% covered (danger)
0.00%
0 / 1
8.38
 createPath
88.89% covered (warning)
88.89%
8 / 9
0.00% covered (danger)
0.00%
0 / 1
5.03
1<?php
2/** @noinspection PhpUnhandledExceptionInspection */
3declare(strict_types=1);
4
5class Folder {
6  /** returns filepath
7   * stream save (PHP's function glob is not)
8   * **/
9  static function glob(string $dir, string $filePattern = null, $reverse = false): array {
10    if (!file_exists($dir) or !is_dir($dir)) {
11      return [];
12    }
13
14    $files = scandir($dir, $reverse ? 1 : 0);
15    $found = [];
16
17    foreach ($files as $filename) {
18      if (in_array($filename, ['.', '..'])) {
19        continue;
20      }
21
22      if (!$filePattern or fnmatch($filePattern, $filename)) {
23        $found[] = "$dir/$filename";
24      }
25    }
26
27    return $found;
28  }
29
30  static function getContentsRecursive(string $path): array {
31    $list = [];
32
33    if ($handle = opendir($path)) {
34      while (false !== ($entry = readdir($handle))) {
35        if ($entry != "." && $entry != "..") {
36          if (is_file("$path/$entry")) {
37            $list[] = $entry;
38          }
39          if (is_dir("$path/$entry")) {
40            $list[$entry] = Folder::getContentsRecursive("$path/$entry");
41          }
42        }
43      }
44      closedir($handle);
45    }
46
47    return $list;
48  }
49
50  static function getContentsFlat(string $path, $localPath = ''): array {
51    $list = [];
52
53    if ($handle = opendir($path)) {
54      while (false !== ($entry = readdir($handle))) {
55        if ($entry != "." && $entry != "..") {
56          $localPathEntry = $localPath ? "$localPath/$entry" : $entry;
57          if (is_file("$path/$entry")) {
58            $list[] = $localPathEntry;
59          }
60          if (is_dir("$path/$entry")) {
61            $list = array_merge($list, Folder::getContentsFlat("$path/$entry", $localPathEntry));
62          }
63        }
64      }
65      closedir($handle);
66    }
67
68    return $list;
69  }
70
71  // TODO unit-test
72  static function deleteContentsRecursive(string $path): void {
73    if (!is_dir($path)) {
74      return;
75    }
76
77    foreach (new DirectoryIterator($path) as $entry) {
78      if ($entry->isDot()) continue; // skip . and ..
79
80      if ($entry->isLink()) continue;
81
82      if ($entry->isFile()) {
83        if (!@unlink($entry->getPathname())) {
84          throw new Exception("Could not delete `$entry`.. permission denied");
85        }
86
87      } else if ($entry->isDir()) {
88        Folder::deleteContentsRecursive($entry->getPathname());
89        rmdir($entry->getPathname());
90      }
91    }
92  }
93
94
95  // TODO unit-test
96
97  /**
98   * creates missing subdirectories for a missing path,
99   * for example: let /var/www/html/vo_data exist
100   * and $filePath be /var/www/html/vo_data/ws_5/Testtakers
101   * this functions creates ws_5 and ws_5/Testtakers in /var/www/html/vo_data
102   * Note: dont' use paths containing filenames!
103   *
104   * difference to getOrCreateSubFolderPath -> can also create workspace-dir itself as well
105   * as sub-sub dirs like SysCheck/reports
106   *
107   * @param $dirPath - a full path
108   * @return string - the path, again
109   * @throws Exception
110   */
111  static function createPath(string $dirPath): string {
112    $pathParts = parse_url($dirPath);
113    return array_reduce(explode('/', $pathParts['path']), function($agg, $item) {
114      $agg .= "$item/";
115      if (file_exists($agg) and !is_dir($agg)) {
116        throw new Exception("$agg is not a directory, but should be!");
117      }
118      if (!file_exists($agg)) {
119        mkdir($agg);
120      }
121      return $agg;
122    }, isset($pathParts['scheme']) ? "{$pathParts['scheme']}://{$pathParts['host']}" : '');
123
124  }
125}