Skip to content

Commit

Permalink
Merge pull request #4 from DravenK/master
Browse files Browse the repository at this point in the history
Related the project on drupal.org
  • Loading branch information
chrishappy authored Dec 15, 2017
2 parents cc362ba + 6966448 commit 90894f5
Show file tree
Hide file tree
Showing 6 changed files with 90 additions and 177 deletions.
31 changes: 26 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,27 @@
# d8-time-range
A time range field for Drupal 8
Time Range
==========
Provides the form widget to fill in time range.
This is just a change to the display form, so that the user doesn't need to
enter too much content.
This module not stored time data. The storage of time is provided by the core.

1. Enable the Date Range field and also the Time Range field
2. Create a Date Range field, making sure that you don't select All Day as field type.
3. To select Time range, go to your content type's "Form Display Settings" and select Time Range
## Installation

Install the module as every other module.

## Usage

1. Enable the **Time Range** module.
2. Create a **Date Range** field, select **Day and time** as field type.
3. To select **Time range**, go to your content type's **Form Display Settings**
and select **Time Range**.

Because it doesn't require you to fill out the date, the default record is the
date of the day.
If you don't want to see the date on content's display, go to your content
type's display settings and change the
Date/Time format in your style.

## Compatibility

This module is compatible with Drupal core 8.x .
10 changes: 7 additions & 3 deletions composer.json
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
{
"name": "chris-happy7/time-range",
"name": "drupal/time_range",
"type": "drupal-module",
"description": "Provides a timerange field.",
"homepage": "https://github.com/Chris-Happy7/d8-time-range/",
"description": "Provides the form widget to fill in time range.",
"homepage": "https://github.com/DravenK/time-range.git",
"license": "GPL-2.0+",
"support": {
"issues": "https://github.com/DravenK/time-range/issues",
"source": "https://github.com/DravenK/time-range.git"
},
"minimum-stability": "dev"
}
29 changes: 6 additions & 23 deletions src/Plugin/Field/FieldWidget/TimeRangeWidget.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,13 @@
use Drupal\Core\Field\FieldItemListInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
use Drupal\datetime_range\Plugin\Field\FieldType\DateRangeItem;
use Symfony\Component\DependencyInjection\ContainerInterface;

/**
* Plugin implementation of the 'daterange_time_only' widget.
* Plugin implementation of the 'time_range' widget.
*
* @FieldWidget(
* id = "daterange_time_only",
* id = "time_range",
* label = @Translation("Time range"),
* field_types = {
* "daterange"
Expand Down Expand Up @@ -58,27 +57,11 @@ public static function create(ContainerInterface $container, array $configuratio
*/
public function formElement(FieldItemListInterface $items, $delta, array $element, array &$form, FormStateInterface $form_state) {
$element = parent::formElement($items, $delta, $element, $form, $form_state);

// Identify the type of date and time elements to use.
switch ($this->getFieldSetting('datetime_type')) {
case DateRangeItem::DATETIME_TYPE_DATE:
case DateRangeItem::DATETIME_TYPE_ALLDAY:
$date_type = 'date';
$time_type = 'none';
$date_format = $this->dateStorage->load('html_date')->getPattern();
$time_format = '';
break;

default:
$date_type = 'date';
$time_type = 'time';
$date_format = $this->dateStorage->load('html_date')->getPattern();
$time_format = $this->dateStorage->load('html_time')->getPattern();
break;
}
$time_type = 'time';
$time_format = $this->dateStorage->load('html_time')->getPattern();

$element['value'] += [
'#date_date_format' => $date_format,
'#date_date_format' => 'none',
'#date_date_element' => 'none',
'#date_date_callbacks' => [],
'#date_time_format' => $time_format,
Expand All @@ -87,7 +70,7 @@ public function formElement(FieldItemListInterface $items, $delta, array $elemen
];

$element['end_value'] += [
'#date_date_format' => $date_format,
'#date_date_format' => 'none',
'#date_date_element' => 'none',
'#date_date_callbacks' => [],
'#date_time_format' => $time_format,
Expand Down
138 changes: 5 additions & 133 deletions src/Plugin/Field/FieldWidget/TimeRangeWidgetBase.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,31 +2,26 @@

namespace Drupal\time_range\Plugin\Field\FieldWidget;

use Drupal\Core\Datetime\DrupalDateTime;
use Drupal\Core\Field\FieldItemListInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\datetime\Plugin\Field\FieldType\DateTimeItem;
use Drupal\datetime\Plugin\Field\FieldWidget\DateTimeWidgetBase;
use Drupal\datetime_range\Plugin\Field\FieldType\DateRangeItem;
use Drupal\datetime_range\Plugin\Field\FieldWidget\DateRangeWidgetBase;

/**
* Base class for the 'daterange_*' widgets.
* Base class for the 'timerange_*' widgets.
*/
class TimeRangeWidgetBase extends DateTimeWidgetBase {
class TimeRangeWidgetBase extends DateRangeWidgetBase {

/**
* {@inheritdoc}
*/
public function formElement(FieldItemListInterface $items, $delta, array $element, array &$form, FormStateInterface $form_state) {
$element = parent::formElement($items, $delta, $element, $form, $form_state);
// Wrap all of the select elements with a fieldset.
$element['#theme_wrappers'][] = 'fieldset';

$element['#element_validate'][] = [$this, 'validateStartEnd'];
$element['value']['#title'] = $this->t('Start');
$element['value']['#title'] = $this->t('Start time');

$element['end_value'] = [
'#title' => $this->t('End'),
'#title' => $this->t('End time'),
] + $element['value'];

if ($items[$delta]->start_date) {
Expand All @@ -44,127 +39,4 @@ public function formElement(FieldItemListInterface $items, $delta, array $elemen
return $element;
}

/**
* {@inheritdoc}
*/
public function massageFormValues(array $values, array $form, FormStateInterface $form_state) {
// The widget form element type has transformed the value to a
// DrupalDateTime object at this point. We need to convert it back to the
// storage timezone and format.
foreach ($values as &$item) {
if (!empty($item['value']) && $item['value'] instanceof DrupalDateTime) {
/** @var \Drupal\Core\Datetime\DrupalDateTime $start_date */
$start_date = $item['value'];
switch ($this->getFieldSetting('datetime_type')) {
case DateRangeItem::DATETIME_TYPE_DATE:
// If this is a date-only field, set it to the default time so the
// timezone conversion can be reversed.
datetime_date_default_time($start_date);
$format = DATETIME_DATE_STORAGE_FORMAT;
break;

case DateRangeItem::DATETIME_TYPE_ALLDAY:
// All day fields start at midnight on the starting date, but are
// stored like datetime fields, so we need to adjust the time.
// This function is called twice, so to prevent a double conversion
// we need to explicitly set the timezone.
$start_date->setTimeZone(timezone_open(drupal_get_user_timezone()));
$start_date->setTime(0, 0, 0);
$format = DATETIME_DATETIME_STORAGE_FORMAT;
break;

default:
$format = DATETIME_DATETIME_STORAGE_FORMAT;
break;
}
// Adjust the date for storage.
$start_date->setTimezone(new \DateTimezone(DATETIME_STORAGE_TIMEZONE));
$item['value'] = $start_date->format($format);
}

if (!empty($item['end_value']) && $item['end_value'] instanceof DrupalDateTime) {
/** @var \Drupal\Core\Datetime\DrupalDateTime $end_date */
$end_date = $item['end_value'];
switch ($this->getFieldSetting('datetime_type')) {
case DateRangeItem::DATETIME_TYPE_DATE:
// If this is a date-only field, set it to the default time so the
// timezone conversion can be reversed.
datetime_date_default_time($end_date);
$format = DATETIME_DATE_STORAGE_FORMAT;
break;

case DateRangeItem::DATETIME_TYPE_ALLDAY:
// All day fields end at midnight on the end date, but are
// stored like datetime fields, so we need to adjust the time.
// This function is called twice, so to prevent a double conversion
// we need to explicitly set the timezone.
$end_date->setTimeZone(timezone_open(drupal_get_user_timezone()));
$end_date->setTime(23, 59, 59);
$format = DATETIME_DATETIME_STORAGE_FORMAT;
break;

default:
$format = DATETIME_DATETIME_STORAGE_FORMAT;
break;
}
// Adjust the date for storage.
$end_date->setTimezone(new \DateTimezone(DATETIME_STORAGE_TIMEZONE));
$item['end_value'] = $end_date->format($format);
}
}

return $values;
}

/**
* #element_validate callback to ensure that the start date <= the end date.
*
* @param array $element
* An associative array containing the properties and children of the
* generic form element.
* @param \Drupal\Core\Form\FormStateInterface $form_state
* The current state of the form.
* @param array $complete_form
* The complete form structure.
*/
public function validateStartEnd(array &$element, FormStateInterface $form_state, array &$complete_form) {
$start_date = $element['value']['#value']['object'];
$end_date = $element['end_value']['#value']['object'];

if ($start_date instanceof DrupalDateTime && $end_date instanceof DrupalDateTime) {
if ($start_date->format('U') !== $end_date->format('U')) {
$interval = $start_date->diff($end_date);
if ($interval->invert === 1) {
$form_state->setError($element, $this->t('The @title end date cannot be before the start date', ['@title' => $element['#title']]));
}
}
}
}

/**
* Creates a date object for use as a default value.
*
* This will take a default value, apply the proper timezone for display in
* a widget, and set the default time for date-only fields.
*
* @param \Drupal\Core\Datetime\DrupalDateTime $date
* The UTC default date.
* @param string $timezone
* The timezone to apply.
*
* @return \Drupal\Core\Datetime\DrupalDateTime
* A date object for use as a default value in a field widget.
*/
protected function createDefaultValue($date, $timezone) {
// The date was created and verified during field_load(), so it is safe to
// use without further inspection.
if ($this->getFieldSetting('datetime_type') == DateTimeItem::DATETIME_TYPE_DATE) {
// A date without time will pick up the current time, use the default
// time.
datetime_date_default_time($date);
}
$date->setTimezone(new \DateTimeZone($timezone));
return $date;
}

}
9 changes: 4 additions & 5 deletions time_range.info.yml
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
name: 'Time Range'
type: module
description: 'Provides the ability to store start and end times.'
package: Fields
description: 'Provides the form widget to fill in time range.'
core: 8.x
project: 'drupal'
package: Field types
dependencies:
- datetime
- datetime_range
- drupal:datetime
- drupal:datetime_range
50 changes: 42 additions & 8 deletions time_range.module
Original file line number Diff line number Diff line change
@@ -1,13 +1,47 @@
<?php

/**
* @file
* Module implementation file.
*/

use Drupal\Core\Routing\RouteMatchInterface;

/**
* Implements hook_help().
*/
function time_range_help($route_name, RouteMatchInterface $route_match) {
switch ($route_name) {
case 'help.page.time_range':
$output = '<h3>' . t('About') . '</h3>';
$output .= '<p>' . t('This module not stored time data. The storage of time is provided by the core.
') . '</p>';
$output .= '<dl>';
$output .= '<dt>' . t('General') . '</dt>';
$output .= '<dd>' . t('Create a Date Range field, select Day and time as field type.') . '</dd>';
$output .= '<dd>' . t("To select Time range, go to your content type\'s form display settings
and select Time Range.") . '</dd>';
$output .= '<dd>' . t("If you don\'t want to see the date on content\'s display, go to your content type\'s display settings and change the
Date/time format in your style.") . '</dd>';
$output .= '<dd>' . t('If you have suggestions or questions . You can write down issue in <a href="https://github.com/DravenK/time-range/issues"> time_range</a>\'s page on github , or <a href="https://www.drupal.org/project/time_range">time_range</a>\'s project page on drupal.org .') . '</dd>';
$output .= '</dl>';

return $output;
}
return NULL;
}

/**
* Implements hook_field_widget_info_alter().
*/
function time_range_field_widget_info() {
return array(
'daterange_time_only' => array(
return [
'time_range' => [
'label' => t('Time Range'),
'field types' => array('datetime_range'),
'settings' => array(
'add_new_text' => 'Add new customer...', //This is probably unneeded
),
),
);
'field types' => ['datetime_range'],
'settings' => [
'add_new_text' => 'Add new customer...',
],
],
];
}

0 comments on commit 90894f5

Please sign in to comment.