social_lms_integrator-1.0.0-beta4/modules/social_lms_integrator_iteration/social_lms_integrator_iteration.module
modules/social_lms_integrator_iteration/social_lms_integrator_iteration.module
<?php
/**
* @file
* Contains social_lms_integrator_iteration.module.
*/
use Drupal\Core\Routing\RouteMatchInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\node\Entity\Node;
use Drupal\node\NodeInterface;
use Drupal\Core\StringTranslation\TranslatableMarkup;
use Drupal\Core\Url;
use Drupal\Core\Link;
use Drupal\Component\Utility\NestedArray;
use Drupal\Core\Datetime\DrupalDateTime;
use Drupal\datetime\Plugin\Field\FieldType\DateTimeItemInterface;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Drupal\group\Entity\GroupInterface;
/**
* Implements hook_theme().
*/
function social_lms_integrator_iteration_theme() {
$theme['node__iteration__iteration_listing'] = [
'template' => 'node--iteration--iteration-listing',
'base hook' => 'node'
];
$theme['iteration_listing_links'] = [
'variables' => [
'title' => [],
'start' => [],
'end' => [],
'links' => [],
],
];
return $theme;
}
/**
* Implements hook_form_alter().
*/
function social_lms_integrator_iteration_form_alter(&$form, FormStateInterface $form_state, $form_id) {
// Form alters for the event add and edit forms.
if ($form_id === 'node_iteration_edit_form' || $form_id === 'node_iteration_form') {
// We are using form states here to disable unwanted checkboxes
$form['field_iteration_enrollment']['widget']['self_application']['#states'] = [
'disabled' => [
[
':input[name="field_iteration_enrollment[open_to_enroll]"]' => ['checked' => TRUE],
],
[
':input[name="field_iteration_enrollment[request_to_enroll]"]' => ['checked' => TRUE],
],
[
':input[name="field_iteration_enrollment[invite_only]"]' => ['checked' => TRUE],
],
]
];
$form['field_iteration_enrollment']['widget']['nomination_by_supervisor']['#states'] = [
'disabled' => [
[
':input[name="field_iteration_enrollment[open_to_enroll]"]' => ['checked' => TRUE],
],
[
':input[name="field_iteration_enrollment[request_to_enroll]"]' => ['checked' => TRUE],
],
[
':input[name="field_iteration_enrollment[invite_only]"]' => ['checked' => TRUE],
],
]
];
$form['field_iteration_enrollment']['widget']['invite_only']['#states'] = [
'disabled' => [
[
':input[name="field_iteration_enrollment[open_to_enroll]"]' => ['checked' => TRUE],
],
[
':input[name="field_iteration_enrollment[request_to_enroll]"]' => ['checked' => TRUE],
],
[
':input[name="field_iteration_enrollment[self_application]"]' => ['checked' => TRUE],
],
[
':input[name="field_iteration_enrollment[nomination_by_supervisor]"]' => ['checked' => TRUE],
],
]
];
$form['field_iteration_enrollment']['widget']['open_to_enroll']['#states'] = [
'disabled' => [
[
':input[name="field_iteration_enrollment[invite_only]"]' => ['checked' => TRUE],
],
[
':input[name="field_iteration_enrollment[request_to_enroll]"]' => ['checked' => TRUE],
],
[
':input[name="field_iteration_enrollment[self_application]"]' => ['checked' => TRUE],
],
[
':input[name="field_iteration_enrollment[nomination_by_supervisor]"]' => ['checked' => TRUE],
],
]
];
$form['field_iteration_enrollment']['widget']['request_to_enroll']['#states'] = [
'disabled' => [
[
':input[name="field_iteration_enrollment[invite_only]"]' => ['checked' => TRUE],
],
[
':input[name="field_iteration_enrollment[open_to_enroll]"]' => ['checked' => TRUE],
],
[
':input[name="field_iteration_enrollment[self_application]"]' => ['checked' => TRUE],
],
[
':input[name="field_iteration_enrollment[nomination_by_supervisor]"]' => ['checked' => TRUE],
],
]
];
// Change the sorting of enrollment methods
$unsorted_iteration_enrollment_options = $form['field_iteration_enrollment']['widget']['#options'];
$sorted_iteration_enrollment_options = social_lms_integrator_iteration_get_enrollment_methods($unsorted_iteration_enrollment_options);
$form['field_iteration_enrollment']['widget']['#options'] = $sorted_iteration_enrollment_options;
// Get user timezone.
$user_timezone = _social_event_user_timezone(date_default_timezone_get());
$timezone_label = t('Time zone');
$markup = '<div class="control-label margin-bottom-s">' . $timezone_label . '</div>';
$markup .= '<div class="bg-gray-lightest btn btn-lg">' . $user_timezone . '</div>';
// Check if user has access to change its timezone.
$date_config = Drupal::config('system.date');
if ($date_config->get('timezone.user.configurable')) {
$description = t('The event date and time are set based on your timezone. @change_timezone.', [
'@change_timezone' => Link::createFromRoute(
t('Change your timezone here'),
'entity.user.edit_form',
['user' => \Drupal::currentUser()->id()],
[
'attributes' => [
'target' => '_blank',
],
'fragment' => 'edit-group-locale-settings',
]
)->toString(),
]);
}
else {
$description = t("The event date and time are set based on the site's default timezone.");
}
$form['timezone_indication'] = [
'#type' => 'container',
'#weight' => 99,
'content' => [
'#type' => 'item',
'#markup' => $markup,
'#description' => $description,
],
];
if ($form['field_iteration_all_day']['widget']['value']['#default_value']) {
$start_date = &$form['field_iteration_date']['widget'][0]['value'];
$start_date['#default_value']->setTimezone(new DateTimeZone(DateTimeItemInterface::STORAGE_TIMEZONE))->setTime(0, 0);
$start_date['#date_timezone'] = DateTimeItemInterface::STORAGE_TIMEZONE;
$end_date = &$form['field_iteration_date_end']['widget'][0]['value'];
$end_date['#default_value']->setTimezone(new DateTimeZone(DateTimeItemInterface::STORAGE_TIMEZONE))->setTime(0, 0);
$end_date['#date_timezone'] = DateTimeItemInterface::STORAGE_TIMEZONE;
}
$form['#fieldgroups']['group_date_time']->children[] = 'timezone_indication';
$form['#group_children']['timezone_indication'] = 'group_date_time';
$form['#after_build'][] = 'social_lms_integrator_iteration_date_after_build';
// Attach styling for the iteration date fields.
$form['#attached']['library'][] = 'social_lms_integrator_iteration/admin';
// Attach clientside validator for enrollment methods.
$form['#attached']['library'][] = 'social_lms_integrator_iteration/enrollment_method_validator';
// Attach settings
$form['#attached']['drupalSettings']['SocialLMSIntegratorIterationEnrollmentMethodValidator'] = [
'exclusive_elements' => [
'field_iteration_enrollment[open_to_enroll]',
'field_iteration_enrollment[request_to_enroll]',
'field_iteration_enrollment[invite_only]',
],
'all_elements' => [
'field_iteration_enrollment[open_to_enroll]',
'field_iteration_enrollment[request_to_enroll]',
'field_iteration_enrollment[invite_only]',
'field_iteration_enrollment[self_application]',
'field_iteration_enrollment[nomination_by_supervisor]',
]
];
$form['actions']['submit']['#submit'][] = 'social_lms_integrator_iteration_form_submit';
}
}
function social_lms_integrator_iteration_form_submit($form, FormStateInterface $form_state) {
$group = _social_group_get_current_group();
if ($group instanceof GroupInterface) {
$url = Url::fromRoute('view.group_iterations.page_group_iterations', ['group' => $group->id()]);
$response = new RedirectResponse($url->toString());
$response->send();
}
}
/**
* Add custom validation to event date fields.
*/
function social_lms_integrator_iteration_date_after_build($form, &$form_state) {
array_unshift($form['field_iteration_date']['widget'][0]['value']['#element_validate'], 'social_lms_integrator_iteration_date_validate');
array_unshift($form['field_iteration_date_end']['widget'][0]['value']['#element_validate'], 'social_lms_integrator_iteration_date_validate');
return $form;
}
/**
* Set default time to the date field if time was not set.
*/
function social_lms_integrator_iteration_date_validate(&$element, FormStateInterface $form_state, &$complete_form) {
$form_values = $form_state->getValues();
$input = NestedArray::getValue($form_values, $element['#parents']);
$all_day = (bool) $form_state->getValue(['field_iteration_all_day', 'value']);
// End date should not be empty if "All day" option was enabled.
if ($all_day) {
if (strpos($element['#name'], 'field_iteration_date_end') !== FALSE) {
if (empty($input['date'])) {
$form_state->setError($element, t('End date is required!'));
return;
}
}
}
// Skip default validation for required time when date is required.
if ($all_day) {
$input['time'] = '00:00:00';
if (is_null($input['object']) && !empty($input['date'])) {
$input['object'] = new DrupalDateTime($input['date'] . ' ' . $input['time'], new DateTimeZone(DateTimeItemInterface::STORAGE_TIMEZONE));
}
elseif ($input['object'] instanceof DrupalDateTime) {
$input['object'] = $input['object']->setTimezone(new DateTimeZone(DateTimeItemInterface::STORAGE_TIMEZONE))->setTime(0, 0);
}
}
else {
if ($input['object'] instanceof DrupalDateTime) {
$input['object'] = new DrupalDateTime($input['object']->format('Y-m-d H:i:s'), new DateTimeZone(date_default_timezone_get()));
}
}
if ($input['object'] instanceof DrupalDateTime) {
$form_state->setValueForElement($element, $input);
}
}
/**
* Implements hook_field_widget_form_alter().
*/
function social_lms_integrator_iteration_field_widget_form_alter(&$element, FormStateInterface $form_state, $context) {
$field_definition = $context['items']->getFieldDefinition();
if ($field_definition->getName() == 'field_iteration_date' || $field_definition->getName() == 'field_iteration_date_end') {
$element['value']['#date_time_callbacks'][] = 'social_lms_integrator_iteration_date_all_day_checkbox';
}
}
/**
* Add 'All day' checkbox to event datetime field.
*/
function social_lms_integrator_iteration_date_all_day_checkbox(&$element, FormStateInterface $form_state, $date) {
// Time field should disappear when 'All day' is checked.
$state = [
':input[name="field_iteration_all_day[value]"]' => [
'checked' => TRUE,
],
];
$element['time']['#states'] = [
'invisible' => $state,
];
}
function social_lms_integrator_iteration_preprocess_node(&$variables) {
if ($variables['view_mode'] === 'iteration_listing') {
$nid = $variables['node']->id();
// Default Enrollment methods
$default_enrollment_methods = [
'open_to_enroll',
'request_to_enroll',
'invite_only'
];
$show_default_enrollment = FALSE;
$show_invite_only = FALSE;
$show_edit_link = FALSE;
$show_date = FALSE;
$all_day = FALSE;
if (isset($variables['node']->field_show_date) && $variables['node']->field_show_date->value == 1) {
$show_date = TRUE;
}
if (isset($variables['node']->field_iteration_all_day) && $variables['node']->field_iteration_all_day->value == 1) {
$all_day = TRUE;
}
if(social_lms_integrator_enrollment_iteration_manager_or_organizer($variables['node'])) {
$show_edit_link = TRUE;
}
$url = Url::fromRoute('entity.node.edit_form',['node' => $nid]);
$url->setOption('query', \Drupal::destination()->getAsArray(),);
$variables['edit_link'] = [
'#title' => t('Edit'),
'#type' => 'link',
'#url' => $url,
'#attributes' => [
'class' => [
'quick-edit-link'
]
]
];
// Construct active iteration enrollment methods
if (isset($variables['node']->field_iteration_enrollment)) {
$enrollment_methods = $variables['node']->field_iteration_enrollment->referencedEntities();
if (isset($enrollment_methods)) {
foreach ($enrollment_methods as $method) {
if ($method->id === 'open_to_enroll' ||
$method->id === 'request_to_enroll') {
$show_default_enrollment = TRUE;
}
elseif ($method->id === 'invite_only') {
$show_default_enrollment = TRUE;
$show_invite_only = TRUE;
}
}
}
}
$variables['show_default_enrollment'] = $show_default_enrollment;
$variables['show_edit_link'] = $show_edit_link;
$variables['show_date'] = $show_date;
$variables['all_day'] = $all_day;
// Add variable for the iteration form
$variables['iteration_form'] = \Drupal::formBuilder()->getForm('\Drupal\social_lms_integrator_enrollment\Form\IterationActionForm', $nid);
// If we have an invite form use this
if ($show_invite_only) {
$variables['enrollment_form'] = \Drupal::formBuilder()->getForm('\Drupal\social_lms_integrator_iteration_invite\Form\IterationInviteEnrollActionForm', $nid);
}
else {
$variables['enrollment_form'] = \Drupal::formBuilder()->getForm('\Drupal\social_lms_integrator_enrollment\Form\IterationEnrollActionForm', $nid);
}
}
}
function social_lms_integrator_iteration_enrollment_links(int $nid) {
// Define the arributes for self application
$attributes_self_application = [
'class' => [
'use-ajax',
'js-form-submit',
'form-submit',
'btn',
'btn-accent',
'btn-lg',
],
'data-dialog-type' => 'modal',
'data-dialog-options' => json_encode([
'title' => t('Request'),
'width' => 'auto',
]),
];
// Define the label for self application
$self_application_button_label = t('Apply');
// Define the arributes for self application
$attributes_nomination_by_supervisor = [
'class' => [
'use-ajax',
'js-form-submit',
'form-submit',
'btn',
'btn-accent',
'btn-lg',
],
'data-dialog-type' => 'modal',
'data-dialog-options' => json_encode([
'title' => t('Request'),
'width' => 'auto',
]),
];
// Get the current user
$current_user = \Drupal::currentUser();
// For self-applications we need to check if already applied
$conditions = [
'uid' => $current_user->id(),
'field_iteration' => $nid,
];
$application = \Drupal::entityTypeManager()->getStorage('application')
->loadByProperties($conditions);
if ($application = array_pop($application)) {
$self_application_button_label = t('Applied');
$self_application_add_classes = ['disabled'];
$attributes_self_application['class'][] = 'disabled';
}
// Define links and ensure the index has the same name
// as the machine name of the iteration enrollment method
$links = [
'self_application' => [
'title' => $self_application_button_label,
'url' => Url::fromRoute('social_lms_integrator_enrollment.request_application_dialog',['node' => $nid]),
'attributes' => $attributes_self_application
],
'nomination_by_supervisor' => [
'title' => 'Nominate',
'url' => Url::fromRoute('social_lms_integrator_enrollment.request_nomination_dialog', ['node' => $nid]),
'attributes' => $attributes_nomination_by_supervisor
]
];
return $links;
}
/**
* Check if iteration date is all day.
*/
function social_lms_integrator_iteration_date_is_all_day(DrupalDateTime $date) {
return $date->format('i') === '01';
}
function social_lms_integrator_iteration_get_enrollment_methods(array $unsorted_options) {
$sorted_iteration_enrollment_methods = [];
if (isset($unsorted_options)) {
$query = \Drupal::entityTypeManager()
->getStorage('iteration_enrollment_method')
->getQuery();
$query->sort('weight' , 'ASC');
$query->accessCheck(FALSE);
$sorted_options = $query->execute();
$sorted_iteration_enrollment_methods = array_merge(array_flip($sorted_options), $unsorted_options);
}
return $sorted_iteration_enrollment_methods;
}
/**
* Return the Iteration from a given page.
*
* @return \Drupal\Core\Entity\EntityInterface|null
* The iteration or NULL if nothing found.
*/
function social_lms_integrator_iteration_get_current_iteration() {
$iteration = &drupal_static(__FUNCTION__);
if (!isset($iteration)) {
$node = \Drupal::service('current_route_match')->getParameter('node');
if ($node !== NULL && (!$node instanceof NodeInterface)) {
$node = Node::load($node);
}
if ($node instanceof NodeInterface && $node->getType() === 'iteration') {
$iteration = $node;
}
// If we don't have an iteration then we can go back to NULL.
if (!isset($iteration)) {
$iteration = NULL;
}
}
return $iteration;
}
