PluginProbe ʕ •ᴥ•ʔ
JetBackup – Backup, Restore & Migrate / 3.1.11.1
JetBackup – Backup, Restore & Migrate v3.1.11.1
3.1.23.6 3.1.23.5 3.1.23.3 3.1.22.4 3.1.22.3 1.4.3 1.4.4 1.4.5 1.4.6 1.4.7 1.4.8 1.4.8.1 1.4.9 1.5.0 1.5.1 1.5.1.1 1.5.2 1.5.3 1.5.4 1.5.5 1.5.6 1.5.7 1.5.8 1.6.0 1.6.10 1.6.11 1.6.12 1.6.13 1.6.15 1.6.5.1 1.6.8.8 1.6.9 1.6.9.1 2.0.3 2.0.4 2.0.5 2.0.6 2.0.7.5 2.0.8.7 2.0.9.11 2.0.9.14 2.0.9.15 2.0.9.6 2.0.9.7 2.0.9.9 3.1.10.7 3.1.11.1 3.1.12.3 3.1.13.4 3.1.14.17 3.1.15.4 3.1.16.1 3.1.17.5 3.1.18.10 3.1.18.8 3.1.18.9 3.1.19.8 3.1.20.3 3.1.21.3 3.1.7.9 3.1.9.2 trunk 1.1.90 1.1.91 1.2.0 1.2.5 1.2.6 1.2.7 1.2.8 1.2.9 1.3.0 1.3.1 1.3.2 1.3.3 1.3.4 1.3.6 1.3.7 1.3.8 1.3.9 1.4.0 1.4.1 1.4.2
backup / src / JetBackup / Entities / Util.php
backup / src / JetBackup / Entities Last commit date
.htaccess 1 year ago Util.php 1 year ago index.html 1 year ago web.config 1 year ago
Util.php
274 lines
1 <?php
2
3 namespace JetBackup\Entities;
4
5 use DateTime;
6 use DateTimeZone;
7 use Exception;
8 use JetBackup\Exception\IOException;
9 use JetBackup\Factory;
10 use JetBackup\Filesystem\File;
11 use JetBackup\JetBackup;
12
13 if (!defined( '__JETBACKUP__')) die('Direct access is not allowed');
14
15 class Util {
16
17 public const WEB_CONFIG_FILE = "%sweb.config";
18 const HTACCESS_FILE = "%s.htaccess";
19 const INDEX_HTML_FILE = "%sindex.html";
20
21 private function __construct() {}
22
23 /**
24 * @param string $directory
25 * @param bool $remove_main
26 * @param bool $verify
27 *
28 * @return void
29 * @throws IOException
30 */
31 public static function rm(string $directory, bool $remove_main=true):void {
32
33 if(!$directory) return;
34
35 $file = new File($directory);
36 if(!$file->exists()) return;
37
38 if($file->isFile() || $file->isLink()) {
39 unlink($directory);
40 return;
41 }
42
43 $main_length = strlen($directory);
44 if (($dir = @dir($directory)) === false) throw new IOException("Cannot delete directory $directory");
45 $queue = [$dir];
46
47 while($queue) {
48 $obj = array_shift($queue);
49
50 while ($obj !== false && ($fileName = $obj->read()) !== false) {
51 if($fileName == '.' || $fileName == '..') continue;
52
53 $file = new File($obj->path . '/' . $fileName);
54
55 if($file->isLink() || !$file->isDir()) {
56 if(!@unlink($file->path()))
57 throw new IOException("cannot remove file \"{$file->path()}\"");
58 continue;
59 }
60 array_unshift($queue, $obj);
61 $obj = dir($file->path());
62 }
63
64 if($obj !== false && ($remove_main || strlen($obj->path) != $main_length) && !@rmdir($obj->path))
65 throw new IOException("cannot remove \"$obj->path\": Directory not empty");
66
67 }
68 }
69
70 public static function cp(string $source, string $destination, int $permissions=0777, array $excludes=[]):void {
71 if(!file_exists($source)) throw new IOException("Source dir does not exist");
72 if(is_file($source)) {
73 foreach($excludes as $exclude) if(preg_match("#$exclude#", $source)) return;
74 if(!copy($source, $destination))
75 throw new IOException("Failed copping file \"$source\"");
76 return;
77 }
78
79 if(!file_exists($destination) || !is_dir($destination)) throw new IOException("Destination dir does not exist");
80
81 $queue = [$source];
82
83 while($queue) {
84 $dirName = array_shift($queue);
85 $dirObj = dir($dirName);
86
87 while (($fileName = $dirObj->read()) !== false) {
88 if($fileName == '.' || $fileName == '..') continue;
89
90 $filePath = $dirObj->path . '/' . $fileName;
91 $destFile = trim(preg_replace('/^' . preg_quote($source, '/') . '/', '', $dirObj->path), '/');
92
93 @mkdir($destination . '/' . $destFile, $permissions);
94
95 if(is_dir($filePath)) {
96 $queue[] = $filePath;
97 continue;
98 }
99
100 foreach($excludes as $exclude) if(preg_match("#$exclude#", $filePath)) continue 2;
101 if(!copy($filePath, $destination . '/' . $destFile . '/' . $fileName))
102 throw new IOException("Failed copping file \"$filePath\"");
103 }
104 }
105 }
106
107 public static function generateRandomString(int $length = 12): string {
108 try {
109 return substr(bin2hex(random_bytes(ceil($length / 2))), 0, $length);
110 } catch (Exception $e) {
111 // Fallback in case /dev/urandom is not readable
112 return substr(base64_encode(uniqid(mt_rand(), true)), 0, $length);
113 }
114 }
115
116
117 /**
118 * @param string|int $time
119 *
120 * @return DateTime
121 * @throws Exception
122 */
123 public static function getDateTime($time='now'): DateTime {
124 if(is_int($time)) $time = '@' . $time;
125 return new DateTime($time, new DateTimeZone(Factory::getSettingsGeneral()->getTimeZone()));
126 }
127
128 /**
129 * @throws Exception
130 */
131 public static function date(string $format, $timestamp=0): string {
132 if (!$timestamp || $timestamp == 0) $timestamp = time();
133 return self::getDateTime($timestamp)->format($format);
134 }
135
136 public static function generateUniqueId(): string {
137 static $inc;
138 if(!$inc) $inc = 0;
139 return sprintf("%08x%08x%08x", time(), floatval(microtime())*1000000, $inc++);
140 }
141
142 public static function generatePassword(int $length = 20 ): string {
143 $chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+';
144 $charLength = strlen($chars);
145 $password = '';
146
147 while (strlen($password) < $length) {
148 $rand = random_int(0, PHP_INT_MAX);
149 $password .= $chars[$rand % $charLength];
150 }
151
152 return $password;
153 }
154
155
156 public static function humanReadableToBytes($sSize) {
157 if (is_numeric($sSize)) return $sSize;
158
159 $iValue = intval($sSize);
160 $sSuffix = strtoupper(substr($sSize, strlen($iValue)));
161
162 switch ($sSuffix) {
163 case 'PB': case 'P': $iValue *= 1125899906842624; break;
164 case 'TB': case 'T': $iValue *= 1099511627776; break;
165 case 'GB': case 'G': $iValue *= 1073741824; break;
166 case 'MB': case 'M': $iValue *= 1048576; break;
167 case 'KB': case 'K': $iValue *= 1024; break;
168 }
169 return $iValue;
170 }
171
172 public static function bytesToHumanReadable($bytes, $precision = 2): string {
173 if (!is_numeric($bytes)) {
174 // Handle the error, return an error message, or throw an exception
175 return 'Invalid numeric value';
176 }
177
178 $units = ['B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'];
179
180 $bytes = max($bytes, 0);
181 $pow = floor(($bytes ? log($bytes) : 0) / log(1024));
182 $pow = min($pow, count($units) - 1);
183 $bytes /= (1 << (10 * $pow));
184
185 return round($bytes, $precision) . ' ' . $units[$pow];
186 }
187
188 /**
189 * @param string $path
190 *
191 * @return string
192 */
193 public static function mb_basename(string $path):string {
194 if(!$path) return '';
195 $path = preg_replace("#/+#", "/", $path);
196 if($path == '/') return '';
197 $path = preg_replace("#/$#", "", $path);
198 $pos = mb_strrpos(mb_convert_encoding($path, 'UTF-8'), "/");
199 return $pos !== false ? mb_substr($path, $pos+1) : $path;
200 }
201
202 /**
203 * @param string $path
204 *
205 * @return string
206 */
207 public static function mb_dirname(string $path):string {
208 if(!$path) return '.';
209 $path = preg_replace("#/+#", "/", $path);
210 if($path == '/') return '/';
211 $path = preg_replace("#/$#", "", $path);
212 $pos = mb_strrpos(mb_convert_encoding($path, 'UTF-8'), "/");
213 return $pos !== false ? mb_substr($path, 0, $pos) : $path;
214 }
215
216 public static function generateTimeZoneList(): array {
217 $timezones = DateTimeZone::listAbbreviations();
218 $timezone_readable = [];
219 foreach ($timezones as $timezone_area) {
220 foreach ($timezone_area as $timezone) {
221 // Ensure timezone_id is not null before trimming
222 if (is_null($timezone['timezone_id']) || trim($timezone['timezone_id']) == '') continue;
223 if (trim($timezone['timezone_id']) == 'GB') continue;
224 $hours = ($timezone['offset'] / 3600);
225 $offset = floor($hours); // Round the result to the nearest 0.5
226 $timezone_readable[$timezone['timezone_id']] = $offset;
227 }
228 }
229 ksort($timezone_readable);
230 return $timezone_readable;
231 }
232
233 public static function IISWebConfig(): string {
234
235 return <<<XML
236 <?xml version="1.0" encoding="UTF-8"?>
237 <configuration>
238 <system.webServer>
239 <security>
240 <authorization>
241 <remove users="*" roles="" verbs="" />
242 <add accessType="Deny" users="*" />
243 </authorization>
244 </security>
245 </system.webServer>
246 </configuration>
247 XML;
248
249 }
250
251 public static function secureFolder($folder): void {
252
253 $config_file = sprintf(self::WEB_CONFIG_FILE, $folder . JetBackup::SEP);
254 $htaccess_file = sprintf(self::HTACCESS_FILE, $folder . JetBackup::SEP);
255 $html_file = sprintf(self::INDEX_HTML_FILE, $folder . JetBackup::SEP);
256
257 if(!file_exists($folder)) mkdir($folder, 0700, true);
258 if(!file_exists($htaccess_file)) file_put_contents($htaccess_file, "Deny from all");
259 if(!file_exists($html_file)) file_put_contents($html_file, "");
260 if(!file_exists($config_file)) file_put_contents($config_file, self::IISWebConfig());
261
262 }
263
264 /**
265 * Normalizes a path format by replacing double forward slashes (//)
266 *
267 * @param string $path The path to be converted.
268 * @return string The converted Windows-style path.
269 */
270 public static function normalizePath(string $path): string
271 {
272 return str_replace('\\', JetBackup::SEP, $path);
273 }
274 }