View source
<?php
namespace Drupal\office_hours\Element;
use Drupal\Component\Utility\NestedArray;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Render\Element\FormElement;
use Drupal\Core\Url;
use Drupal\office_hours\OfficeHoursDateHelper;
class OfficeHoursList extends FormElement {
public function getInfo() {
$info = [
'#input' => TRUE,
'#tree' => TRUE,
'#process' => [
[
static::class,
'processOfficeHoursSlot',
],
],
'#element_validate' => [
[
static::class,
'validateOfficeHoursSlot',
],
],
];
return $info;
}
public static function getDefaultOperations(array $element) {
$operations = [];
$max_delta = $element['#field_settings']['cardinality_per_day'] - 1;
$day_delta = $element['#daydelta'];
$day = isset($element['#value']['day']) ? (int) $element['#value']['day'] : 0;
$suffix = ' ';
$operations['delete'] = [];
if (isset($element['#value']['starthours']) || isset($element['#value']['endhours'])) {
$operations['delete'] = [
'#type' => 'link',
'#title' => t('Remove'),
'#weight' => 12,
'#url' => Url::fromRoute('<front>'),
'#suffix' => $suffix,
'#attributes' => [
'class' => [
'office-hours-delete-link',
'office-hours-link',
],
],
];
}
$operations['copy'] = [];
if ($day_delta == 0) {
$operations['copy'] = [
'#type' => 'link',
'#title' => $day !== OfficeHoursDateHelper::getFirstDay() ? t('Copy previous day') : t('Copy last day'),
'#weight' => 16,
'#url' => Url::fromRoute('<front>'),
'#suffix' => $suffix,
'#attributes' => [
'class' => [
'office-hours-copy-link',
'office-hours-link',
],
],
];
}
$operations['add'] = [];
if ($day_delta < $max_delta) {
$operations['add'] = [
'#type' => 'link',
'#title' => t('Add @node_type', [
'@node_type' => t('time slot'),
]),
'#weight' => 11,
'#url' => Url::fromRoute('<front>'),
'#suffix' => $suffix,
'#attributes' => [
'class' => [
'office-hours-add-link',
'office-hours-link',
],
],
];
}
return $operations;
}
public static function processOfficeHoursSlot(&$element, FormStateInterface $form_state, &$complete_form) {
$field_settings = $element['#field_settings'];
$day = isset($element['#value']['day']) ? $element['#value']['day'] : '';
$day_delta = $element['#daydelta'];
$element['#attributes']['class'][] = 'form-item';
$element['#attributes']['class'][] = 'office-hours-slot';
$element['day'] = [
'#type' => 'select',
'#options' => OfficeHoursDateHelper::weekDays(FALSE),
'#default_value' => $day,
];
$element['starthours'] = [
'#type' => $field_settings['element_type'],
'#field_settings' => $field_settings,
'#hour_options' => OfficeHoursDateHelper::hours($field_settings['time_format'], FALSE, $field_settings['limit_start'], $field_settings['limit_end']),
'#date_part_order' => in_array($field_settings['time_format'], [
'g',
'h',
]) ? [
'hour',
'minute',
'ampm',
] : [
'hour',
'minute',
],
'#date_increment' => $field_settings['increment'],
'#date_time_element' => 'time',
'#date_time_format' => OfficeHoursDateHelper::getTimeFormat($field_settings['time_format']),
'#date_timezone' => '+0000',
];
$element['endhours'] = $element['starthours'];
$element['starthours']['#default_value'] = isset($element['#value']['starthours']) ? $element['#value']['starthours'] : NULL;
$element['endhours']['#default_value'] = isset($element['#value']['endhours']) ? $element['#value']['endhours'] : NULL;
$element['comment'] = !$field_settings['comment'] ? NULL : [
'#type' => 'textfield',
'#default_value' => isset($element['#value']['comment']) ? $element['#value']['comment'] : NULL,
'#size' => 20,
'#maxlength' => 255,
'#field_settings' => $field_settings,
];
$element['operations'] = [
'data' => OfficeHoursList::getDefaultOperations($element),
];
$element['day_delta'] = [
'#type' => 'value',
'#value' => $day_delta,
];
return $element;
}
public static function validateOfficeHoursSlot(&$element, FormStateInterface $form_state, &$complete_form) {
$error_text = '';
$input_exists = FALSE;
$input = NestedArray::getValue($form_state
->getValues(), $element['#parents'], $input_exists);
$input_exists = TRUE;
if (OfficeHoursDatetime::isEmpty($input)) {
return;
}
$field_settings = $element['#field_settings'];
$validate_hours = $field_settings['valhrs'];
$limit_start = $field_settings['limit_start'];
$limit_end = $field_settings['limit_end'];
$start = OfficeHoursDatetime::get($input['starthours'], 'Hi');
$end = OfficeHoursDatetime::get($input['endhours'], 'Hi');
$required_start = $field_settings['required_start'] ?? FALSE;
if ($required_start && empty($start)) {
$error_text = 'Opening hours must be set.';
$erroneous_element =& $element['starthours'];
}
$required_end = $field_settings['required_end'] ?? FALSE;
if ($required_end && empty($end)) {
$error_text = 'Closing hours must be set.';
$erroneous_element =& $element['endhours'];
}
if ($validate_hours) {
if ((!empty($start) xor !empty($end)) && !empty($limit_end)) {
$error_text = 'Both Opening hours and Closing hours must be set.';
$erroneous_element =& $element;
}
elseif ($end < $start && $end == '0000') {
$error_text = 'Closing hours are earlier than Opening hours.';
$erroneous_element =& $element;
}
elseif (!empty($limit_start) || !empty($limit_end)) {
if ($start && $limit_start * 100 > $start || $end && $limit_end * 100 < $end) {
$error_text = 'Hours are outside limits ( @start - @end ).';
$erroneous_element =& $element;
}
}
}
if ($error_text) {
$day_name = OfficeHoursDateHelper::weekDays(FALSE)[$input['day']];
$error_text = $day_name . ': ' . t($error_text, [
'@start' => $limit_start . ':00',
'@end' => $limit_end . ':00',
], [
'context' => 'office_hours',
]);
$form_state
->setError($erroneous_element, $error_text);
}
}
}