'g:i a',
'count' => 1,
'mode' => self::MODE_ELEMENT,
'required' => null,
'minutesInterval' => 15,
'minuteOptions' => null,
'emptyOptions' => false,
'smartOptions' => true, // automatically insert value into options
'dayPrefix' => 'Day %s ',
'startTimeLabel' => 'Start Time:',
'endTimeLabel' => 'End Time:',
);
protected $_params = array(
'format', 'count', 'mode', 'required', 'minutesInterval', 'minuteOptions', 'emptyOptions', 'smartOptions'
);
protected function _getInfo($name, $value = null, $attribs = null, $options = null, $listsep = null)
{
$info = parent::_getInfo($name, $value, $attribs, $options, $listsep);
foreach ($this->_params as $paramName) {
if (isset($info['attribs'][$paramName])) {
$this->{$paramName} = $info['attribs'][$paramName];
unset($info['attribs'][$paramName]);
} else {
$this->{$paramName} = $this->_defaults[$paramName];
}
}
return $info;
}
/**
* @param string $name
* @param array|null $value [['H:i:s', 'H:i:s'], ...]
* @param array|null $attribs
* @return string
*/
public function formTimeRanges($name, $value = null, $attribs = null)
{
$info = $this->_getInfo($name, $value, $attribs);
$id = $name = $value = $attribs = $disable = $escape = null;
extract($info);
$this->name = $name;
$this->disable = $disable;
$value = (array) $value;
if (self::MODE_TEMPLATE === $this->mode) {
list($time1, $time2) = reset($value);
return $this->_renderRow('{index}', $time1, $time2);
}
$keys = array_keys($value);
$keyCount = count($keys);
$content = '';
for ($i = 0; $i < $this->count; ++$i) {
$time1 = $time2 = null;
if ($i < $keyCount) {
list($time1, $time2) = $value[$keys[$i]];
}
$rowIndex = $i + 1;
$content .= $this->_renderRow($rowIndex, $time1, $time2);
}
if ($content) {
$attribs['id'] = $id;
$_attribs = $this->_htmlAttribs(array_filter($attribs));
$content = "
";
}
return $content;
}
/**
* @param string $index
* @param string|null $time1
* @param string|null $time2
* @return string
*/
protected function _renderRow($index, $time1 = null, $time2 = null)
{
$element1 = $this->_renderElement($index, 0, $time1);
$element2 = $this->_renderElement($index, 1, $time2);
$dayPrefix = sprintf($this->dayPrefix, $index);
$label1 = $this->startTimeLabel;
$label2 = $this->endTimeLabel;
$content = "{$dayPrefix} {$label1} {$element1} | "
. "{$dayPrefix} {$label2} {$element2} |
";
return $content;
}
/**
* @param int $row
* @param int $index
* @param string $time Time in "H:i:s" format
* @return string
*/
protected function _renderElement($row, $index, $time = null)
{
$content = '';
$dateTime = ($time) ? DateTime::createFromFormat('H:i:s', $time) : null;
for ($i = 0, $length = strlen($this->format); $i < $length; ++$i) {
$char = $this->format[$i];
switch ($char) {
case 'H':
$options = range(0, 23);
$options = array_combine($options, $options);
break;
case 'i':
if ($this->minuteOptions) {
$options = (array) $this->minuteOptions;
} else {
$options = range(0, 59, $this->minutesInterval ?: 1);
}
if ($this->smartOptions && $dateTime && !in_array(($_value = $dateTime->format($char)), $options)) {
$options[] = $_value;
sort($options);
}
$options = array_map(function ($option) { return str_pad($option, 2, '0'); }, $options);
$options = array_combine($options, $options);
break;
case 's':
$options = range(0, 59);
$options = array_combine($options, $options);
break;
case 'g':
$options = range(1, 12);
$options = array_combine($options, $options);
break;
case 'a':
$options = array('am' => 'am', 'pm' => 'pm');
break;
case 'A':
$options = array('AM' => 'AM', 'PM' => 'PM');
break;
default:
$content .= $char;
continue 2;
}
$_value = ($dateTime) ? $dateTime->format($char) : null;
$_attribs = array('class' => 'time_' . $char);
if ($this->disable) {
$_attribs['disabled'] = 'disabled';
}
if (!$this->required || $this->emptyOptions) {
$options = array('' => '') + (array) $options;
}
$name = trim($this->name, '[]') . "[{$row}][{$index}][{$char}]";
$content .= $this->view->formSelect($name, $_value, $_attribs, $options);
}
return $content;
}
}