Last active
March 9, 2020 06:18
-
-
Save hackimov/eea45e8c99f8291b7180bb6dc16db2bc to your computer and use it in GitHub Desktop.
Реализация файлового менеджера на Laravel
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php /** @noinspection PhpUnused */ | |
| /** | |
| * Автор класса Александр Хакимов. https://github.com/hackimov | |
| * Данный класс реализует файловый менеджер и все типы операций связанные с файлами и директориями | |
| * index возвращает список файлов и папок согласно указанному адресу или корневую директорию загрузки | |
| * destroy удаляет файл или директорию. В случае с директорией это происзодит рекурсивно | |
| * element_rename переименовывает файл иди ректорию | |
| * add_file добавляет файл в переданную пользователем директорию, если в адресе ничего не передано добавляет в корень | |
| * add_dir добавляет директорию по указанному адресу, если в адресе ничего не передано добавляет в корень | |
| */ | |
| namespace App\Http\Controllers\API\v1; | |
| use App\Http\Controllers\Controller; | |
| use App\Services\ErgResponseService; | |
| use Exception; | |
| use Illuminate\Http\JsonResponse; | |
| use Illuminate\Http\Request; | |
| use Illuminate\Support\Facades\File; | |
| class ErgStorageFileSystemController extends Controller | |
| { | |
| private static $upload_dir; | |
| private static $var_point = '..'; | |
| private static $link_char = '/'; | |
| private static $char = DIRECTORY_SEPARATOR; | |
| private static $sort = SCANDIR_SORT_NONE; | |
| public static function index(Request $request): ?JsonResponse | |
| { | |
| try { | |
| self::$upload_dir = storage_path() . self::$char . self::$var_point . self::$char . self::$var_point . self::$char; | |
| $storage_search = scandir(self::$upload_dir, self::$sort); | |
| $index = 0; | |
| foreach ($storage_search as $current_search) { | |
| if (stripos($current_search, 'storage') !== false) { | |
| $needle_index = $index; | |
| } | |
| $index++; | |
| } | |
| if (isset($storage_search[$needle_index])) { | |
| self::$upload_dir .= $storage_search[$needle_index] . self::$char . 'upload'; | |
| } | |
| $exploded_url = explode(self::$char, self::$upload_dir); | |
| while(in_array(self::$var_point, $exploded_url, true)){ | |
| foreach ($exploded_url as $i => $i_value) { | |
| if($i_value === self::$var_point && $exploded_url[$i-1] !== self::$var_point){ | |
| unset($exploded_url[$i], $exploded_url[$i-1]); | |
| break; | |
| } | |
| } | |
| $exploded_url = array_values($exploded_url); | |
| } | |
| self::$upload_dir = implode(self::$char, $exploded_url); | |
| $dir = $request->get('dir'); | |
| if (empty($dir)) { | |
| $dir = self::$upload_dir; | |
| } else { | |
| $dir = self::$upload_dir . self::$char . $dir; | |
| } | |
| $dir_finish = []; | |
| $increment = 0; | |
| $dir_list = scandir($dir, self::$sort); | |
| if ($dir === self::$upload_dir) { | |
| unset($dir_list[0], $dir_list[1]); | |
| } else { | |
| unset($dir_list[0]); | |
| } | |
| $dir_list = array_values($dir_list); | |
| foreach ($dir_list as $dir_element_name) { | |
| $exp_url = explode(self::$char, $dir . self::$char . $dir_element_name); | |
| $inc = 0; | |
| foreach($exp_url as $exp_l){ | |
| if(stripos($exp_l, 'storage') !== false){ | |
| $storage_index = $inc; | |
| } | |
| $inc++; | |
| } | |
| foreach($exp_url as $key_exp_l => $val_exp_l){ | |
| if($key_exp_l < $storage_index) { | |
| unset($exp_url[$key_exp_l]); | |
| } | |
| } | |
| $link = implode(self::$link_char, $exp_url); | |
| /** @noinspection all */ | |
| $link = preg_replace('/\/{2,}/', '/', $link); | |
| if(isset($link{0}) && $link{0} === self::$link_char) { | |
| $link = substr($link, 1); | |
| } | |
| if ($_SERVER['REMOTE_ADDR'] === '127.0.0.1') { | |
| $link = 'http:' . self::$link_char . self::$link_char . $link; | |
| } else { | |
| $link = 'https:' . self::$link_char . self::$link_char . $link; | |
| } | |
| if (is_dir($dir . self::$char . $dir_element_name)) { | |
| $dir_finish[$increment]['is_dir'] = true; | |
| $dir_finish[$increment]['extension'] = null; | |
| $dir_finish[$increment]['mime_type'] = File::mimeType($dir . self::$char . $dir_element_name); | |
| $dir_finish[$increment]['file_name'] = $dir_element_name; | |
| $dir_finish[$increment]['link'] = $link; | |
| $dir_finish[$increment]['size'] = self::format_file_size(self::recursive_directory_size($dir . self::$char . $dir_element_name)); | |
| } else { | |
| $dir_finish[$increment]['is_dir'] = false; | |
| $dir_finish[$increment]['extension'] = File::extension($dir . self::$char . $dir_element_name); | |
| if ($dir_element_name !== '.' && $dir_element_name !== self::$var_point) { | |
| $dir_finish[$increment]['mime_type'] = File::mimeType($dir . self::$char . $dir_element_name); | |
| $dir_finish[$increment]['file_name'] = $dir_element_name; | |
| $dir_finish[$increment]['link'] = $link; | |
| $dir_finish[$increment]['size'] = self::format_file_size(filesize($dir . self::$char . $dir_element_name)); | |
| } else { | |
| $dir_finish[$increment]['mime_type'] = 'directory'; | |
| $dir_finish[$increment]['file_name'] = $dir_element_name; | |
| $dir_finish[$increment]['link'] = $link; | |
| $dir_finish[$increment]['size'] = null; | |
| } | |
| } | |
| $increment++; | |
| } | |
| } catch (Exception $exception){ | |
| $data['exception'] = $exception->getMessage(); | |
| $data['exception_trace'] = $exception->getTrace(); | |
| return ErgResponseService::error('failed to get list of directory', 500, 500, $data); | |
| } | |
| return ErgResponseService::success('directory list sent successfully',$dir_finish); | |
| } | |
| public static function delete(Request $request): JsonResponse | |
| { | |
| try{ | |
| $dir = $request->get('dir'); | |
| $dir_element_name = $request->get('element'); | |
| self::$upload_dir = storage_path() . self::$char . self::$var_point . self::$char . self::$var_point . self::$char; | |
| $storage_search = scandir(self::$upload_dir , self::$sort); | |
| $index = 0; | |
| foreach ($storage_search as $current_search) { | |
| if (stripos($current_search, 'storage') !== false) { | |
| $needle_index = $index; | |
| } | |
| $index++; | |
| } | |
| if (isset($storage_search[$needle_index])) { | |
| self::$upload_dir .= $storage_search[$needle_index] . self::$char . 'upload'; | |
| } | |
| $exploded_url = explode(self::$char, self::$upload_dir); | |
| while(in_array(self::$var_point, $exploded_url, true)){ | |
| foreach ($exploded_url as $i => $i_value) { | |
| if($i_value === self::$var_point && $exploded_url[$i-1] !== self::$var_point){ | |
| unset($exploded_url[$i], $exploded_url[$i-1]); | |
| break; | |
| } | |
| } | |
| $exploded_url = array_values($exploded_url); | |
| } | |
| self::$upload_dir = implode(self::$char, $exploded_url); | |
| if (empty($dir)) { | |
| $dir = self::$upload_dir; | |
| } else { | |
| $dir = self::$upload_dir . self::$char . $dir; | |
| } | |
| if (is_dir($dir . self::$char . $dir_element_name)) { | |
| self::recursive_rmdir($dir . self::$char . $dir_element_name); | |
| } else { | |
| File::delete($dir . self::$char . $dir_element_name); | |
| } | |
| } catch (Exception $exception){ | |
| $data['exception'] = $exception->getMessage(); | |
| $data['exception_trace'] = $exception->getTrace(); | |
| return ErgResponseService::error('element ' . $request->get('element') . ' remove failed', 500, 500, $data); | |
| } | |
| return ErgResponseService::success('element ' . $request->get('element') . ' removed successfully'); | |
| } | |
| public static function element_rename(Request $request): ?JsonResponse | |
| { | |
| try{ | |
| $dir = $request->get('dir'); | |
| $dir_element_old_name = $request->get('old_name'); | |
| $dir_element_new_name = $request->get('new_name'); | |
| self::$upload_dir = storage_path() . self::$char . self::$var_point . self::$char . self::$var_point . self::$char; | |
| $storage_search = scandir(self::$upload_dir, self::$sort); | |
| $index = 0; | |
| foreach ($storage_search as $current_search) { | |
| if (stripos($current_search, 'storage') !== false) { | |
| $needle_index = $index; | |
| } | |
| $index++; | |
| } | |
| if (isset($storage_search[$needle_index])) { | |
| self::$upload_dir .= $storage_search[$needle_index] . self::$char . 'upload'; | |
| } | |
| $exploded_url = explode(self::$char, self::$upload_dir); | |
| while(in_array(self::$var_point, $exploded_url, true)){ | |
| foreach ($exploded_url as $i => $i_value) { | |
| if($i_value === self::$var_point && $exploded_url[$i-1] !== self::$var_point){ | |
| unset($exploded_url[$i], $exploded_url[$i-1]); | |
| break; | |
| } | |
| } | |
| $exploded_url = array_values($exploded_url); | |
| } | |
| self::$upload_dir = implode(self::$char, $exploded_url); | |
| if (empty($dir)) { | |
| $dir = self::$upload_dir; | |
| } else { | |
| $dir = self::$upload_dir . self::$char . $dir; | |
| } | |
| rename($dir . self::$char . $dir_element_old_name,$dir . self::$char . $dir_element_new_name); | |
| } catch (Exception $exception){ | |
| $data['exception'] = $exception->getMessage(); | |
| $data['exception_trace'] = $exception->getTrace(); | |
| return ErgResponseService::error('failed to rename ' . $dir_element_old_name, 500, 500, $data); | |
| } | |
| return ErgResponseService::success('file ' . $dir_element_old_name . ' renamed successfully'); | |
| } | |
| public static function add_file(Request $request): JsonResponse | |
| { | |
| try{ | |
| $dir = $request->get('dir'); | |
| $element = $request->get('file_name'); | |
| $file_data = $request->get('file_data'); | |
| self::$upload_dir = storage_path() . self::$char . self::$var_point . self::$char . self::$var_point . self::$char; | |
| $storage_search = scandir(self::$upload_dir, self::$sort); | |
| $index = 0; | |
| foreach ($storage_search as $current_search) { | |
| if (stripos($current_search, 'storage') !== false) { | |
| $needle_index = $index; | |
| } | |
| $index++; | |
| } | |
| if (isset($storage_search[$needle_index])) { | |
| self::$upload_dir .= $storage_search[$needle_index] . self::$char . 'upload'; | |
| } | |
| $exploded_url = explode(self::$char, self::$upload_dir); | |
| while(in_array(self::$var_point, $exploded_url, true)){ | |
| foreach ($exploded_url as $i => $i_value) { | |
| if($i_value === self::$var_point && $exploded_url[$i-1] !== self::$var_point){ | |
| unset($exploded_url[$i], $exploded_url[$i-1]); | |
| break; | |
| } | |
| } | |
| $exploded_url = array_values($exploded_url); | |
| } | |
| self::$upload_dir = implode(self::$char, $exploded_url); | |
| if (empty($dir)) { | |
| $dir = self::$upload_dir; | |
| } else { | |
| $dir = self::$upload_dir . self::$char . $dir; | |
| } | |
| $data = explode(',', $file_data); | |
| if(empty($element) || empty($file_data)) { | |
| return ErgResponseService::error('Error creation file , file name or file data is empty', 400, 400); | |
| } | |
| $file_data = base64_decode($data[1]); | |
| File::put($dir . self::$char . $element, $file_data); | |
| } catch (Exception $exception){ | |
| $data['exception'] = $exception->getMessage(); | |
| $data['exception_trace'] = $exception->getTrace(); | |
| return ErgResponseService::error('file ' . $element . ' create failed', 500, 500, $data); | |
| } | |
| return ErgResponseService::success('file ' . $element . ' created successfully'); | |
| } | |
| public static function add_dir(Request $request): JsonResponse | |
| { | |
| try{ | |
| $dir = $request->get('dir'); | |
| $folder = $request->get('folder'); | |
| self::$upload_dir = storage_path() . self::$char . self::$var_point . self::$char . self::$var_point . self::$char; | |
| $storage_search = scandir(self::$upload_dir, self::$sort); | |
| $index = 0; | |
| foreach ($storage_search as $current_search) { | |
| if (stripos($current_search, 'storage') !== false) { | |
| $needle_index = $index; | |
| } | |
| $index++; | |
| } | |
| if (isset($storage_search[$needle_index])) { | |
| self::$upload_dir .= $storage_search[$needle_index] . self::$char . 'upload'; | |
| } | |
| $exploded_url = explode(self::$char, self::$upload_dir); | |
| while(in_array(self::$var_point, $exploded_url, true)){ | |
| foreach ($exploded_url as $i => $i_value) { | |
| if($i_value === self::$var_point && $exploded_url[$i-1] !== self::$var_point){ | |
| unset($exploded_url[$i], $exploded_url[$i-1]); | |
| break; | |
| } | |
| } | |
| $exploded_url = array_values($exploded_url); | |
| } | |
| self::$upload_dir = implode(self::$char, $exploded_url); | |
| if (empty($dir)) { | |
| $dir = self::$upload_dir; | |
| } else { | |
| $dir = self::$upload_dir . self::$char . $dir; | |
| } | |
| !mkdir($concurrent_directory = $dir . self::$char . $folder) && !is_dir($concurrent_directory); | |
| } catch (Exception $exception){ | |
| $data['exception'] = $exception->getMessage(); | |
| $data['exception_trace'] = $exception->getTrace(); | |
| return ErgResponseService::error('directory ' . $folder . ' create failed', 500, 500, $data); | |
| } | |
| return ErgResponseService::success('directory ' . $folder . ' created successfully'); | |
| } | |
| public static function recursive_rmdir(string $dir): void | |
| { | |
| if (($dir !== self::$upload_dir) && is_dir($dir)) { | |
| $objects = scandir($dir , self::$sort); | |
| foreach ($objects as $object) { | |
| if ($object !== '.' && $object !== self::$var_point) { | |
| if (is_dir($dir . self::$char . $object) && !is_link($dir . self::$char . $object)) { | |
| self::recursive_rmdir($dir . self::$char . $object); | |
| } else { | |
| unlink($dir . self::$char . $object); | |
| } | |
| } | |
| } | |
| rmdir($dir); | |
| } | |
| } | |
| public static function recursive_directory_size(string $folder_path): int | |
| { | |
| $files = scandir($folder_path); | |
| unset($files[0], $files[1]); | |
| $size = 0; | |
| foreach ($files as $file) { | |
| if (file_exists($folder_path . self::$char . $file)) { | |
| $size += filesize($folder_path . self::$char . $file); | |
| if (is_dir($folder_path . self::$char . $file)) { | |
| $size += self::recursive_directory_size($folder_path . self::$char . $file); | |
| } | |
| } | |
| } | |
| return $size; | |
| } | |
| public static function format_file_size($size, int $precision = 2): string { | |
| $base = log($size, 1024); | |
| $suffixes = array('B', 'KB', 'MB', 'GB', 'TB'); | |
| /** @noinspection all */ | |
| return round(1024 ** ($base - floor($base)), $precision) .' '. $suffixes[floor($base)]; | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment