calendar_event_notifications-1.0.0/calendar_event_notifications.module
calendar_event_notifications.module
<?php
/**
* @file
* Contains functions related to send email notifications after node operations.
*/
use Drupal\Core\Entity\EntityInterface;
use Drupal\node\Entity\Node;
use Drupal\views\ViewExecutable;
/**
* Implements hook_help().
*/
function calendar_event_notifications_help($route_name) {
switch ($route_name) {
// Main module help for the calendar_event_notifications module.
case 'help.page.calendar_event_notifications':
$output = '';
$output .= '<h3>' . t('About') . '</h3>';
$output .= '<p>' . t('This module gives feature to send reminder emails for an upcoming event before x days of the event based on the admin configuration..') . '</p>';
return $output;
default:
}
}
/**
* Implements hook_views_pre_render().
*/
function calendar_event_notifications_views_pre_render(ViewExecutable $view) {
if (isset($view) && ($view->storage->id() == 'calendar_event_notification')) {
$view->element['#attached']['library'][] = 'calendar_event_notifications/cen';
$create = \Drupal::currentUser()->hasPermission('create calendar_event_notification content');
$view->element['#attached']['drupalSettings']['calendar_event_notifications'] = [
'event_create' => $create,
];
}
}
/**
* Implements hook_ENTITY_TYPE_predelete() for node entities.
*/
function calendar_event_notifications_node_predelete(EntityInterface $entity) {
// Check if the entity is of the "calendar_event_notification" type.
if ($entity->getType() == 'calendar_event_notification') {
// Handle deleted event.
calendar_event_notifications_send_deleted_event_notification_email($entity);
}
}
/**
* Implements hook_ENTITY_TYPE_presave() for node entities.
*/
function calendar_event_notifications_node_presave(EntityInterface $entity) {
// Check if the entity is of the "calendar_event_notification" type and has the required field.
if ($entity->getType() == 'calendar_event_notification' && $entity->hasField('field_notify_mail')) {
// Check if it's a new event or an update.
if ($entity->isNew() && $entity->get('field_notify_mail')->value) {
// Handle new event.
calendar_event_notifications_send_event_notification_email($entity);
}
elseif (!$entity->isNew() && $entity->get('field_notify_mail')->value) {
// Handle updated event.
calendar_event_notifications_send_updated_event_notification_email($entity);
}
}
}
/**
* Custom function to send email notification for a new event.
*/
function calendar_event_notifications_send_event_notification_email($event) {
// Check if the field_start_date and field_end_date fields exist or not.
if ($event->hasField('field_event_date') && !$event->get('field_event_date')->isEmpty()) {
// Get the referenced user.
if ($event->hasField('field_user') && !$event->get('field_user')->isEmpty()) {
$user = $event->get('field_user')->entity;
// Check if the user has an email address.
if ($user && $user->getEmail()) {
// Get the event date range values.
$event_date_range = $event->get('field_event_date')->getValue();
// Check if the date range values are set.
if (!empty($event_date_range[0]['value']) && !empty($event_date_range[0]['end_value'])) {
$start_date = $event_date_range[0]['value'];
$end_date = $event_date_range[0]['end_value'];
// Build the email parameters.
$params = [
'subject' => t('New Event Notification'),
'body' => t('A new event has been created. Event title: @title,Event
start date: @startdate,
Event end date: @enddate', [
'@title' => $event->label(),
'@startdate' => $start_date,
'@enddate' => $end_date,
]
),
];
// Send the email using dependency injection.
\Drupal::service('plugin.manager.mail')->mail(
'calendar_event_notifications',
'event_notifications',
$user->getEmail(),
$user->getPreferredLangcode(),
$params
);
}
}
}
}
}
/**
* Custom function to send email notification for an updated event.
*/
function calendar_event_notifications_send_updated_event_notification_email($event) {
// Check if the field_start_date and field_end_date fields exist or not.
if ($event->hasField('field_event_date') && !$event->get('field_event_date')->isEmpty()) {
// Get the referenced user.
if ($event->hasField('field_user') && !$event->get('field_user')->isEmpty()) {
$user = $event->get('field_user')->entity;
// Check if the user has an email address.
if ($user && $user->getEmail()) {
// Get the event date range values.
$event_date_range = $event->get('field_event_date')->getValue();
// Check if the date range values are set.
if (!empty($event_date_range[0]['value']) && !empty($event_date_range[0]['end_value'])) {
$start_date = $event_date_range[0]['value'];
$end_date = $event_date_range[0]['end_value'];
// Build the email parameters.
$params = [
'subject' => t('Updated Event Notification'),
'body' => t('An event has been updated. Event title: @title, Event start date: @startdate, Event end date: @enddate', [
'@title' => $event->label(),
'@startdate' => $start_date,
'@enddate' => $end_date,
]),
];
// Send the email using dependency injection.
\Drupal::service('plugin.manager.mail')->mail(
'calendar_event_notifications',
'event_notifications',
$user->getEmail(),
$user->getPreferredLangcode(),
$params
);
}
}
}
}
}
/**
* Custom function to send email notification for a deleted event.
*/
function calendar_event_notifications_send_deleted_event_notification_email($event) {
// Check if the 'field_user' exists and has a value.
if ($event->hasField('field_user') && !$event->get('field_user')->isEmpty()) {
// Get the referenced user.
$user = $event->get('field_user')->entity;
// Check if the user has an email address.
if ($user && $user->getEmail()) {
// Check if the field 'field_event_date' is present and not null.
if ($event->hasField('field_event_date')) {
$event_date_field = $event->get('field_event_date');
if (!$event_date_field->isEmpty()) {
// Get the start and end date of the deleted event.
$start_date = $event_date_field->start_date->getTimestamp();
$end_date = $event_date_field->end_date->getTimestamp();
// Get the current date and time.
$current_time = \Drupal::time()->getRequestTime();
// Check if the event is in the future.
if ($start_date >= $current_time) {
// Build the email parameters.
$params = [
'subject' => t('Deleted Event Notification'),
'body' => t('An event has been deleted. Deleted details: Event from @start_date to @end_date', [
'@start_date' => date('Y-m-d H:i
:s
', $start_date),
'@end_date' => date('Y-m-d H:i
:s
', $end_date),
]),
];
// Send the email.
\Drupal::service('plugin.manager.mail')->mail(
'calendar_event_notifications',
'event_notifications',
$user->getEmail(),
$user->getPreferredLangcode(),
$params
);
}
}
}
}
}
}
/**
* Implements hook_mail().
*/
function calendar_event_notifications_mail($key, &$message, $params) {
switch ($key) {
case 'event_notification':
$message['subject'] = $params['subject'];
$message['body'][] = $params['body'];
break;
}
}
/**
* Implements hook_cron().
*/
function calendar_event_notifications_cron() {
// Fetch upcoming calendar_event_notification.
$upcoming_events = calendar_event_notifications_get_upcoming_events();
// Check if the cron has already run for these events.
foreach ($upcoming_events as $event) {
$node = $event['node'];
// Check if the cron has run for this event.
if (!$node->get('field_cron_run_once')->value) {
$config = \Drupal::config('calendar_event_notifications.settings');
$subject = $config->get('email_subject');
$body = $config->get('email_body');
$days = $config->get('days_before_event');
$timezone_string = \Drupal::config('system.date')->get('timezone')['default'];
// Create a DateTimeZone object from the timezone string.
$timezone = new DateTimeZone($timezone_string);
// Create a DateTime object using the DateTimeZone.
$current_date = new DateTime('now', $timezone);
$target_date = clone $current_date;
$modified_date = $target_date->modify('+' . $days . ' days');
$target_date_formatted = $modified_date->format('d');
$date = date_create($event['start_date']);
if (date_format($date, "d") == $target_date_formatted) {
calendar_event_notifications_send_notification_email($event, $subject, $body);
}
}
}
}
/**
* Custom function to send email notification for upcoming events.
*/
function calendar_event_notifications_get_upcoming_events() {
$config = \Drupal::config('calendar_event_notifications.settings');
$days = $config->get('days_before_event');
if ($days) {
$timezone_string = \Drupal::config('system.date')->get('timezone')['default'];
// Create a DateTimeZone object from the timezone string.
$timezone = new DateTimeZone($timezone_string);
// Create a DateTime object using the DateTimeZone.
$current_date = new DateTime('now', $timezone);
$target_date = clone $current_date;
// Modify the cloned date.
$modified_date = $target_date->modify('+ ' . $days . ' day');
// Check if modification was successful.
if ($modified_date !== FALSE) {
// Format the modified date.
$target_date_formatted = $modified_date->format('Y-m-d');
// Query upcoming events.
$query = \Drupal::entityQuery('node')
->condition('type', 'calendar_event_notification')
->condition('field_event_date', $target_date_formatted, '>=')
// Updated condition.
->condition('field_cron_run_once', [0, NULL], 'IN')
->accessCheck(TRUE)
->sort('field_event_date');
$nids = $query->execute();
$events = [];
foreach ($nids as $nid) {
$event = Node::load($nid);
// Assuming 'field_user' is the reference field to the user entity.
$event->get('field_user')->referencedEntities();
$event_date_range = $event->get('field_event_date')->getValue();
$start_date = '';
$end_date = '';
if (!empty($event_date_range[0]['value']) && !empty($event_date_range[0]['end_value'])) {
$start_date = $event_date_range[0]['value'];
$end_date = $event_date_range[0]['end_value'];
}
$events[] = [
'event_title' => $event->getTitle(),
'start_date' => $start_date,
'end_date' => $end_date,
'node' => $event,
];
}
return $events;
}
else {
// Handle the case where modification fails.
\Drupal::logger('calendar_event_notifications')->error('Failed to modify date.');
return [];
}
}
else {
// Handle the case where modification fails.
\Drupal::logger('calendar_event_notifications')->error('Configuration is not set in config form for calendar_event_notification module.');
return [];
}
}
/**
* Send notification emails for upcoming events.
*/
function calendar_event_notifications_send_notification_email($event) {
$config = \Drupal::config('calendar_event_notifications.settings');
$email_subject = $config->get('email_subject');
$email_body = $config->get('email_body');
// Get the referenced users.
$user_reference_items = $event['node']->get('field_user')->referencedEntities();
foreach ($user_reference_items as $key => $referenced_user) {
// Ensure that the recipient email address is not null.
if ($referenced_user && $referenced_user->id() > 0) {
$to = $referenced_user->getEmail();
if ($to) {
// Replace tokens in the email body.
$token_data = [
'node' => $event['node'],
'user' => $referenced_user,
];
$langcode = ($event['node'] && $event['node']->language) ? $event['node']->language : 'en';
$token_options = [
'langcode' => $langcode,
'callback' => 'user_mail_tokens',
'clear' => TRUE,
];
// Use Drupal's token service for replacement.
$token_service = \Drupal::token();
$email_body_after_replace = $token_service->replace($email_body, $token_data, $token_options);
$mail_subject = $token_service->replace($email_subject, $token_data, $token_options);
// Build the email.
// Use the modified email body.
$params = [
'message' => $email_body_after_replace,
'subject' => $mail_subject,
];
// Use Drupal's mail system.
$mailManager = \Drupal::service('plugin.manager.mail');
// Replace with your module's machine name.
$module = 'calendar_event_notifications';
$key = 'notifications_email';
$langcode = \Drupal::currentUser()->getPreferredLangcode();
// Send the email.
$result = $mailManager->mail($module, $key, $to, $langcode, $params);
if ($result['result'] !== TRUE) {
// Handle error.
\Drupal::logger('calendar_event_notifications')->error('Error sending email to user @user for event @event: @error', [
'@user' => $referenced_user->getAccountName(),
'@error' => $result['result'],
'@event' => $event['node']->getTitle(),
]);
}
else {
// Mark the event as cron has run for it.
\Drupal::logger('calendar_event_notifications')->error('Successfully send email to user @user for event @event: @error', [
'@user' => $referenced_user->getAccountName(),
'@error' => $result['result'],
'@event' => $event['node']->getTitle(),
]);
$event['node']->set('field_cron_run_once', 1);
$event['node']->save();
}
}
}
}
}
