Skip to content

Instantly share code, notes, and snippets.

@hackimov
Last active March 9, 2020 06:18
Show Gist options
  • Select an option

  • Save hackimov/eea45e8c99f8291b7180bb6dc16db2bc to your computer and use it in GitHub Desktop.

Select an option

Save hackimov/eea45e8c99f8291b7180bb6dc16db2bc to your computer and use it in GitHub Desktop.
Реализация файлового менеджера на Laravel
<?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