Skip to content

Commit

Permalink
Merge pull request #2 from Pharaonic/feature/structure-enhancement
Browse files Browse the repository at this point in the history
Version 4.0
  • Loading branch information
MoamenEltouny authored Dec 12, 2024
2 parents 9844dea + f4de4ba commit e6c83ae
Show file tree
Hide file tree
Showing 23 changed files with 717 additions and 660 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
/vendor
composer.lock
6 changes: 3 additions & 3 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,12 @@
"authors": [
{
"name": "Moamen Eltouny (Raggi)",
"email": "raggi@raggitech.com"
"email": "raggigroup@gmail.com"
}
],
"require": {
"php": ">=7.2",
"laravel/framework": ">=6.0",
"php": ">=8.0",
"laravel/framework": ">=9.0",
"pharaonic/laravel-readable": ">=1.0",
"intervention/image": "^2.6.1"
},
Expand Down
38 changes: 38 additions & 0 deletions config/uploader.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
<?php

return [
/**
* Storage Disk (local, public, s3, ...)
*/
'disk' => env('FILESYSTEM_DISK', 'local'),

/**
* Uploading Path
*/
'path' => '/',

/**
* Expiry time of temporary-url in minutes (S3)
*/
'expire' => 30,

/**
* Visibility of the uploaded files (S3)
*/
'visibility' => 'private',

/**
* Include the file extension in the URL (local)
*/
'extensional' => true,

/**
* Route Contoller Class
*/
'controller' => \Pharaonic\Laravel\Uploader\Http\Controllers\UploadController::class,

/**
* Route URI (/file/{hash})
*/
'uri' => '/file',
];
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

class CreateUploadsTable extends Migration
return new class extends Migration
{
/**
* Run the migrations.
Expand All @@ -14,22 +14,18 @@ class CreateUploadsTable extends Migration
public function up()
{
Schema::create('uploads', function (Blueprint $table) {
$table->bigIncrements('id');
$table->id();
$table->foreignId('thumbnail_id')->nullable()->constrained('uploads')->nullOnDelete();

$table->string('hash', 350)->index();
$table->string('disk')->nullable();
$table->string('visibility')->nullable();

$table->string('hash', 350);
$table->string('name');
$table->string('path');
$table->bigInteger('size');
$table->string('extension', 20);
$table->string('mime', 50);
$table->string('disk')->nullable();

$table->boolean('visitable')->default(false);
$table->unsignedBigInteger('visits')->default(0);
$table->boolean('private')->default(false);

$table->unsignedBigInteger('thumbnail_id')->nullable();
$table->unsignedBigInteger('uploader_id')->nullable();
$table->unsignedBigInteger('size');
$table->string('extension', 25);
$table->string('mime', 70);

$table->timestamps();
});
Expand All @@ -44,4 +40,4 @@ public function down()
{
Schema::dropIfExists('uploads');
}
}
};
11 changes: 11 additions & 0 deletions routes/web.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<?php

use Illuminate\Support\Facades\Route;
use Pharaonic\Laravel\Uploader\Facades\Uploader;

Route::middleware('web')
->name('uploader.file')
->get(
Uploader::route()->uri(),
Uploader::route()->action()
);
145 changes: 145 additions & 0 deletions src/Actions/CreateFile.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
<?php

namespace Pharaonic\Laravel\Uploader\Actions;

use Illuminate\Http\UploadedFile;
use Illuminate\Support\Facades\File;
use Illuminate\Support\Str;
use Intervention\Image\Facades\Image;
use Pharaonic\Laravel\Uploader\Facades\Uploader;
use Pharaonic\Laravel\Uploader\Models\Upload;

class CreateFile
{
/**
* Handle the action.
*
* @param UploadedFile $file
* @param array|null $options
* @return Upload
*/
public function handle(UploadedFile $file, array $options = [])
{
$hash = $this->generateHash($file);
$extension = $file->extension();
extract($this->options($options));

$file->storeAs($path, $hash . '.' . $extension, [
'disk' => $disk,
'visibility' => $visibility,
]);

// Thumbnail Generating
if (str_starts_with($file->getMimeType(), 'image/') && isset($options['thumbnail'])) {
$thumbnail = $this->uploadThumbnail($file, $options);
}

return Upload::create([
'thumbnail_id' => isset($thumbnail) ? $thumbnail->id : null,
'hash' => $hash,
'disk' => $disk,
'visibility' => $visibility,
'path' => $path . $hash . '.' . $extension,
'extension' => $extension,
'name' => $file->getClientOriginalName(),
'mime' => $file->getMimeType(),
'size' => $file->getSize(),
]);
}

/**
* Generate a new Hash.
*
* @param UploadedFile $file
* @return string
*/
protected function generateHash(UploadedFile $file)
{
$hash = Str::random(27) . pathinfo($file->hashName(), PATHINFO_FILENAME);

if (Upload::whereHash($hash)->exists())
return $this->generateHash($file);

return $hash;
}

/**
* Get the options list.
*
* @param array $options
* @return array
*/
protected function options(array $options)
{
$originalOptions = Uploader::options();

$path = trim($originalOptions['path'], '/') . '/';
$filePath = trim($options['path'] ?? '', '/');

if (!empty($filePath)) {
$path .= $filePath . '/';
}

return [
'disk' => $disk = ($options['disk'] ?? $originalOptions['disk']),
'visibility' => config('filesystems.disks.' . $disk . '.driver') != 'local' ? ($options['visibility'] ?? $originalOptions['visibility']) : null,
'path' => str_replace(
'/',
DIRECTORY_SEPARATOR,
$path . date('Y-m-d', time()) . '/'
),
];
}

/**
* Upload Thumbnail.
*
* @param UploadedFile $file
* @param array $options
* @return Upload
*/
protected function uploadThumbnail(UploadedFile $file, array $options = [])
{
$ratio = $options['thumbnail']['ratio'] ?? false;
$width = $options['thumbnail']['width'] ?? null;
$height = $options['thumbnail']['height'] ?? null;
unset($options['thumbnail']);

if (!$width && !$height) {
throw new \Exception('You have to set width or height thumbnail\'s option.');
}

$thumbnail = Image::make($file);

// Ratio or Fixed
if ($ratio) {
$thumbnail->resize(
$width ?? null,
$width > 0 ? null : $height,
fn($constraint) => $constraint->aspectRatio()
);
} else {
$thumbnail->resize($width, $height);
}

// Create Fake file
$name = Str::random(37) . '.' . $file->extension();

File::ensureDirectoryExists(storage_path('app/public/pharaonic-thumbs'));
$thumbnail->save(storage_path('app/public/pharaonic-thumbs/' . $name), 100);

$file = $this->handle(
new UploadedFile(
storage_path('app/public/pharaonic-thumbs/' . $name),
$file->getClientOriginalName() . '-thumbnail',
$thumbnail->mime()
),
$options
);

// Delete Fake File
File::delete(storage_path('app/public/pharaonic-thumbs/' . $name));

return $file;
}
}
30 changes: 30 additions & 0 deletions src/Actions/DeleteFile.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<?php

namespace Pharaonic\Laravel\Uploader\Actions;

use Illuminate\Support\Facades\Storage;
use Pharaonic\Laravel\Uploader\Models\Upload;

class DeleteFile
{
/**
* Delete file with the thumbnail.
*
* @param Upload $file
* @return void
*/
public function handle(Upload $file)
{
if ($file->thumbnail_id) {
$file->thumbnail->delete();
}

$fs = Storage::disk($file->disk);

if (!$fs->exists($file->path)) {
return;
}

return $fs->delete($file->path);
}
}
47 changes: 47 additions & 0 deletions src/Classes/Router.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
<?php

namespace Pharaonic\Laravel\Uploader\Classes;

/**
* @method array action()
* @method string uri()
*/
class Router
{
/**
* The options list.
*
* @var array
*/
protected array $options;

/**
* Create a new Router instance.
*
* @param array $options
*/
public function __construct(array $options)
{
$this->options = $options;
}

/**
* Get route action.
*
* @return array
*/
public function action()
{
return $this->options['controller'];
}

/**
* Get route URI.
*
* @return string
*/
public function uri()
{
return $this->options['uri'] . '/{hash}';
}
}
Loading

0 comments on commit e6c83ae

Please sign in to comment.