dvamigos / yii2-notifications
Yii 2+ 的通知系统
Requires
- php: >=7.0
- yiisoft/yii2: 2.0.*
Suggests
- guzzlehttp/guzzle: Required when using AndroidFcmTarget (version ^6.3.3)
This package is not auto-updated.
Last update: 2024-09-29 09:52:38 UTC
README
Yii 2+ 的通知系统
使用方法
默认存储为您的数据库。为此,您需要从 src/migrations 文件夹中插入迁移。
要插入这些迁移,您需要运行迁移命令
yii migrate --migrationPath=@vendor/dvamigos/yii2-notifications/src/migrations
这将创建数据库中的 notification 表。如果您不打算在数据库中存储通知,则此步骤不是必需的。
在您的应用程序配置中添加通知组件配置
[
'components' => [
'notifications' => [
'class' => '\dvamigos\Yii2\Notifications\NotificationManager',
'types' => [
'text' => [
'my_notification' => 'This is my notification'
]
]
]
]
]
然后在您的代码中,您可以直接使用以下方式发送通知
Yii::$app->notifications->push('my_notification');
这将保存当前登录用户的通知。
通知类型
您可以为您的通知定义任意数量的类型,以便存储所需的数据。
以下是一个具有 title 和 message 的示例通知。
[
'components' => [
'notifications' => [
'class' => '\dvamigos\Yii2\Notifications\NotificationManager',
'types' => [
'new_user' => [
'text' => [
'title' => 'New user created!',
'message' => 'New user {username} is created.'
],
'default' => [
'username' => ''
]
]
]
]
]
]
字段 {username} 将在创建通知时从传递给通知的数据中替换。
要传递数据,只需使用以下方式
Yii::$app->notifications->push('new_user', [ 'username' => 'JohnDoe94' ]);
您不必始终将所有必要的键传递到数据中。如果您不传递所需的键,则其值将从该通知的 'default' 中获取。
您还可以使用此数组传递任何可以序列化为 JSON 字符串的任意信息,从而有效地存储显示或使用通知所需的任何所需数据。
在模型/控制器/组件中使用
您可以在具有 events() 函数的每个组件中使用 PushNotification、UpdateNotification 或 ReplaceNotification 类。
要包含 events() 函数,请使用 EventListAwareTrait。
例如,要在模型中设置它,可以定义以下内容
public function events() { self::EVENT_AFTER_INSERT => [ new \dvamigos\Yii2\Notifications\events\PushNotification([ 'type' => 'my_notification', 'data' => ['my_data' => 1] ]) ] }
类型可以在之后解决
public function events() { self::EVENT_AFTER_INSERT => [ new \dvamigos\Yii2\Notifications\events\PushNotification([ 'type' => function(PushNotification $n) { return 'my_type'; }, 'data' => function(PushNotification $n) { return ['my_key' => $this->getPrimaryKey()]; } ]) ] }
如果您希望使用行为方法,这也可以通过 NotificationBehavior 类实现。
要使用该类,您可以在支持行为的模型/组件中简单添加
public function behaviors() { return [ 'notification' => [ 'class' => \dvamigos\Yii2\Notifications\events\NotificationBehavior::class, 'events' => [ self::EVENT_AFTER_INSERT => [ [ 'class' => \dvamigos\Yii2\Notifications\events\PushNotification, 'type' => function(PushNotification $n) { return 'my_type'; }, 'data' => function(PushNotification $n) { return ['my_key' => $this->getPrimaryKey()]; } ] ] ] ] ]; }
如果您想封装自己的逻辑,那么通过扩展 \dvamigos\Yii2\Notifications\events\PushNotification 来创建自己的类也是可能的。
示例
class MyNotification extends \dvamigos\Yii2\Notifications\events\PushNotification { public $type = 'my_notification_type'; public function init() { $this->data = [$this, 'handleMyData']; parent::init(); } public function handleMyData(MyNotification $instance, \yii\base\Event $event) { // You logic for returning data here... } }
public function behaviors() { return [ 'notification' => [ 'class' => \dvamigos\Yii2\Notifications\events\NotificationBehavior::class, 'events' => [ self::EVENT_AFTER_INSERT => [ MyNotification::class ] ] ] ]; }
然后您可以简单地添加以下通知
多个目标
在发送通知时,您可以定义多个目标,从而有效地同时向手机设备、数据库等推送通知。
您的默认目标是数据库,但您可以使用以下方式定义自己的目标
[
'components' => [
'notifications' => [
'class' => '\dvamigos\Yii2\Notifications\NotificationManager',
'activeTarget' => ['database', 'android', 'ios'],
'targets' => [
'database' => [
'class' => '\dvamigos\Yii2\Notifications\targets\DatabaseTarget',
// ... config
],
'android' => [
'class' => '\dvamigos\Yii2\Notifications\targets\AndroidFcmTarget',
'apiKey' => 'YOUR API KEY',
'tokenRetriever' => function(NotificationInterface $n) {
return $n->getData()['fcmToken'];
}
],
'ios' => [
'class' => '\dvamigos\Yii2\Notifications\targets\IosApnTarget',
'pemFile' => '@app/path/to/your/pem/file.pem',
'password' => 'yourpassphrase',
'tokenRetriever' => function(NotificationInterface $n) {
return $n->getData()['iosToken'];
}
]
],
'types' => [
'new_user' => [
'text' => [
'title' => 'New user created!',
'message' => 'New user {username} is created.'
],
'default' => [
'username' => '',
'fullName' => 'Unknown',
'gender' => 'male'
]
]
]
]
]
]
注意
请注意,Android 和 iOS 目标是 WIP 且未完全测试,可能无法正常工作。
使用上述配置,当调用以下内容时
Yii::$app->notifications->push('new_user', [ 'username' => 'JohnDoe94', 'fcmToken' => "Your user's android notification token", 'iosToken' => "Your user's ios notification token" ]);
您将向数据库、您的用户的 Android 设备和 iOS 设备发送通知。
您可以在任何时间切换目标
Yii::$app->notification->pushTarget('database'); // Will only send to database. Yii::$app->notification->pushTarget('android'); // Will only send to android. Yii::$app->notification->pushTarget(['android', 'ios']); // Will only send to android and ios targets. // Send notification to android/ios Yii::$app->notification->popTarget(); // restores previous target - 'android' // Send notification to android Yii::$app->notification->popTarget(); // restores previous target - 'database' // Send notification to database Yii::$app->notification->popTarget(); // restores previous target - as defined in initial configuration.
请注意,您应该使用 popTarget() 来恢复旧的行为。例如
Yii::$app->notification->pushTarget(['android', 'ios']); // Will only send to android and ios targets. // send notification Yii::$app->notification->popTarget(); // restores previous active target.
您可以使用以下方式调用特定的目标
Yii::$app->notification->getTarget('database'); // Returns DatabaseTarget
或者您可以使用 forTargets() 在特定目标上执行命令
Yii::$app->notification->forTargets(['ios', 'android'], function(NotificationManager $manager) { $manager->push('notification'); // Will only push notification to ios, android ]);
令牌检索
由于某些目标在发送通知时需要额外的令牌数据,因此您可以根据每个目标需要哪些令牌来实现自己的令牌检索逻辑。
令牌检索器可以是一个 callable 闭包
[
'components' => [
'notifications' => [
'class' => '\dvamigos\Yii2\Notifications\NotificationManager',
'activeTarget' => ['database', 'android', 'ios'],
'targets' => [
'android' => [
'class' => '\dvamigos\Yii2\Notifications\targets\AndroidFcmTarget',
'apiKey' => 'YOUR API KEY',
'tokenRetriever' => function(NotificationInterface $n) {
return $n->getData()['fcmToken'];
}
]
],
]
]
tokenRetriever 可调用将在每次发送通知时需要令牌时调用。
tokenRetriever 也可以是一个实现了 dvamigos\Yii2\Notifications\TokenRetrievalInterface 的类。
类
class MyTokenRetrieval extends BaseObject implements dvamigos\Yii2\Notifications\TokenRetrievalInterface { public $target; protected $cachedTokens = []; // This example assumes you have UserTokens ActiveRecord // which has columns: user_id, type, token // And that will be used to retrieve user's token. public function getToken(NotificationInterface $n) { // This will cache tokens so that you dont need to // hit database for every notification. if (!empty($this->cachedTokens[$n->getUserId()])) { return $this->cachedTokens[$n->getUserId()]; } // Returns and caches token. return $this->cachedTokens[$n->getUserId()] = UserTokens::find() ->where([ 'user_id' => $n->getId(), 'type' => $this->target ]) ->select('token') ->scalar() ?: ''; } }
配置
[
'components' => [
'notifications' => [
'class' => '\dvamigos\Yii2\Notifications\NotificationManager',
'activeTarget' => ['database', 'android', 'ios'],
'targets' => [
'android' => [
'class' => '\dvamigos\Yii2\Notifications\targets\AndroidFcmTarget',
'apiKey' => 'YOUR API KEY',
'tokenRetriever' => [
'class' => MyTokenRetrieval::class,
'target' => 'android'
]
],
'ios' => [
'class' => '\dvamigos\Yii2\Notifications\targets\IosApnTarget',
'pemFile' => '@app/path/to/your/pem/file.pem',
'password' => 'yourpassphrase',
'tokenRetriever' => [
'class' => MyTokenRetrieval::class,
'target' => 'ios'
]
]
],
]
]
显示通知
您可以使用 NotificationList 小部件来显示您的通知。
请注意,根据您的使用情况,您需要配置此小部件以满足您的需求。此小部件假定您的组件名称为 notification,尽管您可以在小部件创建期间传递不同的名称。
您需要使用此小部件指定通知的模板。
以下是一个简单列表的示例,其中通知被定义为。
[
'components' => [
'notifications' => [
'class' => '\dvamigos\Yii2\Notifications\NotificationManager',
'types' => [
'new_user' => [
'text' => [
'title' => 'New user created!',
'message' => 'New user {username} is created.'
],
'default' => [
'username' => '',
'fullName' => 'Unknown',
'gender' => 'male'
]
]
]
]
]
]
<?= \dvamigos\Yii2\Notifications\widgets\NotificationList::widget([ 'containerTemplate' => '<ul>{notifications}{emptyText}</ul>', 'emptyText' => '<li>No notifications available.</li>', 'itemTemplate' => ' <li> <span class="title">{text.title}</span> <span class="message">{text.message}</span> <span class="at">{timestamp}</span> </li> ' ]); ?>
也支持自定义部分。您可以定义它们为
<?= \dvamigos\Yii2\Notifications\widgets\NotificationList::widget([ 'containerTemplate' => '<ul>{notifications}{emptyText}</ul>', 'emptyText' => '<li>No notifications available.</li>', 'itemTemplate' => ' <li> <span class="title">{text.title}</span> <span class="message">{text.message}</span> <span class="message">User full name: {section.fullName}</span> </li> ', 'sections' => [ 'fullName' => function($context) { /** @var \dvamigos\Yii2\Notifications\NotificationInterface $n */ $n = $context['notification']; if ($n->getType() !== 'new_user') { return ''; } return $n->getData()['fullName']; } ] ]); ?>
请参考代码中的 NotificationList 文档以获取有关可用信息的更多信息。
最佳实践是扩展此 NotificationList 小部件以适应您自己的,并根据您自己的项目需求实现此功能。