Чат Telegram
Группа ВКонтакте
Новый комментарий


Kirill.K 17.10.2018 в 20:35

ArticlesController/edit:

if(!$this->user->isAdmin()) {
            throw new Forbidden('Для редактирования статьи нужно обладать правами администратора');
        }

Templates/articles/view:

<?php if(isset($_COOKIE['token']) and $user->isAdmin()): ?>
    <p><a href="http://myproject.loc/articles/<?= $article->getId() ?>/edit">Редактировать статью</a></p>
<? endif; ?>
ivashkevich 19.10.2018 в 00:23
isset($_COOKIE['token'])

Этого достаточно, чтобы знать, что пользователь залогинен? А если в этой куке ерунда какая-нибудь бессмысленная записана? Тогда $user будет null, и при попытке вызвать у него метод произойдет ошибка.

Kirill.K 19.10.2018 в 19:10

Хм... тогда, наверное, так:

<?php if($_COOKIE['token'] === $user->getId() . ':' . $user->getAuthToken() and $user->isAdmin()): ?>
    <p><a href="http://myproject.loc/articles/<?= $article->getId() ?>/edit">Редактировать статью</a></p>
<? endif; ?>

Громоздко, конечно, как то получается...

ivashkevich 19.10.2018 в 21:58

Да нет, все проще. Если пользователь не авторизован, то в $user будет null.
Достаточно проверить:

if ($user !== null && $user->isAdmin())
ilyaOrlov 02.12.2018 в 21:54

Проверил свой код несколько раз. Всё так, как вы написали. Но при редактировании, если передавать какое-то поле пустым, то вылетает ошибка о том, что $article->getId() становится null в шаблоне edit.php. Решил проблему передачей вместе с ошибкой еще и массива $article.

$this->view->renderHtml('articles/edit.php', ['error' => $e->getMessage(), 'article' => $article]);

Тогда все работает. В чем проблема, не подскажите?

ivashkevich 02.12.2018 в 22:58

Была ошибка, исправил. Спасибо. В шаблоне использовалась $article, я почему-то подумал, что если произойдет ошибка, то в шаблоне мы статью не будем выводить.

Metey 27.07.2019 в 19:27

При попытке обновления статьи НЕ админом – бросайте исключение ForbiddenException, как в прошлом уроке.

 public function edit(int $articleId): void
    { 
        $article = Article::getById($articleId);
        if ($article === null) {
            throw new NotFoundException();
        }
        if ($this->user === null) {
            throw new UnauthorizedException();
        }
        if (!$this->user->isAdmin()) {
            throw new ForbiddenException('Для доступа к данной странице необходимы права администратора!');
        }
    ......

Добавьте ссылку на странице показа статьи с текстом «Редактировать», которая будет вести на страницу редактирования этой статьи.
Сделайте так, чтобы эта ссылка показывалась только если пользователь залогинен и он админ.

<h1><?= $article->getName() ?></h1>
    <p><?= $article->getText() ?></p>
    <p>Автор: <?= $article->getAuthor()->getNickname() ?></p>

    <?if ($user!==null && $user->isAdmin()):?>
    <p><a href="/articles/<?= $article->getId() ?>/edit">Редактировать</a></p>
    <?endif?>
ivashkevich 28.07.2019 в 13:38

Отлично

Iliusha99 03.08.2019 в 17:57

Добавил метод в модель Юзера:

public function allowEdit(): bool
    {
        if ($this === null || $this->getRole() !== 'admin') {
            return false;
        }
        return true;
    }

В ArticleControllers при попытке переходить по ссылке ред. :

if (!$this->user->allowEdit()) {
            throw new AccessForbidden();
        }

И в шаблоне в зависимости от значения $user->allowEdit() решаем показать <<Редактировать>> или нет :

<?php if($user->allowEdit()):?> <p><a href="<?= $article->getId() ?>/edit">Редактировать</a></p> <?php endif; ?>
ivashkevich 03.08.2019 в 20:39

$this === null - такого не бывает. Если есть $this, значит есть объект. null там быть не может

ivashkevich 03.08.2019 в 20:42
public function allowEdit(): bool
    {
        if ($this === null || $this->getRole() !== 'admin') {
            return false;
        }
        return true;
    }

Сокращается до

public function allowEdit(): bool
    {
        return $this->getRole() === 'admin';
    }

А вообще, метод для проверки возможности редактирования должен быть у статьи, а не у пользователя. В этот метод аргументом должен передаваться объект пользователя, права которого нужно проверить.

Iliusha99 03.08.2019 в 20:44

ок, поправлю

ivashkevich 03.08.2019 в 20:44

В шаблон лучше передавать уже готовую переменную, которая будет говорить о том, разрешено ли редактирование статьи, например, isEditable. Эта переменная должна формироваться в контроллере и передаваться во view.

Moskva 07.08.2019 в 18:24

1.ArticlesConroller.php

...
if(!$this->user->IsAdmin()){
            throw new ForbiddenException();
        }
...

2-3.view.php

...
<? if(!empty($user) && ($user->isAdmin())): ?>
    <hr>
    <div style="text-align: right;"><a href="/articles/<?= $article->getId()?>/edit">Редактировать</a><div>
<? endif; ?>
...
ivashkevich 07.08.2019 в 18:57

if(!$this->user->IsAdmin()) - имена методов пишутся с маленькой буквы!

Moskva 08.08.2019 в 20:17

Не уследил, спасибо.

artemship 06.09.2019 в 18:21

articles/view.php

<?php if ($isEditable): ?>
    <p><a href="/articles/<?= $article->getId() ?>/edit">Редактировать</a></p>
<?php endif; ?>

ArticlesController

    public function edit(int $articleId): void
    {
    ...
        if (!$this->user->isAdmin()) {
            throw new ForbiddenException('Статьи могут редактировать только администраторы');
        }
    ...

    public function view(int $articleId): void
    {
    ...
        if ($this->user === null) {
            $isEditable = false;
        } else {
            $isEditable = ($this->user->isAdmin());
        }

        $this->view->renderHtml('articles/view.php', [
            'article' => $article,
            'isEditable' => $isEditable
        ]);
    ...

Тут вопрос: можно ли в экшене view проверку заменить на

        if ($this->user !== null) {
            $isEditable = ($this->user->isAdmin());
        }

В таком случае в методе $this->view->renderHtml высвечивается предупреждение, что переменная $isEditable "might have not been defined". При этом ошибок в рендере шаблона нет. Как лучше поступить?

ivashkevich 08.09.2019 в 09:37
$isEditable = ($this->user->isAdmin())

Для чего скобки?

Ответ на твой вопрос - нет, нельзя. Потому что если пользователь будет не залогинен, возникнет ошибка.

Логические задачи с собеседований