Create a todo for a remote command on Laravel

Salute, Khabrovsk. The following article was written by one of our regular readers and definitely does not claim to be hardcore material, but it may well serve as a tutorial for a beginner. We look forward to hearing your opinion on the article in the comments, and for more hardcore knowledge we invite you to our Framework Laravel course .




Hello everyone! Today, in such a β€œremote” time for everyone, I would like to make out the creation of a simple todo in which you can create your own tasks. It sounds like what is written in the official Laravel documentation, and the way it is - I use their todo as a base, transform it a bit, and the bulk of my story will be about how to create an administrator role and create another ridiculous clone Trello seem very inconsistent .

Create the foundation




As I said, we will take the next guide as a basis . It is very simple and focuses more on working with migrations and routing than on programming controllers and models. Unfortunately, it was not updated from version 5.1, and if you are just starting to program in Laravel on the last 7 version (it was only fresh on March 3), you will not have to write the routing to app/Http/routes.php, but to routes/web.php(this has already changed since version 6 ), and in general, the whole difference ends here. In the end, you should get something like this:



I also changed the layout framework from bootstrap to bulma. Firstly, I like it better, but secondly, I already had the code base of the blade registration templates (although, on the other hand, building up the registration and authorization pages is very simple, I will show how).

This version of the project can be downloaded here in the master branch (and in the new branch you can download the finished application). You can activate it using the following commands, provided that you already have composer and laravel installed:

composer install
//   .env,    .env example,     
php artisan key:generate //  
php artisan serve // 

We create authorization and registration

Out of the box authorizations have changed from version 6. Now for quick creation you need to install a package that can quickly generate controllers and blade templates:

composer install laravel/ui
php artisan ui vue --auth
 

Several new files should appear in your project: an auth subfolder will appear

in the resourses folder , in which there will be blade template files dedicated to authorization, passwords. Initially, the blade templates were made up in bootstrap , however, I transformed them a bit into bulma to keep the css framework common in the project. However, in order to be comfortable using the website, we need a navigation bar. In resources, I created the includes folder , in which I placed the auxiliary files - header and nav . In order not to take up much space, I will say that in the header I had only a head with a bulma connection, and in was the following:nav.blade.php

<nav class="navbar has-background-black-ter" role="navigation" aria-label="main navigation">
  <div class="navbar-brand">
    <a class="navbar-item has-text-white is-size-4" href="/">
      TODO
    </a>
    <a role="button" class="navbar-burger" aria-label="menu" aria-expanded="false">
      <span aria-hidden="true"></span>
      <span aria-hidden="true"></span>
      <span aria-hidden="true"></span>
    </a>
  </div>
  <div class="navbar-menu">
    <div class="navbar-start">
      @if (Auth::check())
      <button type="button" class="button is-primary">
        <!--   ,  ->   -->
        {{{ Auth::user()->name}}}
      </button>
      @else
      <!--    -->
      <a class="navbar-item has-text-danger" href="{{route('register')}}"></a>
      <a class="navbar-item has-text-danger" href="{{route('login')}}"></a>
      @endif
      @if (Auth::check())
      <!--  ,       -->
      <!--      -->

      <a class="navbar-item has-text-danger" href="{{url('/logout') }}" onclick="event.preventDefault();
                  document.getElementById('logout-form').submit();">
         </a>
      <form id="logout-form" action="{{ url('/logout') }}" method="POST" style="display: none;">
        {{ csrf_field() }}
      </form>

      @endif
      </ul>
    </div>

    <div class="navbar-end">
      <!-- navbar items -->
    </div>
  </div>
</nav>
 

We begin to create our architecture


It’s time to discuss the structure of our project already. Then the reader will be able to transform the application to their needs, but now, let's say, I want the application to have one administrator (say, a project manager) who can set and delete tasks, and some kind of team that can see these commands. Of course, it would be quite nice if someone could take tasks and indicate that it was he who performs them, but more on that later.

Okay, that means we will have two groups of users and agree that only authorized users who have been given access will be able to see our task board, and some super administrators can add tasks. Let's get started.

For a little simplification, I decided to split the application into two pages: one on which we will only have tasks without the ability to edit, and the second, which will be available only to the super admin. I decided to name the page available to the team welcome.blade.php:

@include('includes.header')

<body>
    @include('includes.nav')
    <div class="columns is-centered">
        <div class="column is-half">
            <div class="panel">
                <div class="panel-heading">
                     
                </div>

                <div class="panel-body">
                    @foreach ($tasks as $task)
                    <a class="panel-block">
                        <button class="button is-rounded">
                            <span>{{ $task->name }}</span>
                        </button>
                        @endforeach
                </div>
            </div>
        </div>
    </div>
<body>
</html>

This page only lists the tasks. To display it, I will add a new path in web.php:

Route::get('/', function () {
    return view('welcome', [
        'tasks' => Task::orderBy('created_at', 'asc')->get(),
    ]);
});

A template in which we have the same list, but with the ability to edit and add, is called task.blade.php. It is too large, so I will place it under the spoiler:

task.blade.php
@extends('layouts.app')

@section('content')
<div class="columns is-centered">
    <div class="column is-half">
        <div class="panel">
            <div class="panel-heading">
                 
            </div>
            <div class="panel-block">
                @include('common.errors')
                <!--     -->
                <form action="{{ url('task')}}" method="POST">
                    {{ csrf_field() }}

                    <div class="field">
                        <label for="task-name" class="label is-medium"></label>
                        <input type=" text" name="name" id="task-name" class="input is-medium"
                            value="{{ old('task') }}">
                    </div>

                    <div class="field">
                        <button type="submit" class="button is-success">
                            <span class="icon">
                                <i class="fa fa-btn fa-plus">
                            </span></i>
                            <span> </span>
                        </button>
                    </div>
                </form>
            </div>
        </div>

        <!-- Current Tasks -->
        @if (count($tasks) > 0)
        <div class="panel">
            <div class="panel-heading">
                 
            </div>

            <div class="panel-body">
                {{-- <table class="table table-striped task-table">
                    <thead>
                        <th></th>
                        <th> </th>
                    </thead>
                    <tbody> --}}
                @foreach ($tasks as $task)
                <a class="panel-block">
                    <button class="button is-rounded">
                    <span>{{ $task->name }}</span>
                </button>
                    <form action="{{ url('task/'.$task->id) }}" method="POST">
                        {{ csrf_field() }}
                        {{ method_field('DELETE') }}
                        <button type="submit" class="button is-danger">
                            <span class="icon is-small"> <i class="fa fa-btn fa-trash"></i></span>
                            <span>  </span>
                        </button>
                    </form>
                </a>
                @endforeach
            </div>
        </div>
        @endif
    </div>
</div>
@endsection



And this template, like the original tutorial, expands to app/layouts.blade.php:

@include('includes.header')

<body>
    @include('includes.nav')

    @yield('content')

</body>

</html>

Fine! We decided on the appearance, now we can proceed to routing and creating ours middlewares.

First, let's go into the Users model and add new types of users:

const ADMIN_TYPE = 'admin';
const TEAM_TYPE = 'team';
#       :

public function isAdmin(){        
    return $this->type === self::ADMIN_TYPE;
    //        
}

Next, go to the last migration of the users table (database / migrations folder) and add a column with our new data type:

$table->string('type')->default('team');
//  ,         

Next, go through app/Http/Controllers/Auth/RegisterController.phpand edit the create function a little (it also looked a bit different in version 5):

protected function create(array $data)
    {
        return User::create([
            'name' => $data['name'],
            'email' => $data['email'],
            'password' => Hash::make($data['password']),
            'type' => User::TEAM_TYPE,  
        ]);
    }


Ok, then we need to create our middleware for the admin. The easiest way to do this is with the following command:

php artisan make:middleware IsAdmin

I hope you have succeeded. In the folder HTTP/middlewareyou should have appeared isAdmin.php, in which the handle function needs to be edited as follows:

public function handle($request, Closure $next)
    {
        if(auth()->user()->isAdmin()) {
            return $next($request);
        //   , .   -   
    }
        return redirect('/');
    }

Next, we need to register our middleware in app/HTTP/Kernelorder to use it:

protected $routeMiddleware = [
    #  ,      
        is_admin' => \App\Http\Middleware\IsAdmin::class,
];

We transform the dash path into web.php, which should only be able to see the super admin:

Route::get('/dash', function () {
    return view('tasks', [
        'tasks' => Task::orderBy('created_at', 'asc')->get(),
    ]); 
})
->middleware('is_admin')    
->name('admin');

#       

Auth::routes();
Route::post('/logout', 'Auth\LoginController@logout')->name('logout');

It remains to create a custom controller for our administrator:

php artisan make:controller AdminController

Editing:

public function __construct()
    {
        $this->middleware('auth');
    }
    public function admin()
    {
        return view('admin');
    }
 

In order to have the registration of all earned exactly, do not forget to fix the redirect in RouteServiceProvider.phpto app/HTTP/Providersbecause it was originally designed for home pattern:

public const HOME = '/';

Now the administrator can appear only with the help of our assistant in the tinker terminal:

php artisan tinker
use App\User;
User::where('email', 'admin@mail.com')->update(['type' => 'admin']);
//    

That's all. If you want to try the finished application, I’ll repeat the link. Of course, our application cannot be used in production right now, because everyone who registered on the resource will be able to see your tasks. But how will you restrict access?

Perhaps you have corporate mail, and then you can restrict access to the team using regulars in mail validation. Or you can add a check for membership in the team in the same way as the admin, having done similar manipulations. By tradition, I’ll provide some useful links for those who are just going to start mastering Laravel:

β†’ A slightly more detailed article than in the documentation about migrations to Laravel
β†’ A good article on Medium about roles in Laravel
β†’ Laravel 7



Β« Β» Forge/Envoyer.



All Articles