@EVOSandru6

Как в Laravel 5.x инкапсулировать загрузку файлов для разных сущностей или хотя бы в рамках разных действий в контроллере?

Добрый день!

Есть форма _form.blade.php , которую тянут blade представления: create.blade.php и update.blade.php

...
    {{ Form::file('photo') }}
    <img src="/storage/images/articles/{{ $article->photo }}" style="height:50px" alt="">
...


Картинка улетает вместе с формой постом. В методе приведены выводы, которые я распечаю ниже:

class ArticlesController extends Controller
{
    public function update(ArticleRequest $request, Article $article)
    {
        $request = $this->saveImage($request);

        dump($request->all());

        dump($request->photo);

        $article->update($request->all());

        dd($article->photo);

        $this->syncTags($article, $request->input('tag_list'));

        return redirect()->back();
    }

private function saveImage(ArticleRequest $request)
    {

        if ($request->hasFile('photo')) {

            $file = $request->file('photo'); // ->isValid()

            $fileNameWithExt = $file->getClientOriginalName();
            $filename = pathinfo($fileNameWithExt, PATHINFO_FILENAME);
            $extension = $file->getClientOriginalExtension();
            $fileNameToStore = $filename . '_' . time() . '.' . $extension;
            $file->storeAs('public/articles', $fileNameToStore);

        } else {
            $fileNameToStore = 'noimage.jpg';
        }

        $request->photo = $fileNameToStore;

        return $request;

    }

}


Вывод dump и dd

1)
array:7 [▼
"_method" => "PATCH"
"_token" => "YPmvNLjhmoqKdxIt7RL2YbviiIjcfpEdqe0JW7ms"
"name" => "Sleep snow"
"content" => "
Sleep snow in winter night with bears and foxes"
"published_at" => "2017-12-14"
"tag_list" => array:1 [▶]
"photo" => UploadedFile {#238 ▶}
]

2)
"logoct_1513334576.png"

3)
UploadedFile {#238 ▼
-test: false
-originalName: "logoct.png"
-mimeType: "image/png"
-size: 55490
-error: 0
#hashName: null
path: "/tmp"
filename: "phpulvqiE"
basename: "phpulvqiE"
pathname: "/tmp/phpulvqiE"
extension: ""
realPath: "/tmp/phpulvqiE"
aTime: 2017-12-15 10:42:56
mTime: 2017-12-15 10:42:56
cTime: 2017-12-15 10:42:56
inode: 21630383
size: 55490
perms: 0100600
owner: 33
group: 33
type: "file"
writable: true
readable: true
executable: false
file: true
dir: false
link: false
}


Сама картинка загружается, проблема в том, что $article->photo остается пустым.

В методе saveImage я хотел присвоить свойству photo имя картинки, но в итоге в свойство $article->photo попадает UploadedFile объект.

Почему так получается? Я же возвращаю $request в методе saveImage, где переопределено свойство photo.

Не нашел ни одного примера, где бы инкапсулировалась данная логика загрузки.

В Yii2 фреймворке такие вещи скармливаилсь поведениям. В Laravel предполагаю, что возможно должны быть как то задействованы middleware для таких случаев - если вообще вынести загрузку картинки и определения имени для сущности при обновлении и добавлении разных сущностей (Также удаление картинки при удалении сущности).

В свойстве $fillable элемент photo присутствует.

Также правило для картинки есть:

class ArticleRequest extends FormRequest{
...
public function rules()
    {
        return [
...
            'photo'=>'image|nullable|max:1999'
...
        ];
    }
...
}
  • Вопрос задан
  • 282 просмотра
Решения вопроса 1
chupacabramiamor
@chupacabramiamor
Инженегр-программист
Я бы так не делал.
Лучшим на мой взгляд решением было бы как раз скармливание объекта UploadedFile в используемую модель. А в самой модели использовать сеттер этого атрибута для перехвата и преобразования значения.

Выглядеть в модели это будет приблизительно так:
public function setPhotoAttribute($value) {
    if ($value instanceOf UploadedFile) {
            $fileNameWithExt = $value->getClientOriginalName();
            $filename = pathinfo($fileNameWithExt, PATHINFO_FILENAME);
            $extension = $value->getClientOriginalExtension();
            $fileNameToStore = $filename . '_' . time() . '.' . $extension;
            $file->storeAs('public/articles', $fileNameToStore);
            return $this->attributes['photo'] = $fileNameToStore;
    }
}


Исходник нужно проверить. Накидал от руки :)
Ответ написан
Пригласить эксперта
Ответы на вопрос 1
@hakkol
Чтобы изменить свойство у $request нужно использовать merge
$request->merge(['photo' => $fileNameToStore]);
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы