11. Управление постами. Часть 3

app/Models/Post.php

В app/Models/Post.php добавим несколько функций:

protected $fillable = ['title', 'description', 'content', 'category_id', 'thumbnail'];

public static function uploadImage(Request $request, $image = null) {
    if ($request->hasFile('thumbnail')) {
        if ($image) {
            Storage::delete($image); // удаляем
        }
        $folder = date('Y-m-d');
        return $request->file('thumbnail')->store("images/{$folder}");
    }
    return null;
}

public function getImage() {
    if ($this->thumbnail) {
        return asset("/uploads/{$this->thumbnail}");
    }
    return asset("no-image.jpg");
}

 

Найдем картинку и поместим ее в public/no-image.jpg . Картинка обозначает, что изображение отсутствует.

edit.blade.php

Скопируем весь код из create.blade.php в edit.blade.php и изменим его, получится так:

@extends('admin.layouts.layout');

@section('content')
    <!-- Content Header (Page header) -->
    <section class="content-header">
        <div class="container-fluid">
            <div class="row mb-2">
                <div class="col-sm-6">
                    <h1>Редактирование статьи</h1>
                </div>
                <div class="col-sm-6">
                    <ol class="breadcrumb float-sm-right">
                        <li class="breadcrumb-item"><a href="#">Статья "{{ $post->title }}"</a></li>
                        <li class="breadcrumb-item active">Редактирование статьи</li>
                    </ol>
                </div>
            </div>
        </div><!-- /.container-fluid -->
    </section>

    <!-- Main content -->
    <section class="content">
        <form action="{{ route('posts.update', ['post' => $post->id]) }}" method="post" enctype="multipart/form-data">
            @csrf
            @method('PUT')
            <div class="card-body">
                <div class="form-group">
                    <label for="title">Статья</label>
                    <input type="text" class="form-control @error('title') is-invalid @enderror" id="title"
                           value="{{ $post->title }}" autocomplete="off" name="title">
                </div>
                <div class="form-group">
                    <label for="description">Цитата</label>
                    <textarea name="description" class="form-control @error('description') is-invalid @enderror" rows="3" id="description">{{ $post->description }}</textarea>
                </div>
                <div class="form-group">
                    <label for="content">Контент</label>
                    <textarea name="content" class="form-control @error('content') is-invalid @enderror" rows="10" id="content">{{ $post->content }}</textarea>
                </div>
                <div class="form-group">
                    <label for="category_id">Категория</label>
                    <select name="category_id" id="category_id" class="form-control @error('category_id') is-invalid @enderror">
                        @foreach ($categories as $k => $v)
                            <option value="{{ $k }}" @if ($k == $post->category_id) selected @endif>{{ $v }}</option>
                        @endforeach
                    </select>
                </div>
                <div class="form-group">
                    <label for="tags">Тэги</label>
                    <select name="tags[]" id="tags" class="select2 @error('tags') is-invalid @enderror" multiple="multiple" data-placeholder="Выберите тэги"
                            style="width: 100%;">
                        @foreach ($tags as $k => $v)
                            <option value="{{ $k }}" @if (in_array($k, $post->tags->pluck('id')->all())) selected @endif>{{ $v }}</option>
                        @endforeach
                    </select>
                </div>
                <div class="form-group">
                    <label for="thumbnail">Выберите изображение</label>
                    <div class="input-group">
                        <div class="custom-file">
                            <input type="file" name="thumbnail" class="custom-file-input @error('thumbnail') is-invalid @enderror" id="thumbnail">
                            <label class="custom-file-label" for="thumbnail">Выберите файл</label>
                        </div>
                    </div>
                </div>
                <img src="{{ $post->getImage() }}" class="img-thumbnail" width="250" alt="Image">
                <div class="card-footer">
                    <button type="submit" class="btn btn-primary">Сохранить</button>
                </div>
            </div>
        </form>
    </section>
    <!-- /.content -->
@endsection

app/Http/Controllers/Admin/PostController.php

<?php

namespace App\Http\Controllers\Admin;

use App\Http\Controllers\Controller;
use App\Models\Category;
use App\Models\Post;
use App\Models\Tag;
use Illuminate\Http\Request;
use Illuminate\Http\Response;
use Illuminate\Support\Facades\Storage;

class PostController extends Controller
{
    /**
     * Display a listing of the resource.
     *
     * @return Response
     */
    public function index()
    {
        $posts = Post::with('tags', 'category')->paginate(10);
        return view('admin.posts.index', compact('posts'));
    }

    /**
     * Show the form for creating a new resource.
     *
     * @return Response
     */
    public function create()
    {
        $categories = Category::pluck('title', 'id')->all();
        $tags = Tag::pluck('title', 'id')->all();
        return view('admin.posts.create', compact('categories', 'tags'));
    }

    /**
     * Store a newly created resource in storage.
     *
     * @param \Illuminate\Http\Request $request
     * @return Response
     */
    public function store(Request $request)
    {
        $request->validate([
            'title' => 'required',
            'description' => 'required',
            'content' => 'required',
            'category_id' => 'integer', // значит, что параметр обязательный и он должен быть integer
            'thumbnail' => 'nullable|image', // значит, что параметр не обязательный, но это должна быть картинка
        ]);

        $data = $request->all();

        // сохраняем изображение
        $data['thumbnail'] = Post::uploadImage($request);

        $post = Post::create($data);

        /*
         * используем https://laravel.com/docs/8.x/eloquent-relationships#syncing-associations
         * для вставки уникальных связи в post_tag таблицу
         */
        $post->tags()->sync($data['tags']);

        return redirect()->route('posts.index')->with('success', 'Статья добавлена!');
    }

    /**
     * Show the form for editing the specified resource.
     *
     * @param int $id
     * @return Response
     */
    public function edit($id)
    {
        $categories = Category::pluck('title', 'id')->all();
        $tags = Tag::pluck('title', 'id')->all();
        $post = Post::find($id);
        return view('admin.posts.edit', compact('post', 'tags', 'categories'));
    }

    /**
     * Update the specified resource in storage.
     *
     * @param \Illuminate\Http\Request $request
     * @param int $id
     * @return Response
     */
    public function update(Request $request, $id)
    {
        $request->validate([
            'title' => 'required',
            'description' => 'required',
            'content' => 'required',
            'category_id' => 'integer', // значит, что параметр обязательный и он должен быть integer
            'thumbnail' => 'nullable|image', // значит, что параметр не обязательный, но это должна быть картинка
        ]);

        $data = $request->all();

        $post = Post::find($id);

        // удаляем старое и сохраняем новое изображение
        $thumbnail = Post::uploadImage($request, $post['thumbnail']);

        if ($thumbnail) {
            $data['thumbnail'] = $thumbnail;
        }

        $post->update($data);

        if (isset($data['tags'])) {
            $post->tags()->sync($data['tags']);
        }

        return redirect()->route('posts.edit', $post->id)->with('success', 'Статья изменена!');
    }

    /**
     * Remove the specified resource from storage.
     *
     * @param int $id
     * @return Response
     */
    public function destroy($id)
    {
        $post = Post::find($id);
        $post->tags()->sync([]); // удаляем тэги
        Storage::delete($post->thumbnail);
        $post->delete();
        return redirect()->route('posts.index')->with('success', 'Статья удалена!');
    }
}

 

0 0 голоса
Рейтинг статьи
Подписаться
Уведомить о
guest

0 комментариев
Межтекстовые Отзывы
Посмотреть все комментарии