2017-05-26 11:41:26 +02:00

293 lines
12 KiB
PHP

<?php
/**
* Class for time picker controls.
*
* @author Stefan Gabos <contact@stefangabos.ro>
* @copyright (c) 2006 - 2016 Stefan Gabos
* @package Controls
*/
class Zebra_Form_Time extends Zebra_Form_Control
{
/**
* Adds a time picker control to the form.
*
* <b>Do not instantiate this class directly! Use the {@link Zebra_Form::add() add()} method instead!</b>
*
* The output of this control will be one, two, three or four {@link Zebra_Form_Select select} controls for hour,
* minutes, seconds and AM/PM respectively, according to the given format as set by the <i>$attributes</i> argument.
*
* Note that even though there will be more select boxes, the submitted values will be available as a single merged
* value (in the form of hh:mm:ss AM/PM, depending on the format), with the name as given by the <i>id</i> argument.
*
* <code>
* // create a new form
* $form = new Zebra_Form('my_form');
*
* // add a time picker control for hour and minutes
* $obj = $form->add('time', 'my_time', date('H:i'), array('format' => 'hm'));
*
* // don't forget to always call this method before rendering the form
* if ($form->validate()) {
*
* // note that even though there will be more select boxes, the submitted
* // values will be available as a single merged value (in the form of
* // mm:mm:ss AM/PM, depending on the format), with the name as given by
* // the "id" argument:
* echo $_POST['my_time'];
*
* }
*
* // output the form using an automatically generated template
* $form->render();
* </code>
*
* @param string $id Unique name to identify the control in the form.
*
* The control's <b>name</b> attribute will be the same as the <b>id</b> attribute!
*
* This is the name to be used when referring to the control's value in the
* POST/GET superglobals, after the form is submitted.
*
* This is also the name of the variable to be used in custom template files, in
* order to display the control.
*
* <code>
* // in a template file, in order to print the generated HTML
* // for a control named "my_time", one would use:
* echo $my_time;
* </code>
*
* @param string $default (Optional) String representing the default time to be shown. Must be set according
* to the format of the time, as specified in <i>$attributes</i>. For example, for a
* time format of "hm", one would set the default time in the form of "hh:mm" while
* for a time format of "hms", one would set the time in the form of "hh:mm:ss".
*
* Default is current system time.
*
* @param array $attributes (Optional) An array of user specified attributes valid for an time picker
* control (format, hours, minutes, seconds, am/pm).
*
* Must be specified as an associative array, in the form of <i>attribute => value</i>.
*
* Available attributes are:
*
* - format - format of time; a string containing one, or a combination of the four
* allowed characters: "h" (hours), "m" (minutes) and "s" (seconds) and "g" for
* using 12-hours format instead of the default 23-hours format; (i.e. setting the
* format to "hm" would allow the selection of hours and minutes, setting the
* format to "hms" would allow the selection of hours, minutes and seconds, and
* setting the format to "hmg" would allow the selection of hours and minutes
* using the 12-hours format instead of the 24-hours format)
*
* - hours - an array of selectable hours (i.e. array(10, 11, 12))
*
* - minutes - an array of selectable minutes (i.e. array(15, 30, 45))
*
* - seconds - an array of selectable seconds
*
* See {@link Zebra_Form_Control::set_attributes() set_attributes()} on how to set
* attributes, other than through the constructor.
*
* @return void
*/
function __construct($id, $default = '', $attributes = '')
{
// call the constructor of the parent class
parent::__construct();
// these will hold the default selectable hours, minutes and seconds
$hours = $minutes = $seconds = array();
// all the 24 hours are available by default
for ($i = 0; $i < 24; $i++) $hours[] = $i;
// all the minutes and seconds are available by default
for ($i = 0; $i < 60; $i++) $minutes[] = $seconds[] = $i;
// set the private attributes of this control
// these attributes are private for this control and are for internal use only
// and will not be rendered by the _render_attributes() method
$this->private_attributes = array(
'disable_xss_filters',
'locked',
'type',
'name',
'id',
'format',
'hours',
'minutes',
'seconds',
'value',
);
// set the default attributes for the text control
// put them in the order you'd like them rendered
$this->set_attributes(
array(
'type' => 'time',
'name' => $id,
'id' => $id,
'value' => $default,
'class' => 'control time',
'format' => 'hm',
'hours' => $hours,
'minutes' => $minutes,
'seconds' => $seconds,
)
);
// sets user specified attributes for the control
$this->set_attributes($attributes);
}
/**
* Generates and returns the control's HTML code.
*
* <i>This method is automatically called by the {@link Zebra_Form::render() render()} method!</i>
*
* @return string The control's HTML code
*/
function toHTML()
{
// get some attributes of the control
$attributes = $this->get_attributes(array('name', 'value', 'class', 'format', 'hours', 'minutes', 'seconds'));
// make sure format is in lower characters
$attributes['format'] = strtolower($attributes['format']);
// if invalid format specified, revert to the default "hm"
if (preg_match('/^[hmsg]+$/i', $attributes['format']) == 0 || strlen(preg_replace('/([a-z]{2,})/i', '$1', $attributes['format'])) != strlen($attributes['format'])) $attributes['format'] = 'hm';
// see what have we sepcified as default time
$time = array_diff(explode(':', trim(str_replace(array('am', 'pm'), '', strtolower($attributes['value'])))), array(''));
// if, according to the time format, we have to show the hours, and the hour is given in the default time
if (($hour_position = strpos($attributes['format'], 'h')) !== false && isset($time[$hour_position]))
// the default selected hour
$selected_hour = $time[$hour_position];
// if, according to the time format, we have to show the minutes, and the minutes are given in the default time
if (($minutes_position = strpos($attributes['format'], 'm')) !== false && isset($time[$minutes_position]))
// the default selected minute
$selected_minute = $time[$minutes_position];
// if, according to the time format, we have to show the seconds, and the seconds are given in the default time
if (($seconds_position = strpos($attributes['format'], 's')) !== false && isset($time[$seconds_position]))
// the default selected minute
$selected_second = $time[$seconds_position];
// if 12-hours format is to be used
if (strpos($attributes['format'], 'g')) {
// set a flag
$ampm = true;
// if this is also present in the default time
if (preg_match('/\bam\b|\bpm\b/i', $attributes['value'], $matches))
// extract the format from the default time
$ampm = strtolower($matches[0]);
}
$output = '';
// if the hour picker is to be shown
if ($hour_position !== false) {
// generate the hour picker
$output .= '
<select name="' . $attributes['name'] . '_hours" id="' . $attributes['name'] . '_hours" ' . $this->_render_attributes() . '>
<option value="">-</option>';
foreach ($attributes['hours'] as $hour)
// show 12 or 24 hours depending on the format
if (!isset($ampm) || ($hour > 0 && $hour < 13))
$output .= '<option value="' . str_pad($hour, 2, '0', STR_PAD_LEFT) . '"' . (isset($selected_hour) && ltrim($selected_hour, '0') == ltrim($hour, '0') ? ' selected="selected"' : '') . '>' . str_pad($hour, 2, '0', STR_PAD_LEFT) . '</option>';
$output .= '
</select>
';
}
// if the minute picker is to be shown
if ($minutes_position !== false) {
// generate the minute picker
$output .= '
<select name="' . $attributes['name'] . '_minutes" id="' . $attributes['name'] . '_minutes" ' . $this->_render_attributes() . '>
<option value="">-</option>';
foreach ($attributes['minutes'] as $minute)
$output .= '<option value="' . str_pad($minute, 2, '0', STR_PAD_LEFT) . '"' . (isset($selected_minute) && ltrim($selected_minute, '0') == ltrim($minute, '0') ? ' selected="selected"' : '') . '>' . str_pad($minute, 2, '0', STR_PAD_LEFT) . '</option>';
$output .= '
</select>
';
}
// if the seconds picker is to be shown
if ($seconds_position !== false) {
// generate the seconds picker
$output .= '
<select name="' . $attributes['name'] . '_seconds" id="' . $attributes['name'] . '_seconds" ' . $this->_render_attributes() . '>
<option value="">-</option>';
foreach ($attributes['seconds'] as $second)
$output .= '<option value="' . str_pad($second, 2, '0', STR_PAD_LEFT) . '"' . (isset($selected_second) && ltrim($selected_second, '0') == ltrim($second, '0') ? ' selected="selected"' : '') . '>' . str_pad($second, 2, '0', STR_PAD_LEFT) . '</option>';
$output .= '
</select>
';
}
// if am/pm picker is to be shown
if (isset($ampm)) {
// generate the AM/PM picker
$output .= '
<select name="' . $attributes['name'] . '_ampm" id="' . $attributes['name'] . '_ampm" ' . $this->_render_attributes() . '>
<option value="">-</option>';
$output .= '<option value="AM"' . ($ampm === 'am' ? ' selected="selected"' : '') . '>AM</option>';
$output .= '<option value="PM"' . ($ampm === 'pm' ? ' selected="selected"' : '') . '>PM</option>';
$output .= '
</select>
';
}
$output .= '<div class="clear"></div>';
return $output;
}
}
?>