Merge remote-tracking branch 'origin/bulk-operations'

# Conflicts:
#	app/Http/Helpers/helpers.php
#	config/vuefilemanager.php
#	public/chunks/app-others.js
#	public/chunks/files~chunks/shared-files~chunks/shared-page~chunks/trash.js
#	public/js/main.js
#	public/mix-manifest.json
#	resources/js/components/FilesView/FileItemList.vue
#	resources/js/components/FilesView/FilePreview.vue
#	resources/js/helpers.js
#	resources/js/store/modules/fileFunctions.js
This commit is contained in:
Peter Papp
2020-12-21 17:02:49 +01:00
167 changed files with 6839 additions and 3151 deletions
@@ -102,7 +102,7 @@ class UserController extends Controller
public function users()
{
return new UsersCollection(
User::sortable()->paginate('20')
User::sortable(['created_at', 'DESC'])->paginate('20')
);
}
@@ -3,8 +3,11 @@
namespace App\Http\Controllers;
use App\FileManagerFolder;
use App\Http\Tools\Editor;
use App\Http\Tools\Guardian;
use App\Share;
use App\User;
use App\Zip;
use Illuminate\Support\Arr;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;
@@ -13,7 +16,11 @@ use Illuminate\Http\Request;
use App\FileManagerFile;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Str;
use Illuminate\Http\Exceptions\HttpResponseException;
use Madnest\Madzipper\Facades\Madzipper;
use Response;
use League\Flysystem\FileNotFoundException;
use Symfony\Component\HttpKernel\Exception\HttpException;
class FileAccessController extends Controller
{
@@ -84,9 +91,63 @@ class FileAccessController extends Controller
$this->check_file_access($shared, $file);
}
// Store user download size
$request->user()->record_download((int)$file->getRawOriginal('filesize'));
return $this->download_file($file);
}
/**
* Get generated zip for user
*
* @param $id
* @return \Symfony\Component\HttpFoundation\StreamedResponse
*/
public function get_zip($id)
{
$zip = Zip::where('id', $id)
->where('user_id', Auth::id())
->first();
$zip_path = 'zip/' . $zip->basename;
$header = [
"Content-Type" => 'application/zip',
"Content-Length" => Storage::disk('local')->size($zip_path),
"Accept-Ranges" => "bytes",
"Content-Range" => "bytes 0-600/" . Storage::disk('local')->size($zip_path),
"Content-Disposition" => "attachment; filename=" . $zip->basename,
];
return Storage::disk('local')->download($zip_path, $zip->basename, $header);
}
/**
* Get generated zip for guest
*
* @param $id
* @param $token
* @return \Symfony\Component\HttpFoundation\StreamedResponse
*/
public function get_zip_public($id, $token)
{
$zip = Zip::where('id', $id)
->where('shared_token', $token)
->first();
$zip_path = 'zip/' . $zip->basename;
$header = [
"Content-Type" => 'application/zip',
"Content-Length" => Storage::disk('local')->size($zip_path),
"Accept-Ranges" => "bytes",
"Content-Range" => "bytes 0-600/" . Storage::disk('local')->size($zip_path),
"Content-Disposition" => "attachment; filename=" . $zip->basename,
];
return Storage::disk('local')->download($zip_path, $zip->basename, $header);
}
/**
* Get file public
*
@@ -113,6 +174,9 @@ class FileAccessController extends Controller
// Check file access
$this->check_file_access($shared, $file);
// Store user download size
User::find($shared->user_id)->record_download((int)$file->getRawOriginal('filesize'));
return $this->download_file($file);
}
@@ -36,6 +36,7 @@ class BrowseController extends Controller
->with(['parent'])
->where('user_id', $user_id)
->whereIn('unique_id', filter_folders_ids($folders_trashed))
->sortable()
->get();
// Get files trashed
@@ -43,6 +44,7 @@ class BrowseController extends Controller
->with(['parent'])
->where('user_id', $user_id)
->whereNotIn('folder_id', array_values(array_unique(recursiveFind($folders_trashed->toArray(), 'unique_id'))))
->sortable()
->get();
// Collect folders and files to single array
@@ -72,11 +74,13 @@ class BrowseController extends Controller
$folders = FileManagerFolder::with(['parent', 'shared:token,id,item_id,permission,protected,expire_in'])
->where('user_id', $user_id)
->whereIn('unique_id', $folder_ids)
->sortable()
->get();
$files = FileManagerFile::with(['parent', 'shared:token,id,item_id,permission,protected,expire_in'])
->where('user_id', $user_id)
->whereIn('unique_id', $file_ids)
->sortable()
->get();
// Collect folders and files to single array
@@ -91,7 +95,9 @@ class BrowseController extends Controller
public function latest() {
// Get User
$user = User::with(['latest_uploads'])
$user = User::with(['latest_uploads' => function($query) {
$query->sortable();
}])
->where('id', Auth::id())
->first();
@@ -106,8 +112,11 @@ class BrowseController extends Controller
public function participant_uploads() {
// Get User
$uploads = FileManagerFile::with(['parent'])->where('user_id', Auth::id())
->whereUserScope('editor')->orderBy('created_at', 'DESC')->get();
$uploads = FileManagerFile::with(['parent'])
->where('user_id', Auth::id())
->whereUserScope('editor')
->sortable()
->get();
return $uploads;
}
@@ -132,12 +141,14 @@ class BrowseController extends Controller
->with('parent')
->where('user_id', $user_id)
->where('parent_id', $unique_id)
->sortable()
->get();
$files = FileManagerFile::onlyTrashed()
->with('parent')
->where('user_id', $user_id)
->where('folder_id', $unique_id)
->sortable()
->get();
// Collect folders and files to single array
@@ -148,13 +159,13 @@ class BrowseController extends Controller
$folders = FileManagerFolder::with(['parent', 'shared:token,id,item_id,permission,protected,expire_in'])
->where('user_id', $user_id)
->where('parent_id', $unique_id)
->orderBy('created_at', 'DESC')
->sortable()
->get();
$files = FileManagerFile::with(['parent', 'shared:token,id,item_id,permission,protected,expire_in'])
->where('user_id', $user_id)
->where('folder_id', $unique_id)
->orderBy('created_at', 'DESC')
->sortable()
->get();
// Collect folders and files to single array
@@ -171,6 +182,7 @@ class BrowseController extends Controller
$folders = FileManagerFolder::with('folders:id,parent_id,unique_id,name')
->where('parent_id', 0)
->where('user_id', Auth::id())
->sortable()
->get(['id', 'parent_id', 'unique_id', 'name']);
return [
@@ -193,33 +205,17 @@ class BrowseController extends Controller
{
// Get user
$user_id = Auth::id();
$query = remove_accents($request->input('query'));
// Search files id db
$searched_files = FileManagerFile::search($request->input('query'))
$searched_files = FileManagerFile::search($query)
->where('user_id', $user_id)
->get();
$searched_folders = FileManagerFolder::search($request->input('query'))
$searched_folders = FileManagerFolder::search($query)
->where('user_id', $user_id)
->get();
// Collect folders and files to single array
return collect([$searched_folders, $searched_files])->collapse();
}
/**
* Get file record
*
* @param $unique_id
* @return mixed
*/
public function file_detail($unique_id)
{
// Get user id
$user_id = Auth::id();
return FileManagerFile::with(['shared:token,id,item_id,permission,protected,expire_in'])
->where('user_id', $user_id)
->where('unique_id', $unique_id)
->firstOrFail();
}
}
@@ -10,6 +10,7 @@ use App\Http\Requests\FileFunctions\UploadRequest;
use App\Http\Tools\Demo;
use Illuminate\Contracts\Routing\ResponseFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use App\Http\Controllers\Controller;
use App\Http\Tools\Guardian;
@@ -168,40 +169,43 @@ class EditItemsController extends Controller
* @return ResponseFactory|\Illuminate\Http\Response
* @throws Exception
*/
public function user_delete_item(DeleteItemRequest $request, $unique_id)
public function user_delete_item(DeleteItemRequest $request)
{
// Demo preview
if (is_demo(Auth::id())) {
return Demo::response_204();
}
// Check permission to delete item for authenticated editor
if ($request->user()->tokenCan('editor')) {
foreach ($request->input('data') as $file) {
$unique_id = $file['unique_id'];
// Prevent force delete for non-master users
if ($request->input('data.force_delete')) abort('401');
// Check permission to delete item for authenticated editor
if ($request->user()->tokenCan('editor')) {
// check if shared_token cookie exist
if (!$request->hasCookie('shared_token')) abort('401');
// Prevent force delete for non-master users
if ($file['force_delete']) abort('401');
// Get shared token
$shared = get_shared($request->cookie('shared_token'));
// check if shared_token cookie exist
if (!$request->hasCookie('shared_token')) abort('401');
// Get file|folder item
$item = get_item($request->input('data.type'), $unique_id, Auth::id());
// Get shared token
$shared = get_shared($request->cookie('shared_token'));
// Check access to requested directory
if ($request->input('data.type') === 'folder') {
Guardian::check_item_access($item->unique_id, $shared);
} else {
Guardian::check_item_access($item->folder_id, $shared);
// Get file|folder item
$item = get_item($file['type'], $unique_id, Auth::id());
// Check access to requested directory
if ($file['type'] === 'folder') {
Guardian::check_item_access($item->unique_id, $shared);
} else {
Guardian::check_item_access($item->folder_id, $shared);
}
}
// Delete item
Editor::delete_item($file, $unique_id);
}
// Delete item
Editor::delete_item($request, $unique_id);
// Return response
return response(null, 204);
}
@@ -214,7 +218,7 @@ class EditItemsController extends Controller
* @return ResponseFactory|\Illuminate\Http\Response
* @throws Exception
*/
public function guest_delete_item(DeleteItemRequest $request, $unique_id, $token)
public function guest_delete_item(DeleteItemRequest $request, $token)
{
// Get shared record
$shared = get_shared($token);
@@ -227,19 +231,22 @@ class EditItemsController extends Controller
// Check shared permission
if (!is_editor($shared)) abort(403);
// Get file|folder item
$item = get_item($request->input('data.type'), $unique_id, $shared->user_id);
foreach ($request->input('data') as $file) {
$unique_id = $file['unique_id'];
// Check access to requested item
if ($request->input('data.type') === 'folder') {
Guardian::check_item_access($item->unique_id, $shared);
} else {
Guardian::check_item_access($item->folder_id, $shared);
// Get file|folder item
$item = get_item($file['type'], $unique_id, $shared->user_id);
// Check access to requested item
if ($file['type'] === 'folder') {
Guardian::check_item_access($item->unique_id, $shared);
} else {
Guardian::check_item_access($item->folder_id, $shared);
}
// Delete item
Editor::delete_item($file, $unique_id, $shared);
}
// Delete item
Editor::delete_item($request, $unique_id, $shared);
// Return response
return response(null, 204);
}
@@ -309,19 +316,13 @@ class EditItemsController extends Controller
}
/**
* Move item for authenticated master|editor user
* User download multiple files via zip
*
* @param MoveItemRequest $request
* @param $unique_id
* @return ResponseFactory|\Illuminate\Http\Response
* @param Request $request
* @return string
*/
public function user_move(MoveItemRequest $request, $unique_id)
public function user_zip_multiple_files(Request $request)
{
// Demo preview
if (is_demo(Auth::id())) {
return Demo::response_204();
}
// Check permission to upload for authenticated editor
if ($request->user()->tokenCan('editor')) {
@@ -331,12 +332,98 @@ class EditItemsController extends Controller
// Get shared token
$shared = get_shared($request->cookie('shared_token'));
$file_parent_folders = FileManagerFile::whereUserId(Auth::id())
->whereIn('unique_id', $request->input('files'))
->get()
->pluck('folder_id')
->toArray();
// Check access to requested directory
Guardian::check_item_access($request->to_unique_id, $shared);
Guardian::check_item_access($file_parent_folders, $shared);
}
// Get requested files
$files = FileManagerFile::whereUserId(Auth::id())
->whereIn('unique_id', $request->input('files'))
->get();
$zip = Editor::zip_files($files);
// Get file
return response([
'url' => route('zip', $zip->id),
'name' => $zip->basename,
], 200);
}
/**
* Guest download multiple files via zip
*
* @param Request $request
* @param $token
* @return string
*/
public function guest_zip_multiple_files(Request $request, $token)
{
// Get shared record
$shared = get_shared($token);
$file_parent_folders = FileManagerFile::whereUserId($shared->user_id)
->whereIn('unique_id', $request->input('files'))
->get()
->pluck('folder_id')
->toArray();
// Check access to requested directory
Guardian::check_item_access($file_parent_folders, $shared);
// Get requested files
$files = FileManagerFile::whereUserId($shared->user_id)
->whereIn('unique_id', $request->input('files'))
->get();
$zip = Editor::zip_files($files, $shared);
// Get file
return response([
'url' => route('zip_public', [
'id' => $zip->id,
'token' => $shared->token,
]),
'name' => $zip->basename,
], 200);
}
/**
* Move item for authenticated master|editor user
*
* @param MoveItemRequest $request
* @param $unique_id
* @return ResponseFactory|\Illuminate\Http\Response
*/
public function user_move(MoveItemRequest $request)
{
// Demo preview
if (is_demo(Auth::id())) {
return Demo::response_204();
}
$to_unique_id = $request->input('to_unique_id');
// Check permission to upload for authenticated editor
if ($request->user()->tokenCan('editor')) {
// check if shared_token cookie exist
if (!$request->hasCookie('shared_token')) abort('401');
// Get shared token
$shared = get_shared($request->cookie('shared_token'));
// Check access to requested directory
Guardian::check_item_access($to_unique_id, $shared);
}
// Move item
Editor::move($request, $unique_id);
Editor::move($request, $to_unique_id);
return response('Done!', 204);
}
@@ -349,11 +436,14 @@ class EditItemsController extends Controller
* @param $token
* @return ResponseFactory|\Illuminate\Http\Response
*/
public function guest_move(MoveItemRequest $request, $unique_id, $token)
public function guest_move(MoveItemRequest $request, $token)
{
// Get shared record
$shared = get_shared($token);
//Unique id of Folder where move
$to_unique_id = $request->input('to_unique_id');
// Demo preview
if (is_demo(Auth::id())) {
return Demo::response_204();
@@ -362,23 +452,28 @@ class EditItemsController extends Controller
// Check shared permission
if (!is_editor($shared)) abort(403);
$moving_unique_id = $unique_id;
foreach ($request->input('items') as $item) {
if ($request->from_type !== 'folder') {
$file = FileManagerFile::where('unique_id', $unique_id)
->where('user_id', $shared->user_id)
->firstOrFail();
$unique_id = $item['unique_id'];
$moving_unique_id = $unique_id;
$moving_unique_id = $file->folder_id;
if ($item['type'] !== 'folder') {
$file = FileManagerFile::where('unique_id', $unique_id)
->where('user_id', $shared->user_id)
->firstOrFail();
$moving_unique_id = $file->folder_id;
}
// Check access to requested item
Guardian::check_item_access([
$to_unique_id, $moving_unique_id
], $shared);
}
// Check access to requested item
Guardian::check_item_access([
$request->to_unique_id, $moving_unique_id
], $shared);
// Move item
Editor::move($request, $unique_id, $shared);
Editor::move($request, $to_unique_id, $shared);
return response('Done!', 204);
}
@@ -20,16 +20,18 @@ class FavouriteController extends Controller
public function store(Request $request)
{
// Validate request
$validator = Validator::make($request->all(), [
'unique_id' => 'required|integer',
$validator = Validator::make($request->input('folders'), [
'*.unique_id' => 'required|integer',
]);
// Return error
if ($validator->fails()) abort(400, 'Bad input');
foreach($request->input('folders') as $item) {
// Get user & folder
$user = Auth::user();
$folder = FileManagerFolder::where('unique_id', $request->unique_id)->first();
$folder = FileManagerFolder::where('unique_id', $item['unique_id'])->first();
if (is_demo($user->id)) {
return Demo::favourites($user);
@@ -39,8 +41,9 @@ class FavouriteController extends Controller
if ($folder->user_id !== $user->id) abort(403);
// Add folder to user favourites
$user->favourite_folders()->syncWithoutDetaching($request->unique_id);
$user->favourite_folders()->syncWithoutDetaching($item['unique_id']);
}
// Return updated favourites
return $user->favourite_folders;
}
@@ -5,6 +5,7 @@ namespace App\Http\Controllers\FileFunctions;
use App\Http\Requests\Share\CreateShareRequest;
use App\Http\Requests\Share\UpdateShareRequest;
use App\Http\Resources\ShareResource;
use App\Zip;
use Illuminate\Contracts\Routing\ResponseFactory;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
@@ -93,15 +94,25 @@ class ShareController extends Controller
* @return ResponseFactory|\Illuminate\Http\Response
* @throws \Exception
*/
public function destroy($token)
public function destroy(Request $request)
{
// Get sharing record
$shared = Share::where('token', $token)
->where('user_id', Auth::id())
->firstOrFail();
foreach($request->input('tokens') as $token) {
// Delete shared record
$shared->delete();
// Get sharing record
Share::where('token', $token)
->where('user_id', Auth::id())
->firstOrFail()
->delete();
// Get zip record
$zip = Zip::where('shared_token', $token)
->where('user_id', Auth::id())
->first();
if ($zip) {
$zip->delete();
}
}
// Done
return response('Done!', 204);
@@ -58,6 +58,10 @@ class FileSharingController extends Controller
->first();
if ($image) {
// Store user download size
User::find($shared->user_id)->record_download((int) $image->getRawOriginal('filesize'));
return $this->show_image($image);
}
}
@@ -247,6 +251,7 @@ class FileSharingController extends Controller
$folders = FileManagerFolder::with('folders:id,parent_id,unique_id,name')
->where('parent_id', $shared->item_id)
->where('user_id', $shared->user_id)
->sortable()
->get(['id', 'parent_id', 'unique_id', 'name']);
// Return folder tree
@@ -277,6 +282,7 @@ class FileSharingController extends Controller
$folders = FileManagerFolder::with('folders:id,parent_id,unique_id,name')
->where('parent_id', $shared->item_id)
->where('user_id', $shared->user_id)
->sortable()
->get(['id', 'parent_id', 'unique_id', 'name']);
// Return folder tree
@@ -399,10 +405,12 @@ class FileSharingController extends Controller
{
$folders = FileManagerFolder::where('user_id', $shared->user_id)
->where('parent_id', $unique_id)
->sortable()
->get();
$files = FileManagerFile::where('user_id', $shared->user_id)
->where('folder_id', $unique_id)
->sortable()
->get();
return [$folders, $files];
@@ -107,7 +107,15 @@ class AccountController extends Controller
*/
public function update_user_settings(Request $request)
{
// TODO: validation
// Validate request
$validator = Validator::make($request->all(), [
'name' => 'string',
'value' => 'string',
]);
// Return error
if ($validator->fails()) abort(400, 'Bad input');
// Get user
$user = Auth::user();
+175 -23
View File
@@ -355,25 +355,6 @@ function format_gigabytes($gigabytes)
}
}
/**
* Format string to formated megabytes string
*
* @param $megabytes
* @return string
*/
function format_megabytes($megabytes)
{
if ($megabytes >= 1000) {
return $megabytes / 1000 . 'GB';
}
if ($megabytes >= 1000000) {
return $megabytes / 1000000 . 'TB';
}
return $megabytes . 'MB';
}
/**
* Convert megabytes to bytes
*
@@ -514,7 +495,6 @@ function get_file_type($file_mimetype)
}
}
/**
* Get file type from mimetype
*
@@ -550,14 +530,186 @@ function get_pretty_name($basename, $name, $mimetype)
}
/**
* Read exif data from jpeg image file
* Get exif data from jpeg image
*
* @param $file
* @return array
*/
function get_image_meta_data($file)
{
if(get_file_type_from_mimetype($file->getMimeType()) === 'jpeg') {
return exif_read_data($file);
if (get_file_type_from_mimetype($file->getMimeType()) === 'jpeg') {
return exif_read_data($file);
}
}
/**
* Check if app is in dev mode
*
* @return bool
*/
function is_dev()
{
return env('APP_ENV') === 'local' ? true : false;
}
/**
* @param $str
* @return bool
*/
function seems_utf8($str)
{
$length = strlen($str);
for ($i=0; $i < $length; $i++) {
$c = ord($str[$i]);
if ($c < 0x80) $n = 0; # 0bbbbbbb
elseif (($c & 0xE0) == 0xC0) $n=1; # 110bbbbb
elseif (($c & 0xF0) == 0xE0) $n=2; # 1110bbbb
elseif (($c & 0xF8) == 0xF0) $n=3; # 11110bbb
elseif (($c & 0xFC) == 0xF8) $n=4; # 111110bb
elseif (($c & 0xFE) == 0xFC) $n=5; # 1111110b
else return false; # Does not match any model
for ($j=0; $j<$n; $j++) { # n bytes matching 10bbbbbb follow ?
if ((++$i == $length) || ((ord($str[$i]) & 0xC0) != 0x80))
return false;
}
}
return true;
}
/**
* Converts all accent characters to ASCII characters.
*
* If there are no accent characters, then the string given is just returned.
*
* @param string $string Text that might have accent characters
* @return string Filtered string with replaced "nice" characters.
*/
function remove_accents($string) {
if ( !preg_match('/[\x80-\xff]/', $string) )
return $string;
if (seems_utf8($string)) {
$chars = array(
// Decompositions for Latin-1 Supplement
chr(195).chr(128) => 'A', chr(195).chr(129) => 'A',
chr(195).chr(130) => 'A', chr(195).chr(131) => 'A',
chr(195).chr(132) => 'A', chr(195).chr(133) => 'A',
chr(195).chr(135) => 'C', chr(195).chr(136) => 'E',
chr(195).chr(137) => 'E', chr(195).chr(138) => 'E',
chr(195).chr(139) => 'E', chr(195).chr(140) => 'I',
chr(195).chr(141) => 'I', chr(195).chr(142) => 'I',
chr(195).chr(143) => 'I', chr(195).chr(145) => 'N',
chr(195).chr(146) => 'O', chr(195).chr(147) => 'O',
chr(195).chr(148) => 'O', chr(195).chr(149) => 'O',
chr(195).chr(150) => 'O', chr(195).chr(153) => 'U',
chr(195).chr(154) => 'U', chr(195).chr(155) => 'U',
chr(195).chr(156) => 'U', chr(195).chr(157) => 'Y',
chr(195).chr(159) => 's', chr(195).chr(160) => 'a',
chr(195).chr(161) => 'a', chr(195).chr(162) => 'a',
chr(195).chr(163) => 'a', chr(195).chr(164) => 'a',
chr(195).chr(165) => 'a', chr(195).chr(167) => 'c',
chr(195).chr(168) => 'e', chr(195).chr(169) => 'e',
chr(195).chr(170) => 'e', chr(195).chr(171) => 'e',
chr(195).chr(172) => 'i', chr(195).chr(173) => 'i',
chr(195).chr(174) => 'i', chr(195).chr(175) => 'i',
chr(195).chr(177) => 'n', chr(195).chr(178) => 'o',
chr(195).chr(179) => 'o', chr(195).chr(180) => 'o',
chr(195).chr(181) => 'o', chr(195).chr(182) => 'o',
chr(195).chr(182) => 'o', chr(195).chr(185) => 'u',
chr(195).chr(186) => 'u', chr(195).chr(187) => 'u',
chr(195).chr(188) => 'u', chr(195).chr(189) => 'y',
chr(195).chr(191) => 'y',
// Decompositions for Latin Extended-A
chr(196).chr(128) => 'A', chr(196).chr(129) => 'a',
chr(196).chr(130) => 'A', chr(196).chr(131) => 'a',
chr(196).chr(132) => 'A', chr(196).chr(133) => 'a',
chr(196).chr(134) => 'C', chr(196).chr(135) => 'c',
chr(196).chr(136) => 'C', chr(196).chr(137) => 'c',
chr(196).chr(138) => 'C', chr(196).chr(139) => 'c',
chr(196).chr(140) => 'C', chr(196).chr(141) => 'c',
chr(196).chr(142) => 'D', chr(196).chr(143) => 'd',
chr(196).chr(144) => 'D', chr(196).chr(145) => 'd',
chr(196).chr(146) => 'E', chr(196).chr(147) => 'e',
chr(196).chr(148) => 'E', chr(196).chr(149) => 'e',
chr(196).chr(150) => 'E', chr(196).chr(151) => 'e',
chr(196).chr(152) => 'E', chr(196).chr(153) => 'e',
chr(196).chr(154) => 'E', chr(196).chr(155) => 'e',
chr(196).chr(156) => 'G', chr(196).chr(157) => 'g',
chr(196).chr(158) => 'G', chr(196).chr(159) => 'g',
chr(196).chr(160) => 'G', chr(196).chr(161) => 'g',
chr(196).chr(162) => 'G', chr(196).chr(163) => 'g',
chr(196).chr(164) => 'H', chr(196).chr(165) => 'h',
chr(196).chr(166) => 'H', chr(196).chr(167) => 'h',
chr(196).chr(168) => 'I', chr(196).chr(169) => 'i',
chr(196).chr(170) => 'I', chr(196).chr(171) => 'i',
chr(196).chr(172) => 'I', chr(196).chr(173) => 'i',
chr(196).chr(174) => 'I', chr(196).chr(175) => 'i',
chr(196).chr(176) => 'I', chr(196).chr(177) => 'i',
chr(196).chr(178) => 'IJ',chr(196).chr(179) => 'ij',
chr(196).chr(180) => 'J', chr(196).chr(181) => 'j',
chr(196).chr(182) => 'K', chr(196).chr(183) => 'k',
chr(196).chr(184) => 'k', chr(196).chr(185) => 'L',
chr(196).chr(186) => 'l', chr(196).chr(187) => 'L',
chr(196).chr(188) => 'l', chr(196).chr(189) => 'L',
chr(196).chr(190) => 'l', chr(196).chr(191) => 'L',
chr(197).chr(128) => 'l', chr(197).chr(129) => 'L',
chr(197).chr(130) => 'l', chr(197).chr(131) => 'N',
chr(197).chr(132) => 'n', chr(197).chr(133) => 'N',
chr(197).chr(134) => 'n', chr(197).chr(135) => 'N',
chr(197).chr(136) => 'n', chr(197).chr(137) => 'N',
chr(197).chr(138) => 'n', chr(197).chr(139) => 'N',
chr(197).chr(140) => 'O', chr(197).chr(141) => 'o',
chr(197).chr(142) => 'O', chr(197).chr(143) => 'o',
chr(197).chr(144) => 'O', chr(197).chr(145) => 'o',
chr(197).chr(146) => 'OE',chr(197).chr(147) => 'oe',
chr(197).chr(148) => 'R',chr(197).chr(149) => 'r',
chr(197).chr(150) => 'R',chr(197).chr(151) => 'r',
chr(197).chr(152) => 'R',chr(197).chr(153) => 'r',
chr(197).chr(154) => 'S',chr(197).chr(155) => 's',
chr(197).chr(156) => 'S',chr(197).chr(157) => 's',
chr(197).chr(158) => 'S',chr(197).chr(159) => 's',
chr(197).chr(160) => 'S', chr(197).chr(161) => 's',
chr(197).chr(162) => 'T', chr(197).chr(163) => 't',
chr(197).chr(164) => 'T', chr(197).chr(165) => 't',
chr(197).chr(166) => 'T', chr(197).chr(167) => 't',
chr(197).chr(168) => 'U', chr(197).chr(169) => 'u',
chr(197).chr(170) => 'U', chr(197).chr(171) => 'u',
chr(197).chr(172) => 'U', chr(197).chr(173) => 'u',
chr(197).chr(174) => 'U', chr(197).chr(175) => 'u',
chr(197).chr(176) => 'U', chr(197).chr(177) => 'u',
chr(197).chr(178) => 'U', chr(197).chr(179) => 'u',
chr(197).chr(180) => 'W', chr(197).chr(181) => 'w',
chr(197).chr(182) => 'Y', chr(197).chr(183) => 'y',
chr(197).chr(184) => 'Y', chr(197).chr(185) => 'Z',
chr(197).chr(186) => 'z', chr(197).chr(187) => 'Z',
chr(197).chr(188) => 'z', chr(197).chr(189) => 'Z',
chr(197).chr(190) => 'z', chr(197).chr(191) => 's',
// Euro Sign
chr(226).chr(130).chr(172) => 'E',
// GBP (Pound) Sign
chr(194).chr(163) => '');
$string = strtr($string, $chars);
} else {
// Assume ISO-8859-1 if not UTF-8
$chars['in'] = chr(128).chr(131).chr(138).chr(142).chr(154).chr(158)
.chr(159).chr(162).chr(165).chr(181).chr(192).chr(193).chr(194)
.chr(195).chr(196).chr(197).chr(199).chr(200).chr(201).chr(202)
.chr(203).chr(204).chr(205).chr(206).chr(207).chr(209).chr(210)
.chr(211).chr(212).chr(213).chr(214).chr(216).chr(217).chr(218)
.chr(219).chr(220).chr(221).chr(224).chr(225).chr(226).chr(227)
.chr(228).chr(229).chr(231).chr(232).chr(233).chr(234).chr(235)
.chr(236).chr(237).chr(238).chr(239).chr(241).chr(242).chr(243)
.chr(244).chr(245).chr(246).chr(248).chr(249).chr(250).chr(251)
.chr(252).chr(253).chr(255);
$chars['out'] = "EfSZszYcYuAAAAAACEEEEIIIINOOOOOOUUUUYaaaaaaceeeeiiiinoooooouuuuyy";
$string = strtr($string, $chars['in'], $chars['out']);
$double_chars['in'] = array(chr(140), chr(156), chr(198), chr(208), chr(222), chr(223), chr(230), chr(240), chr(254));
$double_chars['out'] = array('OE', 'oe', 'AE', 'DH', 'TH', 'ss', 'ae', 'dh', 'th');
$string = str_replace($double_chars['in'], $double_chars['out'], $string);
}
return $string;
}
@@ -25,8 +25,9 @@ class DeleteItemRequest extends FormRequest
public function rules()
{
return [
'data.type' => 'required|string',
'data.force_delete' => 'required|boolean',
'data[*].force_delete' => 'required|boolean',
'data[*].type' => 'required|string',
'data[*].unique_id' => 'required|integer'
];
}
}
@@ -25,8 +25,9 @@ class MoveItemRequest extends FormRequest
public function rules()
{
return [
'to_unique_id' => 'required|integer',
'from_type' => 'required|string',
'to_unique_id' => 'required|integer',
'items[*].type' => 'required|string',
'items[*].unique_id' => 'required|integer',
];
}
}
+119 -29
View File
@@ -8,6 +8,7 @@ use App\FileManagerFile;
use App\FileManagerFolder;
use App\Http\Requests\FileFunctions\RenameItemRequest;
use App\User;
use App\Zip;
use Aws\Exception\MultipartUploadException;
use Aws\S3\MultipartUploader;
use Carbon\Carbon;
@@ -18,11 +19,83 @@ use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Str;
use Intervention\Image\ImageManagerStatic as Image;
use League\Flysystem\FileNotFoundException;
use Madnest\Madzipper\Facades\Madzipper;
use Symfony\Component\HttpKernel\Exception\HttpException;
class Editor
{
/**
* Zip selected files, store it in /zip folder and retrieve zip record
*
* @param $files
* @param null $shared
* @return mixed
* @throws \Illuminate\Contracts\Filesystem\FileNotFoundException
*/
public static function zip_files($files, $shared = null)
{
// Local storage instance
$disk_local = Storage::disk('local');
// Create zip directory
if (!$disk_local->exists('zip')) {
$disk_local->makeDirectory('zip');
}
// Move file to local storage from external storage service
if (!is_storage_driver('local')) {
// Create temp directory
if (!$disk_local->exists('temp')) {
$disk_local->makeDirectory('temp');
}
foreach ($files as $file) {
try {
$disk_local->put('temp/' . $file['basename'], Storage::get('file-manager/' . $file['basename']));
} catch (FileNotFoundException $e) {
throw new HttpException(404, 'File not found');
}
}
}
// Get zip path
$zip_name = Str::random(16) . '.zip';
$zip_path = 'zip/' . $zip_name;
// Create zip
$zip = Madzipper::make(storage_path() . '/app/' . $zip_path);
// Get files folder on local storage drive
$files_directory = is_storage_driver('local') ? 'file-manager' : 'temp';
// Add files to zip
$files->each(function ($file) use ($zip, $files_directory) {
$zip->addString($file['name'], File::get(storage_path() . '/app/' . $files_directory . '/' . $file['basename']));
});
// Close zip
$zip->close();
// Delete temporary files
if (!is_storage_driver('local')) {
$files->each(function ($file) use ($disk_local) {
$disk_local->delete('temp/' . $file['basename']);
});
}
// Store zip record
return Zip::create([
'user_id' => $shared->user_id ?? Auth::id(),
'shared_token' => $shared->token ?? null,
'basename' => $zip_name,
]);
}
/**
* Create new directory
*
@@ -86,13 +159,13 @@ class Editor
* @param null $shared
* @throws \Exception
*/
public static function delete_item($request, $unique_id, $shared = null)
public static function delete_item($file, $unique_id, $shared = null)
{
// Get user id
$user = is_null($shared) ? Auth::user() : User::findOrFail($shared->user_id);
// Delete folder
if ($request->input('data.type') === 'folder') {
if ($file['type'] === 'folder') {
// Get folder
$folder = FileManagerFolder::withTrashed()
@@ -113,7 +186,7 @@ class Editor
}
// Force delete children files
if ($request->input('data.force_delete')) {
if ($file['force_delete']) {
// Get children folder ids
$child_folders = filter_folders_ids($folder->trashed_folders, 'unique_id');
@@ -142,7 +215,7 @@ class Editor
}
// Soft delete items
if (!$request->input('data.force_delete')) {
if (!$file['force_delete']) {
// Remove folder from user favourites
$user->favourite_folders()->detach($unique_id);
@@ -153,10 +226,10 @@ class Editor
}
// Delete item
if ($request->input('data.type') !== 'folder') {
if ($file['type'] !== 'folder') {
// Get file
$file = FileManagerFile::withTrashed()
$item = FileManagerFile::withTrashed()
->where('user_id', $user->id)
->where('unique_id', $unique_id)
->first();
@@ -173,23 +246,23 @@ class Editor
}
// Force delete file
if ($request->input('data.force_delete')) {
if ($file['force_delete']) {
// Delete file
Storage::delete('/file-manager/' . $file->basename);
Storage::delete('/file-manager/' . $item->basename);
// Delete thumbnail if exist
if ($file->thumbnail) Storage::delete('/file-manager/' . $file->getRawOriginal('thumbnail'));
if ($item->thumbnail) Storage::delete('/file-manager/' . $item->getRawOriginal('thumbnail'));
// Delete file permanently
$file->forceDelete();
$item->forceDelete();
}
// Soft delete file
if (!$request->input('data.force_delete')) {
if (!$file['force_delete']) {
// Soft delete file
$file->delete();
$item->delete();
}
}
}
@@ -201,32 +274,36 @@ class Editor
* @param $unique_id
* @param null $shared
*/
public static function move($request, $unique_id, $shared = null)
public static function move($request, $to_unique_id, $shared = null)
{
// Get user id
$user_id = is_null($shared) ? Auth::id() : $shared->user_id;
if ($request->from_type === 'folder') {
foreach ($request->input('items') as $item) {
$unique_id = $item['unique_id'];
// Move folder
$item = FileManagerFolder::where('user_id', $user_id)
->where('unique_id', $unique_id)
->firstOrFail();
if ($item['type'] === 'folder') {
$item->update([
'parent_id' => $request->to_unique_id
]);
// Move folder
$item = FileManagerFolder::where('user_id', $user_id)
->where('unique_id', $unique_id)
->firstOrFail();
} else {
$item->update([
'parent_id' => $to_unique_id
]);
// Move file under new folder
$item = FileManagerFile::where('user_id', $user_id)
->where('unique_id', $unique_id)
->firstOrFail();
} else {
$item->update([
'folder_id' => $request->to_unique_id
]);
// Move file under new folder
$item = FileManagerFile::where('user_id', $user_id)
->where('unique_id', $unique_id)
->firstOrFail();
$item->update([
'folder_id' => $to_unique_id
]);
}
}
}
@@ -316,6 +393,19 @@ class Editor
'user_id' => $user_id,
];
// Store user upload size
if ($request->user()) {
// If upload a loged user
$request->user()->record_upload($file_size);
} else {
// If upload guest
User::find($shared->user_id)->record_upload($file_size);
}
// Return new file
return FileManagerFile::create($options);
}