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


Sparkqy 02.10.2018 в 00:26

UsersController

    public function activate(int $userId, string $activationCode)
    {
        try
        {
            $user = User::getById($userId);
        } catch (UserActivationException $e)
        {
            $this->view->renderHtml('mail/userActivationError.php', [
                'error' => $e->getMessage()
            ],422);
            return;
        }

        try
        {
            $isCodeValid = UserActivationService::checkActivationCode($user, $activationCode);
        } catch (UserActivationException $e)
        {
            $this->view->renderHtml('mail/userActivationError.php', [
                'error' => $e->getMessage()
            ],422);
            return;
        }

        if ($isCodeValid) {
            $user->activate();
            echo 'OK!';
            UserActivationService::deleteActivationCode($userId, $activationCode);
        }
    }

UserActivationService

public static function checkActivationCode(User $user, string $code): bool
    {
        $db = Db::getInstance();
        $result = $db->query(
            'SELECT * FROM `' . self::TABLE_NAME . '` WHERE `user_id` = :user_id AND `code` = :code',
            [
                'user_id' => $user->getId(),
                'code' => $code
            ]
        );

        if (!$result)
        {
            throw new UserActivationException('Ошибка активации. Проверочный код не валидный.');
        }

        return !empty($result);
    }

    public static function deleteActivationCode(int $userId, string $activationCode): void
    {
        $db = Db::getInstance();
        $db->query(
            'DELETE FROM `' . self::TABLE_NAME . '` WHERE `user_id` = :userId AND `code` = :activationCode;', [
                ':userId' => $userId,
                ':activationCode' => $activationCode,
            ]
        );
    }

Так же для проверки на "если в ссылку активации подставить несуществующего пользователя" в методе getById бросаю исключение при получении пустого массива после запроса в БД. \
Все верно?

ivashkevich 02.10.2018 в 22:45
    public function activate(int $userId, string $activationCode)
    {
        try {
            $user = User::getById($userId);
        } catch (UserActivationException $e)

Неправильно - в процессе получения пользователя по id никак не должно бросаться исключение с типом UserActivationException. UserActivationException - только для ошибок, связанных с активацией. Само по себе получение пользователя из базы никак не связано с активацией.

echo 'OK!';

а где шаблон для успешного случая?

if (!$result)
        {
            throw new UserActivationException('Ошибка активации. Проверочный код не валидный.');
        }

        return !empty($result);

конкретно здесь !$result и !empty($result) - дадут просто противоположные значения. Не имеет смыла здесь кидать исключение - достаточно только вернуть true или false. Этот метод должен сказать, является ли код валидным или нет. То есть если он невалидный - это не исключительная ситуация, а вполне себе штатная. Поэтому исключение здесь не нужно.

Таким образом, в контроллере вам не нужно ничего ловить, нужно просто проверять пользователя на !== null и то что метод проверки кода вернул true.

Sparkqy 02.10.2018 в 23:13

Согласен, еще не до конца понимаю где кидать и ловить нужно, с простым рендерингом ошибок было легче. Буду разбираться

ivashkevich 03.10.2018 в 10:57

Ничего, я тоже поначалу не понимал, даже когда устраивался на работу - это придет с опытом.

Kirill.K 10.10.2018 в 23:43

UsersActivationService:

    public static function existCode($userId): bool
    {
        $db = Db::getInstance();
        $code = $db->query(
            'SELECT code FROM ' . self::TABLE_NAME . ' WHERE user_id = :user_id',
            [
                'user_id' => $userId
            ]

        );
        return !empty($code);
    }

    public static function deleteActivationCode(int $userId): void
    {
        $db = Db::getInstance();
        $db->query(
            'DELETE FROM ' . self::TABLE_NAME . ' WHERE user_id = :user_id',
            [
                'user_id' => $userId
            ]
        );
    }

Функцию delete провожу без сверки с кодом, так как мы запускаем её непосредственно после проверки кода на валидность, или это открывает возможность появления каких-либо ошибок?

UsrsController:

public function activate(int $userId, string $activationCode)
    {
        try {
            $user = User::getById($userId);
            if ($user === null) {
                throw new ActivateException('Нет такого пользователя');
            }
            if ($user->getIsConfirmed() == 1) {
                throw new ActivateException('Пользователь уже активирован');
            }

            if (!UserActivationService::existCode($userId)) {
                throw new ActivateException('Не создан код активации');
            }

            $isCodeValid = UserActivationService::checkActivationCode($user, $activationCode);
            if ($isCodeValid) {
                $user->activate();
                UserActivationService::deleteActivationCode($userId);
                echo 'OK!';
            } else {
                echo 'Код активации не верен';
            }
        } catch (ActivateException $e) {
            $this->view->renderHtml('errors/noId.php', ['error' => $e->getMessage()]);
            return;
        }
    }

Я пытался учесть замечание Sparky, про то, что Activation-исключение бросается в процессе получения пользователя, но ума не приложу, как сделать правильно... нужно бросать другое исключение? или выносить catch в index?
Ещё не сделал шаблоны, ибо это не сложно, но времяёмко, а уже поздно и пора спать) Поэтому проторопился и сделал просто вывод месаджами(

ivashkevich 12.10.2018 в 09:10

1) Удаление кода без проверки кода в модели - норм. Ошибки вряд ли тут будут.
2) Логику, отвечающую за проверку существования кода можно перенести внутрь UserActivationService::checkActivationCode(). Если кода нет - просто возвращать false, исключение тут не нужно.
3) Исключения вы бросаете в нужном месте. Не надо ничего усложнять, у Вас все просто и понятно.
4) Когда код активации неверен - тоже можно бросить исключение.
5) Структуру кода можно переделать так, что сначала проверяются все исключительные ситуации и бросаются исключения, а затем, если все хорошо, просто работает код для успешного исхода. Суть такая:

if (что-то плохо) {
    бросаем исключение
}

if (что-то другое плохо) {
    бросаем исключение
}

если дошли до сюда, то просто рисуем шаблон, никаких if-ов уже не нужно.
dnldcode 06.03.2019 в 23:11
    public function activate(int $userId, string $activationCode): void
    {
        try {
            $user = User::getById($userId);

            if ($user === null) {
                throw new ActivationException('User was not found');
            }
            if ($user->isActivated()) {
                throw new ActivationException('User is already activated');
            }
            $isCodeValid = UserActivationService::checkActivationCode($user, $activationCode);
            if (!$isCodeValid) {
                throw new ActivationException('Code is not valid');
            }

            $user->activate();
            UserActivationService::removeActivationCode($user);
            $this->view->renderHtml('users/activationSuccess.php');
        } catch (ActivationException $e) {
            $this->view->renderHtml('errors/activationError.php', ['error' => $e->getMessage()], 422);
        }
    }

Вопросы:

  1. Обязательно делать проверку на то что код уже активирован? В нашем случае это же невозможно и делается в виде подстраховки. Лишний код? Хотелось бы детальнее узнать, нужны ли эти дополнительный проверки на каждую функцию делать в будущем?
  2. В методе checkActivationCode обязательно делать проверку на то, существует ли данный код? Ведь если запрос сам не найдет - значит не существует.
ivashkevich 09.03.2019 в 19:21
  1. Такая проверка позволит узнать о возможных ошибках в логике работы программы в других местах. Если пользователь уже активирован, и его пытаются активировать еще раз, говорит о том, что где-то косяк.
  2. А какая там проверка. Там только смотрим, что запрос вернул непустой результат. Как вы и написали.
alepawka 23.03.2019 в 22:18

UserController

public function activate(int $userId, string $activationCode)
    {
        try {
            $user = User::getById($userId);
            if ($user->getConfirmed() === 1) {
                throw new InvalidActivationException('Пользователь уже авторизован');
            }
            $isCodeValid = UserActivationService::checkActivationCode($user, $activationCode);

            if ($isCodeValid) {
                $user->activate();
                UserActivationService::deleteCode($user->getId());

                $this->view->renderHTML('users/successValidation.php');
            } else {
                throw new InvalidActivationException('Произошла ошибка авторизации. Попробуйте снова');
            }
        } catch (InvalidActivationException $e) {
            $this->view->renderHTML('users/UserError.php', ['error' => $e->getMessage()]);
        }
    }

далее, шаблон с ошибками(идентичен 500.php)

<h1>Что то пошло не так...</h1>
<?= $error; ?>

Ну и шаблон успешной авторизации

<?php include __DIR__ . '/../header.php'; ?>
<h1>Вы успешно подтвердили свою почту</h1>
<a href="/">Перейти к просмотру всех статей</a>
<?php include __DIR__ . '/../footer.php'; ?>
ivashkevich 23.03.2019 в 22:35
throw new InvalidActivationException('Пользователь уже авторизован');

В условии проверяется другое.

В остальной логике все ок.

excent63 03.04.2019 в 11:26

Добрый день! Решение д/з:
UserActivationService

    public static function deleteActivationCode(User $user, string $code)
    {
        $db = Db::getInstance();
        $db->query(
            'DELETE FROM ' . self::TABLE_NAME . ' WHERE `user_id` = :user_id AND `code` = :code;',
            [
                ':user_id' => $user->getId(),
                ':code' => $code
            ]
        );
    }

UsersController

...
    public function activate(int $userId, string $activationCode): void
    {
        try {
            $user = User::getById($userId);

            if ($user === null) {
                throw new ActivationException('Пользователь не найден.');
            }

            if ($user->IsConfirmed()) {
                throw new ActivationException('Пользователь уже активирован');
            }

            $isCodeValid = UserActivationService::checkActivationCode($user, $activationCode);

            if (!$isCodeValid) {
                throw new ActivationException('Неверный код активации');
            }

            if ($isCodeValid) {
                $user->activate();
                $this->view->renderHtml('users/successfulActivation.php');
                UserActivationService::deleteActivationCode($user, $activationCode);
                return;
            }

        } catch (ActivationException $e) {
            $this->view->renderHtml('users/nonexistentCode.php', ['error' => $e->getMessage()]);
        }
    }
...

nonexistensCode

<?php include __DIR__ . '/../header.php'; ?>
    <div style="text-align: center;">
        <h1>Не удалось активировать пользователя.</h1><br>
        <?= $error ?>
    </div>
<?php include __DIR__ . '/../footer.php'; ?>

successfulActivation

<?php include __DIR__ . '/../header.php'; ?>
<div style="text-align: center;">
    <h1>Ваша учётная запись успешно активирована!</h1>
    Вы можете перейти на <a href="/">главную страницу</a>.
</div>
<?php include __DIR__ . '/../footer.php'; ?>

Получается вот так?

ivashkevich 03.04.2019 в 22:59

getIsConfirmed() лучше просто isConfirmed(), и возвращаться должно булево значение, а не единичка.
В остальном - отличная домашка!

polvanovv 11.06.2019 в 11:37

Подскажите, в чем проблема? Мой код соответствует коду урока но после перехода по ссылке в письме выдает ошибку:

( ! ) Fatal error: Uncaught TypeError: Argument 1 passed to MyProject\Models\Users\UserActivationService::checkActivationCode() must be an instance of MyProject\Models\Users\User, null given, called in W:\domains\newProject\src\MyProject\Controllers\UserController.php on line 26 and defined in W:\domains\newProject\src\MyProject\Models\Users\UserActivationService.php on line 31

( ! ) TypeError: Argument 1 passed to MyProject\Models\Users\UserActivationService::checkActivationCode() must be an instance of MyProject\Models\Users\User, null given, called in W:\domains\newProject\src\MyProject\Controllers\UserController.php on line 26 in W:\domains\newProject\src\MyProject\Models\Users\UserActivationService.php on line 31

Никак не могу разобраться.

ivashkevich 11.06.2019 в 11:47

Ожидается, что в метод прилетит объект класса User, а прилетел null. Используйте Xdebug, и учитесь читать ошибки, на этом уроке не должно возникать подобных вопросов.

polvanovv 11.06.2019 в 17:00

Проблема была в двух опечатках в sql запросе. Невнимательность = минус день.

ivashkevich 11.06.2019 в 20:33

Со временем научитесь разбираться быстрее)

polvanovv 12.06.2019 в 14:21

1

public static function deleteActivationCode(int $userId, string $code): void
    {
        $db = Db::getInstance();
        $result = $db->query(
            'DELETE FROM `' . self::TABLE_NAME . '` WHERE `code` = :code AND `user_id` = :user_id',
        [
            'user_id' => $userId,
            'code' => $code
        ]
        );
    }

2

public function activate(int $userId, string $activationCode)
    {
        try {
            $user = User::getById($userId);
            if ($user == null){
                throw new UserActivationException('Такого пользователя не существует!');
            }
            if($user->isConfirmed()){
                throw new UserActivationException('Аккаунт уже активирован!');
            }
            if (empty($activationCode)){
                throw new UserActivationException('Время активации аккаунта истекло');
            }
            $isCodeValid = UserActivationService::checkActivationCode($user, $activationCode);
            if ($isCodeValid) {
                $user->activate();
                $this->view->renderHtml('mail/UserActivationSuccessful.php');
                UserActivationService::deleteActivationCode($userId, $activationCode);
            }else{
                throw new UserActivationException('Неверный код активации аккаунта!');
            }
        }catch (UserActivationException $e){
            $this->view->renderHtml('errors/userActivationError.php', ['error' => $e->getMessage(), 422]);
            return;
        }
    }

3

<?php include __DIR__ . '/../header.php'; ?>
    <div style="text-align: center">
        <h2>Поздравляем! Активация аккаунта прошла успешно!</h2>
    </div>
<?php include __DIR__ . '/../footer.php'; ?>
<?php include __DIR__ . '/../header.php'; ?>
<div style="text-align: center">
<h1>Ошибка активации аккаунта: </h1>
<?= $error ?>
</div>
<?php include __DIR__ . '/../footer.php'; ?>

Правильно что надо два шаблона?

ivashkevich 13.06.2019 в 19:39
            if (empty($activationCode)){
                throw new UserActivationException('Время активации аккаунта истекло');
            }

Тут этого быть не должно. Должно быть в вызывающем этот метод коде.

Исключения бросать и тут же ловить в этом же методе - бесполезное занятие. Можно сразу вызывать рисование шаблона с ошибкой и делать return.

2 шаблона - это ок

sirserik 28.06.2019 в 14:23

Доброго времени суток автор, скажите а как все это проверить и настроить на linux ubuntu 19.04 я установил апач c php mysql но письма не отправляются. При поиске в интернет нашел статьи но они очень старые не подскажешь куда смортеть и как фиксить?

ivashkevich 30.06.2019 в 14:57

Погуглите, готовой инструкции на этот случай у меня нет.

Metey 23.07.2019 в 19:01
public function activate(int $userId, string $activationCode)
    {
        $user = User::getById($userId); 
        if ($user === null){ //если пользователя нет - исключение
            throw new \MyProject\Exceptions\UserNotFoundException();
        }
        $isCodeValid = UserActivationService::checkActivationCode($user, $activationCode);
        $isConfirmed = $user->getConfirmed(); // активирован пользователь? - добавил метод в User
        if ($isCodeValid) { //если код есть в базе, то активируем и ок
            $user->activate();
            echo 'OK!';
        }
        elseif ($isConfirmed == 1){ //если кода нет в базе(удален после активации??), но есть актив юзер
            $this->view->renderHtml('users/alreadyActivated.php');//
        }
        else { //если юзер не активный и кода вб азе нет - исключение!
            throw new \MyProject\Exceptions\CodeNotFoundException();
        }
        UserActivationService::deleteActivationCode($user);  //добавил в UserActivationService Метод deleteActivationCode

    }

а это метод deleteActivationCode :

 public static function deleteActivationCode(User $user): void
    {
        $db = Db::getInstance();
        $db->query(
            'DELETE FROM `' . self::TABLE_NAME . '` WHERE user_id = :user_id',
            [':user_id' => $user->getId() ]
        );
    }

вот добавил ловлю исключений в index :

........
$controller = new $controllerName();  
$controller->$actionName(...$matches);
} catch (\MyProject\Exceptions\DbException $e) {
    $view = new \MyProject\View\View(__DIR__ . '/../templates/errors');
    $view->renderHtml('500.php', ['error' => $e->getMessage()], 500);
} catch (\MyProject\Exceptions\NotFoundException $e) {
    $view = new \MyProject\View\View(__DIR__ . '/../templates/errors');
    $view->renderHtml('404.php', ['error' => $e->getMessage()], 404);
} catch (\MyProject\Exceptions\UserNotFoundException $e) {
    $view = new \MyProject\View\View(__DIR__ . '/../templates/errors');
    $view->renderHtml('UserNotFound.php', ['error' => $e->getMessage()], 404);
} catch (\MyProject\Exceptions\CodeNotFoundException $e) {
    $view = new \MyProject\View\View(__DIR__ . '/../templates/errors');
    $view->renderHtml('CodeNotFound.php', ['error' => $e->getMessage()], 404);
}

и вот такие шаблоны добавил для каждого случая :

alreadyActivated.php
<?php include __DIR__ . '/../header.php'; ?>
    <div style="text-align: center;">
        <h1>Пользователь уже активирован!</h1>
    </div>

CodeNotFound.php
<?php include __DIR__ . '/../header.php'; ?>
    <div style="text-align: center;">
        <h1>Код активации не найден!</h1>

    </div>
<?php include __DIR__ . '/../footer.php'; ?>

UserNotFound.php

<?php include __DIR__ . '/../header.php'; ?>
    <div style="text-align: center;">
        <h1>Такого пользователя не существует!</h1>

    </div>
<?php include __DIR__ . '/../footer.php'; ?>
ivashkevich 27.07.2019 в 18:34

В целом хорошо. Шаблоны ошибок все одинаковые, за исключением текста ошибки. Для такого случая можно сделать один шаблон, в котором выводить текст исключения.

Metey 27.07.2019 в 18:57

Спасибо, понял, исправлю

Iliusha99 30.07.2019 в 19:37

Вот так я доработал метод, если ID юзера нет то будет ошибка и соответственно если код не правильный будет тоже ошибка. Шаблон ошибок тот же и в зависимости от ошибки будет меняться в переменную $error.

public function activate(int $userId, string $activationCode)
    {
        try {
            $user = User::getById($userId);

            if ($user === null) {
                throw new UserNotFoundException('Пользователь не найден');
            }

            $isCodeValid = UserActivationService::checkActivationCode($user, $activationCode);
            if ($isCodeValid) {
                $user->activate();

                echo 'OK!';
                return;
            } else {
                throw new IncorrectUserActivationCode('Некорректный код активации');
            }
        } catch (UserNotFoundException $e) {
            $this->view->renderHtml('errors/404.php', ['error' => $e->getMessage()], 404);
        } catch(IncorrectUserActivationCode $e) {
            $this->view->renderHtml('errors/404.php', ['error' => $e->getMessage()], 404);
        }
    }

Удаление производил сразу после активации пользователя при условии что активация произошла успешно:

public static function checkActivationCode(User $user, string $code): bool
    {
        $db = Db::getInstance();
        $result = $db->query(
            'SELECT * FROM ' . self::TABLE_NAME . ' WHERE user_id = :user_id AND code = :code',
            [
                'user_id' => $user->getId(),
                'code' => $code
            ]
        );

        if (!empty($result)) {
            $db->query(
                'DELETE FROM ' . self::TABLE_NAME . ' WHERE user_id = :user_id AND code = :code',
                [
                    'user_id' => $user->getId(),
                    'code' => $code
                ]
            );
        }
        return !empty($result);
    } 
ivashkevich 30.07.2019 в 19:47
            if ($isCodeValid) {
                $user->activate();

                echo 'OK!';
                return;
            } else {
                throw new IncorrectUserActivationCode('Некорректный код активации');
            }

Тут можно инвертировать условие, и код станет с меньшей вложенностью:

            if (!$isCodeValid) {
                throw new IncorrectUserActivationCode('Некорректный код активации');
            }
            $user->activate();
            echo 'OK!';
Iliusha99 30.07.2019 в 19:51

Почему сразу не подумал, спасибо))

ivashkevich 30.07.2019 в 19:52

Придет с практикой, не за что

Iliusha99 30.07.2019 в 19:42

Сразу подумал и сделал отдельный метод для удаления

public static function DeleteUserActivationCode(int $userId, string $activationCode): void
{
    $db = Db::getInstance();
    $db->query(
        'DELETE FROM ' . self::TABLE_NAME . ' WHERE user_id = :user_id AND code = :code',
        [
            'user_id' => $userId,
            'code' => $activationCode
        ]
    );
}

но не знал как будет правильнее, ведь здесь должны тоже получить какое нибудь булевое значение, и подумал что логичнее будет сразу же удалить если активация уже прошла, как прислал выше. Поступил ли я правильно? Если нет, хотелось бы совет в этом направлении. Спасибо))

ivashkevich 30.07.2019 в 19:49

Всё ок, удалять можно сразу после активации. А вот имена методов пишутся с маленькой буквы.

artemship 28.08.2019 в 13:14

UserActivationService.php:

    public static function deleteActivationCode(User $user): void
    {
        $db = Db::getInstance();
        $db->query('DELETE FROM ' . self::TABLE_NAME . ' WHERE user_id = :user_id',
            ['user_id' => $user->getId()]
        );
    }

UsersController.php:

    public function activate(int $userId, string $activationCode): void
    {
        try {
            $user = User::getById($userId);
            if ($user === null) {
                throw new UserActivationException('Пользователь не найден');
            }
            if ($user->isConfirmed()) {
                throw new UserActivationException('Пользователь уже активирован');
            }
            $isCodeValid = UserActivationService::checkActivationCode($user, $activationCode);
            if (!$isCodeValid) {
                throw new UserActivationException('Неверный код активации');
            }
        } catch (UserActivationException $e) {
            $this->view->renderHtml('users/activationFailed.php', ['error' => $e->getMessage()]);
            return;
        }

        $user->activate();
        UserActivationService::deleteActivationCode($user);
        $this->view->renderHtml('users/activationSuccessful.php');
    }

Шаблон activationFailed.php:

<?php include __DIR__ . '/../header.php'; ?>
    <div style="text-align: center;">
        <h1>Не удалось активировать аккаунт</h1>
        <?= $error ?>
    </div>
<?php include __DIR__ . '/../footer.php'; ?>

Шаблон activationSuccessful.php:

<?php include __DIR__ . '/../header.php'; ?>
    <div style="text-align: center;">
        <h1>Активация аккаунта прошла успешно!</h1>
    </div>
<?php include __DIR__ . '/../footer.php'; ?>
ivashkevich 28.08.2019 в 17:55

Нет смысла бросать исключение и тут же его ловить в том же методе. В остальном всё ок

artemship 29.08.2019 в 11:11

Понял, спасибо большое! Вынес catch в index.php:

} catch (UserActivationException $e) {
    $view = new View(__DIR__ . '/../templates/users');
    $view->renderHtml('activation.php', ['error' => $e->getMessage()]);
}

Экшн activate приобрел следующий вид:

    public function activate(int $userId, string $activationCode): void
    {
        $user = User::getById($userId);
        if ($user === null) {
            throw new UserActivationException('Пользователь не найден');
        }
        if ($user->isConfirmed()) {
            throw new UserActivationException('Пользователь уже активирован');
        }
        $isCodeValid = UserActivationService::checkActivationCode($user, $activationCode);
        if (!$isCodeValid) {
            throw new UserActivationException('Неверный код активации');
        }

        $user->activate();
        UserActivationService::deleteActivationCode($user);
        $this->view->renderHtml('users/activation.php');
    }

Ну и объединил в один шаблон activation.php:

<?php include __DIR__ . '/../header.php'; ?>
    <div style="text-align: center;">
        <?php if (!empty($error)): ?>
            <h1>Не удалось активировать аккаунт</h1>
            <?= $error ?>
        <?php else: ?>
            <h1>Активация аккаунта прошла успешно!</h1>
        <?php endif; ?>

    </div>
<?php include __DIR__ . '/../footer.php'; ?>
ivashkevich 30.08.2019 в 04:37

Нет. В index.html его выносить тоже не имело смысла. Такого рода исключения должны бросаться в слое модели и обрабатываться в слое контроллера. Но конкретно здесь не нужно вообще исключений, достаточно if-else использовать для рендеринга разных шаблонов.

artemship 03.09.2019 в 15:01

Ладно, спасибо за ответы! Видимо я не до конца понимаю когда надо использовать исключения, а когда нет. Позже попытаюсь разобраться)

ivashkevich 03.09.2019 в 18:54

Ну, в принципе, первый вариант допустим. Исключения бросаются в исключительных ситуациях - когда дальнейшее выполнение кода не имеет смысла.

artemship 04.09.2019 в 17:29

Попробую еще раз) Убрал исключения, пользовался только if-else. Так норм?

UsersController.php:

public function activate(int $userId, string $activationCode): void
{
    $error = null;
    $user = User::getById($userId);

    if ($user === null) {
        $error = 'Пользователь не найден';
    } elseif ($user->isConfirmed()) {
        $error = 'Пользователь уже активирован';
    } elseif (!UserActivationService::checkActivationCode($user, $activationCode)) {
        $error = 'Неверный код активации';
    } else {
        $user->activate();
        UserActivationService::deleteActivationCode($user);
    }

    $this->view->renderHtml('users/activation.php', ['error' => $error]);
}

UserActivationService.php:

public static function deleteActivationCode(User $user): void
{
    $db = Db::getInstance();
    $db->query('DELETE FROM ' . self::TABLE_NAME . ' WHERE user_id = :user_id',
        ['user_id' => $user->getId()]
    );
}

Шаблон activation.php:

<?php include __DIR__ . '/../header.php'; ?>
    <div style="text-align: center;">
        <?php if (!empty($error)): ?>
            <h1>Не удалось активировать аккаунт</h1>
            <?= $error ?>
        <?php else: ?>
            <h1>Активация аккаунта прошла успешно!</h1>
        <?php endif; ?>
    </div>
<?php include __DIR__ . '/../footer.php'; ?>
ivashkevich 04.09.2019 в 21:24

Отлично)

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