View source
<?php
namespace Drupal\visitors\Form;
use Drupal\Component\Utility\NestedArray;
use Drupal\Core\Datetime\DrupalDateTime;
use Drupal\Core\Form\FormBase;
use Drupal\Core\Datetime\DateHelper;
use Drupal\Core\Form\FormStateInterface;
class DateFilter extends FormBase {
protected $_order = array(
'month',
'day',
'year',
);
protected function _getOrder() {
return $this->_order;
}
public function getFormID() {
return 'visitors_date_filter_form';
}
protected function _setSessionDateRange() {
if (!isset($_SESSION['visitors_from'])) {
$_SESSION['visitors_from'] = array(
'month' => date('n'),
'day' => 1,
'year' => date('Y'),
);
}
if (!isset($_SESSION['visitors_to'])) {
$_SESSION['visitors_to'] = array(
'month' => date('n'),
'day' => date('j'),
'year' => date('Y'),
);
}
}
public function buildForm(array $form, FormStateInterface $form_state) {
$this
->_setSessionDateRange();
$from = DrupalDateTime::createFromArray($_SESSION['visitors_from']);
$to = DrupalDateTime::createFromArray($_SESSION['visitors_to']);
$form = array();
$form['visitors_date_filter'] = array(
'#collapsed' => FALSE,
'#collapsible' => FALSE,
'#description' => t('Choose date range'),
'#title' => t('Date filter'),
'#type' => 'fieldset',
);
$form['visitors_date_filter']['from'] = array(
'#date_part_order' => $this
->_getOrder(),
'#date_timezone' => date_default_timezone_get(),
'#default_value' => $from,
'#element_validate' => array(
array(
$this,
'datelistValidate',
),
),
'#process' => array(
array(
$this,
'formProcessDatelist',
),
),
'#title' => t('From'),
'#type' => 'datelist',
'#value_callback' => array(
$this,
'datelistValueCallback',
),
);
$form['visitors_date_filter']['to'] = array(
'#date_part_order' => $this
->_getOrder(),
'#date_timezone' => date_default_timezone_get(),
'#default_value' => $to,
'#element_validate' => array(
array(
$this,
'datelistValidate',
),
),
'#process' => array(
array(
$this,
'formProcessDatelist',
),
),
'#title' => t('To'),
'#type' => 'datelist',
'#value_callback' => array(
$this,
'datelistValueCallback',
),
);
$form['submit'] = array(
'#type' => 'submit',
'#value' => t('Save'),
);
return $form;
}
public function validateForm(array &$form, FormStateInterface $form_state) {
$fromvalue = $form_state
->getValue('from');
$tovalue = $form_state
->getValue('to');
$from = array();
$to = array();
$from['month'] = (int) $fromvalue
->format('m');
$from['day'] = (int) $fromvalue
->format('d');
$from['year'] = (int) $fromvalue
->format('y');
$to['month'] = (int) $tovalue
->format('m');
$to['day'] = (int) $tovalue
->format('d');
$to['year'] = (int) $tovalue
->format('y');
$error_message = $this
->t('The specified date is invalid.');
if (!checkdate($from['month'], $from['day'], $from['year'])) {
return $this
->setFormError('from', $form_state, $error_message);
}
if (!checkdate($to['month'], $to['day'], $to['year'])) {
return $this
->setFormError('to', $form_state, $error_message);
}
$from = mktime(0, 0, 0, $from['month'], $from['day'], $from['year']);
$to = mktime(23, 59, 59, $to['month'], $to['day'], $to['year']);
if ((int) $from <= 0) {
return $this
->setFormError('from', $form_state, $error_message);
}
if ((int) $to <= 0) {
return $this
->setFormError('to', $form_state, $error_message);
}
if ($from > $to) {
return $this
->setFormError('from', $form_state, $error_message);
}
}
public function submitForm(array &$form, FormStateInterface $form_state) {
$from = $form_state
->getValue('from');
$to = $form_state
->getValue('to');
$_SESSION['visitors_from'] = array(
'month' => $from
->format('n'),
'day' => $from
->format('j'),
'year' => $from
->format('Y'),
);
$_SESSION['visitors_to'] = array(
'month' => $to
->format('n'),
'day' => $to
->format('j'),
'year' => $to
->format('Y'),
);
}
public function datelistValidate($element, FormStateInterface $form_state) {
$input_exists = FALSE;
$input = NestedArray::getValue($form_state
->getValues(), $element['#parents'], $input_exists);
if (!$input_exists) {
return;
}
if (empty($input['year']) || empty($input['month']) || empty($input['day'])) {
$form_state
->setError($element, $this
->t('The %field date is required.'));
return;
}
if (!checkdate($input['month'], $input['day'], $input['year'])) {
$this
->setError($element, $this
->t('The specified date is invalid.'));
return;
}
$date = DrupalDateTime::createFromArray($input);
if ($date instanceof DrupalDateTime && !$date
->hasErrors()) {
$form_state
->setValueForElement($element, $date);
return;
}
$form_state
->setError($element, $this
->t('The %field date is invalid.'));
}
public function datelistValueCallback($element, $input = FALSE, &$form_state = array()) {
$parts = $this
->_getOrder();
$return = array_fill_keys($parts, '');
foreach ($parts as $part) {
$return[$part] = $input[$part];
}
return $return;
}
public function formProcessDatelist($element, &$form_state) {
if (empty($element['#value']['month']) || empty($element['#value']['day']) || empty($element['#value']['year'])) {
$element['#value'] = array(
'month' => $element['#default_value']
->format('n'),
'day' => $element['#default_value']
->format('j'),
'year' => $element['#default_value']
->format('Y'),
);
}
$element['#tree'] = TRUE;
foreach ($this
->_getOrder() as $part) {
switch ($part) {
case 'month':
$options = DateHelper::monthNamesAbbr(TRUE);
$title = t('Month');
break;
case 'day':
$options = DateHelper::days(TRUE);
$title = t('Day');
break;
case 'year':
$options = DateHelper::years($this
->_getMinYear(), date('Y'), TRUE);
$title = t('Year');
break;
}
$element['#attributes']['title'] = $title;
$element[$part] = array(
'#attributes' => $element['#attributes'],
'#options' => $options,
'#required' => $element['#required'],
'#title' => $title,
'#title_display' => 'invisible',
'#type' => 'select',
'#value' => (int) $element['#value'][$part],
);
}
return $element;
}
protected function _getMinYear() {
$query = \Drupal::database()
->select('visitors');
$query
->addExpression('MIN(visitors_date_time)');
$min_timestamp = $query
->execute()
->fetchField();
$timezone = date_default_timezone_get();
return \Drupal::service('date.formatter')
->format($min_timestamp, 'custom', 'Y', $timezone);
}
}