diff --git a/admin_content_notification.module b/admin_content_notification.module
index 1f2cbef..d6174c7 100644
--- a/admin_content_notification.module
+++ b/admin_content_notification.module
@@ -39,13 +39,24 @@ function admin_content_notification_node_update(EntityInterface $node) {
}
}
+/**
+ * Implements hook_node_delete().
+ */
+function admin_content_notification_node_delete(EntityInterface $node) {
+ if (!empty(\Drupal::config('admin_content_notification.settings')->get('admin_content_notification_trigger_on_node_delete')) && \Drupal::service('admin_content_notification.common')->isCurrentUserRoleAllowedToSendNotification()) {
+ \Drupal::service('admin_content_notification.common')->sendMail($node, FALSE, TRUE);
+ }
+}
+
/**
* Implements hook_mail().
*/
function admin_content_notification_mail($key, &$message, $params) {
switch ($key) {
case 'admin_content_notification_key':
- $message['headers']['bcc'] = $params['bcc'];
+ if (isset($params['bcc'])) {
+ $message['headers']['bcc'] = $params['bcc'];
+ }
$message['subject'] = $params['subject'];
$message['body'][] = $params['body'];
break;
diff --git a/src/AdminContentNotificationService.php b/src/AdminContentNotificationService.php
index 3b6cf62..a1b8689 100644
--- a/src/AdminContentNotificationService.php
+++ b/src/AdminContentNotificationService.php
@@ -13,6 +13,8 @@ use Drupal\Core\Utility\LinkGeneratorInterface;
use Drupal\Core\StringTranslation\StringTranslationTrait;
use Drupal\Core\Logger\LoggerChannelTrait;
use Drupal\Core\Extension\ModuleHandlerInterface;
+use Drupal\Core\Link;
+use Drupal\Core\Render\Markup;
/**
* AdminContentNotificationService implement helper service class.
@@ -112,8 +114,9 @@ class AdminContentNotificationService {
*
* @param Drupal\node\NodeInterface $node
* @param bool $is_new
+ * @param bool $is_deleted
*/
- public function sendMail(NodeInterface $node, $is_new = FALSE) {
+ public function sendMail(NodeInterface $node, $is_new = FALSE, $is_deleted = FALSE) {
global $base_url;
$config = $this->getConfigs();
$node_type = $node->getType();
@@ -138,12 +141,21 @@ class AdminContentNotificationService {
$user_name = $user->getDisplayName();
$url = Url::fromUri($base_url . '/node/' . $node->id());
$internal_link = $this->linkGenerator->generate($this->t('@title', ['@title' => $node->label()]), $url);
+ $diff = $this->getDiff($node);
+ $editor_user = $node->getRevisionUser();
+ $editor_user_name = $editor_user->getDisplayName();
$variables = [
'@user_who_posted' => $user_name,
+ '@user_who_edited' => $editor_user_name,
'@content_link' => $internal_link,
'@content_title' => $node->label(),
'@content_type' => $node_type_label,
'@action' => $is_new ? $this->t('posted') : $this->t('updated'),
+ // Source: https://www.drupal.org/project/admin_content_notification/issues/3078319#comment-13241651
+ '@action' => $is_deleted ? 'törlés történt' : ($is_new ? 'jött létre' : 'módosult'),
+ // Case: https://atrium.macroweb.hu/oktav/node/26861#comment-133956
+ '@diff' => render($diff),
+ '@supplement' => $this->supplement($node)
];
$subject = $this->t($config->get('admin_content_notification_email_subject'), $variables);
$body = $this->t($config->get('admin_content_notification_email_body'), $variables);
@@ -166,13 +178,16 @@ class AdminContentNotificationService {
}
$admin_email = implode(',', $emails);
}
- $to = \Drupal::config('system.site')->get('mail');
+ $to = ($admin_email) ? $admin_email : \Drupal::config('system.site')->get('mail');
$params = [
- 'body' => $body,
+ 'body' => Markup::create($body),
'subject' => $subject,
- 'bcc' => $admin_email,
'nid' => $node->id(),
];
+
+ if (!empty($admin_email)) {
+ $params['bcc'] = $admin_email;
+ }
// Allow to alter $admin_email
// by using hook_admin_content_notification_recipients_alter().
@@ -204,5 +219,210 @@ class AdminContentNotificationService {
public function isTokenEnabled() {
return $this->moduleHandler->moduleExists('token');
}
+
+ /**
+ * Custom function to get diffs
+ */
+ private function getDiff($node) {
+ $return = '';
+ $fields = $node->toArray();
+ $revisions = array_reverse(\Drupal::entityTypeManager()->getStorage('node')->revisionIds($node));
+ $vid = $fields['vid'][0]['value'];
+ if (isset($revisions[1])) {
+ $last_vid = $revisions[1];
+ $last_revision = \Drupal::entityTypeManager()->getStorage('node')->loadRevision($last_vid);
+ if ($last_revision) {
+ $last_fields = $last_revision->toArray();
+ }
+ }
+ else {
+ return '';
+ }
+
+ // Excluding some fields
+ $exclude_fields = [
+ 'nid', 'uid', 'uuid', 'vid', 'langcode', 'type', 'revision_timestamp', 'revision_uid', 'revision_log',
+ 'created', 'changed', 'default_langcode','revision_default', 'revision_translation_affected',
+ 'content_translation_source', 'content_translation_outdated', 'menu_link', 'path',
+ 'metatag'
+ ];
+ foreach ($exclude_fields as $exclude_field) {
+ unset($fields[$exclude_field], $last_fields[$exclude_field]);
+ }
+
+ $node_properties = [
+ 'title' => ($node->bundle() == 'training') ? 'Megnevezés' : 'Cím',
+ 'status' => 'Közzétéve',
+ 'promote' => 'Címlapra helyezve',
+ 'sticky' => 'Kiemelt'
+ ];
+
+ $field_settings = [];
+ foreach ($fields as $field_name => $field_array) {
+ $field_storage_config = \Drupal::entityTypeManager()->getStorage('field_storage_config')->load('node.' . $field_name);
+ $cardinality = (method_exists($field_storage_config, 'get')) ? $field_storage_config->get('cardinality') : 1;
+ $field_instance_config = \Drupal::entityTypeManager()->getStorage('field_config')->load('node.' . $node->bundle() . '.' . $field_name);
+ $field_type = method_exists($field_instance_config, 'getType') ? $field_instance_config->getType() : NULL;
+ $field_instance_settings = method_exists($field_instance_config, 'getSettings') ? $field_instance_config->getSettings() : NULL;
+ $target_type = ($field_instance_settings && isset($field_instance_settings['target_type'])) ? $field_instance_settings['target_type'] : '';
+
+ $field_settings[$field_name] = [
+ 'field_name' => $field_name,
+ 'cardinality' => $cardinality,
+ 'field_type' => $field_type,
+ 'field_label' => ($field_instance_config) ? $field_instance_config->getLabel() : (($node_properties[$field_name]) ? $node_properties[$field_name] : $field_name),
+ 'target_type' => $target_type,
+ 'old_values' => [],
+ 'new_values' => []
+ ];
+ foreach ($field_array as $index => $value_array) {
+ foreach ($value_array as $value_key => $value) {
+ if ($value_key != 'format') {
+ $field_settings[$field_name]['value_key'] = $value_key;
+ $field_settings[$field_name]['new_values'][] = $value;
+ }
+ }
+ }
+ foreach ($last_fields[$field_name] as $last_index => $last_value_array) {
+ foreach ($last_value_array as $last_value_key => $last_value) {
+ if ($last_value_key != 'format') {
+ $field_settings[$field_name]['old_values'][] = $last_value;
+ }
+ }
+ }
+ }
+
+ $diff = [];
+
+ foreach ($field_settings as $field_name => $field_data) {
+ switch ($field_data['field_type']) {
+ case 'entity_reference':
+ $target_storage = ($field_data['target_type']) ? \Drupal::entityTypeManager()->getStorage($field_data['target_type']) : NULL;
+ if ($field_data['cardinality'] == 1) {
+ if ($field_data['old_values'] != $field_data['new_values']) {
+ $diff[$field_name]['old_value'] = ($target_storage && isset($field_data['old_values'][0]) && method_exists($target_storage->load($field_data['old_values'][0]), 'label'))
+ ? $target_storage->load($field_data['old_values'][0])->label()
+ : $field_data['old_values'];
+ $diff[$field_name]['new_value'] = ($target_storage && method_exists($target_storage->load($field_data['new_values'][0]), 'label'))
+ ? $target_storage->load($field_data['new_values'][0])->label()
+ : $field_data['new_values'];
+ }
+ }
+ else {
+ if (array_diff($field_data['new_values'], $field_data['old_values']) || array_diff($field_data['old_values'], $field_data['new_values'])) {
+ $diff[$field_name]['new_value'] = '';
+ foreach ($field_data['new_values'] as $new_value) {
+ $diff[$field_name]['new_value'] .= ($target_storage && $target_storage->load($new_value) && method_exists($target_storage->load($new_value), 'label'))
+ ? $target_storage->load($new_value)->label() . '
'
+ : $new_value . '
';
+ }
+ $diff[$field_name]['old_value'] = '';
+ foreach ($field_data['old_values'] as $old_value) {
+ $diff[$field_name]['old_value'] .= ($target_storage && $target_storage->load($old_value) && method_exists($target_storage->load($old_value), 'label'))
+ ? $target_storage->load($old_value)->label() . '
'
+ : $old_value . '
';
+ }
+ }
+ }
+ break;
+ case 'string':
+ case 'string_long':
+ if ($field_data['cardinality'] == 1) {
+ if (isset($field_data['old_values'][0]) && !isset($field_data['new_values'][0])) {
+ $diff[$field_name]['old_value'] = $field_data['old_values'][0];
+ $diff[$field_name]['new_value'] = '';
+ }
+ else if (isset($field_data['new_values'][0]) && !isset($field_data['old_values'][0])) {
+ $diff[$field_name]['old_value'] = '';
+ $diff[$field_name]['new_value'] = $field_data['new_values'][0];
+ }
+ else if (isset($field_data['new_values'][0]) && isset($field_data['old_values'][0]) && $field_data['old_values'][0] != $field_data['new_values'][0]) {
+ $diff[$field_name]['old_value'] = $field_data['old_values'][0];
+ $diff[$field_name]['new_value'] = $field_data['new_values'][0];
+ }
+ }
+ else {
+ // There are no multivalue string and string_long type fields yet
+ }
+ break;
+ case 'text_long':
+ // formatted text
+ if (isset ($field_data['value_key']) && $field_data['value_key'] == 'value') { // we dont care about format changes
+ if ($field_data['cardinality'] == 1) {
+ if (isset($field_data['old_values'][0]) && !isset($field_data['new_values'][0])) {
+ $diff[$field_name]['old_value'] = $field_data['old_values'][0];
+ $diff[$field_name]['new_value'] = '';
+ }
+ else if (isset($field_data['new_values'][0]) && !isset($field_data['old_values'][0])) {
+ $diff[$field_name]['old_value'] = '';
+ $diff[$field_name]['new_value'] = $field_data['new_values'][0];
+ }
+ else if (isset($field_data['new_values'][0]) && isset($field_data['old_values'][0]) && $field_data['old_values'][0] != $field_data['new_values'][0]) {
+ $diff[$field_name]['old_value'] = $field_data['old_values'][0];
+ $diff[$field_name]['new_value'] = $field_data['new_values'][0];
+ }
+ }
+ else {
+ // There are no multivalue string, string_long and text_long type fields yet
+ }
+ }
+ break;
+ }
+ }
+
+ if (empty($diff)) {
+ return '';
+ }
+ else {
+ $rows = [];
+
+ foreach ($diff as $field_name => $field) {
+ $rows []= [
+ ['data' => $field_settings[$field_name]['field_label'], 'style' => ['border: 1px solid #aaa']],
+ ['data' => Markup::create(($field['old_value'] || !empty($field['old_value'])) ? $field['old_value'] : ' - '), 'style' => ['border: 1px solid #aaa']],
+ ['data' => Markup::create($field['new_value']), 'style' => ['border: 1px solid #aaa']]
+ ];
+ }
+ if (!empty($rows)) {
+ $return = [
+ 'label' => ['#markup' => $this->t('Modfications: ')],
+ 'table' => [
+ '#type' => 'table',
+ '#header' => ['', $this->t('Old value'), $this->t('New value')],
+ '#rows' => $rows,
+ '#attributes' => [
+ 'style' => 'border:1px solid #aaa; width: 100%; border-collapse: collapse;',
+ 'class' => ['modifications-table']
+ ],
+ '#attached' => [
+ 'library' => ['admin_content_notification/mail']
+ ]
+ ],
+ ];
+ }
+ }
+ return $return;
+ }
+
+ /**
+ *
+ */
+ private function supplement($node) {
+ $return = '';
+ if ($node->bundle() == 'place') {
+ $return .= 'Jelen levél csak az adott helyszínen induló ezen képzés összes időpontjára KÖZÖS mezőmódosulásokat tartalmazza táblázatosan (korábbi érték, jelenlegi érték).
';
+ $return .= 'Az egy-egy időpontot érintő módosulásokhoz kérjük, látogasd meg a honlapot.
';
+ $return .= '(Az alábbi módosulások nincsenek részletezve a levélben, ezek a honlapon ellenőrizendők:';
+ $return .= '- kezdés jellege (folyamatos vagy fix időpontos)
';
+ $return .= '- indulás időpontja
';
+ $return .= '- időpont aktiválása/inaktiválása
';
+ $return .= '- Képzési napok
';
+ $return .= '- Egyéb (Biztosan indul, Céghez kihelyezetten is stb)
';
+ $return .= '- Díjak és kedvezmények
';
+ $return .= '- Tanfolyamvezetők)
';
+ }
+
+ return Markup::create($return);
+ }
}
diff --git a/src/Form/AdminContentNotification.php b/src/Form/AdminContentNotification.php
index 9314667..b126e83 100644
--- a/src/Form/AdminContentNotification.php
+++ b/src/Form/AdminContentNotification.php
@@ -73,6 +73,14 @@ class AdminContentNotification extends ConfigFormBase {
'#default_value' => $trigger_node_update,
'#description' => $this->t('Please check on it if you want to send notification on update action as well.'),
];
+
+ $trigger_node_delete = ($config->get('admin_content_notification_trigger_on_node_delete')) ?: FALSE;
+ $form['admin_content_notification_trigger_on_node_delete'] = [
+ '#type' => 'checkbox',
+ '#title' => $this->t('Enable on content delete'),
+ '#default_value' => $trigger_node_delete,
+ '#description' => $this->t('Please check on it if you want to send notification on delete action as well.'),
+ ];
$trigger_node_status = ($config->get('admin_content_notification_trigger_on_node_status')) ?: 0;
$content_status = [];
@@ -115,7 +123,7 @@ class AdminContentNotification extends ConfigFormBase {
'#type' => 'textarea',
'#title' => $this->t("Email Id's to whom the notification is to be sent, add comma separated emails in case of multiple recipients"),
'#default_value' => isset($admin_content_notification_email) ? $admin_content_notification_email : $site_email,
- '#description' => $this->t('You can add emails upto Recipients Limit (Max)'),
+ '#description' => $this->t('You can add emails upto Recipients Limit (Max). Leave empty to send notifications to site email address.'),
];
$form['admin_content_notification_recepient_fieldset']['admin_content_notification_email_or_markup']['#markup'] = '' . $this->t('OR') . '';
@@ -224,6 +232,7 @@ class AdminContentNotification extends ConfigFormBase {
$config = $this->configFactory->getEditable('admin_content_notification.settings');
$config->set('admin_content_notification_node_types', $user_input_values['admin_content_notification_node_types']);
$config->set('admin_content_notification_trigger_on_node_update', $user_input_values['admin_content_notification_trigger_on_node_update']);
+ $config->set('admin_content_notification_trigger_on_node_delete', $user_input_values['admin_content_notification_trigger_on_node_delete']);
$config->set('admin_content_notification_trigger_on_node_status', $user_input_values['admin_content_notification_trigger_on_node_status']);
$config->set('admin_content_notification_email_limit', $user_input_values['admin_content_notification_email_limit']);
$config->set('admin_content_notification_allowed_roles', $user_input_values['admin_content_notification_allowed_roles']);