Проблема заключалась в том, что UploadedFile (то, что вы получаете из запроса на загрузку) не сериализуем и поэтому не может быть обработан заданием.Поэтому мне пришлось создать новую модель + таблицу для временного хранения изображения.
Способ изображения следующий:
- храниться локально как файл
- создать новый экземпляр временной модели
- передать эту модель в задание
- заново создать изображение типа UploadedFile и обработать изображение (создать четыре разрешения и загрузить его в цифровой океан)
- удалить локальный файл
- удалить временную модель
Новая модель:
use App\DBEntities\MasterEntity;
class VehicleImageForJob extends MasterEntity
{
protected $guarded = ['id'];
}
Новая таблица:
class CreateVehicleImageForJobsTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('vehicle_image_for_jobs', function (Blueprint $table) {
$table->increments('id');
$table->string('file');
$table->string('mime_type');
$table->string('original_name');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('vehicle_image_for_jobs');
}
}
Новый диск вfilesystem.php:
'vehicle_image_temp' => [
'driver' => 'local',
'root' => storage_path('app/vehicle_images/temp')
]
Модифицированный контроллер:
protected function uploadSingleImage(UploadedFile $image)
{
$disk = 'vehicle_image_temp';
$path = $image->store("/", [
'disk' => $disk
]);
$vehicleImageForJob = VehicleImageForJob::create([
'file' => $path,
'mime_type' => $image->getMimeType(),
'original_name' => $image->getClientOriginalName()
]);
VehicleImageUploaderJob::dispatch($vehicleImageForJob, $this->getVehicle());
}
Модифицированное задание:
class VehicleImageUploaderJob implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
protected $vehicle;
protected $image;
protected $disk = 'vehicle_image_temp';
/**
* VehicleImageUploaderJob constructor.
* @param VehicleImageForJob $image
* @param Vehicle $vehicle
*/
public function __construct(VehicleImageForJob $image, Vehicle $vehicle)
{
$this->vehicle = $vehicle;
$this->image = $image;
}
/**
* @param UploadedFile $image
* @throws \Exception
*/
public function handle()
{
$image = new UploadedFile(storage_path("app/vehicle_images/temp/{$this->image->file}"),
$this->image->original_name,
$this->image->mime_type,
null,
null,
true
);
$disk = FilesystemHelper::getDisk('producerData');
$originalName = basename($image->getClientOriginalName(), '.'.$image->getClientOriginalExtension());
$extension = $image->getClientOriginalExtension();
$dbImage = new Image();
// Store image in original size
$path = $image->storeAs(
'producers/' . $this->getVehicle()->producer->id . '/vehicles/' . $this->getVehicle()->id, // Folder or Directory
$image->getClientOriginalName(), // File Name
$disk // Disk
);
Storage::disk($disk)->setVisibility($path, 'public');
$dbImage->original = $path;
$dbImage->disk = $disk;
$file = ImageManipulator::make($image);
foreach(config('images.vehicles.formats') as $format => $values){
$file->backup();
$fileName = $originalName . '-' . str_random(6) . '-' . $values['width'] . 'x' . $values['height'] . '.' . $extension;
if($format === 'thumbnail'){
$file->fit($values['width'],$values['height'])
->save();
} else {
$file->fit($values['width'], $values['height'], function ($constraint) {
$constraint->aspectRatio();
$constraint->upsize();
})->save();
}
$path = $image->storeAs(
'producers/' . $this->getVehicle()->producer->id . '/vehicles/' . $this->getVehicle()->id, // Folder or Directory
$fileName, // File Name
$disk // Disk
);
Storage::disk($disk)->setVisibility($path, 'public');
$dbImage->{$format} = $path;
$file->reset();
}
$dbImage->save();
$this->getVehicle()->images()->attach($dbImage->id);
$this->getVehicle()->save();
Storage::disk($this->disk)->delete($this->image->file);
$this->image->delete();
}
protected function getVehicle(): Vehicle
{
if($this->vehicle instanceof Vehicle){
return $this->vehicle;
} else {
throw new \Exception("Vehicle not set on ImageUploaderJob");
}
}
}