Уведомления — это как сигнал светофора для вашего приложения: без них пользователь блуждает в темноте, не понимая, что произошло. Сегодня разберем, как построить удобную систему уведомлений на Yii2, которая не заставит вас краснеть перед заказчиком. Вы узнаете, как сделать флеш-сообщения, отправлять письма и даже телеграм-сообщения — и всё это без лишней магии.

Digital-студия WNDER

Флеш-сообщения: база, которую нужно знать

Начнем с простого. Флеш-сообщения — это одноразовые уведомления, которые показываются пользователю после действия (например, после сохранения формы). В Yii2 они реализованы из коробки, но многие используют их неправильно.

Секрет в том, что флеш-сообщения хранятся в сессии и исчезают после первого отображения. Это идеально для подтверждения действий. Вот как это выглядит в контроллере:

public function actionCreate()
{
    $model = new Post();
    if ($model->load(Yii::$app->request->post()) && $model->save()) {
        Yii::$app->session->setFlash('success', 'Пост успешно создан!');
        return $this->redirect(['view', 'id' => $model->id]);
    }
    return $this->render('create', ['model' => $model]);
}

А в представлении (например, в layout) выводим:

<?php foreach (Yii::$app->session->getAllFlashes() as $key => $message): ?>
    <div class="alert alert-<?= $key ?>"><?= $message ?></div>
<?php endforeach; ?>
Правило: Всегда используйте именованные флеш-сообщения (например, 'success', 'error'), чтобы легко стилизовать их в CSS. Не смешивайте типы — это запутает пользователя.

Создаем компонент уведомлений: когда флешей мало

Флеши хороши, но что если нужно отправить уведомление на почту или в Telegram? Или сохранить историю уведомлений в базе? Тогда нужен отдельный компонент. Давайте создадим сервис, который будет управлять всеми типами уведомлений.

Создаем файл components/NotificationService.php:

namespace app\components;

use Yii;
use yii\base\Component;

class NotificationService extends Component
{
    public function send($userId, $type, $message, $data = [])
    {
        // Логируем в базу (если нужно)
        // Отправляем email
        // Отправляем в Telegram
        // И т.д.
    }
}

Регистрируем его в конфигурации приложения (например, в config/web.php):

'components' => [
    'notification' => [
        'class' => 'app\components\NotificationService',
    ],
],

Теперь в любом месте можно вызвать:

Yii::$app->notification->send($user->id, 'new_message', 'Вам пришло новое сообщение');

Email-уведомления: шлем письма через Yii2

Email — классика. В Yii2 есть встроенный компонент mailer, который поддерживает SwiftMailer и Symfony Mailer. Настроим его в config/web.php:

'mailer' => [
    'class' => 'yii\swiftmailer\Mailer',
    'useFileTransport' => false, // false для реальной отправки
    'transport' => [
        'class' => 'Swift_SmtpTransport',
        'host' => 'smtp.gmail.com',
        'username' => 'your_email@gmail.com',
        'password' => 'your_password',
        'port' => '587',
        'encryption' => 'tls',
    ],
],

Теперь в нашем сервисе добавим метод для отправки письма:

public function sendEmail($to, $subject, $body)
{
    return Yii::$app->mailer->compose()
        ->setFrom(['noreply@example.com' => 'My App'])
        ->setTo($to)
        ->setSubject($subject)
        ->setHtmlBody($body)
        ->send();
}

Совет: для тестов используйте useFileTransport = true — тогда письма будут сохраняться в файл, а не улетать в космос.

Telegram-уведомления: добавляем мессенджер

Телеграм — это быстро и удобно. Чтобы отправлять сообщения, нужен бот и его токен. Создаем бота через @BotFather, получаем токен, а затем пишем метод:

public function sendTelegram($chatId, $message)
{
    $token = 'YOUR_BOT_TOKEN';
    $url = "https://api.telegram.org/bot{$token}/sendMessage";

    $data = [
        'chat_id' => $chatId,
        'text' => $message,
    ];

    $options = [
        'http' => [
            'header' => "Content-Type: application/x-www-form-urlencoded\r\n",
            'method' => 'POST',
            'content' => http_build_query($data),
        ],
    ];

    $context = stream_context_create($options);
    file_get_contents($url, false, $context);
}

Или, что лучше, используем библиотеку telegram-bot/api через Composer:

composer require telegram-bot/api

Тогда код станет чище:

use Telegram\Bot\Api;

$telegram = new Api('YOUR_BOT_TOKEN');
$telegram->sendMessage([
    'chat_id' => $chatId,
    'text' => $message,
]);

База данных для уведомлений: храним историю

Если нужно хранить уведомления, создадим таблицу и модель. Вот миграция:

$this->createTable('notification', [
    'id' => $this->primaryKey(),
    'user_id' => $this->integer()->notNull(),
    'type' => $this->string(50)->notNull(),
    'message' => $this->text()->notNull(),
    'data' => $this->json(),
    'is_read' => $this->boolean()->defaultValue(false),
    'created_at' => $this->timestamp()->defaultExpression('NOW()'),
]);

Модель Notification и запись в сервисе:

public function send($userId, $type, $message, $data = [])
{
    $model = new Notification();
    $model->user_id = $userId;
    $model->type = $type;
    $model->message = $message;
    $model->data = $data;
    $model->save();

    // Дополнительно: отправка email/telegram
    $this->sendEmail(...);
    $this->sendTelegram(...);
}

Теперь можно выводить список уведомлений в интерфейсе и помечать прочитанными.

Практические советы и лайфхаки

Соберем несколько важных моментов, которые пригодятся в бою.

Тип уведомления Когда использовать Сложность реализации
Флеш-сообщения Подтверждение действий, ошибки форм Низкая
Email Важные события, рассылки Средняя
Telegram Срочные уведомления, админ-оповещения Средняя
База данных История, личный кабинет Высокая (но гибкая)
Лайфхак: Чтобы не дублировать код, создайте единый интерфейс для всех каналов. Например, каждый канал — класс с методом send($message). Тогда легко добавлять новые каналы (например, Slack) без изменения основной логики.

Что в итоге

Мы разобрали, как сделать систему уведомлений на Yii2 с нуля. Начинали с простых флеш-сообщений, затем создали компонент-сервис, подключили email и Telegram, а также научились хранить уведомления в базе. Теперь вы можете выбрать нужный уровень сложности под свою задачу.

Главное — не перегружайте пользователя. Уведомления должны быть полезными и своевременными. И помните: хорошая система уведомлений — это как вежливый официант, который вовремя подскажет, что блюдо готово.

Студия WNDER