From 1b3b95e70f776707eacebe8d9f5134b6bd8f9691 Mon Sep 17 00:00:00 2001 From: Mohammad Khazaee Date: Mon, 1 Aug 2022 19:52:37 +0430 Subject: [PATCH] compelete store part --- Dockerfile | 3 +- app/Http/Controllers/FileController.php | 69 +------- app/Http/Controllers/Traits/FileTrait.php | 9 +- app/Http/Kernel.php | 2 +- .../BindCollectionModelMiddleware.php | 6 +- .../Middleware/BindFileModelMiddleware.php | 16 +- app/Http/Requests/FileStoreRequest.php | 73 ++++++++ app/Image/ImageProcessor.php | 61 ++++--- app/Models/File.php | 16 +- app/Models/Traits/Validatable.php | 3 +- app/Providers/AppServiceProvider.php | 2 +- config/filesystems.php | 8 + database/factories/BaseFactory.php | 12 -- .../Documents/PolicyDocumentFactory.php | 9 + database/factories/FileFactory.php | 1 + database/seeders/DatabaseSeeder.php | 69 +++++--- public/image-modified.webp | Bin 44538 -> 0 bytes routes/api.php | 15 +- routes/web.php | 17 +- storage/image-modified.webp | Bin 43934 -> 0 bytes tests/Feature/FileStoreTest.php | 163 ++++++++++++++++-- 21 files changed, 376 insertions(+), 178 deletions(-) create mode 100644 app/Http/Requests/FileStoreRequest.php delete mode 100644 public/image-modified.webp delete mode 100644 storage/image-modified.webp diff --git a/Dockerfile b/Dockerfile index 311052a..b7547b6 100644 --- a/Dockerfile +++ b/Dockerfile @@ -9,4 +9,5 @@ RUN apt-get -y update \ && apt-get -y install libvips-tools \ && apt-get -y install libvips-dev \ && pecl install vips \ - && echo 'extension="vips.so"' > /usr/local/etc/php/conf.d/20-vips.ini + && echo 'extension="vips.so"' > /usr/local/etc/php/conf.d/20-vips.ini \ + && echo "ffi.enable=true" >> /usr/local/etc/php/php.ini diff --git a/app/Http/Controllers/FileController.php b/app/Http/Controllers/FileController.php index 919db7a..4a5e417 100644 --- a/app/Http/Controllers/FileController.php +++ b/app/Http/Controllers/FileController.php @@ -13,6 +13,8 @@ use Illuminate\Support\Facades\Storage; use Illuminate\Support\Facades\Validator; use Symfony\Component\Console\Input\Input; +use function PHPUnit\Framework\isNull; + class FileController extends Controller { public function show($collection, $uuid, $ext) @@ -22,68 +24,17 @@ class FileController extends Controller public function private($collection, $path) { - // Storage::disk(app()->collection->disk)->download($path); + Storage::disk('local')->download($path); } - public function store(Request $request, ImageProcessor $imageProcessor) + public function store(FileStoreRequest $request, ImageProcessor $imageProcessor) { - - if (!app()->collection->tmp_support && !$request->model_id) { - return abort(403); - } - - if (app()->collection->count !== 1 && (app()->collection->count <= File::where('model_id', auth()->id())->count()) && !app()->collection->tmp_support) { - return abort(403); - } - - if (!isset(app()->file) && is_null($request->file('file'))) { - return abort(403); - } - - $fieldsValidate = [ - "alts" => [app()->collection->alt_required ? "required" : "nullable", 'array'], - "alts.*" => [app()->collection->alt_required ? "required" : "nullable", 'max:1000'], - "description" => [app()->collection->description_required ? "required" : "nullable", 'max:300'], - 'original_name' => ["string", "nullable", 'max:300'], - 'public' => ['boolean', 'nullable'], - 'published_at' => ['date_format:Y-m-d H:i:s', 'nullable'], - ]; - - $fieldsValidate['file'] = - is_null($request->file('file')) ? - [ - 'string', - 'required', - 'max:300' - ] : - [ - "mimes:" . app()->collection->getExts(), - "mimetypes:" . app()->collection->getMimeTypes(), - !$this->isImage($request->file->path()) ?: "dimensions:min_width=" . app()->collection->min_width . ",min_height=" . app()->collection->min_height . ',max_width=' . app()->collection->max_width . ',max_height=' . app()->collection->max_height, - "max:" . app()->collection->max_file_size, - "min:" . app()->collection->min_file_size, - ]; - - $validated = $request->validate($fieldsValidate); - - if (is_null($request->file('file'))) { - $storedImage = new \Illuminate\Http\File(Storage::disk('local')->path(app()->file->server_path)); - $validated = Validator::make(['file' => $storedImage], ["file" => [ - "mimes:" . app()->collection->getExts(), - "mimetypes:" . app()->collection->getMimeTypes(), - "dimensions:min_width=" . app()->collection->min_width . ",min_height=" . app()->collection->min_height . ',max_width=' . app()->collection->max_width . ',max_height=' . app()->collection->max_height, - "max:" . app()->collection->max_file_size, - "min:" . app()->collection->min_file_size - ]])->validate(); - } - + $request->file = $imageProcessor->convertImage($request->file->path(),'/tmp/' . app()->uuid . '.' . app()->collection->ext); if (!is_null(app()->collection->process)) { - $imageProcessor->process($request->file->path(), $request->file->path(), app()->collection->process); + $request->file = $imageProcessor->process($request->file->path(),'/tmp/' . app()->uuid. '.' . app()->collection->ext, app()->collection->process); } - DB::transaction(function () use ($request) { - $uuid = app()->uuid; $request->resourceFile = File::create([ 'uuid' => $uuid, @@ -101,22 +52,20 @@ class FileController extends Controller 'ip' => $request->ip(), 'collection_id' => app()->collection->id, 'published_at' => $request->published_at, - 'server_path' => '/' . date('y') . '/' . date('m') . '/' . $uuid . '.' . app()->collection->ext, + 'server_path' => '/' . date('y') . '/' . date('m') . '/', ]); - if (!app()->collection->tmp_support && app()->collection->count == 1) { File::where('user_id', auth()->id())->delete(); } - $storedImage = $request->file->storeAs($request->resourceFile->server_path, app()->uuid . '.' . app()->collection->ext, app()->collection->disk); + $storedFile = Storage::disk(app()->collection->disk)->putFileAs('', $request->file,$request->resourceFile->server_path . $request->resourceFile->uuid . '.' . app()->collection->ext); if (app()->collection->public) { - Storage::setVisibility($storedImage, 'public'); + Storage::disk(app()->collection->disk)->setVisibility($storedFile, 'public'); } }); return new FileResource($request->resourceFile); } - public function update(Request $request, $id) { // diff --git a/app/Http/Controllers/Traits/FileTrait.php b/app/Http/Controllers/Traits/FileTrait.php index 097bb69..a413431 100644 --- a/app/Http/Controllers/Traits/FileTrait.php +++ b/app/Http/Controllers/Traits/FileTrait.php @@ -4,12 +4,5 @@ namespace App\Http\Controllers\Traits; trait FileTrait { - public function isImage($file) - { - if(@is_array(getimagesize($file))){ - return true; - } else { - return false; - } - } + } diff --git a/app/Http/Kernel.php b/app/Http/Kernel.php index 9217b71..35fb8b0 100644 --- a/app/Http/Kernel.php +++ b/app/Http/Kernel.php @@ -45,7 +45,7 @@ class Kernel extends HttpKernel // \Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful::class, 'throttle:api', \Illuminate\Routing\Middleware\SubstituteBindings::class, - BindModelDocumentMiddleware::class, + // BindModelDocumentMiddleware::class, BindCollectionModelMiddleware::class, BindFileModelMiddleware::class, ], diff --git a/app/Http/Middleware/BindCollectionModelMiddleware.php b/app/Http/Middleware/BindCollectionModelMiddleware.php index ddabc53..f984c8c 100644 --- a/app/Http/Middleware/BindCollectionModelMiddleware.php +++ b/app/Http/Middleware/BindCollectionModelMiddleware.php @@ -18,15 +18,15 @@ class BindCollectionModelMiddleware */ public function handle(Request $request, Closure $next) { - if ($request->route()->action['as'] == 'api.file.store') { + if ($request->route()->action['as'] == 'api.files.store') { app()->singleton('collection', function () use ($request) { - return Collection::where('name', $request->route('collection_name'))->get()->first(); + return Collection::where('name', $request->route('collection_name'))->firstOrFail(); }); } if ($request->route()->action['as'] == 'api.file.private') { app()->singleton('collection', function () use ($request) { - return Collection::where('name', $request->route('collection_name'))->get()->first(); + return Collection::where('name', $request->route('collection_name'))->firstOrFail(); }); } diff --git a/app/Http/Middleware/BindFileModelMiddleware.php b/app/Http/Middleware/BindFileModelMiddleware.php index e1289be..8bfad45 100644 --- a/app/Http/Middleware/BindFileModelMiddleware.php +++ b/app/Http/Middleware/BindFileModelMiddleware.php @@ -2,10 +2,12 @@ namespace App\Http\Middleware; +use App\Models\Collection; use App\Models\File; use Closure; use Illuminate\Support\Str; use Illuminate\Http\Request; +use Illuminate\Support\Facades\Storage; class BindFileModelMiddleware { @@ -18,11 +20,15 @@ class BindFileModelMiddleware */ public function handle(Request $request, Closure $next) { - if ($request->route()->action['as'] == 'api.file.store') { - if(is_null($request->file('file'))){ - app()->bind('file', function () use ($request) { - return File::find($request->file); - }); + if (($request->route()->action['as'] == 'api.files.store') && is_null($request->file('file'))) { + $file = File::find($request->file); + if (!is_null($file)) { + $Collection = Collection::where('name', $request->route('collection_name'))->firstOrFail(); + if (Storage::disk($Collection->disk)->exists($file->server_path . $file->uuid . '.' . $Collection->ext)) { + app()->bind('file', function () use ($file) { + return $file; + }); + } } } diff --git a/app/Http/Requests/FileStoreRequest.php b/app/Http/Requests/FileStoreRequest.php new file mode 100644 index 0000000..45b602d --- /dev/null +++ b/app/Http/Requests/FileStoreRequest.php @@ -0,0 +1,73 @@ +collection->tmp_support && !$this->model_id) { + return false; + } + + if (app()->collection->count !== 1 && (app()->collection->count <= File::where('model_id', auth()->id())->count()) && !app()->collection->tmp_support) { + + return false; + } + if (!app()->bound('file') && is_null($this->file('file'))) { + return false; + } + + if (!$this->hasFile('file')) { + $this->replace([ + 'file' => new \Illuminate\Http\File(Storage::disk(app()->collection->disk)->path(app()->file->server_path . app()->file->uuid . '.' . app()->collection->ext), app()->file->uuid . '.' . app()->collection->ext) + ]); + } + + return true; + } + + /** + * Get the validation rules that apply to the request. + * + * @return array + */ + public function rules() + { + return [ + "file" => [ + "mimes:" . app()->collection->getExts(), + "mimetypes:" . app()->collection->getMimeTypes(), + !$this->isImage(request()->file->path()) ?: "dimensions:min_width=" . app()->collection->min_width . ",min_height=" . app()->collection->min_height . ',max_width=' . app()->collection->max_width . ',max_height=' . app()->collection->max_height, + "max:" . app()->collection->max_file_size, + "min:" . app()->collection->min_file_size, + ], + "alts" => [app()->collection->alt_required ? "required" : "nullable", 'array'], + "alts.*" => [app()->collection->alt_required ? "required" : "nullable", 'max:1000'], + "description" => [app()->collection->description_required ? "required" : "nullable", 'max:300'], + 'original_name' => ["string", "nullable", 'max:300'], + 'public' => ['boolean', 'nullable'], + 'published_at' => ['date_format:Y-m-d H:i:s', 'nullable'], + ]; + } +} diff --git a/app/Image/ImageProcessor.php b/app/Image/ImageProcessor.php index bc61664..954655c 100644 --- a/app/Image/ImageProcessor.php +++ b/app/Image/ImageProcessor.php @@ -7,32 +7,10 @@ use Jcupitt\Vips\Interpretation; class ImageProcessor { - public function brightness($image, float $brightness = 1.0, float $saturation = 1.0, float $hue = 0.0) - { - $oldInterpretation = $image->interpretation; - $hue %= 360; - if ($hue < 0) { - $hue = 360 + $hue; - } - if ($image->hasAlpha()) { - $imageWithoutAlpha = $image->extract_band(0, ['n' => $image->bands - 1]); - $alpha = $image->extract_band($image->bands - 1, ['n' => 1]); - return $imageWithoutAlpha - ->colourspace(Interpretation::LCH) - ->linear([$brightness, $saturation, 1.0], [0.0, 0.0, $hue]) - ->colourspace($oldInterpretation) - ->bandjoin($alpha); - } - return $image - ->colourspace(Interpretation::LCH) - ->linear([$brightness, $saturation, 1.0], [0.0, 0.0, $hue]) - ->colourspace($oldInterpretation); - } - public function process(string $filename, string $target, array $options = ["w" => null, "h" => null, "r" => null,"flip" => null , "canv" => null,"rotation" => null],$saveOptions = ['Q' => 100]) { if (!isset($options['w']) && !isset($options['h'])) { - $image = Image::thumbnail($filename, getimagesize($filename)[0]); + $image = Image::thumbnail($filename, getimagesize($filename)[1]); } if (isset($options['r'])) { @@ -105,6 +83,41 @@ class ImageProcessor $image->writeToFile($target,$saveOptions); - return $target; + return new \Illuminate\Http\File($target); + } + + public function createFakeImage($stub,$path, $saveOptions = ['Q' => 100],$options = ["w" => null, "h" => null, "r" => null,"flip" => null , "canv" => null,"rotation" => null]) + { + $image = $this->process($stub,$path,$options,$saveOptions); + } + + + public function brightness($image, float $brightness = 1.0, float $saturation = 1.0, float $hue = 0.0) + { + $oldInterpretation = $image->interpretation; + $hue %= 360; + if ($hue < 0) { + $hue = 360 + $hue; + } + if ($image->hasAlpha()) { + $imageWithoutAlpha = $image->extract_band(0, ['n' => $image->bands - 1]); + $alpha = $image->extract_band($image->bands - 1, ['n' => 1]); + return $imageWithoutAlpha + ->colourspace(Interpretation::LCH) + ->linear([$brightness, $saturation, 1.0], [0.0, 0.0, $hue]) + ->colourspace($oldInterpretation) + ->bandjoin($alpha); + } + return $image + ->colourspace(Interpretation::LCH) + ->linear([$brightness, $saturation, 1.0], [0.0, 0.0, $hue]) + ->colourspace($oldInterpretation); + } + + public function convertImage(string $filePath,string $target,array $options = ['Q' => 100]) : \Illuminate\Http\File + { + $tmpFile = \Jcupitt\Vips\Image::newFromFile($filePath); + $tmpFile->writeToFile($target,$options); + return new \Illuminate\Http\File($target); } } diff --git a/app/Models/File.php b/app/Models/File.php index 69650ed..eb555d7 100644 --- a/app/Models/File.php +++ b/app/Models/File.php @@ -3,6 +3,7 @@ namespace App\Models; use App\Models\Traits\Validatable; +use App\Models\Traits\ValidationMaker; use Illuminate\Database\Eloquent\Casts\Attribute; use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; @@ -15,6 +16,8 @@ class File extends Model protected $primaryKey = 'uuid'; + public $incrementing = false; + protected $fillable = [ "uuid", "original_name", @@ -46,16 +49,5 @@ class File extends Model ); } - // public function rules(): array - // { - // return [ - // "image" => [ - // "mimes:" . app()->collection->getExts(), - // "mimetypes:" . app()->collection->getMimeTypes(), - // "dimensions:min_width=" . app()->collection->min_width . ",min_height=" . app()->collection->min_height . ',max_width=' . app()->collection->max_width . ',max_height=' . app()->collection->max_height, - // "max:" . app()->collection->max_size, - // "min:" . app()->collection->min_size, - // ], - // ]; - // } + } diff --git a/app/Models/Traits/Validatable.php b/app/Models/Traits/Validatable.php index ddf6915..ca2e336 100644 --- a/app/Models/Traits/Validatable.php +++ b/app/Models/Traits/Validatable.php @@ -59,7 +59,9 @@ trait Validatable $rules = array_merge($rules, $this->createValidations()); $rules = array_merge($rules, $this->createValidations('category_data')); + $validator = Validator::make($this->toArray(), $rules); + if ($abort && $validator->fails()) { throw new ValidationException($validator, new JsonResponse([ @@ -83,7 +85,6 @@ trait Validatable return $abort ? $this : true; } - public function getLoads() { return []; diff --git a/app/Providers/AppServiceProvider.php b/app/Providers/AppServiceProvider.php index 34c5d64..6f766d5 100644 --- a/app/Providers/AppServiceProvider.php +++ b/app/Providers/AppServiceProvider.php @@ -27,7 +27,7 @@ class AppServiceProvider extends ServiceProvider { Storage::disk('local')->buildTemporaryUrlsUsing(function ($path, $expiration, $options) { return URL::temporarySignedRoute( - 'api.file.private', + 'api.files.private', $expiration, array_merge($options, ['path' => $path]) ); diff --git a/config/filesystems.php b/config/filesystems.php index 1b24a72..374f1ca 100644 --- a/config/filesystems.php +++ b/config/filesystems.php @@ -48,6 +48,14 @@ return [ ], ], + 'tmp' => [ + 'driver' => 'local', + 'root' => '/tmp', + 'url' => env('APP_URL') . '/storage', + 'visibility' => 'public', + 'throw' => false, + ], + // 'public' => [ // 'driver' => 'local', // 'root' => storage_path('app/public'), diff --git a/database/factories/BaseFactory.php b/database/factories/BaseFactory.php index 912ed3c..36b663d 100644 --- a/database/factories/BaseFactory.php +++ b/database/factories/BaseFactory.php @@ -69,16 +69,4 @@ trait BaseFactory }); } - - public function withImage() - { - return null; - } - - public function createImage($path, $saveOptions = ['Q' => 100],$options = ["w" => null, "h" => null, "r" => null,"flip" => null , "canv" => null,"rotation" => null]) - { - $imageProcessor = new ImageProcessor; - $image = $imageProcessor->process(storage_path('stub') . '/image.png',$path,$options,$saveOptions); - return $this; - } } diff --git a/database/factories/Documents/PolicyDocumentFactory.php b/database/factories/Documents/PolicyDocumentFactory.php index 2446684..238b797 100755 --- a/database/factories/Documents/PolicyDocumentFactory.php +++ b/database/factories/Documents/PolicyDocumentFactory.php @@ -4,10 +4,14 @@ namespace Database\Factories\Documents; use App\Documents\ModelDocument; use App\Documents\PolicyDocument; +use Database\Factories\BaseFactory; use Illuminate\Database\Eloquent\Factories\Factory; class PolicyDocumentFactory extends Factory + { + use BaseFactory; + protected $model = PolicyDocument::class; public function definition() @@ -19,4 +23,9 @@ class PolicyDocumentFactory extends Factory 'needs' => [], ]; } + + public function dependencyProvider() + { + return []; + } } diff --git a/database/factories/FileFactory.php b/database/factories/FileFactory.php index 5949c0a..344efe0 100644 --- a/database/factories/FileFactory.php +++ b/database/factories/FileFactory.php @@ -29,6 +29,7 @@ class FileFactory extends Factory "height" => rand(300, 2000), "file_size" => rand(300, 2000), "sort" => rand(0, 23), + "server_path" => '/' . date('y') . '/' . date('m') . '/', "alts" => [ 'hello wroldswdfouiwref iuwrhgf ow rgfaw ghfawej', 'jhsf asduyfsadf sadf safsuf isfjsdfsudifsduiyf sdiuf sd' diff --git a/database/seeders/DatabaseSeeder.php b/database/seeders/DatabaseSeeder.php index a406d7e..6e89110 100644 --- a/database/seeders/DatabaseSeeder.php +++ b/database/seeders/DatabaseSeeder.php @@ -2,8 +2,12 @@ namespace Database\Seeders; +use App\Image\ImageProcessor; +use App\Models\Collection; +use App\Models\File; use Illuminate\Database\Console\Seeds\WithoutModelEvents; use Illuminate\Database\Seeder; +use Illuminate\Support\Facades\Storage; class DatabaseSeeder extends Seeder { @@ -21,28 +25,49 @@ class DatabaseSeeder extends Seeder // 'email' => 'test@example.com', // ]); - \App\Models\Collection::factory()->create([ - "name" => "fuck", - "count" => 1, - "tmp_support" => 0, - "remove_tmp_time" => 132, - "max_file_size" => 100000000, - "min_file_size" => 10, - "max_width" =>2000, - "min_width" =>10, - "max_height" => 2000, - "min_height" =>10, - "alt_required" => 0, - "description_required" =>0, - "exts" => [ - "jpg", - "jpeg", - "png", - "webp" - ], - "ext" => "webp", + // \App\Models\Collection::factory()->create([ + // "name" => "fuck", + // "count" => 1, + // "tmp_support" => 0, + // "remove_tmp_time" => 132, + // "max_file_size" => 100000000, + // "min_file_size" => 10, + // "max_width" =>2000, + // "min_width" =>10, + // "max_height" => 2000, + // "min_height" =>10, + // "alt_required" => 0, + // "description_required" =>0, + // "exts" => [ + // "jpg", + // "jpeg", + // "png", + // "webp" + // ], + // "ext" => "webp", + // ]); + // \App\Models\Collection::factory(10)->create(); + // \App\Models\File::factory()->create(); + $collection = Collection::factory()->createQuietly([ + 'alt_required' => false, + 'description_required' => false, + 'tmp_support' => true, + 'max_width' => 2000, + 'max_height' => 2000, + 'min_width' => 1, + 'min_height' => 1, + 'min_file_size' => 0, + 'public' => false + ]); + $uuid = app()->uuid; + $file = File::factory()->createQuietly([ + 'uuid' => $uuid, + 'server_path' => '/' . date('y') . '/' . date('m') . '/', + 'user_id' => auth()->id(), + 'collection_id' => $collection->id ]); - \App\Models\Collection::factory(10)->create(); - \App\Models\File::factory()->create(); + $imageProcessor = new ImageProcessor; + $imageProcessor->createFakeImage(storage_path('stub') . '/image.png', Storage::disk($collection->disk)->path($file->server_path . $uuid . '.' . $collection->ext)); + } } diff --git a/public/image-modified.webp b/public/image-modified.webp deleted file mode 100644 index a3d801fbaf261095dc4e8de60a839961693e438c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 44538 zcmV($K;yqsNk&HUtpEU5MM6+kP&il$000080001{0RW}}09H^qAQG(r05CuSodGJR z0jB`~001S7{JycxqQSJsWuLprHxzdwAkiCezytixh%JEokk1-#?$^w)h`}xI?c>;Y zjrwcx*W3The}4Y${}cS@$*=r>aoss|ul$eiUy&Z>-cR~3_)qVj=Ks+Dga5z&ukMHX z@A%)EA1J@8|DFGj`N8xH`i1@b`*L=D*wgf`2mpnfF`!|Mxxr5B}G=r}&@vKly#bzoq|h|5f>W z`~UX&{~!ME`cL)${XUa_vHz_9v;K$uU;eM559Z(4zu11z|H}RU|K0cj|9{%A_y_#| zP!Cb~wCS(ocj^bJe~x^s_HXRp=6}flbN|8qv*S1WPVs#;|CjvV`EOwVko~0lul7&c zAMYRiKiK`{{$Kt-`Y*^|N&Yf_fBpOSFa1BrN8~@vKfZr&{igo||HJ(^*w^9z+Wn63 zU$>w6{X+fb`)~T6@L#q6=09q^!N17-+V_L?U+^FAe=vW4{{a7#|2_Wy{sZ=-{Ad4P z_FruO)Bn-s5BNX!AM*d*{!0CUe>(oJ{+Ij@_}}^e<$wNv@ceWBp%2=ng8|p6a2sWm-)Z%f9C(<|AYVi|0nNP|2Mji+&}(4>7TG4_ft=o z+d%d!BP#6XK{684<_08M>O{V8zKw!KgTeM0eq`~czQdR0SsR32Gc0ouspY++;um#l zl$r{H4mH|K{GZEHLtla1vvra6ZLd$6F=tnz^VHA0u=4}V&8c5Jjr!GD>C_tHFFUC; zUVZ29IM%+bZFiex++*PJc^3j^_i|?RTd>=}91|o*<{1UG>GLOdy-z0!iNd|U3L{*& zd9^VhOf9SPlo`0@b$|SgB!-Ng{*W}mG$86br9d_QX&PT&wQ)VYtVFy>u8JJJZO<-$ z95zb1cyfqbUp08-ykq818o4DP&=>saa8wO8km(yA)vZ2-`JCf}`gg*Kvry{B%GS!f zKOv0jTGz%P)zzy1wPLm|2b*me`I3t%tJ9a)#Aqpg-rD^4(6t&Lh7r*g=s&U4ah+Jr zWNi4)31Wbb58w$uSO6Ca`}do->ZGl?rACS+$XX^e+3&Px%b!3>>*yv$&?rNBT8zC2 zgDmWV-gaB)v>;-E{OS$*rKgsCfS!5fi)EzIKh>L9Bos&bwBbmmg`7x%^F6h42 z=>vv9X)sr`qToqwZ8AjpEU{{pqNi5cS>;^Ur+X3`YR-CF`P@NAN>+U-ZZ|>LVhil@ ztrD$fkk=g{jVdJ-nHF=0mb~B#

`8UwL*81La3a#eG`XSF(3^XcJKCI({T0c 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 diff --git a/routes/api.php b/routes/api.php index 62cc75d..3c462a3 100644 --- a/routes/api.php +++ b/routes/api.php @@ -2,7 +2,10 @@ use App\Http\Controllers\CollectionController; use App\Http\Controllers\FileController; +use App\Models\File; +use Illuminate\Http\UploadedFile; use Illuminate\Support\Facades\Route; +use Illuminate\Support\Facades\Storage; /* |-------------------------------------------------------------------------- @@ -19,10 +22,16 @@ use Illuminate\Support\Facades\Route; // return $request->user(); // }); +Route::get('newTmp/{uuid}', function ($uuid) { + $file = File::find($uuid); + return Storage::disk('local')->temporaryUrl($file->server_path . $file->uuid . '.webp', now()->addMinutes(5),['collection_name'=>'Paris Renner II']); +})->name('newTmp'); + + Route::group(['as' => 'api.'], function () { Route::apiResource('collections', CollectionController::class); Route::delete('collections/{collection}', [CollectionController::class, "destroy"])->withTrashed(); - Route::get('{collection_name}/{uuid}.{extention}', [FileController::class, 'show'])->name('file.show'); - Route::get('{collection_name}/{path}', [FileController::class, 'private'])->name('file.private'); - Route::post('{collection_name}/{model_id?}', [FileController::class, 'store'])->name('file.store'); + // Route::get('{collection_name}/{uuid}.{extention}', [FileController::class, 'show'])->name('files.show'); + Route::get('{collection_name}/{path}', [FileController::class, 'private'])->name('files.private'); + Route::post('{collection_name}/{model_id?}', [FileController::class, 'store'])->name('files.store'); }); diff --git a/routes/web.php b/routes/web.php index 0958771..e4a55a9 100644 --- a/routes/web.php +++ b/routes/web.php @@ -21,17 +21,14 @@ use Jcupitt\Vips\Utils; | contains the "web" middleware group. Now create something great! | */ -Route::get('/fuck.webp',function(Request $request,ImageProcessor $imageProcessor) +Route::get('/fuck',function(Request $request,ImageProcessor $imageProcessor) { - $option = [ - 'w' => $request->w, - 'h' => $request->h, - 'r' => $request->r, - 'canv' => $request->canv, - ]; - $imageProcessor->process(public_path('image.png'),public_path('image-modified.webp'),$option); - - return response()->file(public_path('image-modified.webp')); + $image = Image::thumbnail(storage_path('stub') . '/image.png', getimagesize(storage_path('stub') . '/image.png')[1]); + $image->writeToFile(public_path(). '/fuck.jpg',['Q'=> 100]); + // $imageProcessor->process(public_path('image.png'),public_path('image-modified.webp')); + + // return response()->file(storage_path('stub') . '/image.png'); + return response()->file(public_path(). '/fuck.jpg'); }); Route::get('/', function (Request $request) { diff --git a/storage/image-modified.webp b/storage/image-modified.webp deleted file mode 100644 index fa30048b116655ec8a22a41d3abc86931f69630a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 43934 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 diff --git a/tests/Feature/FileStoreTest.php b/tests/Feature/FileStoreTest.php index 40f826f..3083266 100644 --- a/tests/Feature/FileStoreTest.php +++ b/tests/Feature/FileStoreTest.php @@ -3,11 +3,13 @@ namespace Tests\Feature; use App\Http\Controllers\Traits\FileTrait; +use App\Image\ImageProcessor; use App\Models\Collection; use App\Models\File; use Illuminate\Foundation\Testing\RefreshDatabase; use Illuminate\Foundation\Testing\WithFaker; use Illuminate\Http\UploadedFile; +use Illuminate\Support\Facades\Storage; use Tests\Bootstrap; use Tests\TestCase; use Illuminate\Support\Str; @@ -28,8 +30,8 @@ class FileStoreTest extends Bootstrap $collection = Collection::factory()->create([ 'tmp_support' => false ]); - $response = $this->loginAs('dick')->postJson(route('api.file.store', ['collection_name' => $collection->name]), $data); + $response = $this->postJson(route('api.files.store', ['collection_name' => $collection->name]), $data); $response->assertForbidden(); } @@ -40,7 +42,7 @@ class FileStoreTest extends Bootstrap 'tmp_support' => false, 'count' => $randomCount ]); - for($i=$randomCount; $i > 0; $i--) { + for ($i = $randomCount; $i > 0; $i--) { $uuid = app()->uuid; $this->one(File::class, [ 'uuid' => $uuid, @@ -56,17 +58,15 @@ class FileStoreTest extends Bootstrap "description" => 'lfjdsklfslfsdlfasdfsfhgsfgsdf', "public" => 1 ]; - $response = $this->loginAs('dick')->postJson(route('api.file.store', ['collection_name' => $collection->name]), $data); + $response = $this->postJson(route('api.files.store', ['collection_name' => $collection->name]), $data); $response->assertForbidden(); } public function test_file_is_not_isset_forbidden() { - $collection = Collection::factory()->create([ 'tmp_support' => true ]); - $data = [ "file" => app()->uuid, "alts" => ['1', '2', '3'], @@ -74,11 +74,29 @@ class FileStoreTest extends Bootstrap "public" => 1 ]; - $response = $this->loginAs('dick')->postJson(route('api.file.store', ['collection_name' => $collection->name]), $data); - + $response = $this->postJson(route('api.files.store', ['collection_name' => $collection->name]), $data); $response->assertForbidden(); } + public function test_user_can_not_access_not_ownered_files() + { + $collection = Collection::factory()->createQuietly(); + $uuid = app()->uuid; + $file = File::factory()->createQuietly([ + 'uuid' => $uuid, + 'user_id' => auth()->id() + 1234, + 'server_path' => '/' . date('y') . '/' . date('m') . '/', + 'collection_id' => $collection->id + ]); + + $data = [ + "file" => $file->uuid, + "public" => 1 + ]; + + $response = $this->postJson(route('api.files.store', ['collection_name' => $collection->name]), $data); + $response->assertForbidden(); + } /** * @dataProvider storeValidationTestProvider @@ -86,7 +104,7 @@ class FileStoreTest extends Bootstrap public function test_store_dynamic_validation_unprocessable($collectionFields, $dataFields) { $collection = Collection::factory()->create($collectionFields); - $response = $this->loginAs('dick')->postJson(route('api.file.store', ['collection_name' => $collection->name]), $dataFields); + $response = $this->postJson(route('api.files.store', ['collection_name' => $collection->name]), $dataFields); $response->assertUnprocessable(); } @@ -104,10 +122,34 @@ class FileStoreTest extends Bootstrap // } - public function test_store_dynamic_validation_stored_file_unprocessable() + /** + * @dataProvider storeValidationTestProvider + */ + public function test_store_dynamic_validation_stored_file_unprocessable($collectionFields) { + $collection = Collection::factory()->createQuietly($collectionFields); + $uuid = app()->uuid; + $file = File::factory()->createQuietly([ + 'uuid' => $uuid, + 'server_path' => '/' . date('y') . '/' . date('m') . '/', + 'user_id' => auth()->id(), + 'collection_id' => $collection->id + ]); + $imageProcessor = new ImageProcessor; + $imageProcessor->createFakeImage(storage_path('stub') . '/image.png', Storage::disk($collection->disk)->path($file->server_path . $uuid . '.' . $collection->ext)); - $collection = Collection::factory()->create([ + $data = [ + "file" => $file->uuid, + "public" => 1 + ]; + + $response = $this->postJson(route('api.files.store', ['collection_name' => $collection->name]), $data); + $response->assertUnprocessable(); + } + + public function test_user_can_store_sent_file_count_multiple_without_image_processor_ok() + { + $collection = Collection::factory()->createQuietly([ 'alt_required' => false, 'description_required' => false, 'tmp_support' => true, @@ -118,21 +160,112 @@ class FileStoreTest extends Bootstrap 'min_file_size' => 0 ]); $uuid = app()->uuid; - $file = File::factory()->createImage(storage_path('app/' . date('y') . '/' . date('m') . '/' . $uuid . '.' . $collection->ext))->create([ + $this->one(File::class, [ 'uuid' => $uuid, + 'user_id' => auth()->id(), + 'collection_id' => $collection->id, 'server_path' => '/' . date('y') . '/' . date('m') . '/', + ]); + + $data = [ + "file" => UploadedFile::fake()->image('test.png'), + "public" => 1 + ]; + $response = $this->postJson(route('api.files.store', ['collection_name' => $collection->name]), $data); + $response->assertCreated(); + } + + public function test_user_can_store_sent_file_uuid_count_multiple_without_image_processor_ok() + { + $collection = Collection::factory()->createQuietly([ + 'alt_required' => false, + 'description_required' => false, + 'tmp_support' => true, + 'max_width' => 2000, + 'max_height' => 2000, + 'min_width' => 1, + 'min_height' => 1, + 'min_file_size' => 0 + ]); + $uuid = app()->uuid; + $file = File::factory()->createQuietly([ + 'uuid' => $uuid, + 'server_path' => '/' . date('y') . '/' . date('m') . '/', + 'user_id' => auth()->id(), 'collection_id' => $collection->id ]); + $imageProcessor = new ImageProcessor; + $imageProcessor->createFakeImage(storage_path('stub') . '/image.png', Storage::disk($collection->disk)->path($file->server_path . $uuid . '.' . $collection->ext)); $data = [ "file" => $file->uuid, - "alts" => ['1', '2', '3'], - "description" => 'lfjdsklfslfsdlfasdfsfhgsfgsdf', "public" => 1 ]; - $response = $this->loginAs('dick')->postJson(route('api.file.store', ['collection_name' => $collection->name]), $data); + $response = $this->postJson(route('api.files.store', ['collection_name' => $collection->name]), $data); + $response->assertCreated(); + } - $response->assertUnprocessable(); + public function test_user_can_store_sent_file_count_one_without_image_processor_ok() + { + $collection = Collection::factory()->createQuietly([ + 'alt_required' => false, + 'description_required' => false, + 'tmp_support' => true, + 'max_width' => 2000, + 'max_height' => 2000, + 'min_width' => 1, + 'min_height' => 1, + 'min_file_size' => 0 + ]); + $uuid = app()->uuid; + $file = File::factory()->createQuietly([ + 'uuid' => $uuid, + 'server_path' => '/' . date('y') . '/' . date('m') . '/', + 'user_id' => auth()->id(), + 'collection_id' => $collection->id + ]); + $imageProcessor = new ImageProcessor; + $imageProcessor->createFakeImage(storage_path('stub') . '/image.png', Storage::disk($collection->disk)->path($file->server_path . $uuid . '.' . $collection->ext)); + + $data = [ + "file" => $file->uuid, + "public" => 1 + ]; + + $response = $this->postJson(route('api.files.store', ['collection_name' => $collection->name]), $data); + $response->assertCreated(); } + + public function test_user_can_store_sent_file_uuid_count_one_without_image_processor_ok() + { + $collection = Collection::factory()->createQuietly([ + 'alt_required' => false, + 'description_required' => false, + 'tmp_support' => true, + 'max_width' => 2000, + 'max_height' => 2000, + 'min_width' => 1, + 'min_height' => 1, + 'min_file_size' => 0 + ]); + $uuid = app()->uuid; + $file = File::factory()->createQuietly([ + 'uuid' => $uuid, + 'server_path' => '/' . date('y') . '/' . date('m') . '/', + 'user_id' => auth()->id(), + 'collection_id' => $collection->id + ]); + $imageProcessor = new ImageProcessor; + $imageProcessor->createFakeImage(storage_path('stub') . '/image.png', Storage::disk($collection->disk)->path($file->server_path . $uuid . '.' . $collection->ext)); + + $data = [ + "file" => $file->uuid, + "public" => 1 + ]; + + $response = $this->postJson(route('api.files.store', ['collection_name' => $collection->name]), $data); + $response->assertCreated(); + } + }