Skip to content

Commit

Permalink
Merge pull request #19 from Vitaliy1995/develop/hw-6.4
Browse files Browse the repository at this point in the history
Домашняя работа 6.4
  • Loading branch information
Vitaliy1995 authored Oct 26, 2021
2 parents c1cefe6 + 55845fd commit f3dbf9b
Show file tree
Hide file tree
Showing 18 changed files with 415 additions and 29 deletions.
89 changes: 89 additions & 0 deletions app/Http/Controllers/AdminPostsController.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
<?php

namespace App\Http\Controllers;

use App\Article;
use App\Http\Requests\ArticlePostRequest;
use App\Services\TagsSynchronizer;
use App\Tag;
use Illuminate\Http\Request;

class AdminPostsController extends Controller
{
private $tagsSynchronizer;

public function __construct(TagsSynchronizer $tagsSynchronizer)
{
$this->middleware('auth');
$this->middleware('can:admin-panel');

$this->tagsSynchronizer = $tagsSynchronizer;
}

public function index()
{
$articles = Article::with('tags')
->latest("updated_at")
->get();

return view("admin.posts.index", compact('articles'));
}

public function create()
{
return view('admin.posts.create');
}

public function store(ArticlePostRequest $request)
{
$validatedData = $request->validated();

if (\request()->has('published')) {
$validatedData['published'] = true;
}

$validatedData['owner_id'] = auth()->id();

$article = Article::create($validatedData);

$this->tagsSynchronizer->sync($article, \request('tags'));

flash('Статья создана успешно!');

return redirect(route('admin.posts.index'));
}

public function show(Article $article)
{
return view("admin.posts.detail", compact('article'));
}

public function edit(Article $article)
{
return view("admin.posts.edit", compact('article'));
}

public function update(Article $article, ArticlePostRequest $request)
{
$validatedData = $request->validated();

$validatedData['published'] = \request()->has('published');

$article->update($validatedData);

$this->tagsSynchronizer->sync($article, \request('tags'));

flash('Статья успешно обновлена!');

return redirect(route('admin.posts.index'));
}

public function destroy(Article $article)
{
$article->delete();

flash('Статья успешно удалена!', 'warning');

return redirect(route('admin.posts.index'));
}
}
39 changes: 18 additions & 21 deletions app/Http/Controllers/ArticleController.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,23 +4,37 @@

use App\Article;
use App\Http\Requests\ArticlePostRequest;
use App\Services\TagsSynchronizer;
use App\Tag;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Gate;

class ArticleController extends Controller
{
public function __construct()
private $tagsSynchronizer;

public function __construct(TagsSynchronizer $tagsSynchronizer)
{
$this->middleware('auth', ['except' => ['index', 'show']]);
$this->middleware('can:update,article')->except(['index', 'show', 'create', 'store']);

$this->tagsSynchronizer = $tagsSynchronizer;
}

public function index()
{
$articles = Article::with('tags')
->latest("updated_at")
->where('published', 1)
->get();

$articles = $articles->filter(function ($article) {
if (Gate::allows('update', [\auth()->user(), $article])) {
return true;
}

return $article->published === 1;
});

return view("index", compact('articles'));
}

Expand All @@ -41,7 +55,7 @@ public function store(ArticlePostRequest $request)

$article = Article::create($validatedData);

$this->syncTagsWithArticle($article, \request('tags'));
$this->tagsSynchronizer->sync($article, \request('tags'));

flash('Статья создана успешно!');

Expand All @@ -68,7 +82,7 @@ public function update(Article $article, ArticlePostRequest $request)

$article->update($validatedData);

$this->syncTagsWithArticle($article, \request('tags'));
$this->tagsSynchronizer->sync($article, \request('tags'));

flash('Статья успешно обновлена!');

Expand All @@ -83,21 +97,4 @@ public function destroy(Article $article)

return redirect(route('posts.index'));
}

private function syncTagsWithArticle(Article $article, $tags)
{
/** @var \Illuminate\Support\Collection $articleTags */
$articleTags = $article->tags->keyBy('name');
$formTags = collect(explode(",", $tags))->keyBy(function ($item) {return $item;});

$syncIds = $articleTags->intersectByKeys($formTags)->pluck('id')->toArray();

$tagsToAttach = $formTags->diffKeys($articleTags);
foreach ($tagsToAttach as $tag) {
$tag = Tag::firstOrCreate(['name' => $tag]);
$syncIds[] = $tag->id;
}

$article->tags()->sync($syncIds);
}
}
6 changes: 6 additions & 0 deletions app/Http/Controllers/TreatmentController.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,12 @@

class TreatmentController extends Controller
{
public function __construct()
{
$this->middleware('auth')->except(['add']);
$this->middleware('can:admin-panel')->except(['add']);
}

public function index()
{
$treatments = Treatment::latest('created_at')->get();
Expand Down
2 changes: 1 addition & 1 deletion app/Policies/ArticlePolicy.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,6 @@ class ArticlePolicy

public function update(User $user, Article $article)
{
return $article->owner_id === $user->id;
return $article->owner_id === $user->id || $user->isAdmin();
}
}
14 changes: 13 additions & 1 deletion app/Providers/AuthServiceProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,11 @@

namespace App\Providers;

use App\User;
use Illuminate\Foundation\Support\Providers\AuthServiceProvider as ServiceProvider;
use Illuminate\Support\Facades\App;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Blade;
use Illuminate\Support\Facades\Gate;

class AuthServiceProvider extends ServiceProvider
Expand All @@ -27,8 +30,17 @@ public function boot(\Illuminate\Contracts\Auth\Access\Gate $gate)
$this->registerPolicies();

$gate->before(function ($user) {
if ($user->id === 1)
if ($user->isAdmin()) {
return true;
}
});

Gate::define('admin-panel', function (User $user) {
return $user->isAdmin();
});

Blade::if('admin', function () {
return Auth::check() && Auth::user()->isAdmin();
});
}
}
18 changes: 18 additions & 0 deletions app/Role.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Role extends Model
{
const ADMIN = 1;
const BASE = 2;

protected $guarded = [];

public function users()
{
return $this->belongsToMany(User::class);
}
}
29 changes: 29 additions & 0 deletions app/Services/TagsSynchronizer.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<?php


namespace App\Services;


use App\Article;
use App\Tag;
use Illuminate\Support\Collection;

class TagsSynchronizer
{
public function sync(Article $article, $tags)
{
/** @var Collection $articleTags */
$articleTags = $article->tags->keyBy('name');
$formTags = collect(explode(",", $tags))->keyBy(function ($item) {return $item;});

$syncIds = $articleTags->intersectByKeys($formTags)->pluck('id')->toArray();

$tagsToAttach = $formTags->diffKeys($articleTags);
foreach ($tagsToAttach as $tag) {
$tag = Tag::firstOrCreate(['name' => $tag]);
$syncIds[] = $tag->id;
}

$article->tags()->sync($syncIds);
}
}
12 changes: 12 additions & 0 deletions app/User.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use Illuminate\Support\Facades\DB;

class User extends Authenticatable
{
Expand Down Expand Up @@ -37,8 +38,19 @@ class User extends Authenticatable
'email_verified_at' => 'datetime',
];

public function roles()
{
return $this->belongsToMany(Role::class);
}

public static function admin()
{
return self::where('email', config('mail.admin_mail'))->first();
}

public function isAdmin()
{
return (bool)$this->belongsToMany(Role::class)
->wherePivot('role_id', Role::ADMIN);
}
}
32 changes: 32 additions & 0 deletions database/migrations/2021_10_18_094319_create_roles_table.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<?php

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

class CreateRolesTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('roles', function (Blueprint $table) {
$table->id();
$table->string('name')->unique();
$table->timestamps();
});
}

/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('roles');
}
}
34 changes: 34 additions & 0 deletions database/migrations/2021_10_18_094445_create_role_user_table.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<?php

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

class CreateRoleUserTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('role_user', function (Blueprint $table) {
$table->unsignedBigInteger('user_id');
$table->unsignedBigInteger('role_id');
$table->primary(['user_id', 'role_id']);
$table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
$table->foreign('role_id')->references('id')->on('roles')->onDelete('cascade');
});
}

/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('role_user');
}
}
Loading

0 comments on commit f3dbf9b

Please sign in to comment.