diff --git a/application/views/helpers/FormDateTime.php b/application/views/helpers/FormDateTime.php index 19a9cc3c5..cb760a620 100644 --- a/application/views/helpers/FormDateTime.php +++ b/application/views/helpers/FormDateTime.php @@ -2,18 +2,30 @@ // {{{ICINGA_LICENSE_HEADER}}} // {{{ICINGA_LICENSE_HEADER}}} -use Zend_View_Helper_FormElement; - /** - * Helper to generate a "datetime" element + * Render date-and-time input controls */ class Zend_View_Helper_FormDateTime extends Zend_View_Helper_FormElement { /** - * Generate a 'datetime' element + * Format date and time + * + * @param DateTime $dateTime + * @param bool $local + * + * @return string + */ + public function formatDate(DateTime $dateTime, $local) + { + $format = (bool) $local === true ? 'Y-m-d\TH:i:s' : DateTime::RFC3339; + return $dateTime->format($format); + } + + /** + * Render the date-and-time input control * * @param string $name The element name - * @param int $value The default timestamp + * @param DateTime $value The default timestamp * @param array $attribs Attributes for the element tag * * @return string The element XHTML @@ -21,50 +33,41 @@ class Zend_View_Helper_FormDateTime extends Zend_View_Helper_FormElement public function formDateTime($name, $value = null, $attribs = null) { $info = $this->_getInfo($name, $value, $attribs); - extract($info); // name, value, attribs, options, listsep, disable - // Is it disabled? + extract($info); // name, id, value, attribs, options, listsep, disable + /** @var string $id */ + /** @var bool $disable */ $disabled = ''; - if ($disabled) { + if ($disable) { $disabled = ' disabled="disabled"'; } - - $jspicker = (isset($attribs['jspicker']) && $attribs['jspicker'] === true) ? true : false; - - if (isset($value) && !empty($value)) { - if ($jspicker) { - $value = ' value="' . $this->view->dateFormat()->format($value, $attribs['defaultFormat']) . '"'; - } else { - $value = ' value="' . $this->view->dateFormat()->formatDateTime($value) . '"'; - } - } else { - $value = ''; + if ($value instanceof DateTime) { + // If value was valid, it's a DateTime object + $value = $this->formatDate($value, $attribs['local']); } - - // Build the element - $xhtml = '
'; - - $xhtml .= '_htmlAttribs($attribs); - - if ($jspicker === true) { - $xhtml .= 'data-icinga-component="app/datetime"'; + $min = ''; + if (! empty($attribs['min'])) { + $min = sprintf(' min="%s"', $this->formatDate($attribs['min'], $attribs['local'])); } - - $xhtml .= $this->getClosingBracket(); - - if ($jspicker === true) { - $xhtml .= '' - . '' - . '' - . '' - . ''; + unset($attribs['min']); // Unset min to not render it again in $this->_htmlAttribs($attribs) + $max = ''; + if (! empty($attribs['max'])) { + $max = sprintf(' max="%s"', $this->formatDate($attribs['max'], $attribs['local'])); } - - $xhtml .= '
'; - - return $xhtml; + unset($attribs['max']); // Unset max to not render it again in $this->_htmlAttribs($attribs) + $type = $attribs['local'] === true ? 'datetime-local' : 'datetime'; + unset($attribs['local']); // Unset local to not render it again in $this->_htmlAttribs($attribs) + $html5 = sprintf( + 'view->escape($name), + $this->view->escape($id), + $this->view->escape($value), + $min, + $max, + $disabled, + $this->_htmlAttribs($attribs), + $this->getClosingBracket() + ); + return $html5; } } diff --git a/library/Icinga/Web/Form/Element/DateTimePicker.php b/library/Icinga/Web/Form/Element/DateTimePicker.php index dd48bd7f2..47f9b26e9 100644 --- a/library/Icinga/Web/Form/Element/DateTimePicker.php +++ b/library/Icinga/Web/Form/Element/DateTimePicker.php @@ -4,100 +4,145 @@ namespace Icinga\Web\Form\Element; -use Icinga\Web\Form\Validator\DateTimeValidator; -use Zend_Form_Element_Text; +use DateTime; use Zend_Form_Element; -use Icinga\Util\DateTimeFactory; +use Icinga\Web\Form\Validator\DateTimeValidator; /** - * Datetime form element which returns the input as Unix timestamp after the input has been proven valid. Utilizes - * DateTimeFactory to ensure time zone awareness + * A date-and-time input control * - * @see isValid() + * @method DateTime getValue() */ -class DateTimePicker extends Zend_Form_Element_Text +class DateTimePicker extends Zend_Form_Element { /** - * Default format used my js picker + * Disable default decorators + * + * \Icinga\Web\Form sets default decorators for elements. * - * @var string - */ - public $defaultFormat = 'Y-m-d H:i:s'; - - /** - * JS picker support on or off * @var bool + * + * @see \Icinga\Web\Form::__construct() For default element decorators. */ - public $jspicker = true; + protected $_disableLoadDefaultDecorators = true; /** - * View helper to use + * Form view helper to use for rendering + * * @var string */ public $helper = 'formDateTime'; /** - * The validator used for datetime validation - * @var DateTimeValidator + * @var bool */ - private $dateValidator; + protected $local = true; /** - * Valid formats to check user input against - * @var array - */ - public $patterns = array(); - - /** - * Create a new DateTimePicker + * The expected lower bound for the element’s value * - * @param array|string|\Zend_Config $spec - * @param null $options - * @see Zend_Form_Element::__construct() + * @var DateTime|null */ - public function __construct($spec, $options = null) + protected $min; + + /** + * The expected upper bound for the element’s + * + * @var DateTime|null + */ + protected $max; + + /** + * (non-PHPDoc) + * @see \Zend_Form_Element::init() For the method documentation. + */ + public function init() { - parent::__construct($spec, $options); + $this->addValidator( + new DateTimeValidator($this->local), true // true for breaking the validator chain on failure + ); + if ($this->min !== null) { + $this->addValidator('GreaterThan', true, array('min' => $this->min)); + } + if ($this->max !== null) { + $this->addValidator('LessThan', true, array('max' => $this->max)); + } + } - $this->patterns[] = $this->defaultFormat; + public function setLocal($local) + { + $this->local = (bool) $local; + return $this; + } - $this->dateValidator = new DateTimeValidator($this->patterns); - $this->addValidator($this->dateValidator); + public function getLocal() + { + return $this->local; } /** - * Validate filtered date/time strings + * Set the expected lower bound for the element’s value * - * Expects one or more valid formats being set in $this->patterns. Sets element value as Unix timestamp - * if the input is considered valid. Utilizes DateTimeFactory to ensure time zone awareness. + * @param DateTime $min + * + * @return $this + */ + public function setMin(DateTime $min) + { + $this->min = $min; + return $this; + } + + /** + * Get the expected lower bound for the element’s value + * + * @return DateTime|null + */ + public function getMin() + { + return $this->min; + } + + /** + * Set the expected upper bound for the element’s value + * + * @param DateTime $max + * + * @return $this + */ + public function setMax(DateTime $max) + { + $this->max = $max; + return $this; + } + + /** + * Get the expected upper bound for the element’s value + * + * @return DateTime|null + */ + public function getMax() + { + return $this->max; + } + + /** + * Is the date and time valid? + * + * @param string|DateTime $value + * @param mixed $context * - * @param string $value - * @param mixed $context * @return bool */ public function isValid($value, $context = null) { - // Overwrite the internal validator to use - - if (!parent::isValid($value, $context)) { + if (! parent::isValid($value, $context)) { return false; } - $pattern = $this->dateValidator->getValidPattern(); - if (!$pattern) { - $this->setValue($value); - return true; + if (! $value instanceof DateTime) { + $format = $this->local === true ? 'Y-m-d\TH:i:s' : DateTime::RFC3339; + $this->setValue(DateTime::createFromFormat($format, $value)); } - $this->setValue(DateTimeFactory::parse($value, $pattern)->getTimestamp()); return true; } - - public function enableJsPicker() - { - $this->jspicker = true; - } - - public function disableJsPicker() - { - $this->jspicker = false; - } }