Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Send review notifications to service contacts #74

Merged
merged 26 commits into from
Mar 26, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
a980317
Added service contact entity
stephen-cox Nov 30, 2023
49c77f9
Added tests for service contact entity
stephen-cox Dec 1, 2023
a04e453
Added tests for service contact entity
stephen-cox Dec 1, 2023
9af7321
Added extra tests and fixed coding standards
stephen-cox Dec 5, 2023
ab44263
Added service contact field to nodes
stephen-cox Dec 12, 2023
2ba7291
Service contacts widget working
stephen-cox Dec 14, 2023
1b75753
Added testing for the service contact widget
stephen-cox Jan 11, 2024
6f0d643
Renamed localgov_review_notifications module to localgov_workflows_no…
stephen-cox Jan 16, 2024
6a8b81f
Add notifications to queue when past it's needs review date
stephen-cox Jan 26, 2024
e4aea0c
Basic email sending implemented
stephen-cox Jan 26, 2024
9394901
Merge branch '1.x' of https://github.com/localgovdrupal/localgov_work…
stephen-cox Jan 30, 2024
7e3b692
Refined email notifications and added a README
stephen-cox Jan 30, 2024
7ace582
Fixed email template
stephen-cox Feb 1, 2024
4e8b7fc
Tweaks from feedback
stephen-cox Feb 13, 2024
6dcea66
Added tests for notifier service
stephen-cox Feb 13, 2024
0b2e75a
Don't test against D9, coding standards fixes
stephen-cox Feb 14, 2024
2cf8bd3
Added tests for cron hook and email sending
stephen-cox Feb 14, 2024
6fa93ea
Increase EmailNotificationQueueWorker run time
stephen-cox Feb 14, 2024
1112380
Added permissions to view and manage service contacts
stephen-cox Mar 7, 2024
ccb85f9
Hide service contact widget if user doesn't have permission to view s…
stephen-cox Mar 7, 2024
504975b
Updated service contact widget description
stephen-cox Mar 7, 2024
53a3feb
Allow null returns for review date entity
stephen-cox Mar 7, 2024
dc53e7b
Set default last email time to first cron run to ensure emails aren't…
stephen-cox Mar 7, 2024
f7b720b
Display warning if a conflicting mail module is already enabled.
stephen-cox Mar 22, 2024
e6d90c1
Added warning to README about email setup
stephen-cox Mar 22, 2024
0c9888b
Coding standards fix
stephen-cox Mar 22, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 0 additions & 12 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,6 @@ jobs:
fail-fast: false
matrix:
include:
- localgov-version: '2.x'
drupal-version: '~9.4'
php-version: '8.1'
- localgov-version: '3.x'
drupal-version: '~10.0'
php-version: '8.1'
Expand Down Expand Up @@ -106,9 +103,6 @@ jobs:
fail-fast: false
matrix:
include:
- localgov-version: '2.x'
drupal-version: '~9.4'
php-version: '8.1'
- localgov-version: '3.x'
drupal-version: '~10.0'
php-version: '8.1'
Expand Down Expand Up @@ -142,9 +136,6 @@ jobs:
fail-fast: false
matrix:
include:
- localgov-version: '2.x'
drupal-version: '~9.4'
php-version: '8.1'
- localgov-version: '3.x'
drupal-version: '~10.0'
php-version: '8.1'
Expand Down Expand Up @@ -177,9 +168,6 @@ jobs:
fail-fast: false
matrix:
include:
- localgov-version: '2.x'
drupal-version: '~9.4'
php-version: '8.1'
- localgov-version: '3.x'
drupal-version: '~10.0'
php-version: '8.1'
Expand Down
1 change: 1 addition & 0 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
"drupal/diff": "^1.0",
"drupal/responsive_preview": "^2.0",
"drupal/scheduled_transitions": "^2.1",
"drupal/symfony_mailer": "^1.4",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This might be minor as we have symfony_mailer installed, but are we sure we want to include the dependency here?

I see some new config for lando and mailhog which feels like it needs to be moved into profile or own module maybe as email config might be used in lots of places.

It would be good to get a sense of others website email setup and if they could be supported (some might be using Gov Notifiy for their email).

I see there is a plugin for Email notifications that uses the new email system that Symfony mailer provides. Do we need to include the dependency for the plugin to work, or could it be a suggestion and dev dependency for the tests?

Copy link
Contributor

@andybroomfield andybroomfield Feb 2, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Although...

$ composer why symfony/mailer
drupal/core             10.2.2 requires  symfony/mailer (^6.4)    
drupal/core-recommended 10.2.2 requires  symfony/mailer (~v6.4.0) 
symfony/http-kernel     v6.4.3 conflicts symfony/mailer (<5.4)    
symfony/mime            v6.4.3 conflicts symfony/mailer (<5.4)  

https://www.drupal.org/node/3369935

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The Symfony Mailer module provides a nice way to edit email template files. It's also easy to add new ones should we wish to add notifications on other events.

I can use the symfony/mailer component included with Drupal, but we would either need to hard code the email templates or implement our own templating system.

As it stands this work assumes the Drupal Symfony module is installed and provides some config for it. It should be possible to work with either, but I would need to investigate.

Do others have opinions on whether we should require this module?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If drupal/core requires it then I see no issue localgov_workflows requiring it as well.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the Drupal Symfony Mailer module (https://www.drupal.org/project/symfony_mailer) rather than the Symfony library that is now included with Drupal core.

Got it now. When I was testing this functionality today, apart from review reminder emails, I also received a system update reminder from the core "update" module. That's when I realized (something Andy explains above already) the Symfony mailer module has become the site-wide mail processor. I am trying to understand if this maybe lead to conflict if a site is already using other mail related modules such as the smtp module.

I agree with Andy when he says above "...feels like it needs to be moved into profile or own module maybe as email config might be used in lots of places." For now, keeping Symfony mailer as a "dev" dependency of this module as per Andy's suggestion may not be a bad idea.

"localgovdrupal/localgov_core": "^2.12"
}
}
2 changes: 1 addition & 1 deletion modules/localgov_review_date/src/Entity/ReviewDate.php
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,7 @@ public function hasEntity(): bool {
/**
* {@inheritdoc}
*/
public function getEntity(): EntityInterface {
public function getEntity(): EntityInterface|NULL {
return $this->get('entity')->entity;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,10 +73,10 @@ public function getCreatedTime(): int;
/**
* Gets the entity that has been reviewed.
*
* @return \Drupal\Core\Entity\EntityInterface
* @return \Drupal\Core\Entity\EntityInterface|null
* The content entity that has been reviewed.
*/
public function getEntity(): EntityInterface;
public function getEntity(): EntityInterface|NULL;

/**
* Gets the langcode for the entity review date.
Expand Down
82 changes: 82 additions & 0 deletions modules/localgov_workflows_notifications/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
# Localgov Workflow Notifications

This module is designed to send notifications to service contacts when content moderation
states change. It currently only implements email notifications when content passes its needs
review date, but it should be easy to implement email notifications on other events.

## Warning

This module enables the [Symfony Mailer](https://www.drupal.org/project/symfony_mailer/)
module which will take over email sending for the site. It's important to test the sites
email settings after install to ensure they work for your environment. This is particularly
important if the site already uses a contrib module to handle email sending as the Symfony
Mailer module will take over from this. Modules that can cause issues:

* [Mail System](https://www.drupal.org/project/mailsystem)
* [Sendgrid Integration](https://www.drupal.org/project/sendgrid_integration)
* [SMTP Authentication Support](https://www.drupal.org/project/smtp)

## Setup

The server must be able to send emails and cron must be running frequently.

For email sending to work you'll need to set the default Symfony Mailer transport for your
environment here: /admin/config/system/mailer/transport. In the settings there's also an
option to send test emails so you can check your settings work.

Emails are sent when either Drupal cron is run or the `localgov_workflows_notifications_email`
queue is processed. It is recommended that Drupal cron runs at least every 10 minutes and uses
an external trigger to run. For more information on setting up an external cron job see
<https://www.drupal.org/node/23714>.

## Structure

There are 3 main components to the module; service contact management, notification creation
and email sending.

### Service contacts

The module defines a service contact entity. A service contact is either an existing Drupal
user or an external user with a name and email address.

One or more service contacts can be associated with a piece of content. In theory this can
be any content entity, but the widget to associate service contacts with content currently
only works with nodes.

### Notifications

Any notifications added to the email queue will be sent at the next cron run.

Needs review notifications are sent every X days for content with a needs review date that
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"every X days" - should this wording remain as it is now?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"drupal/symfony_mailer": "^1.4",

This is the Drupal Symfony Mailer module (https://www.drupal.org/project/symfony_mailer) rather than the Symfony library that is now included with Drupal core.

"every X days" - should this wording remain as it is now?

This number of days is configurable, but the wording can certainly be improved.

has passed in that time and hasn't already been reviewed. The frequency for this can be
set at /admin/config/workflow/localgov-workflows-notifications.

### Email sending

This module uses the Drupal [Symfony Mailer](https://www.drupal.org/project/symfony_mailer/)
module to send emails. This module provides a flexible way to send emails.

To send emails you'll need to ensure the correct mailer transport has been configured at
/admin/config/system/mailer/transport.

The content of the notification can be changed by editing the body of the LocalGov Workflows
Notifications policy at /admin/config/system/mailer/policy/localgov_workflows_notifications.

If you want more control on the email content you can define your own Twig templates and
inject CSS into the email. More information can be found in the
[Synfony Mailer documentation](https://www.drupal.org/docs/contributed-modules/drupal-symfony-mailer/getting-started)
on drupal.org.

Two mailer transports are defined; Lando and Mailhog. The Lando transport is for use when
developing in Lando and Mailhog can be used when using a mail catcher, like Mailhog, on a
testing server. They can be deleted if not needed. To enable one adding the following to
your `settings.local.php` file:

```php
$config['symfony_mailer.settings']['default_transport'] = 'lando';
```

## Adding a new notification type

1. Create a trigger / cron job to add content to the `localgov_workflows_notifications_email` queue with your new type name.
2. Optionally, create a new Symfony Mailer policy for this type.
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
email_enabled: true
email_frequency: 1.0
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
langcode: en
status: true
dependencies:
module:
- localgov_workflows_notifications
id: localgov_workflows_notifications.needs_review
configuration:
email_body:
content:
value: "<p>Dear {{ service_contact.getName() }},</p>\r\n<p>The following content needs reviewing:</p>\r\n<ul>\r\n{% for entity in entities %}\r\n <li><a href=\"{{ path('entity.node.canonical', {'node': entity.id}) }}\">{{ entity.label }}</li>\r\n{% endfor %}\r\n</ul>\r\n"
format: email_html
email_subject:
value: 'Content needing review on the [site:name] site'
email_theme:
theme: _default
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
langcode: en
status: true
dependencies:
module:
- localgov_workflows_notifications
id: localgov_service_contact_delete_action
label: 'Delete service contacts'
type: localgov_service_contact
plugin: entity:delete_action:localgov_service_contact
configuration: { }
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
langcode: en
status: true
dependencies:
module:
- localgov_workflows_notifications
id: localgov_service_contact_save_action
label: 'Save service contacts'
type: localgov_service_contact
plugin: entity:save_action:localgov_service_contact
configuration: { }
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
langcode: en
status: true
dependencies: { }
id: lando
label: Lando
plugin: smtp
configuration:
user: ''
pass: ''
host: mailhog
port: 1025
query:
verify_peer: false
local_domain: ''
restart_threshold: null
restart_threshold_sleep: null
ping_threshold: null
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
langcode: en
status: true
dependencies: { }
id: mailhog
label: Mailhog
plugin: smtp
configuration:
user: ''
pass: ''
host: 127.0.0.1
port: 1025
query:
verify_peer: false
local_domain: ''
restart_threshold: null
restart_threshold_sleep: null
ping_threshold: null
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
field.value.service_contacts:
type: mapping
label: Default value
mapping:
value:
type: label
label: Value
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# Schema for the configuration files of the LocalGov Workflows Notifications module.
localgov_workflows_notifications.settings:
type: config_object
label: 'LocalGov Workflows Notifications settings'
mapping:
email_enabled:
type: boolean
label: 'Enable email notifications'
email_frequency:
type: float
label: 'Email frequency in days'
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
name: 'LocalGov Workflows Notifications'
type: module
description: 'Send notifications to service contacts when content needs reviewing.'
package: LocalGov Drupal
core_version_requirement: ^9 || ^10
dependencies:
- localgov_workflows:localgov_workflows
- symfony_mailer:symfony_mailer
configure: localgov_workflows_notifications.settings
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<?php

/**
* @file
* Install functions for the LocalGov Review Notifications module.
*/

/**
* Implements hook_install().
*/
function localgov_workflows_notifications_install($is_syncing) {

// Display a message if a conflicting mail module is enabled.
$conflicts = [
'sendgrid' => 'Sendgrid',
'smtp' => 'SMTP',
'mailsystem' => 'Mail System',
];
foreach ($conflicts as $module => $title) {
if (\Drupal::moduleHandler()->moduleExists($module)) {
\Drupal::logger('localgov_workflows_notifications')->warning(
'The @title module is installed and this is incompatible with the Symfony Mailer module which has just been enabled. Please disable the conflicting module and review the sites email settings.',
['@title' => $title]);
\Drupal::messenger()->addWarning(t(
'The @title module is installed and this is incompatible with the Symfony Mailer module which has just been enabled. Please disable the conflicting module and review the sites email settings.',
['@title' => $title]));
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
localgov_service_contact.add_form:
title: 'Add service contact'
route_name: entity.localgov_service_contact.add_form
appears_on:
- entity.localgov_service_contact.collection
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
entity.localgov_service_contact.edit_form:
route_name: entity.localgov_service_contact.edit_form
group: localgov_service_contact
title: 'Edit'

entity.localgov_service_contact.delete_form:
route_name: entity.localgov_service_contact.delete_form
group: localgov_service_contact
title: 'Delete'
weight: 10
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
entity.localgov_service_contact.collection:
title: 'Service contacts'
description: 'List of service contacts.'
route_name: entity.localgov_service_contact.collection
parent: system.admin_content

localgov_workflows_notifications.settings:
title: 'LocalGov workflow notifications'
description: 'Administer LocalGov workflow notifications'
parent: system.admin_config_workflow
route_name: localgov_workflows_notifications.settings
weight: 10
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
entity.localgov_service_contact.view:
title: 'View'
route_name: entity.localgov_service_contact.canonical
base_route: entity.localgov_service_contact.canonical
entity.localgov_service_contact.edit_form:
title: 'Edit'
route_name: entity.localgov_service_contact.edit_form
base_route: entity.localgov_service_contact.canonical
entity.localgov_service_contact.delete_form:
title: 'Delete'
route_name: entity.localgov_service_contact.delete_form
base_route: entity.localgov_service_contact.canonical
weight: 10
entity.localgov_service_contact.collection:
title: 'Service contacts'
route_name: entity.localgov_service_contact.collection
base_route: system.admin_content
weight: 10
Loading
Loading