mirror of
https://github.com/VueFileManager/vuefilemanager.git
synced 2026-04-26 18:30:38 +00:00
src folder refactoring
This commit is contained in:
@@ -0,0 +1,114 @@
|
||||
<?php
|
||||
namespace App\Services;
|
||||
|
||||
use App\Models\File;
|
||||
use ByteUnits\Metric;
|
||||
use App\Models\Folder;
|
||||
use Illuminate\Support\Str;
|
||||
use Illuminate\Contracts\Routing\ResponseFactory;
|
||||
use App\Http\Requests\FileFunctions\RenameItemRequest;
|
||||
|
||||
class DemoService
|
||||
{
|
||||
/**
|
||||
* Create new directory
|
||||
*
|
||||
* @param $request
|
||||
* @return array
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function create_folder($request)
|
||||
{
|
||||
return [
|
||||
'user_id' => 1,
|
||||
'id' => Str::uuid(),
|
||||
'parent_id' => random_int(1000, 9999),
|
||||
'name' => $request->name,
|
||||
'type' => 'folder',
|
||||
'author' => $request->user() ? 'user' : 'visitor',
|
||||
'items' => '0',
|
||||
'color' => isset($request->icon['color']) ? $request->icon['color'] : null,
|
||||
'emoji' => isset($request->icon['emoji']) ? $request->icon['emoji'] : null,
|
||||
'updated_at' => now()->format('j M Y \a\t H:i'),
|
||||
'created_at' => now()->format('j M Y \a\t H:i'),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Rename item name
|
||||
*
|
||||
* @param RenameItemRequest $request
|
||||
* @param $id
|
||||
* @return mixed
|
||||
*/
|
||||
public function rename_item($request, $id)
|
||||
{
|
||||
// Get item
|
||||
if ($request->type === 'folder') {
|
||||
$item = Folder::where('id', $id)
|
||||
->where('user_id', 1)
|
||||
->first();
|
||||
} else {
|
||||
$item = File::where('id', $id)
|
||||
->where('user_id', 1)
|
||||
->first();
|
||||
}
|
||||
|
||||
if ($item) {
|
||||
$item->name = $request->name;
|
||||
$item->emoji = $request->icon['emoji'] ?? null;
|
||||
$item->color = $request->icon['color'] ?? null;
|
||||
|
||||
return $item;
|
||||
}
|
||||
|
||||
return [
|
||||
'id' => $request->id,
|
||||
'name' => $request->name,
|
||||
'type' => $request->type,
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Upload file
|
||||
*
|
||||
* @param $request
|
||||
* @return array
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function upload($request)
|
||||
{
|
||||
// File
|
||||
$file = $request->file('file');
|
||||
$filename = Str::random() . '-' . str_replace(' ', '', $file->getClientOriginalName());
|
||||
$thumbnail = null;
|
||||
$filesize = $file->getSize();
|
||||
$filetype = get_file_type($file->getMimeType());
|
||||
|
||||
return [
|
||||
'id' => Str::uuid(),
|
||||
'folder_id' => $request->parent_id,
|
||||
'thumbnail' => 'data:' . $request->file('file')->getMimeType() . ';base64, ' . base64_encode(file_get_contents($request->file('file'))),
|
||||
'name' => $file->getClientOriginalName(),
|
||||
'basename' => $filename,
|
||||
'mimetype' => $file->getClientOriginalExtension(),
|
||||
'filesize' => Metric::bytes($filesize)->format(),
|
||||
'type' => $filetype,
|
||||
'file_url' => 'https://vuefilemanager.hi5ve.digital/assets/vue-file-manager-preview.jpg',
|
||||
'author' => $request->user() ? 'user' : 'visitor',
|
||||
'created_at' => now()->format('j M Y \a\t H:i'),
|
||||
'updated_at' => now()->format('j M Y \a\t H:i'),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Return 204 status
|
||||
*
|
||||
* @param $user
|
||||
* @return ResponseFactory|\Illuminate\Http\Response
|
||||
*/
|
||||
public function favourites($user)
|
||||
{
|
||||
return $user->favouriteFolders->makeHidden(['pivot']);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
<?php
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use Illuminate\Auth\Middleware\Authenticate as Middleware;
|
||||
|
||||
class Authenticate extends Middleware
|
||||
{
|
||||
/**
|
||||
* Get the path the user should be redirected to when they are not authenticated.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @return string|null
|
||||
*/
|
||||
protected function redirectTo($request)
|
||||
{
|
||||
if (! $request->expectsJson()) {
|
||||
return url('/');
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
<?php
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use Illuminate\Foundation\Http\Middleware\CheckForMaintenanceMode as Middleware;
|
||||
|
||||
class CheckForMaintenanceMode extends Middleware
|
||||
{
|
||||
/**
|
||||
* The URIs that should be reachable while maintenance mode is enabled.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $except = [
|
||||
'/service/upgrade-database',
|
||||
'/service/down',
|
||||
'/service/up',
|
||||
];
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
<?php
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use Illuminate\Cookie\Middleware\EncryptCookies as Middleware;
|
||||
|
||||
class EncryptCookies extends Middleware
|
||||
{
|
||||
/**
|
||||
* The names of the cookies that should not be encrypted.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $except = [
|
||||
];
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
<?php
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use Illuminate\Foundation\Http\Middleware\PreventRequestsDuringMaintenance as Middleware;
|
||||
|
||||
class PreventRequestsDuringMaintenance extends Middleware
|
||||
{
|
||||
/**
|
||||
* The URIs that should be reachable while maintenance mode is enabled.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $except = [
|
||||
];
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
<?php
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use Closure;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
|
||||
class RedirectIfAuthenticated
|
||||
{
|
||||
/**
|
||||
* Handle an incoming request.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param \Closure $next
|
||||
* @param string|null ...$guards
|
||||
* @return mixed
|
||||
*/
|
||||
public function handle($request, Closure $next, ...$guards)
|
||||
{
|
||||
$guards = empty($guards) ? [null] : $guards;
|
||||
|
||||
foreach ($guards as $guard) {
|
||||
if (Auth::guard($guard)->check()) {
|
||||
return redirect('/files');
|
||||
}
|
||||
}
|
||||
|
||||
return $next($request);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
<?php
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use Illuminate\Foundation\Http\Middleware\TrimStrings as Middleware;
|
||||
|
||||
class TrimStrings extends Middleware
|
||||
{
|
||||
/**
|
||||
* The names of the attributes that should not be trimmed.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $except = [
|
||||
'password',
|
||||
'password_confirmation',
|
||||
];
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
<?php
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
use Fideloper\Proxy\TrustProxies as Middleware;
|
||||
|
||||
class TrustProxies extends Middleware
|
||||
{
|
||||
/**
|
||||
* The trusted proxies for this application.
|
||||
*
|
||||
* @var array|string
|
||||
*/
|
||||
protected $proxies;
|
||||
|
||||
/**
|
||||
* The headers that should be used to detect proxies.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
protected $headers = Request::HEADER_X_FORWARDED_ALL;
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
<?php
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use Illuminate\Foundation\Http\Middleware\VerifyCsrfToken as Middleware;
|
||||
|
||||
class VerifyCsrfToken extends Middleware
|
||||
{
|
||||
/**
|
||||
* Indicates whether the XSRF-TOKEN cookie should be set on the response.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
protected $addHttpCookie = true;
|
||||
|
||||
/**
|
||||
* The URIs that should be excluded from CSRF verification.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $except = [
|
||||
'/deploy',
|
||||
'/stripe/*',
|
||||
];
|
||||
}
|
||||
@@ -0,0 +1,89 @@
|
||||
<?php
|
||||
namespace App\Services;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use App\Models\Zip;
|
||||
use App\Models\User;
|
||||
use App\Models\Share;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
|
||||
class SchedulerService
|
||||
{
|
||||
/**
|
||||
* Delete old zips
|
||||
*/
|
||||
public function delete_old_zips(): void
|
||||
{
|
||||
Zip::where('created_at', '<=', now()->subDay()->toDateTimeString())
|
||||
->get()
|
||||
->each(function ($zip) {
|
||||
// Delete zip file
|
||||
Storage::disk('local')->delete("zip/$zip->basename");
|
||||
|
||||
// Delete zip record
|
||||
$zip->delete();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Get and delete expired shared links
|
||||
*/
|
||||
public function delete_expired_shared_links(): void
|
||||
{
|
||||
Share::whereNotNull('expire_in')
|
||||
->get()
|
||||
->each(function ($share) {
|
||||
// Get dates
|
||||
$created_at = Carbon::parse($share->created_at);
|
||||
|
||||
// If time was over, then delete share record
|
||||
if ($created_at->diffInHours(now()) >= $share->expire_in) {
|
||||
$share->delete();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Get and delete failed files older than 24 hours
|
||||
*/
|
||||
public function delete_failed_files(): void
|
||||
{
|
||||
$local_disk = Storage::disk('local');
|
||||
|
||||
// Get all files from storage
|
||||
$files = collect([
|
||||
//$local_disk->allFiles('files'),
|
||||
$local_disk->allFiles('chunks'),
|
||||
])->collapse();
|
||||
|
||||
$files->each(function ($file) use ($local_disk) {
|
||||
// Get the file's last modification time.
|
||||
$last_modified = $local_disk
|
||||
->lastModified($file);
|
||||
|
||||
// Get diffInHours
|
||||
$diff = Carbon::parse($last_modified)
|
||||
->diffInHours(now());
|
||||
|
||||
// Delete if file is in local storage more than 24 hours
|
||||
if ($diff >= 24) {
|
||||
Log::info("Failed file or chunk $file deleted.");
|
||||
|
||||
// Delete file from local storage
|
||||
$local_disk->delete($file);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete unverified users older than 30 days
|
||||
*/
|
||||
public function delete_unverified_users(): void
|
||||
{
|
||||
User::where('created_at', '<=', now()->subDays(30)->toDateString())
|
||||
->where('email_verified_at', null)
|
||||
->get()
|
||||
->each(fn ($user) => $user->delete());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,449 @@
|
||||
<?php
|
||||
namespace App\Services;
|
||||
|
||||
use DB;
|
||||
use App\Models\Zip;
|
||||
use App\Models\User;
|
||||
use App\Models\Share;
|
||||
use App\Models\Folder;
|
||||
use Illuminate\Support\Arr;
|
||||
use Illuminate\Support\Str;
|
||||
use App\Models\File as UserFile;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\Support\Facades\File;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
use League\Flysystem\FileNotFoundException;
|
||||
use App\Http\Requests\FileFunctions\RenameItemRequest;
|
||||
use Symfony\Component\HttpKernel\Exception\HttpException;
|
||||
|
||||
class FileManagerService
|
||||
{
|
||||
private $helper;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->helper = resolve(HelperService::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Zip requested folder
|
||||
*
|
||||
* @param $id
|
||||
* @param $shared
|
||||
* @return mixed
|
||||
* @throws \Illuminate\Contracts\Filesystem\FileNotFoundException
|
||||
*/
|
||||
public function zip_folder($id, $shared = null)
|
||||
{
|
||||
// Get folder
|
||||
$requested_folder = Folder::with(['folders.files', 'files'])
|
||||
->where('id', $id)
|
||||
->where('user_id', Auth::id() ?? $shared->user_id)
|
||||
->with('folders')
|
||||
->first();
|
||||
|
||||
$files = get_files_for_zip($requested_folder, collect([]));
|
||||
|
||||
// Local storage instance
|
||||
$disk_local = Storage::disk('local');
|
||||
|
||||
// Move file to local storage from external storage service
|
||||
if (! is_storage_driver('local')) {
|
||||
foreach ($files as $file) {
|
||||
try {
|
||||
$disk_local->put("temp/{$file['basename']}", Storage::get("files/$requested_folder->user_id/{$file['basename']}"));
|
||||
} catch (FileNotFoundException $e) {
|
||||
throw new HttpException(404, 'File not found');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Get zip path
|
||||
$zip_name = Str::random(16) . '-' . Str::slug($requested_folder->name) . '.zip';
|
||||
|
||||
// Create zip
|
||||
$zipper = new \Madnest\Madzipper\Madzipper;
|
||||
$zip = $zipper->make($disk_local->path("zip/$zip_name"));
|
||||
|
||||
// Add files to zip
|
||||
foreach ($files as $file) {
|
||||
$file_path = is_storage_driver('local')
|
||||
? $disk_local->path("files/$requested_folder->user_id/{$file['basename']}")
|
||||
: $disk_local->path("temp/{$file['basename']}");
|
||||
|
||||
$zip
|
||||
->folder($file['folder_path'])
|
||||
->addString("{$file['name']}.{$file['mimetype']}", File::get($file_path));
|
||||
}
|
||||
|
||||
// Close zip
|
||||
//$zip->close();
|
||||
|
||||
// Delete temporary files
|
||||
if (! is_storage_driver('local')) {
|
||||
foreach ($files as $file) {
|
||||
$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,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 function zip_files($files, $shared = null)
|
||||
{
|
||||
// Local storage instance
|
||||
$disk_local = Storage::disk('local');
|
||||
|
||||
// Move file to local storage from external storage service
|
||||
if (! is_storage_driver('local')) {
|
||||
$files->each(function ($file) use ($disk_local) {
|
||||
try {
|
||||
$disk_local->put("temp/$file->basename", Storage::get("files/$file->user_id/$file->basename"));
|
||||
} catch (FileNotFoundException $e) {
|
||||
throw new HttpException(404, 'File not found');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Get zip path
|
||||
$zip_name = Str::random(16) . '.zip';
|
||||
|
||||
// Create zip
|
||||
$zipper = new \Madnest\Madzipper\Madzipper;
|
||||
$zip = $zipper->make($disk_local->path("zip/$zip_name"));
|
||||
|
||||
// Add files to zip
|
||||
$files->each(function ($file) use ($zip, $disk_local) {
|
||||
$file_path = is_storage_driver('local')
|
||||
? $disk_local->path("files/$file->user_id/$file->basename")
|
||||
: $disk_local->path("temp/$file->basename");
|
||||
|
||||
$zip->addString("$file->name.$file->mimetype", File::get($file_path));
|
||||
});
|
||||
|
||||
// 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
|
||||
*
|
||||
* @param $request
|
||||
* @param null $shared
|
||||
* @return Folder|\Illuminate\Database\Eloquent\Model
|
||||
*/
|
||||
public function create_folder($request, $shared = null)
|
||||
{
|
||||
return Folder::create([
|
||||
'parent_id' => $request->parent_id,
|
||||
'author' => $shared ? 'visitor' : 'user',
|
||||
'user_id' => $shared ? $shared->user_id : Auth::id(),
|
||||
'name' => $request->name,
|
||||
'color' => $request->color ?? null,
|
||||
'emoji' => $request->emoji ?? null,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Rename item name
|
||||
*
|
||||
* @param RenameItemRequest $request
|
||||
* @param $id
|
||||
* @param null $shared
|
||||
* @return \Illuminate\Database\Eloquent\Builder|\Illuminate\Database\Eloquent\Model
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function rename_item($request, $id, $shared = null)
|
||||
{
|
||||
// Get user id
|
||||
$user_id = $shared ? $shared->user_id : Auth::id();
|
||||
|
||||
// Get item
|
||||
$item = get_item($request->type, $id, $user_id);
|
||||
|
||||
// Rename item
|
||||
$item->update([
|
||||
'name' => $request->name,
|
||||
]);
|
||||
|
||||
// Return updated item
|
||||
return $item;
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete file or folder
|
||||
*
|
||||
* @param $item
|
||||
* @param $id
|
||||
* @param null $shared
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function delete_item($item, $id, $shared = null)
|
||||
{
|
||||
// Delete folder
|
||||
if ($item['type'] === 'folder') {
|
||||
// Get folder
|
||||
$folder = Folder::withTrashed()
|
||||
->with('folders')
|
||||
->find($id);
|
||||
|
||||
// Get folder shared record
|
||||
$shared = Share::where('type', 'folder')
|
||||
->where('item_id', $id)
|
||||
->first();
|
||||
|
||||
// Delete folder shared record
|
||||
if ($shared) {
|
||||
$shared->delete();
|
||||
}
|
||||
|
||||
// Remove folder from user favourites
|
||||
DB::table('favourite_folder')
|
||||
->where('folder_id', $folder->id)
|
||||
->delete();
|
||||
|
||||
// Soft delete items
|
||||
if (! $item['force_delete']) {
|
||||
// Soft delete folder record
|
||||
$folder->delete();
|
||||
}
|
||||
|
||||
// Force delete children files
|
||||
if ($item['force_delete']) {
|
||||
// Get children folder ids
|
||||
$child_folders = filter_folders_ids($folder->trashed_folders, 'id');
|
||||
|
||||
// Get children files
|
||||
$files = UserFile::onlyTrashed()
|
||||
->whereIn('folder_id', Arr::flatten([$id, $child_folders]))
|
||||
->get();
|
||||
|
||||
// Remove all children files
|
||||
foreach ($files as $file) {
|
||||
// Delete file
|
||||
Storage::delete("/files/$file->user_id/$file->basename");
|
||||
|
||||
// Delete thumbnail if exist
|
||||
if ($file->thumbnail) {
|
||||
Storage::delete(
|
||||
"/files/$file->user_id/{$file->getRawOriginal('thumbnail')}"
|
||||
);
|
||||
}
|
||||
|
||||
// Delete file permanently
|
||||
$file->forceDelete();
|
||||
}
|
||||
|
||||
// Delete folder record
|
||||
$folder->forceDelete();
|
||||
}
|
||||
}
|
||||
|
||||
// Delete item
|
||||
if ($item['type'] !== 'folder') {
|
||||
// Get file
|
||||
$file = UserFile::withTrashed()
|
||||
->find($id);
|
||||
|
||||
// Get folder shared record
|
||||
$shared = Share::where('type', 'file')
|
||||
->where('item_id', $id)
|
||||
->first();
|
||||
|
||||
// Delete file shared record
|
||||
if ($shared) {
|
||||
$shared->delete();
|
||||
}
|
||||
|
||||
// Force delete file
|
||||
if ($item['force_delete']) {
|
||||
// Delete file
|
||||
Storage::delete("/files/$file->user_id/$file->basename");
|
||||
|
||||
// Delete thumbnail if exist
|
||||
if ($file->thumbnail) {
|
||||
Storage::delete(
|
||||
"/files/$file->user_id/{$file->getRawOriginal('thumbnail')}"
|
||||
);
|
||||
}
|
||||
|
||||
// Delete file permanently
|
||||
$file->forceDelete();
|
||||
}
|
||||
|
||||
// Soft delete file
|
||||
if (! $item['force_delete']) {
|
||||
// Soft delete file
|
||||
$file->delete();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Move folder or file to new location
|
||||
*
|
||||
* @param $request
|
||||
* @param $to_id
|
||||
*/
|
||||
public function move($request, $to_id)
|
||||
{
|
||||
foreach ($request->items as $item) {
|
||||
// Move folder
|
||||
if ($item['type'] === 'folder') {
|
||||
Folder::find($item['id'])
|
||||
->update(['parent_id' => $to_id]);
|
||||
}
|
||||
|
||||
// Move file
|
||||
if ($item['type'] !== 'folder') {
|
||||
UserFile::find($item['id'])
|
||||
->update(['folder_id' => $to_id]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Upload file
|
||||
*
|
||||
* @param $request
|
||||
* @param null $shared
|
||||
* @return File|\Illuminate\Database\Eloquent\Model
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function upload($request, $shared = null)
|
||||
{
|
||||
// Get parent_id from request
|
||||
$file = $request->file('file');
|
||||
|
||||
// File name
|
||||
$disk_file_name = basename('chunks/' . $file->getClientOriginalName(), '.part');
|
||||
$temp_filename = $file->getClientOriginalName();
|
||||
|
||||
// File Path
|
||||
$file_path = Storage::disk('local')->path('chunks/' . $temp_filename);
|
||||
|
||||
// Generate file
|
||||
File::append($file_path, $file->get());
|
||||
|
||||
// Size of file
|
||||
$file_size = File::size($file_path);
|
||||
|
||||
// Size of limit
|
||||
$limit = get_setting('upload_limit');
|
||||
|
||||
// File size handling
|
||||
if ($limit && $file_size > format_bytes($limit)) {
|
||||
abort(413);
|
||||
}
|
||||
|
||||
// If last then process file
|
||||
if ($request->boolean('is_last')) {
|
||||
$metadata = get_image_meta_data($file);
|
||||
|
||||
$disk_local = Storage::disk('local');
|
||||
|
||||
// Get user data
|
||||
$user_id = $shared->user_id ?? Auth::id();
|
||||
|
||||
// File Info
|
||||
$file_size = $disk_local->size("chunks/$temp_filename");
|
||||
|
||||
$file_mimetype = $disk_local->mimeType("chunks/$temp_filename");
|
||||
|
||||
// Check if user has enough space to upload file
|
||||
$this->helper->check_user_storage_capacity($user_id, $file_size, $temp_filename);
|
||||
|
||||
// Create thumbnail
|
||||
$thumbnail = $this->helper->create_image_thumbnail("chunks/$temp_filename", $disk_file_name, $user_id);
|
||||
|
||||
// Move finished file from chunk to file-manager directory
|
||||
$disk_local->move("chunks/$temp_filename", "files/$user_id/$disk_file_name");
|
||||
|
||||
// Move files to external storage
|
||||
if (! is_storage_driver(['local'])) {
|
||||
$this->helper->move_file_to_external_storage($disk_file_name, $user_id);
|
||||
}
|
||||
|
||||
// Store user upload size
|
||||
User::find($user_id)
|
||||
->record_upload($file_size);
|
||||
|
||||
// Return new file
|
||||
return UserFile::create([
|
||||
'mimetype' => get_file_type_from_mimetype($file_mimetype),
|
||||
'type' => get_file_type($file_mimetype),
|
||||
'folder_id' => $request->folder_id,
|
||||
'metadata' => $metadata,
|
||||
'name' => $request->filename,
|
||||
'basename' => $disk_file_name,
|
||||
'author' => $shared ? 'visitor' : 'user',
|
||||
'thumbnail' => $thumbnail,
|
||||
'filesize' => $file_size,
|
||||
'user_id' => $user_id,
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Store folder icon
|
||||
*
|
||||
* @param $request
|
||||
* @param $id
|
||||
*/
|
||||
public function edit_folder_properties($request, $id)
|
||||
{
|
||||
// Get folder
|
||||
$folder = Folder::find($id);
|
||||
|
||||
// Set default folder icon
|
||||
if ($request->emoji === 'default') {
|
||||
$folder->update([
|
||||
'emoji' => null,
|
||||
'color' => null,
|
||||
]);
|
||||
}
|
||||
|
||||
// Set emoji
|
||||
if ($request->filled('emoji')) {
|
||||
$folder->update([
|
||||
'emoji' => $request->emoji,
|
||||
'color' => null,
|
||||
]);
|
||||
}
|
||||
|
||||
// Set color
|
||||
if ($request->filled('color')) {
|
||||
$folder->update([
|
||||
'emoji' => null,
|
||||
'color' => $request->color,
|
||||
]);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,310 @@
|
||||
<?php
|
||||
namespace App\Services;
|
||||
|
||||
use DB;
|
||||
use App\Models\File;
|
||||
use App\Models\Share;
|
||||
use App\Models\Folder;
|
||||
use Illuminate\Support\Arr;
|
||||
use Aws\S3\MultipartUploader;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
use Aws\Exception\MultipartUploadException;
|
||||
use Intervention\Image\ImageManagerStatic as Image;
|
||||
use Symfony\Component\HttpKernel\Exception\HttpException;
|
||||
|
||||
class HelperService
|
||||
{
|
||||
/**
|
||||
* Delete all user data including files, folders, avatar etc.
|
||||
*
|
||||
* @param $user
|
||||
*/
|
||||
public function erase_user_data($user)
|
||||
{
|
||||
// Delete user avatar if exists
|
||||
if ($user->settings->getRawOriginal('avatar')) {
|
||||
Storage::delete($user->settings->getRawOriginal('avatar'));
|
||||
}
|
||||
|
||||
// Delete all user files
|
||||
Storage::deleteDirectory("files/$user->id");
|
||||
|
||||
// Delete all user records in database
|
||||
collect(['folders', 'files', 'user_settings', 'shares', 'favourite_folder', 'zips'])
|
||||
->each(function ($table) use ($user) {
|
||||
DB::table($table)
|
||||
->whereUserId($user->id)
|
||||
->delete();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Check access to requested directory
|
||||
*
|
||||
* @param int|array $requested_id
|
||||
* @param string $shared Shared record detail
|
||||
*/
|
||||
public function check_item_access($requested_id, $shared)
|
||||
{
|
||||
// Get all children folders
|
||||
$foldersIds = Folder::with('folders:id,parent_id,id,name')
|
||||
->where('user_id', $shared->user_id)
|
||||
->where('parent_id', $shared->item_id)
|
||||
->get();
|
||||
|
||||
// Get all authorized parent folders by shared folder as root of tree
|
||||
$accessible_folder_ids = Arr::flatten([filter_folders_ids($foldersIds), $shared->item_id]);
|
||||
|
||||
// Check user access
|
||||
if (is_array($requested_id)) {
|
||||
foreach ($requested_id as $id) {
|
||||
if (! in_array($id, $accessible_folder_ids)) {
|
||||
abort(403);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (! is_array($requested_id)) {
|
||||
if (! in_array($requested_id, $accessible_folder_ids)) {
|
||||
abort(403);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check user file access
|
||||
*
|
||||
* @param $shared
|
||||
* @param $file
|
||||
*/
|
||||
public function check_guest_access_to_shared_items($shared, $file): void
|
||||
{
|
||||
// Check by parent folder permission
|
||||
if ($shared->type === 'folder') {
|
||||
$this->check_item_access($file->folder_id, $shared);
|
||||
}
|
||||
|
||||
// Check by single file permission
|
||||
if ($shared->type === 'file') {
|
||||
if ($shared->item_id !== $file->id) {
|
||||
abort(403);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if user has enough space to upload file
|
||||
*
|
||||
* @param $user_id
|
||||
* @param int $file_size
|
||||
* @param $temp_filename
|
||||
*/
|
||||
public function check_user_storage_capacity($user_id, int $file_size, $temp_filename): void
|
||||
{
|
||||
// Get user storage percentage and get storage_limitation setting
|
||||
$user_storage_used = user_storage_percentage($user_id, $file_size);
|
||||
|
||||
// Check if user can upload
|
||||
if (get_setting('storage_limitation') && $user_storage_used >= 100) {
|
||||
// Delete file
|
||||
Storage::disk('local')
|
||||
->delete("chunks/$temp_filename");
|
||||
|
||||
// Abort uploading
|
||||
// TODO: test pre exceed storage limit
|
||||
abort(423, 'You exceed your storage limit!');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Move file to external storage if is set
|
||||
*
|
||||
* @param string $file
|
||||
* @param string $user_id
|
||||
*/
|
||||
public function move_file_to_external_storage($file, $user_id): void
|
||||
{
|
||||
$disk_local = \Storage::disk('local');
|
||||
|
||||
// Get file size
|
||||
$filesize = $disk_local->size("files/$user_id/$file");
|
||||
|
||||
// If file is bigger than 5.2MB then run multipart upload
|
||||
if ($filesize > 5242880) {
|
||||
// Get driver
|
||||
$driver = \Storage::getDriver();
|
||||
|
||||
// Get adapter
|
||||
$adapter = $driver->getAdapter();
|
||||
|
||||
// Get client
|
||||
$client = $adapter->getClient();
|
||||
|
||||
// Prepare the upload parameters.
|
||||
// TODO: replace local files with temp folder
|
||||
$uploader = new MultipartUploader($client, config('filesystems.disks.local.root') . "/files/$user_id/$file", [
|
||||
'bucket' => $adapter->getBucket(),
|
||||
'key' => "files/$user_id/$file",
|
||||
]);
|
||||
|
||||
try {
|
||||
// Upload content
|
||||
$uploader->upload();
|
||||
} catch (MultipartUploadException $e) {
|
||||
// Write error log
|
||||
Log::error($e->getMessage());
|
||||
|
||||
// Delete file after error
|
||||
$disk_local->delete("files/$user_id/$file");
|
||||
|
||||
throw new HttpException(409, $e->getMessage());
|
||||
}
|
||||
} else {
|
||||
// Stream file object to s3
|
||||
// TODO: replace local files with temp folder
|
||||
Storage::putFileAs("files/$user_id", config('filesystems.disks.local.root') . "/files/$user_id/$file", $file, 'private');
|
||||
}
|
||||
|
||||
// Delete file after upload
|
||||
$disk_local->delete("files/$user_id/$file");
|
||||
}
|
||||
|
||||
/**
|
||||
* Create image thumbnail from gif, jpeg, jpg, png, webp or svg
|
||||
*
|
||||
* @param string $file_path
|
||||
* @param string $filename
|
||||
* @param string $user_id
|
||||
* @return string|null
|
||||
*/
|
||||
public function create_image_thumbnail($file_path, $filename, $user_id)
|
||||
{
|
||||
// Create thumbnail from image
|
||||
if (in_array(Storage::disk('local')->mimeType($file_path), ['image/gif', 'image/jpeg', 'image/jpg', 'image/png', 'image/webp'])) {
|
||||
// Get thumbnail name
|
||||
$thumbnail = "thumbnail-$filename";
|
||||
|
||||
// Create intervention image
|
||||
$image = Image::make(Storage::disk('local')->path($file_path))
|
||||
->orientate();
|
||||
|
||||
// Resize image
|
||||
$image->resize(512, null, function ($constraint) {
|
||||
$constraint->aspectRatio();
|
||||
})->stream();
|
||||
|
||||
// Store thumbnail to disk
|
||||
Storage::put("files/$user_id/$thumbnail", $image);
|
||||
}
|
||||
|
||||
// Return thumbnail as svg file
|
||||
if (Storage::disk('local')->mimeType($file_path) === 'image/svg+xml') {
|
||||
$thumbnail = $filename;
|
||||
}
|
||||
|
||||
return $thumbnail ?? null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Call and download file
|
||||
*
|
||||
* @param $file
|
||||
* @param $user_id
|
||||
* @return mixed
|
||||
*/
|
||||
public function download_file($file, $user_id)
|
||||
{
|
||||
// Get file path
|
||||
$path = "files/$user_id/$file->basename";
|
||||
|
||||
// Check if file exist
|
||||
if (! Storage::exists($path)) {
|
||||
abort(404);
|
||||
}
|
||||
|
||||
// Get pretty name
|
||||
$pretty_name = get_pretty_name($file->basename, $file->name, $file->mimetype);
|
||||
|
||||
return response()
|
||||
->download(Storage::path($path), $pretty_name, [
|
||||
'Accept-Ranges' => 'bytes',
|
||||
'Content-Type' => Storage::mimeType($path),
|
||||
'Content-Length' => Storage::size($path),
|
||||
'Content-Range' => 'bytes 0-600/' . Storage::size($path),
|
||||
'Content-Disposition' => "attachment; filename=$pretty_name",
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get image thumbnail for browser
|
||||
*
|
||||
* @param $file
|
||||
* @param $user_id
|
||||
* @return mixed
|
||||
*/
|
||||
public function download_thumbnail_file($file, $user_id)
|
||||
{
|
||||
// Get file path
|
||||
$path = "/files/$user_id/{$file->getRawOriginal('thumbnail')}";
|
||||
|
||||
// Check if file exist
|
||||
if (! Storage::exists($path)) {
|
||||
abort(404);
|
||||
}
|
||||
|
||||
// Return image thumbnail
|
||||
return Storage::download($path, $file->getRawOriginal('thumbnail'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all folders and files under the share record
|
||||
*
|
||||
* @param $id
|
||||
* @param $shared
|
||||
* @return array
|
||||
*/
|
||||
public function get_items_under_shared_by_folder_id($id, $shared): array
|
||||
{
|
||||
$folders = Folder::where('user_id', $shared->user_id)
|
||||
->where('parent_id', $id)
|
||||
->sortable()
|
||||
->get();
|
||||
|
||||
$files = File::where('user_id', $shared->user_id)
|
||||
->where('folder_id', $id)
|
||||
->sortable()
|
||||
->get();
|
||||
|
||||
return [$folders, $files];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Share $shared
|
||||
*/
|
||||
public function check_protected_share_record(Share $shared): void
|
||||
{
|
||||
if ($shared->is_protected) {
|
||||
$abort_message = "Sorry, you don't have permission";
|
||||
|
||||
if (! request()->hasCookie('share_session')) {
|
||||
abort(403, $abort_message);
|
||||
}
|
||||
|
||||
// Get shared session
|
||||
$share_session = json_decode(
|
||||
request()->cookie('share_session')
|
||||
);
|
||||
|
||||
// Check if is requested same share record
|
||||
if ($share_session->token !== $shared->token) {
|
||||
abort(403, $abort_message);
|
||||
}
|
||||
|
||||
// Check if share record was authenticated previously via ShareController@authenticate
|
||||
if (! $share_session->authenticated) {
|
||||
abort(403, $abort_message);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,998 @@
|
||||
<?php
|
||||
|
||||
use Carbon\Carbon;
|
||||
use App\Models\File;
|
||||
use App\Models\User;
|
||||
use App\Models\Share;
|
||||
use ByteUnits\Metric;
|
||||
use App\Models\Folder;
|
||||
use App\Models\Setting;
|
||||
use App\Models\Language;
|
||||
use Illuminate\Support\Str;
|
||||
use Illuminate\Support\Collection;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\QueryException;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
use Intervention\Image\ImageManagerStatic as Image;
|
||||
use Illuminate\Database\Eloquent\ModelNotFoundException;
|
||||
|
||||
if (! function_exists('obfuscate_email')) {
|
||||
/**
|
||||
* Obfuscate email
|
||||
*
|
||||
* @param $email
|
||||
* @return string
|
||||
*/
|
||||
function obfuscate_email($email)
|
||||
{
|
||||
$em = explode('@', $email);
|
||||
$name = implode('@', array_slice($em, 0, count($em) - 1));
|
||||
$len = floor(strlen($name) / 2);
|
||||
|
||||
return substr($name, 0, $len) . str_repeat('*', $len) . '@' . end($em);
|
||||
}
|
||||
}
|
||||
|
||||
if (! function_exists('get_setting')) {
|
||||
/**
|
||||
* Get single value from settings table
|
||||
*
|
||||
* @param $setting
|
||||
* @return |null
|
||||
*/
|
||||
function get_setting($setting)
|
||||
{
|
||||
return Setting::find($setting)->value ?? null;
|
||||
}
|
||||
}
|
||||
|
||||
if (! function_exists('get_settings_in_json')) {
|
||||
/**
|
||||
* Get all app settings and return them as json
|
||||
*/
|
||||
function get_settings_in_json()
|
||||
{
|
||||
return json_decode(
|
||||
Setting::all()
|
||||
->pluck('value', 'name')
|
||||
->toJson()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if (! function_exists('get_setup_status')) {
|
||||
/**
|
||||
* Check if setup wizard was passed
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
function get_setup_status()
|
||||
{
|
||||
$setup_success = get_setting('setup_wizard_success');
|
||||
|
||||
return boolval($setup_success) ? 'setup-done' : 'setup-disclaimer';
|
||||
}
|
||||
}
|
||||
|
||||
if (! function_exists('add_paragraphs')) {
|
||||
/**
|
||||
* Create paragraph from text
|
||||
*
|
||||
* @param $str
|
||||
* @return mixed|null|string|string[]
|
||||
*/
|
||||
function add_paragraphs($str)
|
||||
{
|
||||
// Trim whitespace
|
||||
if (($str = trim($str)) === '') {
|
||||
return '';
|
||||
}
|
||||
|
||||
// Standardize newlines
|
||||
$str = str_replace(["\r\n", "\r"], "\n", $str);
|
||||
|
||||
// Trim whitespace on each line
|
||||
$str = preg_replace('~^[ \t]+~m', '', $str);
|
||||
$str = preg_replace('~[ \t]+$~m', '', $str);
|
||||
|
||||
// The following regexes only need to be executed if the string contains html
|
||||
if ($html_found = (strpos($str, '<') !== false)) {
|
||||
// Elements that should not be surrounded by p tags
|
||||
$no_p = '(?:p|div|article|header|aside|hgroup|canvas|output|progress|section|figcaption|audio|video|nav|figure|footer|video|details|main|menu|summary|h[1-6r]|ul|ol|li|blockquote|d[dlt]|pre|t[dhr]|t(?:able|body|foot|head)|c(?:aption|olgroup)|form|s(?:elect|tyle)|a(?:ddress|rea)|ma(?:p|th))';
|
||||
|
||||
// Put at least two linebreaks before and after $no_p elements
|
||||
$str = preg_replace('~^<' . $no_p . '[^>]*+>~im', "\n$0", $str);
|
||||
$str = preg_replace('~</' . $no_p . '\s*+>$~im', "$0\n", $str);
|
||||
}
|
||||
|
||||
// Do the <p> magic!
|
||||
$str = '<p>' . trim($str) . '</p>';
|
||||
$str = preg_replace('~\n{2,}~', "</p>\n\n<p>", $str);
|
||||
|
||||
// The following regexes only need to be executed if the string contains html
|
||||
if ($html_found !== false) {
|
||||
// Remove p tags around $no_p elements
|
||||
$str = preg_replace('~<p>(?=</?' . $no_p . '[^>]*+>)~i', '', $str);
|
||||
$str = preg_replace('~(</?' . $no_p . '[^>]*+>)</p>~i', '$1', $str);
|
||||
}
|
||||
|
||||
// Convert single linebreaks to <br />
|
||||
$str = preg_replace('~(?<!\n)\n(?!\n)~', "<br>\n", $str);
|
||||
|
||||
return $str;
|
||||
}
|
||||
}
|
||||
|
||||
if (! function_exists('setEnvironmentValue')) {
|
||||
/**
|
||||
* Set environment value
|
||||
*
|
||||
* @param $key
|
||||
* @param $value
|
||||
* @return bool
|
||||
*/
|
||||
function setEnvironmentValue(array $values)
|
||||
{
|
||||
$envFile = app()->environmentFilePath();
|
||||
$str = file_get_contents($envFile);
|
||||
|
||||
if (count($values) > 0) {
|
||||
foreach ($values as $envKey => $envValue) {
|
||||
$str .= "\n"; // In case the searched variable is in the last line without \n
|
||||
$keyPosition = strpos($str, "{$envKey}=");
|
||||
$endOfLinePosition = strpos($str, "\n", $keyPosition);
|
||||
$oldLine = substr($str, $keyPosition, $endOfLinePosition - $keyPosition);
|
||||
|
||||
// If key does not exist, add it
|
||||
$str = str_replace($oldLine, "{$envKey}={$envValue}", $str);
|
||||
}
|
||||
}
|
||||
|
||||
$str = substr($str, 0, -1);
|
||||
|
||||
return ! (! file_put_contents($envFile, $str));
|
||||
}
|
||||
}
|
||||
|
||||
if (! function_exists('get_invoice_number')) {
|
||||
/**
|
||||
* Get invoice number
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
function get_invoice_number()
|
||||
{
|
||||
$invoices = \App\Invoice::all();
|
||||
|
||||
if ($invoices->isEmpty()) {
|
||||
return now()->year . '001';
|
||||
}
|
||||
|
||||
return (int) $invoices->last()->order + 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (! function_exists('cache_forget_many')) {
|
||||
/**
|
||||
* Forget many cache keys at once
|
||||
* @param $cache
|
||||
*/
|
||||
function cache_forget_many($cache)
|
||||
{
|
||||
foreach ($cache as $item) {
|
||||
\Illuminate\Support\Facades\Cache::forget($item);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (! function_exists('get_storage')) {
|
||||
/**
|
||||
* Get app version from config
|
||||
*
|
||||
* @return \Illuminate\Config\Repository|mixed
|
||||
*/
|
||||
function get_storage()
|
||||
{
|
||||
return env('FILESYSTEM_DRIVER');
|
||||
}
|
||||
}
|
||||
|
||||
if (! function_exists('is_storage_driver')) {
|
||||
/**
|
||||
* Check if is running AWS s3 as storage
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
function is_storage_driver($driver)
|
||||
{
|
||||
if (is_array($driver)) {
|
||||
return in_array(config('filesystems.default'), $driver);
|
||||
}
|
||||
|
||||
return config('filesystems.default') === $driver;
|
||||
}
|
||||
}
|
||||
|
||||
if (! function_exists('get_version')) {
|
||||
/**
|
||||
* Get app version from config
|
||||
*
|
||||
* @return \Illuminate\Config\Repository|mixed
|
||||
*/
|
||||
function get_version()
|
||||
{
|
||||
return config('vuefilemanager.version');
|
||||
}
|
||||
}
|
||||
|
||||
if (! function_exists('is_demo')) {
|
||||
/**
|
||||
* Check if is demo
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
function is_demo()
|
||||
{
|
||||
return config('vuefilemanager.is_demo');
|
||||
}
|
||||
}
|
||||
|
||||
if (! function_exists('is_demo_account')) {
|
||||
/**
|
||||
* Check if is demo
|
||||
*
|
||||
* @param $email
|
||||
* @return mixed
|
||||
*/
|
||||
function is_demo_account($email)
|
||||
{
|
||||
return config('vuefilemanager.is_demo') && $email === 'howdy@hi5ve.digital';
|
||||
}
|
||||
}
|
||||
|
||||
if (! function_exists('get_item')) {
|
||||
/**
|
||||
* Get folder or file item
|
||||
*
|
||||
* @param $type
|
||||
* @param $id
|
||||
* @return \Illuminate\Database\Eloquent\Builder|Model
|
||||
*/
|
||||
function get_item($type, $id)
|
||||
{
|
||||
$model = strtolower($type) === 'folder' ? 'Folder' : 'File';
|
||||
|
||||
return ("App\\Models\\$model")::find($id);
|
||||
}
|
||||
}
|
||||
|
||||
if (! function_exists('get_shared')) {
|
||||
/**
|
||||
* Get shared token
|
||||
*
|
||||
* @param $token
|
||||
* @return \Illuminate\Database\Eloquent\Builder|Model
|
||||
*/
|
||||
function get_shared($token)
|
||||
{
|
||||
return Share::whereToken($token)
|
||||
->firstOrFail();
|
||||
}
|
||||
}
|
||||
|
||||
if (! function_exists('is_editor')) {
|
||||
/**
|
||||
* Check if shared permission is editor
|
||||
*
|
||||
* @param $shared
|
||||
* @return bool
|
||||
*/
|
||||
function is_editor($shared)
|
||||
{
|
||||
return $shared->permission === 'editor';
|
||||
}
|
||||
}
|
||||
|
||||
if (! function_exists('is_visitor')) {
|
||||
/**
|
||||
* Check if shared permission is visitor
|
||||
*
|
||||
* @param $shared
|
||||
* @return bool
|
||||
*/
|
||||
function is_visitor($shared)
|
||||
{
|
||||
return $shared->permission === 'visitor';
|
||||
}
|
||||
}
|
||||
|
||||
if (! function_exists('store_avatar')) {
|
||||
/**
|
||||
* Store user avatar to storage
|
||||
*
|
||||
* @param $request
|
||||
* @param $name
|
||||
* @return string|null
|
||||
*/
|
||||
function store_avatar($request, $name)
|
||||
{
|
||||
if (! $request->hasFile($name)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$image = $request->file($name);
|
||||
|
||||
// Store avatar
|
||||
$image_path = Str::random(16) . '-' . $image->getClientOriginalName();
|
||||
|
||||
if (in_array($image->getClientMimeType(), ['image/gif', 'image/jpeg', 'image/jpg', 'image/png', 'image/webp'])) {
|
||||
// Create intervention image
|
||||
$img = Image::make($image->getRealPath());
|
||||
|
||||
// Generate thumbnail
|
||||
$img->fit('150', '150')->stream();
|
||||
|
||||
// Store thumbnail to disk
|
||||
Storage::put("avatars/$image_path", $img);
|
||||
}
|
||||
|
||||
if ($image->getClientMimeType() === 'image/svg+xml') {
|
||||
Storage::putFileAs('avatars', $image, $image_path);
|
||||
}
|
||||
|
||||
// Return path to image
|
||||
return "avatars/$image_path";
|
||||
}
|
||||
}
|
||||
|
||||
if (! function_exists('store_system_image')) {
|
||||
/**
|
||||
* Store system image
|
||||
*
|
||||
* @param $request
|
||||
* @param $name
|
||||
* @return string|null
|
||||
*/
|
||||
function store_system_image($request, $name)
|
||||
{
|
||||
if (! $request->hasFile($name)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$image = $request->file($name);
|
||||
|
||||
// Store avatar
|
||||
$filename = Str::random(8) . '-' . str_replace(' ', '', $image->getClientOriginalName());
|
||||
|
||||
// Store image to disk
|
||||
Storage::putFileAs('system', $image, $filename);
|
||||
|
||||
// Return path to image
|
||||
return "system/$filename";
|
||||
}
|
||||
}
|
||||
|
||||
if (! function_exists('make_single_input')) {
|
||||
/**
|
||||
* Make input from request
|
||||
*
|
||||
* @param $request
|
||||
* @return array
|
||||
*/
|
||||
function make_single_input($request)
|
||||
{
|
||||
// Create container
|
||||
$data = [];
|
||||
|
||||
// Add data to array
|
||||
$data[$request->name] = $request->value;
|
||||
|
||||
// Return input
|
||||
return $data;
|
||||
}
|
||||
}
|
||||
|
||||
if (! function_exists('format_gigabytes')) {
|
||||
/**
|
||||
* Format integer to gigabytes
|
||||
*
|
||||
* @param $gigabytes
|
||||
* @return string
|
||||
*/
|
||||
function format_gigabytes($gigabytes)
|
||||
{
|
||||
if ($gigabytes >= 1000) {
|
||||
return Metric::gigabytes($gigabytes)->format('Tb/');
|
||||
}
|
||||
|
||||
return Metric::gigabytes($gigabytes)->format('GB/');
|
||||
}
|
||||
}
|
||||
|
||||
if (! function_exists('format_megabytes')) {
|
||||
/**
|
||||
* 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';
|
||||
}
|
||||
}
|
||||
|
||||
if (! function_exists('format_bytes')) {
|
||||
/**
|
||||
* Convert megabytes to bytes
|
||||
*
|
||||
* @param $megabytes
|
||||
* @return int|string
|
||||
*/
|
||||
function format_bytes($megabytes)
|
||||
{
|
||||
return Metric::megabytes($megabytes)->numberOfBytes();
|
||||
}
|
||||
}
|
||||
|
||||
if (! function_exists('get_storage_fill_percentage')) {
|
||||
/**
|
||||
* Get storage usage in percent
|
||||
*
|
||||
* @param $used
|
||||
* @param $capacity
|
||||
* @return string
|
||||
*/
|
||||
function get_storage_fill_percentage($used, $capacity)
|
||||
{
|
||||
// Format gigabytes to bytes
|
||||
$total = intval(Metric::gigabytes($capacity)->numberOfBytes());
|
||||
|
||||
// Count progress
|
||||
if ($total == 0) {
|
||||
$progress = 100;
|
||||
} else {
|
||||
$progress = ($used * 100) / $total;
|
||||
}
|
||||
|
||||
// Return in 2 decimal
|
||||
return number_format((float) $progress, 2, '.', '');
|
||||
}
|
||||
}
|
||||
|
||||
if (! function_exists('user_storage_percentage')) {
|
||||
/**
|
||||
* Get user capacity fill by percentage
|
||||
*
|
||||
* @param $id
|
||||
* @param null $additionals
|
||||
* @return string
|
||||
*/
|
||||
function user_storage_percentage($id, $additionals = null)
|
||||
{
|
||||
$user = User::findOrFail($id);
|
||||
|
||||
$used = $user->used_capacity;
|
||||
|
||||
if ($additionals) {
|
||||
$used = $user->used_capacity + $additionals;
|
||||
}
|
||||
|
||||
return get_storage_fill_percentage($used, $user->settings->storage_capacity);
|
||||
}
|
||||
}
|
||||
|
||||
if (! function_exists('recursiveFind')) {
|
||||
/**
|
||||
* Find all key values in recursive array
|
||||
*
|
||||
* @param array $array
|
||||
* @param $needle
|
||||
* @return array
|
||||
*/
|
||||
function recursiveFind(array $array, $needle)
|
||||
{
|
||||
$iterator = new RecursiveArrayIterator($array);
|
||||
$recursive = new RecursiveIteratorIterator($iterator, RecursiveIteratorIterator::SELF_FIRST);
|
||||
$aHitList = [];
|
||||
|
||||
foreach ($recursive as $key => $value) {
|
||||
if ($key === $needle) {
|
||||
array_push($aHitList, $value);
|
||||
}
|
||||
}
|
||||
|
||||
return $aHitList;
|
||||
}
|
||||
}
|
||||
|
||||
if (! function_exists('appeared_once')) {
|
||||
/**
|
||||
* Get values which appears only once in array
|
||||
* @param $arr
|
||||
* @return array
|
||||
*/
|
||||
function appeared_once($arr)
|
||||
{
|
||||
$array_count_values = array_count_values($arr);
|
||||
|
||||
$single_time_comming_values_array = [];
|
||||
|
||||
foreach ($array_count_values as $key => $val) {
|
||||
if ($val == 1) {
|
||||
$single_time_comming_values_array[] = $key;
|
||||
}
|
||||
}
|
||||
|
||||
return $single_time_comming_values_array;
|
||||
}
|
||||
}
|
||||
|
||||
if (! function_exists('filter_folders_ids')) {
|
||||
/**
|
||||
* @param $folders
|
||||
* @param string $by_column
|
||||
* @return array
|
||||
*/
|
||||
function filter_folders_ids($folders, $by_column = 'id')
|
||||
{
|
||||
$folder_ids = recursiveFind($folders->toArray(), $by_column);
|
||||
|
||||
return appeared_once($folder_ids);
|
||||
}
|
||||
}
|
||||
|
||||
if (! function_exists('format_date')) {
|
||||
/**
|
||||
* Format localized date
|
||||
*
|
||||
* @param $date
|
||||
* @param string $format
|
||||
* @return string
|
||||
*/
|
||||
function format_date($date, $format = '%d. %B. %Y, %H:%M')
|
||||
{
|
||||
$start = Carbon::parse($date);
|
||||
|
||||
return $start->formatLocalized($format);
|
||||
}
|
||||
}
|
||||
|
||||
if (! function_exists('get_file_type')) {
|
||||
/**
|
||||
* Get file type from mimetype
|
||||
*
|
||||
* @param $file_mimetype
|
||||
* @return string
|
||||
*/
|
||||
function get_file_type($file_mimetype)
|
||||
{
|
||||
// Get mimetype from file
|
||||
$mimetype = explode('/', $file_mimetype);
|
||||
|
||||
if (in_array($mimetype[0], ['image', 'video', 'audio'])) {
|
||||
return $mimetype[0];
|
||||
}
|
||||
|
||||
return 'file';
|
||||
}
|
||||
}
|
||||
|
||||
if (! function_exists('map_language_translations')) {
|
||||
/**
|
||||
* It map language translations as language key and language value
|
||||
*
|
||||
* @param $translations
|
||||
* @return mixed
|
||||
*/
|
||||
function map_language_translations($translations): Collection
|
||||
{
|
||||
return $translations->map(function ($string) {
|
||||
return [$string->key => $string->value];
|
||||
})->collapse();
|
||||
}
|
||||
}
|
||||
|
||||
if (! function_exists('get_file_type_from_mimetype')) {
|
||||
/**
|
||||
* Get file type from mimetype
|
||||
*
|
||||
* @param $mimetype
|
||||
* @return mixed
|
||||
*/
|
||||
function get_file_type_from_mimetype($mimetype)
|
||||
{
|
||||
return explode('/', $mimetype)[1];
|
||||
}
|
||||
}
|
||||
|
||||
if (! function_exists('get_pretty_name')) {
|
||||
/**
|
||||
* Format pretty name file
|
||||
*
|
||||
* @param $basename
|
||||
* @param $name
|
||||
* @param $mimetype
|
||||
* @return string
|
||||
*/
|
||||
function get_pretty_name($basename, $name, $mimetype)
|
||||
{
|
||||
$file_extension = substr(strrchr($basename, '.'), 1);
|
||||
|
||||
if (strpos($name, $file_extension) !== false) {
|
||||
return $name;
|
||||
}
|
||||
|
||||
if ($file_extension) {
|
||||
return $name . '.' . $file_extension;
|
||||
}
|
||||
|
||||
return $name . '.' . $mimetype;
|
||||
}
|
||||
}
|
||||
|
||||
if (! function_exists('get_image_meta_data')) {
|
||||
/**
|
||||
* Get exif data from jpeg image
|
||||
*
|
||||
* @param $file
|
||||
* @return array|null
|
||||
*/
|
||||
function get_image_meta_data($file)
|
||||
{
|
||||
if (get_file_type_from_mimetype($file->getMimeType()) === 'jpeg') {
|
||||
try {
|
||||
// Try to get the exif data
|
||||
return mb_convert_encoding(Image::make($file->getRealPath())->exif(), 'UTF8', 'UTF8');
|
||||
} catch (\Exception $e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (! function_exists('get_default_language_translations')) {
|
||||
/**
|
||||
* @return Collection
|
||||
*/
|
||||
function get_default_language_translations(): Collection
|
||||
{
|
||||
return collect([
|
||||
config('language-translations.extended'),
|
||||
config('language-translations.regular'),
|
||||
config('custom-language-translations'),
|
||||
])->collapse();
|
||||
}
|
||||
}
|
||||
|
||||
if (! function_exists('is_dev')) {
|
||||
/**
|
||||
* Check if app is in dev mode
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
function is_dev()
|
||||
{
|
||||
return env('APP_ENV') === 'local';
|
||||
}
|
||||
}
|
||||
|
||||
if (! function_exists('seems_utf8')) {
|
||||
/**
|
||||
* @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;
|
||||
}
|
||||
}
|
||||
|
||||
if (! function_exists('remove_accents')) {
|
||||
/**
|
||||
* 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 = [
|
||||
// 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'] = [chr(140), chr(156), chr(198), chr(208), chr(222), chr(223), chr(230), chr(240), chr(254)];
|
||||
$double_chars['out'] = ['OE', 'oe', 'AE', 'DH', 'TH', 'ss', 'ae', 'dh', 'th'];
|
||||
$string = str_replace($double_chars['in'], $double_chars['out'], $string);
|
||||
}
|
||||
|
||||
return $string;
|
||||
}
|
||||
}
|
||||
|
||||
if (! function_exists('get_files_for_zip')) {
|
||||
/**
|
||||
* Get all files from folder and get their folder location in VueFileManager directories
|
||||
*
|
||||
* @param $folders
|
||||
* @param null $files
|
||||
* @param array $path
|
||||
* @return array
|
||||
*/
|
||||
function get_files_for_zip($folders, $files, $path = [])
|
||||
{
|
||||
// Return file list
|
||||
if (! isset($folders->folders)) {
|
||||
return $files->unique()->values()->all();
|
||||
}
|
||||
|
||||
// Push file path
|
||||
array_push($path, $folders->name);
|
||||
|
||||
// Push file to collection
|
||||
$folders->files->each(function ($file) use ($files, $path) {
|
||||
$files->push([
|
||||
'name' => $file->name,
|
||||
'basename' => $file->basename,
|
||||
'mimetype' => $file->mimetype,
|
||||
'folder_path' => implode('/', $path),
|
||||
]);
|
||||
});
|
||||
|
||||
// Get all children folders and folders within
|
||||
if ($folders->folders->isNotEmpty()) {
|
||||
$folders->folders->map(function ($folder) use ($files, $path) {
|
||||
return get_files_for_zip($folder, $files, $path);
|
||||
});
|
||||
}
|
||||
|
||||
return get_files_for_zip($folders->folders->first(), $files, $path);
|
||||
}
|
||||
}
|
||||
|
||||
if (! function_exists('set_time_by_user_timezone')) {
|
||||
/**
|
||||
* Set time by user timezone GMT
|
||||
*
|
||||
* @param $time
|
||||
* @return Carbon
|
||||
*/
|
||||
function set_time_by_user_timezone($time)
|
||||
{
|
||||
$user = Auth::user();
|
||||
|
||||
if ($user) {
|
||||
$time_zone = intval($user->settings->timezone * 60 ?? null);
|
||||
|
||||
return Carbon::parse($time)->addMinutes($time_zone ?? 0);
|
||||
}
|
||||
|
||||
return Carbon::parse($time);
|
||||
}
|
||||
}
|
||||
|
||||
if (! function_exists('__t')) {
|
||||
/**
|
||||
* Translate the given message.
|
||||
* @param $key
|
||||
* @param null $values
|
||||
* @return string
|
||||
* @throws Exception
|
||||
*/
|
||||
function __t($key, $values = null): string
|
||||
{
|
||||
// Get current locale
|
||||
$locale = cache()->rememberForever('language', function () {
|
||||
try {
|
||||
return get_setting('language') ?? 'en';
|
||||
} catch (QueryException $e) {
|
||||
return 'en';
|
||||
}
|
||||
});
|
||||
|
||||
// Get language strings
|
||||
$strings = cache()->rememberForever("language-translations-$locale", function () use ($locale) {
|
||||
try {
|
||||
return Language::whereLocale($locale)->firstOrFail()->languageTranslations;
|
||||
} catch (QueryException | ModelNotFoundException $e) {
|
||||
return null;
|
||||
}
|
||||
}) ?? get_default_language_translations();
|
||||
|
||||
// Find the string by key
|
||||
$string = $strings->firstWhere('key', $key)->value ?? $strings->get($key);
|
||||
|
||||
if ($values) {
|
||||
return replace_occurrence($string, collect($values));
|
||||
}
|
||||
|
||||
return $string;
|
||||
}
|
||||
}
|
||||
|
||||
if (! function_exists('replace_occurrence')) {
|
||||
/**
|
||||
* Replace string occurrence in __t() by their values
|
||||
*
|
||||
* @param $string
|
||||
* @param $values
|
||||
* @return string|string[]
|
||||
*/
|
||||
function replace_occurrence($string, $values)
|
||||
{
|
||||
$occurrences = $values->map(function ($message, $key) {
|
||||
return [
|
||||
'key' => ":$key",
|
||||
'message' => $message,
|
||||
];
|
||||
});
|
||||
|
||||
return str_ireplace(
|
||||
$occurrences->pluck('key')->toArray(),
|
||||
$occurrences->pluck('message')->toArray(),
|
||||
$string
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user