{"id":13606384,"url":"https://github.com/wintercms/wn-notify-plugin","last_synced_at":"2025-05-13T16:31:49.676Z","repository":{"id":52424486,"uuid":"345013947","full_name":"wintercms/wn-notify-plugin","owner":"wintercms","description":"Manage notifications in Winter CMS","archived":false,"fork":false,"pushed_at":"2025-05-05T20:40:38.000Z","size":147,"stargazers_count":3,"open_issues_count":1,"forks_count":4,"subscribers_count":4,"default_branch":"main","last_synced_at":"2025-05-05T21:40:52.840Z","etag":null,"topics":["hacktoberfest"],"latest_commit_sha":null,"homepage":"","language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/wintercms.png","metadata":{"funding":{"github":"wintercms","open_collective":"wintercms"},"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2021-03-06T05:30:07.000Z","updated_at":"2025-05-03T01:50:46.000Z","dependencies_parsed_at":"2024-04-17T05:20:29.473Z","dependency_job_id":"cfd29f6e-8533-445d-b9e5-9b0ebb49291a","html_url":"https://github.com/wintercms/wn-notify-plugin","commit_stats":{"total_commits":54,"total_committers":13,"mean_commits":4.153846153846154,"dds":0.6481481481481481,"last_synced_commit":"341a3d5c8fb1d1a2bb6c6efe0e28358f7ecbfecf"},"previous_names":[],"tags_count":2,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wintercms%2Fwn-notify-plugin","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wintercms%2Fwn-notify-plugin/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wintercms%2Fwn-notify-plugin/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wintercms%2Fwn-notify-plugin/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/wintercms","download_url":"https://codeload.github.com/wintercms/wn-notify-plugin/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":253594063,"owners_count":21933157,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["hacktoberfest"],"created_at":"2024-08-01T19:01:08.700Z","updated_at":"2025-05-13T16:31:49.617Z","avatar_url":"https://github.com/wintercms.png","language":"PHP","readme":"# Notification Engine Plugin\n[![MIT License](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/wintercms/wn-notify-plugin/blob/main/LICENSE)\n\n\u003e**NOTE:** Plugin is currently in Beta status. Proceed with caution.\n\nAdds support for sending notifications across a variety of different channels, including mail, SMS and Slack.\n\nNotifications are managed in the backend area by navigating to *Settings \u003e Notification rules*.\n\n## Installation\n\nThis plugin is available for installation via [Composer](http://getcomposer.org/).\n\n```bash\ncomposer require winter/wn-notify-plugin\n```\n\nAfter installing the plugin you will need to run the migrations and (if you are using a [public folder](https://wintercms.com/docs/develop/docs/setup/configuration#using-a-public-folder)) [republish your public directory](https://wintercms.com/docs/develop/docs/console/setup-maintenance#mirror-public-files).\n\n```bash\nphp artisan migrate\n```\n\n## Notification workflow\n\nWhen a notification fires, it uses the following workflow:\n\n1. Plugin registers associated actions, conditions and events using `registerNotificationRules`\n1. A notification class is bound to a system event using `Notifier::bindEvent`\n1. A system event is fired `Event::fire`\n1. The parameters of the event are captured, along with any global context parameters\n1. A command is pushed on the queue to process the notification `Queue::push`\n1. The command finds all notification rules using the notification class and triggers them\n1. The notification conditions are checked and only proceed if met\n1. The notification actions are triggered\n\nHere is an example of a plugin registering notification rules. The `groups` definition will create containers that are used to better organise events. The `presets` definition specifies notification rules defined by the system.\n\n```php\npublic function registerNotificationRules()\n{\n    return [\n        'events' =\u003e [\n            \\Winter\\User\\NotifyRules\\UserActivatedEvent::class,\n        ],\n        'actions' =\u003e [\n            \\Winter\\User\\NotifyRules\\SaveToDatabaseAction::class,\n        ],\n        'conditions' =\u003e [\n            \\Winter\\User\\NotifyRules\\UserAttributeCondition::class\n        ],\n        'groups' =\u003e [\n            'user' =\u003e [\n                'label' =\u003e 'User',\n                'icon' =\u003e 'icon-user'\n            ],\n        ],\n        'presets' =\u003e '$/winter/user/config/notify_presets.yaml',\n    ];\n}\n```\n\nHere is an example of triggering a notification. The system event `winter.user.activate` is bound to the `UserActivatedEvent` class.\n\n```php\n// Bind to a system event\n\\Winter\\Notify\\Classes\\Notifier::bindEvents([\n    'winter.user.activate' =\u003e \\Winter\\User\\NotifyRules\\UserActivatedEvent::class\n]);\n\n// Fire the system event\nEvent::fire('winter.user.activate', [$this]);\n```\n\nHere is an example of registering context parameters, which are available globally to all notifications.\n\n```php\n\\Winter\\Notify\\Classes\\Notifier::instance()-\u003eregisterCallback(function($manager) {\n    $manager-\u003eregisterGlobalParams([\n        'user' =\u003e Auth::getUser()\n    ]);\n});\n```\n\nHere is an example of an event preset:\n\n```yaml\n# ===================================\n#  Event Presets\n# ===================================\n\nwelcome_email:\n    name: Send welcome email to user\n    event: Winter\\User\\NotifyRules\\UserRegisteredEvent\n    items:\n        - action: Winter\\Notify\\NotifyRules\\SendMailTemplateAction\n          mail_template: winter.user::mail.welcome\n          send_to_mode: user\n    conditions:\n        - condition: Winter\\Notify\\NotifyRules\\ExecutionContextCondition\n          subcondition: environment\n          operator: is\n          value: dev\n          condition_text: Application environment \u003cspan class=\"operator\"\u003eis\u003c/span\u003e dev\n```\n\n## Creating Event classes\n\nAn event class is responsible for preparing the parameters passed to the conditions and actions. The static method `makeParamsFromEvent` will take the arguments provided by the system event and convert them in to parameters.\n\n```php\nclass UserActivatedEvent extends \\Winter\\Notify\\Classes\\EventBase\n{\n    /**\n     * @var array Local conditions supported by this event.\n        */\n    public $conditions = [\n        \\Winter\\User\\NotifyRules\\UserAttributeCondition::class\n    ];\n\n    /**\n     * Returns information about this event, including name and description.\n     */\n    public function eventDetails()\n    {\n        return [\n            'name'        =\u003e 'Activated',\n            'description' =\u003e 'A user is activated',\n            'group'       =\u003e 'user'\n        ];\n    }\n\n    /**\n     * Defines the usable parameters provided by this class.\n     */\n    public function defineParams()\n    {\n        return [\n            'name' =\u003e [\n                'title' =\u003e 'Name',\n                'label' =\u003e 'Name of the user',\n            ],\n            // ...\n        ];\n    }\n\n    public static function makeParamsFromEvent(array $args, $eventName = null)\n    {\n        return [\n            'user' =\u003e array_get($args, 0)\n        ];\n    }\n}\n```\n\n## Creating Action classes\n\nAction classes define the final step in a notification and subsequently perform the notification itself. Some examples might be sending and email or writing to the database.\n\n```php\nclass SendMailTemplateAction extends \\Winter\\Notify\\Classes\\ActionBase\n{\n    /**\n     * Returns information about this event, including name and description.\n     */\n    public function actionDetails()\n    {\n        return [\n            'name'        =\u003e 'Compose a mail message',\n            'description' =\u003e 'Send a message to a recipient',\n            'icon'        =\u003e 'icon-envelope'\n        ];\n    }\n\n    /**\n     * Field configuration for the action.\n     */\n    public function defineFormFields()\n    {\n        return 'fields.yaml';\n    }\n\n    public function getText()\n    {\n        $template = $this-\u003ehost-\u003etemplate_name;\n\n        return 'Send a message using '.$template;\n    }\n\n    /**\n     * Triggers this action.\n     * @param array $params\n        * @return void\n        */\n    public function triggerAction($params)\n    {\n        $email = 'test@email.tld';\n        $template = $this-\u003ehost-\u003etemplate_name;\n\n        Mail::sendTo($email, $template, $params);\n    }\n}\n```\n\nA form fields definition file is used to provide form fields when the action is established. These values are accessed from condition using the host model via the `$this-\u003ehost` property.\n\n```yaml\n# ===================================\n#  Field Definitions\n# ===================================\n\nfields:\n\n    template_name:\n        label: Template name\n        type: text\n```\n\nAn action may choose to provide no form fields by simply returning false from the `defineFormFields` method.\n\n```php\npublic function defineFormFields()\n{\n    return false;\n}\n```\n\n## Creating Condition classes\n\nA condition class should specify how it should appear in the user interface, providing a name, title and summary text. It also must declare an `isTrue` method for evaluating whether the condition is true or not.\n\n```php\nclass MyCondition extends \\Winter\\Notify\\Classes\\ConditionBase\n{\n    /**\n     * Return either ConditionBase::TYPE_ANY or ConditionBase::TYPE_LOCAL\n     */\n    public function getConditionType()\n    {\n        // If the condition should appear for all events\n        return ConditionBase::TYPE_ANY;\n\n        // If the condition should appear only for some events\n        return ConditionBase::TYPE_LOCAL;\n    }\n\n    /**\n     * Field configuration for the condition.\n     */\n    public function defineFormFields()\n    {\n        return 'fields.yaml';\n    }\n\n    public function getName()\n    {\n        return 'My condition is checked';\n    }\n\n    public function getTitle()\n    {\n        return 'My condition';\n    }\n\n    public function getText()\n    {\n        $value = $this-\u003ehost-\u003emycondition;\n\n        return 'My condition \u003cspan class=\"operator\"\u003eis\u003c/span\u003e '.$value;\n    }\n\n    /**\n     * Checks whether the condition is TRUE for specified parameters\n     * @param array $params\n        * @return bool\n        */\n    public function isTrue(\u0026$params)\n    {\n        return true;\n    }\n}\n```\n\nA form fields definition file is used to provide form fields when the condition is established. These values are accessed from condition using the host model via the `$this-\u003ehost` property.\n\n```yaml\n# ===================================\n#  Field Definitions\n# ===================================\n\nfields:\n\n    mycondition:\n        label: My condition\n        type: dropdown\n        options:\n            true: True\n            false: False\n```\n\n## Model attribute condition classes\n\nModel attribute conditions are designed specially for applying conditions to sets of model attributes.\n\n```php\nclass UserAttributeCondition extends \\Winter\\Notify\\Classes\\ModelAttributesConditionBase\n{\n    protected $modelClass = \\Winter\\User\\Models\\User::class;\n\n    public function getGroupingTitle()\n    {\n        return 'User attribute';\n    }\n\n    public function getTitle()\n    {\n        return 'User attribute';\n    }\n\n    /**\n     * Checks whether the condition is TRUE for specified parameters\n     * @param array $params Specifies a list of parameters as an associative array.\n        * @return bool\n        */\n    public function isTrue(\u0026$params)\n    {\n        $hostObj = $this-\u003ehost;\n\n        $attribute = $hostObj-\u003esubcondition;\n\n        if (!$user = array_get($params, 'user')) {\n            throw new ApplicationException('Error evaluating the user attribute condition: the user object is not found in the condition parameters.');\n        }\n\n        return parent::evalIsTrue($user);\n    }\n}\n```\n\nAn attributes definition file is used to specify which attributes should be included in the condition.\n\n```yaml\n# ===================================\n#  Condition Attribute Definitions\n# ===================================\n\nattributes:\n\n    name:\n        label: Name\n\n    email:\n        label: Email address\n\n    country:\n        label: Country\n        type: relation\n        relation:\n            model: Winter\\Location\\Models\\Country\n            label: Name\n            nameFrom: name\n            keyFrom: id\n```\n\n## Save to database action\n\nThere is a dedicated table in the database for storing events and their parameters. This table is accessed using the `Winter\\Notify\\Models\\Notification` model and can be referenced as a relation from your own models. In this example the `MyProject` model contains its own notification channel called `notifications`.\n\n```php\nclass MyProject extends Model\n{\n    // ...\n\n    public $morphMany = [\n        'my_notifications' =\u003e [\n            \\Winter\\Notify\\Models\\Notification::class,\n            'name' =\u003e 'notifiable'\n        ]\n    ];\n}\n```\n\nThis channel should be registered with the `Winter\\Notify\\NotifyRules\\SaveDatabaseAction` so it appears as a related object when selecting the action.\n\n```php\nSaveDatabaseAction::extend(function ($action) {\n    $action-\u003eaddTableDefinition([\n        'label'    =\u003e 'Project activity',\n        'class'    =\u003e MyProject::class,\n        'relation' =\u003e 'my_notifications',\n        'param'    =\u003e 'project'\n    ]);\n});\n```\n\nThe **label** is shown as the related object, the **class** references the model class, the **relation** refers to the relation name. The **param** defines the parameter name, passed to the triggering event.\n\nSo essentially if you pass a `project` to the event parameters, or if `project` is a global parameter, a notification model is created with the parameters stored in the `data` attribute. Equivalent to the following code:\n\n```php\n$myproject-\u003emy_notifications()-\u003ecreate([\n    // ...\n    'data' =\u003e $params\n]);\n```\n\n## Dynamically adding conditions to events\n\nEvents can be extended to include new local conditions. Simply add the condition class to the event `$conditions` array property.\n\n```php\nUserActivatedEvent::extend(function($event) {\n    $event-\u003econditions[] = \\Winter\\UserPlus\\NotifyRules\\UserLocationAttributeCondition::class;\n});\n```\n","funding_links":["https://github.com/sponsors/wintercms","https://opencollective.com/wintercms"],"categories":["Uncategorized"],"sub_categories":["Uncategorized"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwintercms%2Fwn-notify-plugin","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fwintercms%2Fwn-notify-plugin","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwintercms%2Fwn-notify-plugin/lists"}