LARAVEL

Третий

LARAVEL

Установка — composer create-project —prefer-dist laravel/laravel laravelblog

 

Что было сделано:

Развернул ларавел, тут есть в папке routes файл web.php и в нем роуты описываются так

Route::get('/admin', \App\Http\Controllers\AdminController::class);

Route::get('/', function () {
    return view('welcome');
});

Route::get('/', \App\Http\Controllers\Main\IndexController::class);

Т.е. по сути либо мы вставляем вторым параметром функцию, либо указываем на контроллер,

где «\App\Http\Controllers\Main\» путь к папке корнтролеру, а в нем есть файл — IndexController, внутри которого такой код:

<?php

namespace App\Http\Controllers\Main;

use App\Http\Controllers\Controller;

class IndexController extends Controller
{
    public function __invoke()
    {
        return view(view:'main.index');
    }
}

где мы создаем класс, наpвание которого = название файла и внутри вызываем view —

‘return view(view:’main.index’);’

Которое находится в resources/views/main/ и там файл index.blade.php

 

Затем мы создали папку в views — layouts, которое содержит шапку и футер сайта (то что подключается на всех страницах)

В папке создали — main.blade.php  , и в нем, там где вставляется разный контент страниц  вызвали функцию

@yield(‘content’)
 <div class="content-wrapper">
   
    @yield('content')
    
    <!-- /.content -->
  </div>

View, которую вызывает контролер, мы добавили функции шаблонизатора:

@extends('layouts.main')

@section('content')
тут то что должно отобразиться
@endsection

Структура папок

 

 

###################################

{{now()}} — хелпер показывает дату текущую

{{now()->year}} — хелпер показывает год

 

 

CRUD

Создаем миграцию и модель

php artisan make:model Category -m — -m чтобы создалась автоматом миграция

 

Файл миграции:

<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

return new class extends Migration
{
    /**
     * Run the migrations.
     */
    public function up(): void
    {
        Schema::create('categories', function (Blueprint $table) {
            $table->id();
            $table->string('title');  - так можно задавать поля для создания в бд
            $table->timestamps();
        });
    }

    /**
     * Reverse the migrations.
     */
    public function down(): void
    {
        Schema::dropIfExists('categories');
    }
};

Затем чтобы как я понял данный файл сделал в бд записи, надо выполнить

php artisan migrate

Видим, что выполнилось:

Затем мы делаем стандартные вещи типа в созданной модели категории пишем код:

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;

class Category extends Model
{
    protected $table = 'categories';
    protected $guarded = false; - говорят обязательно
}

6 видео,  2мин

 

Чел создает какие то инвокбл контроллер,

php artisan make:controller Category/IndexController

Таким образом нафигачил еще кучу контроллеров под любое действие

Причем, внутри контроллеров, сделал 1 функцию invoke как я понял, когда вы контроллере 1 функция, то единственную функцию так называют

<?php

namespace App\Http\Controllers\Category;

use App\Http\Controllers\Controller;
use Illuminate\Http\Request;

class CreateController extends Controller
{
    public function __invoke(){
        
    }
}

Создал кучу роутов для категорий, через группу роутов

Route::group(['prefix'=>'categories'],function(){
    Route::get('/', \App\Http\Controllers\Category\IndexController::class)->name('category.index');
    Route::get('/create', \App\Http\Controllers\Category\CreateController::class)->name('category.create');
    Route::post('/', \App\Http\Controllers\Category\StoreController::class)->name('category.store');
    Route::get('/{category}/edit', \App\Http\Controllers\Category\EditController::class)->name('category.edit');
    Route::get('/{category}', \App\Http\Controllers\Category\ShowController::class)->name('category.show');
    Route::patch('/{category}', \App\Http\Controllers\Category\UpdateController::class)->name('category.update');
    Route::delete('/{category}', \App\Http\Controllers\Category\DeleteController::class)->name('category.delete');
});

Затем сделали view для страниц категорий, взяв дизайн из main

Создаем какие то реквесты:

php artisan make:request Category/StoreRequest, как я понял потому что стор через реквест работает

ПРичем сделали такие правки в обоих файлах реквестов

<?php

namespace App\Http\Requests\Category;

use Illuminate\Foundation\Http\FormRequest;

class UpdateRequest extends FormRequest
{
    /**
     * Determine if the user is authorized to make this request.
     */
    public function authorize(): bool
    {
        return true; - тут
    }

    /**
     * Get the validation rules that apply to the request.
     *
     * @return array<string, \Illuminate\Contracts\Validation\Rule|array|string>
     */
    public function rules(): array
    {
        return [
           'title'=>'required|string'  - тут
        ];
    }
}

Нужно почитать зачем они и что делает public function authorize(): bool

 

 

indexController

<?php

namespace App\Http\Controllers\Category;

use App\Http\Controllers\Controller;
use App\Models\Category;
use Illuminate\Http\Request;

class IndexController extends Controller
{
    public function __invoke()
    {

        $categories = Category::all();
        return view('category.index',compact('categories'));
    }
}

$categories = Category::all();  — магически получает все категории,  и затем как то используем compact

public function __invoke(StoreRequest $request){
    }
как я понял, внутрь инвока можно вставить параметры, и тут вставлен приходящий реквест
StoreController
<?php

namespace App\Http\Controllers\Category;

use App\Http\Controllers\Controller;
use App\Http\Requests\Category\StoreRequest;
use App\Models\Category;
use Illuminate\Http\Request;

class StoreController extends Controller
{
    public function __invoke(StoreRequest $request){
        $data= $request->validated();
        Category::firstOrCreate($data);
        return redirect()->route('category.index');
    }
}

Обрати внимание на лаконичный редирект по имени роута

Как я понял, то что мы передали в компакт в контроллере, становится доступным во вью, например в инщдексном категории мы отображаем категории так

@foreach ($categories as $category)
    <tr>
        <td>{{$category->id}}</td>
        <td>{{$category->title}}</td>
    </tr>
@endforeach

А вот и для чего реквесты, например форму мы отправляем через роут на реквест файл

 <form action="{{route('category.store')}}" method="POST"></form>

12 56 6 урок

 

 

КАк в итоге сделали круд на категорию:

Route::group(['prefix'=>'categories'],function(){
    Route::get('/create', \App\Http\Controllers\Category\CreateController::class)->name('category.create');
    Route::post('/', \App\Http\Controllers\Category\StoreController::class)->name('category.store');
  });

 

Затем есть форма во вьювз, которая отвечает за создание категории

<form action="{{route('category.store')}}" method="POST">
              @csrf - валидация какая то
              <div class="form-group">
                <input type="text" name="title" class="form-control" placeholder="Наименование">
              </div>
              <div class="form-group">
                <input type="submit" class="btn btn-primary" value="Добавить">
              </div>
            </form>

Видим что форма отправиться на роут — category.store, который ведет на контроллер —

App\Http\Controllers\Category\StoreController

Внутри данного контроллера

<?php

namespace App\Http\Controllers\Category;

use App\Http\Controllers\Controller;
use App\Http\Requests\Category\StoreRequest; //- импортируется реквест
use App\Models\Category;
use Illuminate\Http\Request;

class StoreController extends Controller
{
    public function __invoke(StoreRequest $request){
        $data= $request->validated();
        Category::firstOrCreate($data);
        return redirect()->route('category.index');
    }
}

Сам реквест

<?php

namespace App\Http\Requests\Category;

use Illuminate\Foundation\Http\FormRequest;

class StoreRequest extends FormRequest
{
    /**
     * Determine if the user is authorized to make this request.
     */
    public function authorize(): bool
    {
        return true;
    }

    /**
     * Get the validation rules that apply to the request.
     *
     * @return array<string, \Illuminate\Contracts\Validation\Rule|array|string>
     */
    public function rules(): array
    {
        return [
            'title'=>'required|string'
         ];
    }
}