Подтверждение регистрации

Добавление статуса ожидания и активности пользователя. Реализация команды подтверждения регистрации по токену из ссылки в электронном письме.

Скрытый контент
Комментарии (8)
Denis
2020-01-27 19:33

Я немного не понял зачем в конструкторе по умолчанию ставить статус? А если мне потребуется из массива заполнить класс User данными? Получается, что статус будет не активный, но а пользователь на самом деле активен. Т.е. через конструктор я не смогу указать текущий статус? Поясните, пожалуйста, в чем дело.

Ответить
Deworker Pro
2020-01-27 20:57

А если мне потребуется из массива заполнить класс User данными?

Конструктор используется по назначению только для первого создания объекта. Как и другие методы он содержит свою бизнес-логику, по которой может присваивать первоначальные значения, бросать исключения и генерировать события.

В случае же восстановления объекта по массиву из БД конструктор не используют. Вместо этого объект там создаётся без конструктора и заполняется данными прямо в приватные поля через рефлексию.

Например, пишем гидратор или находим любой готовый вроде такого:

class Hydrator
{
    public function hydrate(string $class, array $data): object
    {
        $reflection = new \ReflectionClass($class);
        $target = $reflection->newInstanceWithoutConstructor();
        foreach ($data as $name => $value) {
            $property = $reflection->getProperty($name);
            $property->setAccessible(true);
            $property->setValue($target, $value);
        }
        return $target;
    }
}

и с помощью него десериализуем объект текущими данными из БД:

$row = $stmt->fetch(PDO::FETCH_ASSOC);

$user = $this->hydrator->hydrate(User::class, [
    'id' => new Id($row['id']),
    'status' => new Status($row['status']),
]);

Если же нужно просто в разных юзкейсах создавать объект по-разному, то в этом случае можно сделать несколько именованных конструкторов, как мы делали в видео о конструкторах. В будущем эпизоде про регистрацию через соцсети мы сделаем именно так.

Ответить
Denis
2020-01-28 06:54

Спасибо за ответ. Сегодня обязательно видео посмотрю.

Ответить
Сергей
2020-02-12 07:50

Всем привет. Дмитрий, добрый день. Вот у меня такой вопрос возник. У нас хендлеры не могут быть описаны каким-то единым интерфейсом, т.к. на вход принимают разные команды. Точнее можно сделать команды , реализующие некий интерфейс или унаследованные от какой-то абстрактной команды, но тут уже будет какой-то костыль.

И вот у меня возникла потребность задекорировать все хендлеры, добавив логирование начала и конца работы каждого хендлера. Как-то это можно реализовать без костылей?

Ответить
Deworker Pro
2020-02-14 06:55

В языках с дженериками можно указать общий интерфейс.

interface Handler<T> {
    public void handle(<T> command)
}

В PHP без шаблонов это пока не работает.

В любом языке можно сделать свой интерфейс CommandBus для запуска команд и декорировать уже шину. В PHP можно взять league/tactician и реализовать логирование через middleware в ней.

Ответить
Сергей
2020-03-20 09:11

Не подскажете еще как быть с автовайрингом? Пытался внедрить симфонячий мессенджер. Указал в конфиге

MessageBusInterface::class => static function (ContainerInterface $container): MessageBusInterface {
    return new MessageBus([
        new HandleMessageMiddleware(new HandlersLocator([
            EmissionCommand::class => [$container->get(EmissionHandler::class)],
            TransferCommand::class => [$container->get(TransferHandler::class)],
        ])),
    ]);
}

Но если в хендлер внедряется MessageBusInterface, то получается Circular dependency. И вот что-то ума не приложу как эту беду победить.

Ответить
Deworker Pro
2020-03-20 13:24

Переделать Locator на доставание хендлера только по требованию:

new HandlersLocator([
    EmissionCommand::class => EmissionHandler::class,
    TransferCommand::class => TransferHandler::class,
], $container)
Ответить
Сергей
2020-03-20 14:52

Спасибо, Дмитрий. Пришлось переписать локатор и всё заработало.

Ответить
Зарегистрируйтесь или войдите чтобы оставить комментарий