| Total Complexity | 176 | 
| Total Lines | 1252 | 
| Duplicated Lines | 0 % | 
| Changes | 13 | ||
| Bugs | 0 | Features | 0 | 
Complex classes like Storage often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.
Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.
While breaking up the class, it is a good idea to analyze how other classes use Storage, and based on these observations, apply Extract Interface, too.
| 1 | <?php  | 
            ||
| 32 | class Storage extends Di\Injectable  | 
            ||
| 33 | { | 
            ||
| 34 | |||
| 35 | /**  | 
            ||
| 36 | * Возвращает директорию для хранения файлов записей разговоров.  | 
            ||
| 37 | *  | 
            ||
| 38 | * @return string  | 
            ||
| 39 | */  | 
            ||
| 40 | public static function getMonitorDir(): string  | 
            ||
| 41 |     { | 
            ||
| 42 | $di = Di::getDefault();  | 
            ||
| 43 |         if ($di !== null) { | 
            ||
| 44 |             return $di->getConfig()->path('asterisk.monitordir'); | 
            ||
| 45 | }  | 
            ||
| 46 | |||
| 47 | return '/tmp';  | 
            ||
| 48 | }  | 
            ||
| 49 | |||
| 50 | /**  | 
            ||
| 51 | * Возвращает директорию для хранения media файлов.  | 
            ||
| 52 | *  | 
            ||
| 53 | * @return string  | 
            ||
| 54 | */  | 
            ||
| 55 | public static function getMediaDir(): string  | 
            ||
| 56 |     { | 
            ||
| 57 | $di = Di::getDefault();  | 
            ||
| 58 |         if ($di !== null) { | 
            ||
| 59 |             return $di->getConfig()->path('core.mediaMountPoint'); | 
            ||
| 60 | }  | 
            ||
| 61 | |||
| 62 | return '/tmp';  | 
            ||
| 63 | }  | 
            ||
| 64 | |||
| 65 | |||
| 66 | /**  | 
            ||
| 67 | * Прверяем является ли диск хранилищем.  | 
            ||
| 68 | *  | 
            ||
| 69 | * @param $device  | 
            ||
| 70 | *  | 
            ||
| 71 | * @return bool  | 
            ||
| 72 | */  | 
            ||
| 73 | public static function isStorageDisk($device): bool  | 
            ||
| 74 |     { | 
            ||
| 75 | $result = false;  | 
            ||
| 76 |         if ( ! file_exists("{$device}")) { | 
            ||
| 77 | return $result;  | 
            ||
| 78 | }  | 
            ||
| 79 | |||
| 80 | $tmp_dir = '/tmp/mnt_' . time();  | 
            ||
| 81 | Util::mwMkdir($tmp_dir);  | 
            ||
| 82 | $out = [];  | 
            ||
| 83 | |||
| 84 | $storage = new Storage();  | 
            ||
| 85 | $uid_part = 'UUID=' . $storage->getUuid($device) . '';  | 
            ||
| 86 | $format = $storage->getFsType($device);  | 
            ||
| 87 |         if ($format === '') { | 
            ||
| 88 | return false;  | 
            ||
| 89 | }  | 
            ||
| 90 |         $mountPath  = Util::which('mount'); | 
            ||
| 91 |         $umountPath = Util::which('umount'); | 
            ||
| 92 |         $rmPath     = Util::which('rm'); | 
            ||
| 93 | |||
| 94 |         Util::mwExec("{$mountPath} -t {$format} {$uid_part} {$tmp_dir}", $out); | 
            ||
| 95 |         if (is_dir("{$tmp_dir}/mikopbx") && trim(implode('', $out)) === '') { | 
            ||
| 96 | // $out - пустая строка, ошибок нет  | 
            ||
| 97 | // присутствует каталог mikopbx.  | 
            ||
| 98 | $result = true;  | 
            ||
| 99 | }  | 
            ||
| 100 |         if (self::isStorageDiskMounted($device)) { | 
            ||
| 101 |             Util::mwExec("{$umountPath} {$device}"); | 
            ||
| 102 | }  | 
            ||
| 103 | |||
| 104 |         if ( ! self::isStorageDiskMounted($device)) { | 
            ||
| 105 |             Util::mwExec("{$rmPath} -rf '{$tmp_dir}'"); | 
            ||
| 106 | }  | 
            ||
| 107 | |||
| 108 | return $result;  | 
            ||
| 109 | }  | 
            ||
| 110 | |||
| 111 | /**  | 
            ||
| 112 | * Получение идентификатора устройства.  | 
            ||
| 113 | *  | 
            ||
| 114 | * @param $device  | 
            ||
| 115 | *  | 
            ||
| 116 | * @return string  | 
            ||
| 117 | */  | 
            ||
| 118 | public function getUuid($device): string  | 
            ||
| 119 |     { | 
            ||
| 120 |         if (empty($device)) { | 
            ||
| 121 | return '';  | 
            ||
| 122 | }  | 
            ||
| 123 |         $blkidPath   = Util::which('blkid'); | 
            ||
| 124 |         $busyboxPath = Util::which('busybox'); | 
            ||
| 125 |         $sedPath     = Util::which('sed'); | 
            ||
| 126 |         $grepPath    = Util::which('grep'); | 
            ||
| 127 |         $awkPath     = Util::which('awk'); | 
            ||
| 128 |         $headPath    = Util::which('head'); | 
            ||
| 129 | |||
| 130 | $res = Util::mwExec(  | 
            ||
| 131 |             "{$blkidPath} -ofull {$device} | {$busyboxPath} {$sedPath} -r 's/[[:alnum:]]+=/\\n&/g' | {$busyboxPath} {$grepPath} \"^UUID\" | {$busyboxPath} {$awkPath} -F \"\\\"\" '{print $2}' | {$headPath} -n 1", | 
            ||
| 132 | $output  | 
            ||
| 133 | );  | 
            ||
| 134 |         if ($res === 0 && count($output) > 0) { | 
            ||
| 135 | $result = $output[0];  | 
            ||
| 136 |         } else { | 
            ||
| 137 | $result = '';  | 
            ||
| 138 | }  | 
            ||
| 139 | |||
| 140 | return $result;  | 
            ||
| 141 | }  | 
            ||
| 142 | |||
| 143 | /**  | 
            ||
| 144 | * Возвращает тип файловой системы блочного устройства.  | 
            ||
| 145 | *  | 
            ||
| 146 | * @param $device  | 
            ||
| 147 | *  | 
            ||
| 148 | * @return string  | 
            ||
| 149 | */  | 
            ||
| 150 | public function getFsType($device): string  | 
            ||
| 151 |     { | 
            ||
| 152 |         $blkidPath   = Util::which('blkid'); | 
            ||
| 153 |         $busyboxPath = Util::which('busybox'); | 
            ||
| 154 |         $sedPath     = Util::which('sed'); | 
            ||
| 155 |         $grepPath    = Util::which('grep'); | 
            ||
| 156 |         $awkPath     = Util::which('awk'); | 
            ||
| 157 | |||
| 158 |         $device = str_replace('/dev/', '', $device); | 
            ||
| 159 | $out = [];  | 
            ||
| 160 | Util::mwExec(  | 
            ||
| 161 |             "{$blkidPath} -ofull /dev/{$device} | {$busyboxPath} {$sedPath} -r 's/[[:alnum:]]+=/\\n&/g' | {$busyboxPath} {$grepPath} \"^TYPE=\" | {$busyboxPath} {$awkPath} -F \"\\\"\" '{print $2}'", | 
            ||
| 162 | $out  | 
            ||
| 163 | );  | 
            ||
| 164 |         $format = implode('', $out); | 
            ||
| 165 |         if ($format == 'msdosvfat') { | 
            ||
| 166 | $format = 'msdos';  | 
            ||
| 167 | }  | 
            ||
| 168 | |||
| 169 | return $format;  | 
            ||
| 170 | }  | 
            ||
| 171 | |||
| 172 | /**  | 
            ||
| 173 | * Проверка, смонтирован ли диск - хранилище.  | 
            ||
| 174 | *  | 
            ||
| 175 | * @param string $filter  | 
            ||
| 176 | * @param string $mount_dir  | 
            ||
| 177 | *  | 
            ||
| 178 | * @return bool  | 
            ||
| 179 | */  | 
            ||
| 180 | public static function isStorageDiskMounted($filter = '', &$mount_dir = ''): bool  | 
            ||
| 212 | }  | 
            ||
| 213 | |||
| 214 | /**  | 
            ||
| 215 | * Монитирование каталога с удаленного сервера SFTP.  | 
            ||
| 216 | *  | 
            ||
| 217 | * @param $host  | 
            ||
| 218 | * @param int $port  | 
            ||
| 219 | * @param string $user  | 
            ||
| 220 | * @param string $pass  | 
            ||
| 221 | * @param string $remout_dir  | 
            ||
| 222 | * @param string $local_dir  | 
            ||
| 223 | *  | 
            ||
| 224 | * @return bool  | 
            ||
| 225 | */  | 
            ||
| 226 | public static function mountSftpDisk($host, $port, $user, $pass, $remout_dir, $local_dir): bool  | 
            ||
| 247 | }  | 
            ||
| 248 | |||
| 249 | /**  | 
            ||
| 250 | * Монитирование каталога с удаленного сервера FTP.  | 
            ||
| 251 | *  | 
            ||
| 252 | * @param $host  | 
            ||
| 253 | * @param $port  | 
            ||
| 254 | * @param $user  | 
            ||
| 255 | * @param $pass  | 
            ||
| 256 | * @param string $remout_dir  | 
            ||
| 257 | * @param $local_dir  | 
            ||
| 258 | *  | 
            ||
| 259 | * @return bool  | 
            ||
| 260 | */  | 
            ||
| 261 | public static function mountFtp($host, $port, $user, $pass, $remout_dir, $local_dir): bool  | 
            ||
| 262 |     { | 
            ||
| 263 | Util::mwMkdir($local_dir);  | 
            ||
| 264 | $out = [];  | 
            ||
| 265 | |||
| 266 | // Собираем строку подключения к ftp.  | 
            ||
| 267 | $auth_line = '';  | 
            ||
| 268 |         if ( ! empty($user)) { | 
            ||
| 269 | $auth_line .= 'user="' . $user;  | 
            ||
| 270 |             if ( ! empty($pass)) { | 
            ||
| 271 |                 $auth_line .= ":{$pass}"; | 
            ||
| 272 | }  | 
            ||
| 273 | $auth_line .= '",';  | 
            ||
| 274 | }  | 
            ||
| 275 | |||
| 276 | $connect_line = 'ftp://' . $host;  | 
            ||
| 277 |         if ( ! empty($port)) { | 
            ||
| 278 |             $connect_line .= ":{$port}"; | 
            ||
| 279 | }  | 
            ||
| 280 |         if ( ! empty($remout_dir)) { | 
            ||
| 281 | $connect_line .= "$remout_dir";  | 
            ||
| 282 | }  | 
            ||
| 283 | |||
| 284 |         $timeoutPath   = Util::which('timeout'); | 
            ||
| 285 |         $curlftpfsPath = Util::which('curlftpfs'); | 
            ||
| 286 |         $command       = "{$timeoutPath} -t 3 {$curlftpfsPath}  -o allow_other -o {$auth_line}fsname={$host} {$connect_line} {$local_dir}"; | 
            ||
| 287 | Util::mwExec($command, $out);  | 
            ||
| 288 |         $response = trim(implode('', $out)); | 
            ||
| 289 |         if ('Terminated' === $response) { | 
            ||
| 290 | // Удаленный сервер не ответил / или не корректно указан пароль.  | 
            ||
| 291 | unset($response);  | 
            ||
| 292 | }  | 
            ||
| 293 | |||
| 294 |         return self::isStorageDiskMounted("$local_dir "); | 
            ||
| 295 | }  | 
            ||
| 296 | |||
| 297 | /**  | 
            ||
| 298 | * Запускает процесс форматирования диска.  | 
            ||
| 299 | *  | 
            ||
| 300 | * @param $dev  | 
            ||
| 301 | *  | 
            ||
| 302 | * @return array|bool  | 
            ||
| 303 | */  | 
            ||
| 304 | public static function mkfs_disk($dev)  | 
            ||
| 326 | }  | 
            ||
| 327 | }  | 
            ||
| 328 | |||
| 329 | /**  | 
            ||
| 330 | * Размонтирует диск. Удаляет каталог в случае успеха.  | 
            ||
| 331 | *  | 
            ||
| 332 | * @param $dir  | 
            ||
| 333 | *  | 
            ||
| 334 | * @return bool  | 
            ||
| 335 | */  | 
            ||
| 336 | public static function umountDisk($dir): bool  | 
            ||
| 351 | }  | 
            ||
| 352 | |||
| 353 | /**  | 
            ||
| 354 | * Разметка диска.  | 
            ||
| 355 | *  | 
            ||
| 356 | * @param string $device  | 
            ||
| 357 | * @param bool $bg  | 
            ||
| 358 | *  | 
            ||
| 359 | * @return mixed  | 
            ||
| 360 | */  | 
            ||
| 361 | public function formatDiskLocal($device, $bg = false)  | 
            ||
| 362 |     { | 
            ||
| 363 |         $partedPath = Util::which('parted'); | 
            ||
| 364 | $retVal = Util::mwExec(  | 
            ||
| 365 |             "{$partedPath} --script --align optimal '{$device}' 'mklabel msdos mkpart primary ext4 0% 100%'" | 
            ||
| 366 | );  | 
            ||
| 367 |         Util::sysLogMsg(__CLASS__, "{$partedPath} returned {$retVal}"); | 
            ||
| 368 |         if (false === $bg) { | 
            ||
| 369 | sleep(1);  | 
            ||
| 370 | }  | 
            ||
| 371 | |||
| 372 | return $this->formatDiskLocalPart2($device, $bg);  | 
            ||
| 373 | }  | 
            ||
| 374 | |||
| 375 | /**  | 
            ||
| 376 | * Форматирование диска.  | 
            ||
| 377 | *  | 
            ||
| 378 | * @param string $device  | 
            ||
| 379 | * @param bool $bg  | 
            ||
| 380 | *  | 
            ||
| 381 | * @return mixed  | 
            ||
| 382 | */  | 
            ||
| 383 | private function formatDiskLocalPart2($device, $bg = false)  | 
            ||
| 384 |     { | 
            ||
| 385 |         if (is_numeric(substr($device, -1))) { | 
            ||
| 386 | $device_id = "";  | 
            ||
| 387 |         } else { | 
            ||
| 388 | $device_id = "1";  | 
            ||
| 389 | }  | 
            ||
| 390 | $format = 'ext4';  | 
            ||
| 391 |         $mkfsPath = Util::which("mkfs.{$format}"); | 
            ||
| 392 |         $cmd      = "{$mkfsPath} {$device}{$device_id}"; | 
            ||
| 393 |         if ($bg === false) { | 
            ||
| 394 |             $retVal = Util::mwExec("{$cmd} 2>&1"); | 
            ||
| 395 |             Util::sysLogMsg(__CLASS__, "{$mkfsPath} returned {$retVal}"); | 
            ||
| 396 |         } else { | 
            ||
| 397 | usleep(200000);  | 
            ||
| 398 | Util::mwExecBg($cmd);  | 
            ||
| 399 | $retVal = true;  | 
            ||
| 400 | }  | 
            ||
| 401 | |||
| 402 | return $retVal;  | 
            ||
| 403 | }  | 
            ||
| 404 | |||
| 405 | /**  | 
            ||
| 406 | * Возвращает текущий статус форматирования диска.  | 
            ||
| 407 | *  | 
            ||
| 408 | * @param $dev  | 
            ||
| 409 | *  | 
            ||
| 410 | * @return string  | 
            ||
| 411 | */  | 
            ||
| 412 | public static function statusMkfs($dev): string  | 
            ||
| 413 |     { | 
            ||
| 414 |         if ( ! file_exists($dev)) { | 
            ||
| 415 |             $dev = "/dev/{$dev}"; | 
            ||
| 416 | }  | 
            ||
| 417 | $out = [];  | 
            ||
| 418 |         $psPath   = Util::which('ps'); | 
            ||
| 419 |         $grepPath = Util::which('grep'); | 
            ||
| 420 |         Util::mwExec("{$psPath} -A -f | {$grepPath} {$dev} | {$grepPath} mkfs | {$grepPath} -v grep", $out); | 
            ||
| 421 |         $mount_dir = trim(implode('', $out)); | 
            ||
| 422 | |||
| 423 | return empty($mount_dir) ? 'ended' : 'inprogress';  | 
            ||
| 424 | }  | 
            ||
| 425 | |||
| 426 | /**  | 
            ||
| 427 | * Clear cache folders from PHP sessions files  | 
            ||
| 428 | */  | 
            ||
| 429 | public static function clearSessionsFiles()  | 
            ||
| 430 |     { | 
            ||
| 431 | $di = Di::getDefault();  | 
            ||
| 432 |         if ($di === null) { | 
            ||
| 433 | return;  | 
            ||
| 434 | }  | 
            ||
| 435 |         $config        = $di->getShared('config'); | 
            ||
| 436 |         $phpSessionDir = $config->path('www.phpSessionDir'); | 
            ||
| 437 |         if ( ! empty($phpSessionDir)) { | 
            ||
| 438 |             $rmPath = Util::which('rm'); | 
            ||
| 439 |             Util::mwExec("{$rmPath} -rf {$phpSessionDir}/*"); | 
            ||
| 440 | }  | 
            ||
| 441 | }  | 
            ||
| 442 | |||
| 443 | /**  | 
            ||
| 444 | * Проверка свободного места на дисках. Уведомление в случае проблем.  | 
            ||
| 445 | */  | 
            ||
| 446 | public function checkFreeSpace(): void  | 
            ||
| 447 |     { | 
            ||
| 448 | $util = new Util();  | 
            ||
| 449 | $hdd = $this->getAllHdd(true);  | 
            ||
| 450 | // Создание больщого файла для тестов.  | 
            ||
| 451 | // head -c 1500MB /dev/urandom > /storage/usbdisk1/big_file.mp3  | 
            ||
| 452 |         foreach ($hdd as $disk) { | 
            ||
| 453 |             if ($disk['sys_disk'] === true && ! self::isStorageDiskMounted("{$disk['id']}4")) { | 
            ||
| 454 | // Это системный диск (4ый раздел). Он не смонтирован.  | 
            ||
| 455 | continue;  | 
            ||
| 456 | }  | 
            ||
| 457 | |||
| 458 | $free = ($disk['free_space'] / $disk['size'] * 100);  | 
            ||
| 459 | $need_alert = false;  | 
            ||
| 460 | $test_alert = '';  | 
            ||
| 461 |             if ($free < 5) { | 
            ||
| 462 | $need_alert = true;  | 
            ||
| 463 |                 $test_alert = "The {$disk['id']} has less than 5% of free space available."; | 
            ||
| 464 | }  | 
            ||
| 465 | |||
| 466 |             if ($disk['free_space'] < 500) { | 
            ||
| 467 | $need_alert = true;  | 
            ||
| 468 |                 $test_alert = "The {$disk['id']} has less than 500MB of free space available."; | 
            ||
| 469 | }  | 
            ||
| 470 | |||
| 471 |             if ($disk['free_space'] < 100) { | 
            ||
| 472 | $need_alert = true;  | 
            ||
| 473 |                 $test_alert = "The {$disk['id']} has less than 100MB of free space available. Old call records will be deleted."; | 
            ||
| 474 | Util::processPHPWorker(WorkerRemoveOldRecords::class);  | 
            ||
| 475 | }  | 
            ||
| 476 | |||
| 477 |             if ( ! $need_alert) { | 
            ||
| 478 | continue;  | 
            ||
| 479 | }  | 
            ||
| 480 | |||
| 481 |             Util::sysLogMsg("STORAGE", $test_alert); | 
            ||
| 482 | $data = [  | 
            ||
| 483 |                 'Device     - ' => "/dev/{$disk['id']}", | 
            ||
| 484 |                 'Directoire - ' => "{$disk['mounted']}", | 
            ||
| 485 | 'Desciption - ' => $test_alert,  | 
            ||
| 486 | ];  | 
            ||
| 487 | // Добавляем задачу на уведомление.  | 
            ||
| 488 |             $util->addJobToBeanstalk('WorkerNotifyError_storage', $data); | 
            ||
| 489 | }  | 
            ||
| 490 | }  | 
            ||
| 491 | |||
| 492 | /**  | 
            ||
| 493 | * Возвращает все подключенные HDD.  | 
            ||
| 494 | *  | 
            ||
| 495 | * @param bool $mounted_only  | 
            ||
| 496 | *  | 
            ||
| 497 | * @return array  | 
            ||
| 498 | */  | 
            ||
| 499 | public function getAllHdd($mounted_only = false): array  | 
            ||
| 500 |     { | 
            ||
| 501 | $res_disks = [];  | 
            ||
| 502 | |||
| 503 |         if (Util::isSystemctl()) { | 
            ||
| 504 | $out = [];  | 
            ||
| 505 |             $grepPath = Util::which('grep'); | 
            ||
| 506 |             $dfPath   = Util::which('df'); | 
            ||
| 507 |             $awkPath  = Util::which('awk'); | 
            ||
| 508 | Util::mwExec(  | 
            ||
| 509 |                 "{$dfPath} -k /storage/usbdisk1 | {$awkPath}  '{ print $1 \"|\" $3 \"|\" $4} ' | {$grepPath} -v 'Available'", | 
            ||
| 510 | $out  | 
            ||
| 511 | );  | 
            ||
| 512 |             $disk_data = explode('|', implode(" ", $out)); | 
            ||
| 513 |             if (count($disk_data) === 3) { | 
            ||
| 514 | $m_size = round(($disk_data[1] + $disk_data[2]) / 1024, 1);  | 
            ||
| 515 | $res_disks[] = [  | 
            ||
| 516 | 'id' => $disk_data[0],  | 
            ||
| 517 | 'size' => "" . $m_size,  | 
            ||
| 518 | 'size_text' => "" . $m_size . " Mb",  | 
            ||
| 519 | 'vendor' => 'Debian',  | 
            ||
| 520 | 'mounted' => '/storage/usbdisk1',  | 
            ||
| 521 | 'free_space' => round($disk_data[2] / 1024, 1),  | 
            ||
| 522 | 'partitions' => [],  | 
            ||
| 523 | 'sys_disk' => true,  | 
            ||
| 524 | ];  | 
            ||
| 525 | }  | 
            ||
| 526 | |||
| 527 | return $res_disks;  | 
            ||
| 528 | }  | 
            ||
| 529 | |||
| 530 | $cd_disks = $this->cdromGetDevices();  | 
            ||
| 531 | $cd_disks = array_unique($cd_disks);  | 
            ||
| 532 | |||
| 533 | // TODO Получение данных о дисках в формате JSON:  | 
            ||
| 534 | // lsblk -J -b -o VENDOR,MODEL,SERIAL,LABEL,TYPE,FSTYPE,MOUNTPOINT,SUBSYSTEMS,NAME,UUID  | 
            ||
| 535 | $disks = $this->diskGetDevices();  | 
            ||
| 536 | $disks = array_unique($disks);  | 
            ||
| 537 | |||
| 538 | $cf_disk = '';  | 
            ||
| 539 |         $varEtcDir = $this->config->path('core.varEtcDir'); | 
            ||
| 540 |         if (file_exists($varEtcDir . '/cfdevice')) { | 
            ||
| 541 | $cf_disk = trim(file_get_contents($varEtcDir . '/cfdevice'));  | 
            ||
| 542 | }  | 
            ||
| 543 | |||
| 544 |         foreach ($disks as $disk) { | 
            ||
| 545 |             if (in_array($disk, $cd_disks)) { | 
            ||
| 546 | // Это CD-ROM.  | 
            ||
| 547 | continue;  | 
            ||
| 548 | }  | 
            ||
| 549 | unset($temp_vendor, $temp_size, $original_size);  | 
            ||
| 550 |             $mounted = self::diskIsMounted("{$disk}"); | 
            ||
| 551 |             if ($mounted_only === true && $mounted === false) { | 
            ||
| 552 | continue;  | 
            ||
| 553 | }  | 
            ||
| 554 | $sys_disk = ($cf_disk == $disk);  | 
            ||
| 555 | |||
| 556 | $mb_size = 0;  | 
            ||
| 557 |             if (is_file("/sys/block/" . $disk . "/size")) { | 
            ||
| 558 |                 $original_size = trim(file_get_contents("/sys/block/" . $disk . "/size")); | 
            ||
| 559 | $original_size = ($original_size * 512 / 1024 / 1024);  | 
            ||
| 560 | $mb_size = $original_size;  | 
            ||
| 561 | }  | 
            ||
| 562 |             if ($mb_size > 100) { | 
            ||
| 563 |                 $temp_size   = sprintf("%.0f MB", $mb_size); | 
            ||
| 564 | $temp_vendor = $this->getVendorDisk($disk);  | 
            ||
| 565 | $free_space = $this->getFreeSpace($disk);  | 
            ||
| 566 | |||
| 567 | $arr_disk_info = $this->determineFormatFs($disk);  | 
            ||
| 568 |                 if (count($arr_disk_info) > 0) { | 
            ||
| 569 | $used = 0;  | 
            ||
| 570 |                     foreach ($arr_disk_info as $disk_info) { | 
            ||
| 571 | $used += $disk_info['used_space'];  | 
            ||
| 572 | }  | 
            ||
| 573 |                     if ($used > 0) { | 
            ||
| 574 | $free_space = $mb_size - $used;  | 
            ||
| 575 | }  | 
            ||
| 576 | }  | 
            ||
| 577 | |||
| 578 | $res_disks[] = [  | 
            ||
| 579 | 'id' => $disk,  | 
            ||
| 580 | 'size' => $mb_size,  | 
            ||
| 581 | 'size_text' => $temp_size,  | 
            ||
| 582 | 'vendor' => $temp_vendor,  | 
            ||
| 583 | 'mounted' => $mounted,  | 
            ||
| 584 | 'free_space' => $free_space,  | 
            ||
| 585 | 'partitions' => $arr_disk_info,  | 
            ||
| 586 | 'sys_disk' => $sys_disk,  | 
            ||
| 587 | ];  | 
            ||
| 588 | }  | 
            ||
| 589 | }  | 
            ||
| 590 | |||
| 591 | return $res_disks;  | 
            ||
| 592 | }  | 
            ||
| 593 | |||
| 594 | /**  | 
            ||
| 595 | * Получение массива подключенныйх cdrom.  | 
            ||
| 596 | *  | 
            ||
| 597 | * @return array  | 
            ||
| 598 | */  | 
            ||
| 599 | private function cdromGetDevices(): array  | 
            ||
| 600 |     { | 
            ||
| 601 |         $grepPath    = Util::which('grep'); | 
            ||
| 602 |         $sysctlPath  = Util::which('sysctl'); | 
            ||
| 603 |         $busyboxPath = Util::which('busybox'); | 
            ||
| 604 |         $cutPath     = Util::which('cut'); | 
            ||
| 605 | |||
| 606 | return explode(  | 
            ||
| 607 | " ",  | 
            ||
| 608 | trim(  | 
            ||
| 609 | exec(  | 
            ||
| 610 |                     "{$sysctlPath} -n dev.cdrom.info | {$busyboxPath} {$grepPath} 'drive name' | {$busyboxPath} {$cutPath} -f 3" | 
            ||
| 611 | )  | 
            ||
| 612 | )  | 
            ||
| 613 | );  | 
            ||
| 614 | }  | 
            ||
| 615 | |||
| 616 | /**  | 
            ||
| 617 | * Получение массива подключенныйх HDD.  | 
            ||
| 618 | *  | 
            ||
| 619 | * @return array  | 
            ||
| 620 | */  | 
            ||
| 621 | private function diskGetDevices(): array  | 
            ||
| 622 |     { | 
            ||
| 623 | // TODO // Переписать через использование lsblk.  | 
            ||
| 624 |         $grepPath = Util::which('grep'); | 
            ||
| 625 |         $lsPath   = Util::which('ls'); | 
            ||
| 626 |         $trPath   = Util::which('tr'); | 
            ||
| 627 | |||
| 628 |         return explode(" ", trim(exec("{$lsPath} /dev | {$grepPath} '^[a-z]d[a-z]' | {$trPath} \"\n\" \" \""))); | 
            ||
| 629 | }  | 
            ||
| 630 | |||
| 631 | /**  | 
            ||
| 632 | * Проверка, смонтирован ли диск.  | 
            ||
| 633 | *  | 
            ||
| 634 | * @param $disk  | 
            ||
| 635 | * @param $filter  | 
            ||
| 636 | *  | 
            ||
| 637 | * @return string|bool  | 
            ||
| 638 | */  | 
            ||
| 639 | public static function diskIsMounted($disk, $filter = '/dev/')  | 
            ||
| 640 |     { | 
            ||
| 641 | $out = [];  | 
            ||
| 642 |         $grepPath  = Util::which('grep'); | 
            ||
| 643 |         $mountPath = Util::which('mount'); | 
            ||
| 644 |         Util::mwExec("{$mountPath} | {$grepPath} '{$filter}{$disk}'", $out); | 
            ||
| 645 |         if (count($out) > 0) { | 
            ||
| 646 | $res_out = end($out);  | 
            ||
| 647 |         } else { | 
            ||
| 648 |             $res_out = implode('', $out); | 
            ||
| 649 | }  | 
            ||
| 650 |         $data = explode(' ', trim($res_out)); | 
            ||
| 651 | |||
| 652 | return (count($data) > 2) ? $data[2] : false;  | 
            ||
| 653 | }  | 
            ||
| 654 | |||
| 655 | /**  | 
            ||
| 656 | * Получение сведений по диску.  | 
            ||
| 657 | *  | 
            ||
| 658 | * @param $disk  | 
            ||
| 659 | *  | 
            ||
| 660 | * @return string  | 
            ||
| 661 | */  | 
            ||
| 662 | private function getVendorDisk($disk): string  | 
            ||
| 663 |     { | 
            ||
| 664 | $temp_vendor = [];  | 
            ||
| 665 |         if (is_file("/sys/block/" . $disk . "/device/vendor")) { | 
            ||
| 666 |             $data = trim(file_get_contents("/sys/block/" . $disk . "/device/vendor")); | 
            ||
| 667 |             if ($data != '') { | 
            ||
| 668 |                 $temp_vendor[] = trim(str_replace(',', ' ', $data)); | 
            ||
| 669 | }  | 
            ||
| 670 | }  | 
            ||
| 671 |         if (is_file("/sys/block/" . $disk . "/device/model")) { | 
            ||
| 672 |             $data = trim(file_get_contents("/sys/block/" . $disk . "/device/model")); | 
            ||
| 673 |             if ($data != '') { | 
            ||
| 674 |                 $temp_vendor[] = trim(str_replace(',', ' ', $data)); | 
            ||
| 675 | }  | 
            ||
| 676 | }  | 
            ||
| 677 |         if (count($temp_vendor) == 0) { | 
            ||
| 678 | $temp_vendor[] = $disk;  | 
            ||
| 679 | }  | 
            ||
| 680 |         if (is_file("/sys/block/" . $disk . "/device/type")) { | 
            ||
| 681 |             $data = trim(file_get_contents("/sys/block/" . $disk . "/device/type")); | 
            ||
| 682 |             if ($data != '') { | 
            ||
| 683 |                 $temp_vendor[] = trim(str_replace(',', ' ', $data)); | 
            ||
| 684 | }  | 
            ||
| 685 | }  | 
            ||
| 686 | |||
| 687 |         return implode(', ', $temp_vendor); | 
            ||
| 688 | }  | 
            ||
| 689 | |||
| 690 | /**  | 
            ||
| 691 | * Получаем свободное место на диске в Mb.  | 
            ||
| 692 | *  | 
            ||
| 693 | * @param $hdd  | 
            ||
| 694 | *  | 
            ||
| 695 | * @return mixed  | 
            ||
| 696 | */  | 
            ||
| 697 | public function getFreeSpace($hdd)  | 
            ||
| 698 |     { | 
            ||
| 699 | $out = [];  | 
            ||
| 700 | $hdd = escapeshellarg($hdd);  | 
            ||
| 701 |         $grepPath = Util::which('grep'); | 
            ||
| 702 |         $awkPath  = Util::which('awk'); | 
            ||
| 703 |         $dfPath   = Util::which('df'); | 
            ||
| 704 |         Util::mwExec("{$dfPath} -m | {$grepPath} {$hdd} | {$awkPath} '{print $4}'", $out); | 
            ||
| 705 | $result = 0;  | 
            ||
| 706 |         foreach ($out as $res) { | 
            ||
| 707 |             if ( ! is_numeric($res)) { | 
            ||
| 708 | continue;  | 
            ||
| 709 | }  | 
            ||
| 710 | $result += (1 * $res);  | 
            ||
| 711 | }  | 
            ||
| 712 | |||
| 713 | return $result;  | 
            ||
| 714 | }  | 
            ||
| 715 | |||
| 716 | /**  | 
            ||
| 717 | * Определить формат файловой системы и размер дисков.  | 
            ||
| 718 | *  | 
            ||
| 719 | * @param $device  | 
            ||
| 720 | *  | 
            ||
| 721 | * @return array|bool  | 
            ||
| 722 | */  | 
            ||
| 723 | public function determineFormatFs($device)  | 
            ||
| 724 |     { | 
            ||
| 725 |         $grepPath      = Util::which('grep'); | 
            ||
| 726 |         $lsPath        = Util::which('ls'); | 
            ||
| 727 |         $trPath        = Util::which('tr'); | 
            ||
| 728 | $allow_formats = ['ext2', 'ext4', 'fat', 'ntfs', 'msdos'];  | 
            ||
| 729 |         $device        = str_replace('/dev/', '', $device); | 
            ||
| 730 |         $devices       = explode(" ", trim(exec("{$lsPath} /dev | {$grepPath} '{$device}' | {$trPath} \"\n\" \" \""))); | 
            ||
| 731 | |||
| 732 | $result_data = [];  | 
            ||
| 733 |         foreach ($devices as $dev) { | 
            ||
| 734 |             if (empty($dev) || (count($devices) > 1 && $device == $dev) || is_dir("/sys/block/{$dev}")) { | 
            ||
| 735 | continue;  | 
            ||
| 736 | }  | 
            ||
| 737 | $mb_size = 0;  | 
            ||
| 738 | $path_size_info = '';  | 
            ||
| 739 |             $tmp_path       = "/sys/block/{$device}/{$dev}/size"; | 
            ||
| 740 |             if (file_exists($tmp_path)) { | 
            ||
| 741 | $path_size_info = $tmp_path;  | 
            ||
| 742 | }  | 
            ||
| 743 |             if (empty($path_size_info)) { | 
            ||
| 744 |                 $tmp_path = "/sys/block/" . substr($dev, 0, 3) . "/{$dev}/size"; | 
            ||
| 745 |                 if (file_exists($tmp_path)) { | 
            ||
| 746 | $path_size_info = $tmp_path;  | 
            ||
| 747 | }  | 
            ||
| 748 | }  | 
            ||
| 749 | |||
| 750 |             if ( ! empty($path_size_info)) { | 
            ||
| 751 | $original_size = trim(file_get_contents($path_size_info));  | 
            ||
| 752 | $original_size = ($original_size * 512 / 1024 / 1024);  | 
            ||
| 753 | $mb_size = $original_size;  | 
            ||
| 754 | }  | 
            ||
| 755 | |||
| 756 |             $tmp_dir = "/tmp/{$dev}_" . time(); | 
            ||
| 757 | $out = [];  | 
            ||
| 758 | |||
| 759 | $fs = null;  | 
            ||
| 760 | $need_unmount = false;  | 
            ||
| 761 | $mount_dir = '';  | 
            ||
| 762 |             if (self::isStorageDiskMounted("/dev/{$dev} ", $mount_dir)) { | 
            ||
| 763 |                 $grepPath  = Util::which('grep'); | 
            ||
| 764 |                 $awkPath   = Util::which('awk'); | 
            ||
| 765 |                 $mountPath = Util::which('mount'); | 
            ||
| 766 |                 Util::mwExec("{$mountPath} | {$grepPath} '/dev/{$dev}' | {$awkPath} '{print $5}'", $out); | 
            ||
| 767 |                 $fs         = trim(implode("", $out)); | 
            ||
| 768 | $fs = ($fs == 'fuseblk') ? 'ntfs' : $fs;  | 
            ||
| 769 |                 $free_space = $this->getFreeSpace("/dev/{$dev} "); | 
            ||
| 770 | $used_space = $mb_size - $free_space;  | 
            ||
| 771 |             } else { | 
            ||
| 772 | $format = $this->getFsType($device);  | 
            ||
| 773 |                 if (in_array($format, $allow_formats)) { | 
            ||
| 774 | $fs = $format;  | 
            ||
| 775 | }  | 
            ||
| 776 | self::mountDisk($dev, $format, $tmp_dir);  | 
            ||
| 777 | |||
| 778 | $need_unmount = true;  | 
            ||
| 779 |                 $used_space   = Util::getSizeOfFile("$tmp_dir"); | 
            ||
| 780 | }  | 
            ||
| 781 | $result_data[] = [  | 
            ||
| 782 | "dev" => $dev,  | 
            ||
| 783 | 'size' => round($mb_size, 2),  | 
            ||
| 784 | "used_space" => round($used_space, 2),  | 
            ||
| 785 | "free_space" => round($mb_size - $used_space, 2),  | 
            ||
| 786 |                 "uuid"       => $this->getUuid("/dev/{$dev} "), | 
            ||
| 787 | "fs" => $fs,  | 
            ||
| 788 | ];  | 
            ||
| 789 |             if ($need_unmount) { | 
            ||
| 790 | self::umountDisk($tmp_dir);  | 
            ||
| 791 | }  | 
            ||
| 792 | }  | 
            ||
| 793 | |||
| 794 | return $result_data;  | 
            ||
| 795 | }  | 
            ||
| 796 | |||
| 797 | /**  | 
            ||
| 798 | * Монтирует диск в указанный каталог.  | 
            ||
| 799 | *  | 
            ||
| 800 | * @param $dev  | 
            ||
| 801 | * @param $format  | 
            ||
| 802 | * @param $dir  | 
            ||
| 803 | *  | 
            ||
| 804 | * @return bool  | 
            ||
| 805 | */  | 
            ||
| 806 | public static function mountDisk($dev, $format, $dir): bool  | 
            ||
| 807 |     { | 
            ||
| 808 |         if (self::isStorageDiskMounted("/dev/{$dev} ")) { | 
            ||
| 809 | return true;  | 
            ||
| 810 | }  | 
            ||
| 811 | Util::mwMkdir($dir);  | 
            ||
| 812 | |||
| 813 |         if ( ! file_exists($dir)) { | 
            ||
| 814 |             Util::sysLogMsg('Storage', "Unable mount $dev $format to $dir. Unable create dir."); | 
            ||
| 815 | |||
| 816 | return false;  | 
            ||
| 817 | }  | 
            ||
| 818 |         $dev = str_replace('/dev/', '', $dev); | 
            ||
| 819 |         if ('ntfs' == $format) { | 
            ||
| 820 |             $mountNtfs3gPath = Util::which('mount.ntfs-3g'); | 
            ||
| 821 |             Util::mwExec("{$mountNtfs3gPath} /dev/{$dev} {$dir}", $out); | 
            ||
| 822 |         } else { | 
            ||
| 823 | $storage = new Storage();  | 
            ||
| 824 |             $uid_part  = 'UUID=' . $storage->getUuid("/dev/{$dev}") . ''; | 
            ||
| 825 |             $mountPath = Util::which('mount'); | 
            ||
| 826 |             Util::mwExec("{$mountPath} -t {$format} {$uid_part} {$dir}", $out); | 
            ||
| 827 | }  | 
            ||
| 828 | |||
| 829 |         return self::isStorageDiskMounted("/dev/{$dev} "); | 
            ||
| 830 | }  | 
            ||
| 831 | |||
| 832 | /**  | 
            ||
| 833 | * Монтирование разделов диска с базой данных настроек.  | 
            ||
| 834 | */  | 
            ||
| 835 | public function configure(): void  | 
            ||
| 877 | }  | 
            ||
| 878 | |||
| 879 | /**  | 
            ||
| 880 | * Получаем настройки диска из базы данных.  | 
            ||
| 881 | *  | 
            ||
| 882 | * @param string $id  | 
            ||
| 883 | *  | 
            ||
| 884 | * @return array  | 
            ||
| 885 | */  | 
            ||
| 886 | public function getDiskSettings($id = ''): array  | 
            ||
| 887 |     { | 
            ||
| 888 | $data = [];  | 
            ||
| 889 |         if ('' === $id) { | 
            ||
| 890 | // Возвращаем данные до модификации.  | 
            ||
| 891 | $data = StorageModel::find()->toArray();  | 
            ||
| 892 |         } else { | 
            ||
| 900 | }  | 
            ||
| 901 | |||
| 902 | /**  | 
            ||
| 903 | * Проверяет, существует ли диск в массиве.  | 
            ||
| 904 | *  | 
            ||
| 905 | * @param $disk  | 
            ||
| 906 | *  | 
            ||
| 907 | * @return bool  | 
            ||
| 908 | */  | 
            ||
| 909 | private function hddExists($disk): bool  | 
            ||
| 910 |     { | 
            ||
| 911 | $result = false;  | 
            ||
| 912 |         $uid    = $this->getUuid("{$disk}"); | 
            ||
| 913 |         if (file_exists("{$disk}") && $uid !== false) { | 
            ||
| 914 | $result = true;  | 
            ||
| 915 | }  | 
            ||
| 916 | |||
| 917 | return $result;  | 
            ||
| 918 | }  | 
            ||
| 919 | |||
| 920 | /**  | 
            ||
| 921 | * After mount storage we will change /mountpoint/ to new $mount_point value  | 
            ||
| 922 | *  | 
            ||
| 923 | * @param string $mount_point  | 
            ||
| 924 | *  | 
            ||
| 925 | */  | 
            ||
| 926 | private function updateConfigWithNewMountPoint(string $mount_point): void  | 
            ||
| 927 |     { | 
            ||
| 928 | $staticSettingsFile = '/etc/inc/mikopbx-settings.json';  | 
            ||
| 929 |         $staticSettingsFileOrig = appPath('config/mikopbx-settings.json'); | 
            ||
| 930 | |||
| 931 | $jsonString = file_get_contents($staticSettingsFileOrig);  | 
            ||
| 932 |         try { | 
            ||
| 933 | $data = json_decode($jsonString, true, 512, JSON_THROW_ON_ERROR);  | 
            ||
| 934 |         } catch (JsonException $exception) { | 
            ||
| 935 |             throw new Error("{$staticSettingsFileOrig} has broken format"); | 
            ||
| 936 | }  | 
            ||
| 937 |         foreach ($data as $rootKey => $rootEntry) { | 
            ||
| 938 |             foreach ($rootEntry as $nestedKey => $entry) { | 
            ||
| 939 |                 if (stripos($entry, '/mountpoint') !== false) { | 
            ||
| 940 |                     $data[$rootKey][$nestedKey] = str_ireplace('/mountpoint', $mount_point, $entry); | 
            ||
| 941 | }  | 
            ||
| 942 | }  | 
            ||
| 943 | }  | 
            ||
| 944 | |||
| 945 | $newJsonString = json_encode($data, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES);  | 
            ||
| 946 | file_put_contents($staticSettingsFile, $newJsonString);  | 
            ||
| 947 | $this->updateEnvironmentAfterChangeMountPoint();  | 
            ||
| 948 | }  | 
            ||
| 949 | |||
| 950 | |||
| 951 | /**  | 
            ||
| 952 | * Recreates DI services and reloads config from JSON file  | 
            ||
| 953 | *  | 
            ||
| 954 | */  | 
            ||
| 955 | private function updateEnvironmentAfterChangeMountPoint(): void  | 
            ||
| 966 | |||
| 967 | }  | 
            ||
| 968 | |||
| 969 | /**  | 
            ||
| 970 | * Generates fstab file  | 
            ||
| 971 | * Mounts volumes  | 
            ||
| 972 | *  | 
            ||
| 973 | * @param string $conf  | 
            ||
| 974 | */  | 
            ||
| 975 | public function saveFstab($conf = ''): void  | 
            ||
| 1012 | }  | 
            ||
| 1013 | |||
| 1014 | /**  | 
            ||
| 1015 | * Creates system folders according to config file  | 
            ||
| 1016 | *  | 
            ||
| 1017 | * @return void  | 
            ||
| 1018 | */  | 
            ||
| 1019 | private function createWorkDirs(): void  | 
            ||
| 1020 |     { | 
            ||
| 1021 | $path = '';  | 
            ||
| 1022 |         $mountPath = Util::which('mount'); | 
            ||
| 1023 |         Util::mwExec("{$mountPath} -o remount,rw /offload 2> /dev/null"); | 
            ||
| 1024 | |||
| 1025 |         $isLiveCd = file_exists('/offload/livecd'); | 
            ||
| 1026 | // Create dirs  | 
            ||
| 1027 | $arrConfig = $this->config->toArray();  | 
            ||
| 1028 |         foreach ($arrConfig as $rootEntry) { | 
            ||
| 1029 |             foreach ($rootEntry as $key => $entry) { | 
            ||
| 1030 |                 if (stripos($key, 'path') === false && stripos($key, 'dir') === false) { | 
            ||
| 1031 | continue;  | 
            ||
| 1032 | }  | 
            ||
| 1033 |                 if (file_exists($entry)) { | 
            ||
| 1034 | continue;  | 
            ||
| 1035 | }  | 
            ||
| 1036 |                 if ($isLiveCd && strpos($entry, '/offload/') === 0) { | 
            ||
| 1037 | continue;  | 
            ||
| 1038 | }  | 
            ||
| 1039 | $path .= " $entry";  | 
            ||
| 1040 | }  | 
            ||
| 1041 | }  | 
            ||
| 1042 | |||
| 1043 |         if ( ! empty($path)) { | 
            ||
| 1044 | Util::mwMkdir($path);  | 
            ||
| 1045 | }  | 
            ||
| 1046 | |||
| 1047 |         $downloadCacheDir = appPath('sites/pbxcore/files/cache'); | 
            ||
| 1048 |         if ( ! $isLiveCd) { | 
            ||
| 1049 | Util::mwMkdir($downloadCacheDir);  | 
            ||
| 1050 |             Util::createUpdateSymlink($this->config->path('www.downloadCacheDir'), $downloadCacheDir); | 
            ||
| 1051 | }  | 
            ||
| 1052 | |||
| 1053 | $this->createAssetsSymlinks();  | 
            ||
| 1054 | |||
| 1055 |         Util::createUpdateSymlink($this->config->path('www.phpSessionDir'), '/var/lib/php/session'); | 
            ||
| 1056 |         Util::createUpdateSymlink($this->config->path('www.uploadDir'), '/ultmp'); | 
            ||
| 1057 | |||
| 1058 |         $filePath = appPath('src/Core/Asterisk/Configs/lua/extensions.lua'); | 
            ||
| 1059 | Util::createUpdateSymlink($filePath, '/etc/asterisk/extensions.lua');  | 
            ||
| 1060 | |||
| 1061 | // Create symlinks to AGI-BIN  | 
            ||
| 1062 |         $agiBinDir = $this->config->path('asterisk.astagidir'); | 
            ||
| 1063 |         if ($isLiveCd && strpos($agiBinDir, '/offload/') !== 0) { | 
            ||
| 1064 | Util::mwMkdir($agiBinDir);  | 
            ||
| 1065 | }  | 
            ||
| 1066 | |||
| 1067 |         $roAgiBinFolder = appPath('src/Core/Asterisk/agi-bin'); | 
            ||
| 1068 |         $files          = glob("{$roAgiBinFolder}/*.{php}", GLOB_BRACE); | 
            ||
| 1069 |         foreach ($files as $file) { | 
            ||
| 1070 | $fileInfo = pathinfo($file);  | 
            ||
| 1071 |             $newFilename = "{$agiBinDir}/{$fileInfo['filename']}.{$fileInfo['extension']}"; | 
            ||
| 1072 | Util::createUpdateSymlink($file, $newFilename);  | 
            ||
| 1073 | }  | 
            ||
| 1074 | $this->clearCacheFiles();  | 
            ||
| 1075 | $this->applyFolderRights();  | 
            ||
| 1076 |         Util::mwExec("{$mountPath} -o remount,ro /offload 2> /dev/null"); | 
            ||
| 1077 | }  | 
            ||
| 1078 | |||
| 1079 | /**  | 
            ||
| 1080 | * Creates JS, CSS, IMG cache folders and links  | 
            ||
| 1081 | *  | 
            ||
| 1082 | */  | 
            ||
| 1083 | public function createAssetsSymlinks(): void  | 
            ||
| 1084 |     { | 
            ||
| 1085 |         $jsCacheDir = appPath('sites/admin-cabinet/assets/js/cache'); | 
            ||
| 1086 |         Util::createUpdateSymlink($this->config->path('adminApplication.assetsCacheDir') . '/js', $jsCacheDir); | 
            ||
| 1087 | |||
| 1088 |         $cssCacheDir = appPath('sites/admin-cabinet/assets/css/cache'); | 
            ||
| 1089 |         Util::createUpdateSymlink($this->config->path('adminApplication.assetsCacheDir') . '/css', $cssCacheDir); | 
            ||
| 1090 | |||
| 1091 |         $imgCacheDir = appPath('sites/admin-cabinet/assets/img/cache'); | 
            ||
| 1092 |         Util::createUpdateSymlink($this->config->path('adminApplication.assetsCacheDir') . '/img', $imgCacheDir); | 
            ||
| 1093 | }  | 
            ||
| 1094 | |||
| 1095 | /**  | 
            ||
| 1096 | * Clears cache folders from old and orphaned files  | 
            ||
| 1097 | */  | 
            ||
| 1098 | public function clearCacheFiles(): void  | 
            ||
| 1099 |     { | 
            ||
| 1100 | $cacheDirs = [];  | 
            ||
| 1101 |         $cacheDirs[] = $this->config->path('www.uploadDir'); | 
            ||
| 1102 |         $cacheDirs[] = $this->config->path('www.downloadCacheDir'); | 
            ||
| 1103 |         $cacheDirs[] = $this->config->path('www.managedCacheDir'); | 
            ||
| 1104 |         $cacheDirs[] = $this->config->path('www.modelsCacheDir'); | 
            ||
| 1105 |         $cacheDirs[] = $this->config->path('adminApplication.assetsCacheDir') . '/js'; | 
            ||
| 1106 |         $cacheDirs[] = $this->config->path('adminApplication.assetsCacheDir') . '/css'; | 
            ||
| 1107 |         $cacheDirs[] = $this->config->path('adminApplication.assetsCacheDir') . '/img'; | 
            ||
| 1108 |         $cacheDirs[] = $this->config->path('adminApplication.voltCacheDir'); | 
            ||
| 1109 |         $rmPath      = Util::which('rm'); | 
            ||
| 1110 |         foreach ($cacheDirs as $cacheDir) { | 
            ||
| 1111 |             if ( ! empty($cacheDir)) { | 
            ||
| 1112 |                 Util::mwExec("{$rmPath} -rf {$cacheDir}/*"); | 
            ||
| 1113 | }  | 
            ||
| 1114 | }  | 
            ||
| 1115 | |||
| 1116 | // Delete boot cache folders  | 
            ||
| 1117 |         if (is_dir('/mountpoint') && self::isStorageDiskMounted()) { | 
            ||
| 1118 |             Util::mwExec("{$rmPath} -rf /mountpoint"); | 
            ||
| 1119 | }  | 
            ||
| 1120 | }  | 
            ||
| 1121 | |||
| 1122 | /**  | 
            ||
| 1123 | * Create system folders and links after upgrade and connect config DB  | 
            ||
| 1124 | */  | 
            ||
| 1125 | public function createWorkDirsAfterDBUpgrade(): void  | 
            ||
| 1132 | }  | 
            ||
| 1133 | |||
| 1134 | /**  | 
            ||
| 1135 | * Restore modules cache folders and symlinks  | 
            ||
| 1136 | */  | 
            ||
| 1137 | public function createModulesCacheSymlinks(): void  | 
            ||
| 1143 | }  | 
            ||
| 1144 | }  | 
            ||
| 1145 | |||
| 1146 | /**  | 
            ||
| 1147 | * Fixes permissions for Folder and Files  | 
            ||
| 1148 | */  | 
            ||
| 1149 | private function applyFolderRights(): void  | 
            ||
| 1150 |     { | 
            ||
| 1151 | // Add Rights to the WWW dirs plus some core dirs  | 
            ||
| 1152 | $www_dirs = [];  | 
            ||
| 1153 | $exec_dirs = [];  | 
            ||
| 1154 | $arrConfig = $this->config->adminApplication->toArray();  | 
            ||
| 1155 |         foreach ($arrConfig as $key => $entry) { | 
            ||
| 1156 | if (stripos($key, 'path') === false  | 
            ||
| 1157 | && stripos($key, 'dir') === false  | 
            ||
| 1158 |             ) { | 
            ||
| 1159 | continue;  | 
            ||
| 1160 | }  | 
            ||
| 1161 | $www_dirs[] = $entry;  | 
            ||
| 1162 | }  | 
            ||
| 1163 | |||
| 1164 | $arrConfig = $this->config->www->toArray();  | 
            ||
| 1165 |         foreach ($arrConfig as $key => $entry) { | 
            ||
| 1166 | if (stripos($key, 'path') === false  | 
            ||
| 1167 | && stripos($key, 'dir') === false  | 
            ||
| 1168 |             ) { | 
            ||
| 1169 | continue;  | 
            ||
| 1170 | }  | 
            ||
| 1171 | $www_dirs[] = $entry;  | 
            ||
| 1172 | }  | 
            ||
| 1173 | |||
| 1174 |         $www_dirs[] = $this->config->path('core.tempDir'); | 
            ||
| 1175 |         $www_dirs[] = $this->config->path('database.logsDir'); | 
            ||
| 1176 | $www_dirs[] = '/etc/version';  | 
            ||
| 1177 |         $www_dirs[] = appPath('/'); | 
            ||
| 1178 | |||
| 1179 | // Add read rights  | 
            ||
| 1180 |         Util::addRegularWWWRights(implode(' ', $www_dirs)); | 
            ||
| 1181 | |||
| 1182 | // Add executable rights  | 
            ||
| 1183 |         $exec_dirs[] = appPath('src/Core/Asterisk/agi-bin'); | 
            ||
| 1184 |         $exec_dirs[] = appPath('src/Core/Rc'); | 
            ||
| 1185 |         Util::addExecutableRights(implode(' ', $exec_dirs)); | 
            ||
| 1186 | |||
| 1187 |         $mountPath = Util::which('mount'); | 
            ||
| 1188 |         Util::mwExec("{$mountPath} -o remount,ro /offload 2> /dev/null"); | 
            ||
| 1189 | }  | 
            ||
| 1190 | |||
| 1191 | /**  | 
            ||
| 1192 | * Creates swap file on storage  | 
            ||
| 1193 | */  | 
            ||
| 1194 | public function mountSwap(): void  | 
            ||
| 1195 |     { | 
            ||
| 1196 |         $tempDir    = $this->config->path('core.tempDir'); | 
            ||
| 1197 |         $swapFile   = "{$tempDir}/swapfile"; | 
            ||
| 1198 |         $swapOffCmd = Util::which('swapoff'); | 
            ||
| 1199 |         Util::mwExec("{$swapOffCmd} {$swapFile}"); | 
            ||
| 1200 |         if (file_exists($swapFile)) { | 
            ||
| 1201 | unlink($swapFile);  | 
            ||
| 1202 | }  | 
            ||
| 1203 | |||
| 1204 | $size = $this->getStorageFreeSpaceMb();  | 
            ||
| 1205 | $swapSize = 0;  | 
            ||
| 1206 |         if ($size > 4000) { | 
            ||
| 1207 | $swapSize = 2048;  | 
            ||
| 1208 |         } elseif ($size > 2000) { | 
            ||
| 1209 | $swapSize = 1024;  | 
            ||
| 1210 |         } elseif ($size > 1000) { | 
            ||
| 1211 | $swapSize = 512;  | 
            ||
| 1212 | }  | 
            ||
| 1213 |         if ($swapSize === 0) { | 
            ||
| 1214 | return;  | 
            ||
| 1215 | }  | 
            ||
| 1216 | |||
| 1217 | $bs = 1024;  | 
            ||
| 1218 | $countBlock = $swapSize * $bs;  | 
            ||
| 1219 |         $ddCmd      = Util::which('dd'); | 
            ||
| 1220 | |||
| 1221 |         Util::sysLogMsg('Swap', 'make swap ' . $swapFile, LOG_INFO, LOG_INFO); | 
            ||
| 1222 |         Util::mwExec("{$ddCmd} if=/dev/zero of={$swapFile} bs={$bs} count={$countBlock}"); | 
            ||
| 1223 | |||
| 1224 |         $mkSwapCmd = Util::which('mkswap'); | 
            ||
| 1225 |         Util::mwExec("{$mkSwapCmd} {$swapFile}"); | 
            ||
| 1226 | |||
| 1227 |         $swapOnCmd = Util::which('swapon'); | 
            ||
| 1228 |         $result    = Util::mwExec("{$swapOnCmd} {$swapFile}"); | 
            ||
| 1229 |         Util::sysLogMsg('Swap', 'connect swap result: ' . $result, LOG_INFO, LOG_INFO); | 
            ||
| 1230 | }  | 
            ||
| 1231 | |||
| 1232 | /**  | 
            ||
| 1233 | * Returns free space on mounted storage disk  | 
            ||
| 1234 | *  | 
            ||
| 1235 | * @return int size in megabytes  | 
            ||
| 1236 | */  | 
            ||
| 1237 | public function getStorageFreeSpaceMb(): int  | 
            ||
| 1238 |     { | 
            ||
| 1239 | $size = 0;  | 
            ||
| 1240 | $mntDir = '';  | 
            ||
| 1241 |         $mounted = self::isStorageDiskMounted('', $mntDir); | 
            ||
| 1242 |         if ( ! $mounted) { | 
            ||
| 1243 | return 0;  | 
            ||
| 1244 | }  | 
            ||
| 1245 | $hd = $this->getAllHdd(true);  | 
            ||
| 1246 |         foreach ($hd as $disk) { | 
            ||
| 1247 |             if ($disk['mounted'] === $mntDir) { | 
            ||
| 1248 | $size = $disk['free_space'];  | 
            ||
| 1249 | break;  | 
            ||
| 1250 | }  | 
            ||
| 1251 | }  | 
            ||
| 1252 | return $size;  | 
            ||
| 1253 | }  | 
            ||
| 1254 | |||
| 1255 | /**  | 
            ||
| 1256 | * Сохраняем новые данные диска.  | 
            ||
| 1257 | *  | 
            ||
| 1258 | * @param $data  | 
            ||
| 1259 | * @param string $id  | 
            ||
| 1260 | */  | 
            ||
| 1261 | public function saveDiskSettings($data, $id = '1'): void  | 
            ||
| 1284 | }  | 
            ||
| 1285 | }  | 
            ||
| 1286 | }  |