Метод viewAny
Метод viewAny класса Policy определяет, может ли текущий пользователь просматривать список моделей определённого типа. Он автоматически вызывается при проверке права на просмотр коллекции моделей через фасад Gate или вспомогательные функции can и cannot. Первым параметром метод принимает объект текущего пользователя, реализующий интерфейс Authenticatable. Метод должен возвращать логическое значение true или false.
Синтаксис
<?php
namespace AppPolicies;
use AppModelsUser;
use AppModelsPost;
class PostPolicy
{
public function viewAny(User $user): bool
{
// logic here
}
}
?>
Пример
Давайте создадим политику для модели Post и определим в ней метод viewAny, который разрешает просмотр списка только администраторам:
<?php
namespace AppPolicies;
use AppModelsUser;
use AppModelsPost;
class PostPolicy
{
public function viewAny(User $user): bool
{
return $user->role === 'admin';
}
}
?>
Теперь проверим работу политики в контроллере:
<?php
namespace AppHttpControllers;
use AppModelsPost;
use IlluminateSupportFacadesAuth;
class PostController extends Controller
{
public function index()
{
if (Auth::user()->can('viewAny', Post::class)) {
$posts = Post::all();
return view('posts.index', ['posts' => $posts]);
}
abort(403, 'Unauthorized action.');
}
}
?>
Пример
Давайте используем метод viewAny для проверки права на просмотр списка в Blade-шаблоне:
@can('viewAny', AppModelsPost::class)
<h1>Posts List</h1>
@foreach ($posts as $post)
<div>
<h2>{{ $post->title }}</h2>
<p>{{ $post->text }}</p>
</div>
@endforeach
@endcan
@cannot('viewAny', AppModelsPost::class)
<p>You do not have permission to view posts.</p>
@endcannot
Пример
Рассмотрим более сложный пример, где метод viewAny проверяет, принадлежит ли пользователь к определённой группе:
<?php
namespace AppPolicies;
use AppModelsUser;
use AppModelsPost;
class PostPolicy
{
public function viewAny(User $user): bool
{
$allowedRoles = ['admin', 'editor', 'moderator'];
return in_array($user->role, $allowedRoles);
}
}
?>
Проверим право через фасад Gate:
<?php
namespace AppHttpControllers;
use AppModelsPost;
use IlluminateSupportFacadesGate;
class PostController extends Controller
{
public function index()
{
if (Gate::allows('viewAny', Post::class)) {
$posts = Post::paginate(10);
return view('posts.index', compact('posts'));
}
return redirect()->route('home')->with('error', 'Access denied.');
}
}
?>
Пример
Давайте используем метод viewAny вместе с дополнительной проверкой через middleware:
<?php
namespace AppHttpControllers;
use AppModelsPost;
use IlluminateHttpRequest;
class PostController extends Controller
{
public function __construct()
{
$this->middleware('can:viewAny,' . Post::class)->only('index');
}
public function index()
{
$posts = Post::with('user')->latest()->get();
return view('posts.index', ['posts' => $posts]);
}
}
?>
Результат выполнения запроса для пользователя с ролью 'admin':
["Post 1", "Post 2", "Post 3", "Post 4", "Post 5"]
Результат выполнения запроса для пользователя с ролью 'guest':
"Redirecting to home with error: Access denied."