setName('form_timerangepickercustom_graphite'); } public function createElements(array $formData) { $this->addElements([ [ 'date', 'start_date', [ 'label' => $this->translate('Start'), 'description' => $this->translate('Start of the date/time range') ] ], [ 'time', 'start_time', [ 'label' => $this->translate('Start'), 'description' => $this->translate('Start of the date/time range') ] ], [ 'date', 'end_date', [ 'label' => $this->translate('End'), 'description' => $this->translate('End of the date/time range') ] ], [ 'time', 'end_time', [ 'label' => $this->translate('End'), 'description' => $this->translate('End of the date/time range') ] ] ]); $this->groupDateTime('start'); $this->groupDateTime('end'); $this->setSubmitLabel($this->translate('Update')); $this->urlToForm('start'); $this->urlToForm('end'); } public function onSuccess() { $start = $this->formToUrl('start', '00:00'); $end = $this->formToUrl('end', '23:59', 'PT59S'); if ($start > $end) { $this->getRedirectUrl()->getParams() ->set('graph_start', $end) ->set('graph_end', $start); } $this->getRedirectUrl()->remove('graph_range'); } /** * Add display group for a date and a time input belonging together * * @param string $part Either 'start' or 'end' */ protected function groupDateTime($part) { $this->addDisplayGroup(["{$part}_date", "{$part}_time"], $part); $group = $this->getDisplayGroup($part); foreach ($group->getElements() as $element) { /** @var \Zend_Form_Element $element */ $elementDecorators = $element->getDecorators(); $element->setDecorators([ 'Zend_Form_Decorator_ViewHelper' => $elementDecorators['Zend_Form_Decorator_ViewHelper'] ]); } $decorators = []; foreach ($elementDecorators as $key => $decorator) { if ($key === 'Zend_Form_Decorator_ViewHelper') { $decorators['Zend_Form_Decorator_FormElements'] = $group->getDecorators()['Zend_Form_Decorator_FormElements']; } else { $decorators[$key] = (new Proxy())->setActualDecorator($decorator->setElement($element)); } } $group->setDecorators($decorators); } /** * Set this form's elements' default values based on the redirect URL's parameters * * @param string $part Either 'start' or 'end' */ protected function urlToForm($part) { $params = $this->getRedirectUrl()->getParams(); $timestamp = $params->get("graph_$part"); if ($timestamp !== null) { if (preg_match($this->timestamp, $timestamp)) { list($date, $time) = explode( 'T', DateTime::createFromFormat('U', $timestamp) ->setTimezone($this->getTimeZone()) ->format($this->dateTimeFormat) ); $this->getElement("{$part}_date")->setValue($date); $this->getElement("{$part}_time")->setValue($time); } else { $params->remove("graph_$part"); } } } /** * Change the redirect URL's parameters based on this form's elements' values * * @param string $part Either 'start' or 'end' * @param string $defaultTime Default if no time given * @param string $addInterval Add this interval to the result * * @return int|null The updated timestamp (if any) */ protected function formToUrl($part, $defaultTime, $addInterval = null) { $date = $this->getValue("{$part}_date"); $time = $this->getValue("{$part}_time"); $params = $this->getRedirectUrl()->getParams(); if ($date === '' && $time === '') { $params->remove("graph_$part"); } else { $dateTime = DateTime::createFromFormat( $this->dateTimeFormat, ($date === '' ? (new DateTime())->setTimezone($this->getTimeZone())->format('Y-m-d') : $date) . 'T' . ($time === '' ? $defaultTime : $time), $this->getTimeZone() ); if ($dateTime === false) { $params->remove("graph_$part"); } else { if ($addInterval !== null) { $dateTime->add(new DateInterval($addInterval)); } $params->set("graph_$part", $dateTime->format('U')); return $dateTime->getTimestamp(); } } } /** * Get {@link timeZone} * * @return DateTimeZone */ public function getTimeZone() { if ($this->timeZone === null) { $timezoneDetect = new TimezoneDetect(); $this->timeZone = new DateTimeZone( $timezoneDetect->success() ? $timezoneDetect->getTimezoneName() : date_default_timezone_get() ); } return $this->timeZone; } /** * Set {@link timeZone} * * @param DateTimeZone $timeZone * * @return $this */ public function setTimeZone(DateTimeZone $timeZone) { $this->timeZone = $timeZone; return $this; } }