mirror of
https://github.com/moodle/moodle.git
synced 2025-04-19 23:42:11 +02:00
MDL-46542 formslib: duration field option for which units to show
Based on the original work of Itamar Tzadok.
This commit is contained in:
parent
4e41ace0be
commit
87554981f0
@ -42,15 +42,15 @@ require_once($CFG->libdir . '/form/text.php');
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class MoodleQuickForm_duration extends MoodleQuickForm_group {
|
||||
/**
|
||||
* Control the fieldnames for form elements
|
||||
* optional => if true, show a checkbox beside the element to turn it on (or off)
|
||||
* @var array
|
||||
*/
|
||||
protected $_options = array('optional' => false, 'defaultunit' => 60);
|
||||
/**
|
||||
* Control the fieldnames for form elements
|
||||
* optional => if true, show a checkbox beside the element to turn it on (or off)
|
||||
* @var array
|
||||
*/
|
||||
protected $_options = array('optional' => false, 'defaultunit' => MINSECS);
|
||||
|
||||
/** @var array associative array of time units (days, hours, minutes, seconds) */
|
||||
private $_units = null;
|
||||
/** @var array associative array of time units (days, hours, minutes, seconds) */
|
||||
private $_units = null;
|
||||
|
||||
/**
|
||||
* constructor
|
||||
@ -58,12 +58,15 @@ class MoodleQuickForm_duration extends MoodleQuickForm_group {
|
||||
* @param string $elementName Element's name
|
||||
* @param mixed $elementLabel Label(s) for an element
|
||||
* @param array $options Options to control the element's display. Recognised values are
|
||||
* 'optional' => true/false - whether to display an 'enabled' checkbox next to the element.
|
||||
* 'defaultunit' => 1|60|3600|86400|604800 - the default unit to display when the time is blank.
|
||||
* If not specified, minutes is used.
|
||||
* 'optional' => true/false - whether to display an 'enabled' checkbox next to the element.
|
||||
* 'defaultunit' => 1|MINSECS|HOURSECS|DAYSECS|WEEKSECS - the default unit to display when
|
||||
* the time is blank. If not specified, minutes is used.
|
||||
* 'units' => array containing some or all of 1, MINSECS, HOURSECS, DAYSECS and WEEKSECS
|
||||
* which unit choices to offer.
|
||||
* @param mixed $attributes Either a typical HTML attribute string or an associative array
|
||||
*/
|
||||
public function __construct($elementName = null, $elementLabel = null, $options = array(), $attributes = null) {
|
||||
public function __construct($elementName = null, $elementLabel = null,
|
||||
$options = array(), $attributes = null) {
|
||||
// TODO MDL-52313 Replace with the call to parent::__construct().
|
||||
HTML_QuickForm_element::__construct($elementName, $elementLabel, $attributes);
|
||||
$this->_persistantFreeze = true;
|
||||
@ -82,6 +85,24 @@ class MoodleQuickForm_duration extends MoodleQuickForm_group {
|
||||
}
|
||||
$this->_options['defaultunit'] = $options['defaultunit'];
|
||||
}
|
||||
if (isset($options['units'])) {
|
||||
if (!is_array($options['units'])) {
|
||||
throw new coding_exception(
|
||||
'When creating a duration form field, units option must be an array.');
|
||||
}
|
||||
// Validate and register requested units.
|
||||
$availableunits = $this->get_units();
|
||||
$displayunits = [];
|
||||
foreach ($options['units'] as $requestedunit) {
|
||||
if (!isset($availableunits[$requestedunit])) {
|
||||
throw new coding_exception($requestedunit .
|
||||
' is not a recognised unit in MoodleQuickForm_duration.');
|
||||
}
|
||||
$displayunits[$requestedunit] = $availableunits[$requestedunit];
|
||||
}
|
||||
krsort($displayunits, SORT_NUMERIC);
|
||||
$this->_options['units'] = $displayunits;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -89,7 +110,8 @@ class MoodleQuickForm_duration extends MoodleQuickForm_group {
|
||||
*
|
||||
* @deprecated since Moodle 3.1
|
||||
*/
|
||||
public function MoodleQuickForm_duration($elementName = null, $elementLabel = null, $options = array(), $attributes = null) {
|
||||
public function MoodleQuickForm_duration($elementName = null, $elementLabel = null,
|
||||
$options = array(), $attributes = null) {
|
||||
debugging('Use of class name as constructor is deprecated', DEBUG_DEVELOPER);
|
||||
self::__construct($elementName, $elementLabel, $options, $attributes);
|
||||
}
|
||||
@ -102,19 +124,34 @@ class MoodleQuickForm_duration extends MoodleQuickForm_group {
|
||||
public function get_units() {
|
||||
if (is_null($this->_units)) {
|
||||
$this->_units = array(
|
||||
604800 => get_string('weeks'),
|
||||
86400 => get_string('days'),
|
||||
3600 => get_string('hours'),
|
||||
60 => get_string('minutes'),
|
||||
WEEKSECS => get_string('weeks'),
|
||||
DAYSECS => get_string('days'),
|
||||
HOURSECS => get_string('hours'),
|
||||
MINSECS => get_string('minutes'),
|
||||
1 => get_string('seconds'),
|
||||
);
|
||||
}
|
||||
return $this->_units;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the units to be used for this field.
|
||||
*
|
||||
* The ones specified in the options passed to the constructor, or all by default.
|
||||
*
|
||||
* @return array number of seconds => lang string.
|
||||
*/
|
||||
protected function get_units_used() {
|
||||
if (!empty($this->_options['units'])) {
|
||||
return $this->_options['units'];
|
||||
} else {
|
||||
return $this->get_units();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts seconds to the best possible time unit. for example
|
||||
* 1800 -> array(30, 60) = 30 minutes.
|
||||
* 1800 -> [30, MINSECS] = 30 minutes.
|
||||
*
|
||||
* @param int $seconds an amout of time in seconds.
|
||||
* @return array associative array ($number => $unit)
|
||||
@ -123,7 +160,7 @@ class MoodleQuickForm_duration extends MoodleQuickForm_group {
|
||||
if ($seconds == 0) {
|
||||
return array(0, $this->_options['defaultunit']);
|
||||
}
|
||||
foreach ($this->get_units() as $unit => $notused) {
|
||||
foreach ($this->get_units_used() as $unit => $notused) {
|
||||
if (fmod($seconds, $unit) == 0) {
|
||||
return array($seconds / $unit, $unit);
|
||||
}
|
||||
@ -144,14 +181,17 @@ class MoodleQuickForm_duration extends MoodleQuickForm_group {
|
||||
}
|
||||
$this->_elements = array();
|
||||
// E_STRICT creating elements without forms is nasty because it internally uses $this
|
||||
$number = $this->createFormElement('text', 'number', get_string('time', 'form'), $attributes, true);
|
||||
$number = $this->createFormElement('text', 'number',
|
||||
get_string('time', 'form'), $attributes, true);
|
||||
$number->set_force_ltr(true);
|
||||
$this->_elements[] = $number;
|
||||
unset($attributes['size']);
|
||||
$this->_elements[] = $this->createFormElement('select', 'timeunit', get_string('timeunit', 'form'), $this->get_units(), $attributes, true);
|
||||
$this->_elements[] = $this->createFormElement('select', 'timeunit',
|
||||
get_string('timeunit', 'form'), $this->get_units_used(), $attributes, true);
|
||||
// If optional we add a checkbox which the user can use to turn if on
|
||||
if($this->_options['optional']) {
|
||||
$this->_elements[] = $this->createFormElement('checkbox', 'enabled', null, get_string('enable'), $this->getAttributes(), true);
|
||||
$this->_elements[] = $this->createFormElement('checkbox', 'enabled', null,
|
||||
get_string('enable'), $this->getAttributes(), true);
|
||||
}
|
||||
foreach ($this->_elements as $element){
|
||||
if (method_exists($element, 'setHiddenLabel')){
|
||||
@ -165,7 +205,7 @@ class MoodleQuickForm_duration extends MoodleQuickForm_group {
|
||||
*
|
||||
* @param string $event Name of event
|
||||
* @param mixed $arg event arguments
|
||||
* @param object $caller calling object
|
||||
* @param MoodleQuickForm $caller calling object
|
||||
* @return bool
|
||||
*/
|
||||
function onQuickFormEvent($event, $arg, &$caller) {
|
||||
|
@ -41,109 +41,122 @@ require_once($CFG->libdir . '/form/duration.php');
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class core_form_duration_testcase extends basic_testcase {
|
||||
/** @var MoodleQuickForm Keeps reference of dummy form object */
|
||||
private $mform;
|
||||
/** @var MoodleQuickForm_duration Keeps reference of MoodleQuickForm_duration object */
|
||||
private $element;
|
||||
|
||||
/**
|
||||
* Initalize test wide variable, it is called in start of the testcase
|
||||
* Get a form that can be used for testing.
|
||||
*
|
||||
* @return MoodleQuickForm
|
||||
*/
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
|
||||
// Get form data.
|
||||
protected function get_test_form() {
|
||||
$form = new temp_form_duration();
|
||||
$this->mform = $form->getform();
|
||||
$this->element = $this->mform->addElement('duration', 'duration');
|
||||
return $form->getform();
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears the data set in the setUp() method call.
|
||||
* @see duration_form_element_test::setUp()
|
||||
* Get a form with a duration element that can be used for testing.
|
||||
*
|
||||
* @return array with two elements, a MoodleQuickForm and a MoodleQuickForm_duration.
|
||||
*/
|
||||
protected function tearDown() {
|
||||
$this->element = null;
|
||||
protected function get_test_form_and_element() {
|
||||
$mform = $this->get_test_form();
|
||||
$element = $mform->addElement('duration', 'duration');
|
||||
return [$mform, $element];
|
||||
}
|
||||
|
||||
/**
|
||||
* Testcase for testing contructor.
|
||||
*
|
||||
* @expectedException coding_exception
|
||||
* @retrun void
|
||||
*/
|
||||
public function test_constructor() {
|
||||
// Test trying to create with an invalid unit.
|
||||
$this->element = $this->mform->addElement('duration', 'testel', null, array('defaultunit' => 123, 'optional' => false));
|
||||
$mform = $this->get_test_form();
|
||||
$mform->addElement('duration', 'testel', null, ['defaultunit' => 123, 'optional' => false]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test contructor only some units.
|
||||
*/
|
||||
public function test_constructor_limited_units() {
|
||||
$mform = $this->get_test_form();
|
||||
$mform->addElement('duration', 'testel', null, ['units' => [MINSECS, 1], 'optional' => false]);
|
||||
$html = $mform->toHtml();
|
||||
$html = preg_replace('~ +>~', '>', $html); // Clean HTML to avoid spurious errors.
|
||||
$this->assertContains('<option value="60" selected>minutes</option>', $html);
|
||||
$this->assertContains('<option value="1">seconds</option>', $html);
|
||||
$this->assertNotContains('value="3600"', $html);
|
||||
}
|
||||
|
||||
/**
|
||||
* Testcase for testing units (seconds, minutes, hours and days)
|
||||
*/
|
||||
public function test_get_units() {
|
||||
$units = $this->element->get_units();
|
||||
ksort($units);
|
||||
$this->assertEquals($units, array(1 => get_string('seconds'), 60 => get_string('minutes'),
|
||||
3600 => get_string('hours'), 86400 => get_string('days'), 604800 => get_string('weeks')));
|
||||
[$mform, $element] = $this->get_test_form_and_element();
|
||||
$units = $element->get_units();
|
||||
$this->assertEquals($units, [1 => get_string('seconds'), 60 => get_string('minutes'),
|
||||
3600 => get_string('hours'), 86400 => get_string('days'), 604800 => get_string('weeks')]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Testcase for testing conversion of seconds to the best possible unit
|
||||
*/
|
||||
public function test_seconds_to_unit() {
|
||||
$this->assertEquals(array(0, 60), $this->element->seconds_to_unit(0)); // Zero minutes, for a nice default unit.
|
||||
$this->assertEquals(array(1, 1), $this->element->seconds_to_unit(1));
|
||||
$this->assertEquals(array(3601, 1), $this->element->seconds_to_unit(3601));
|
||||
$this->assertEquals(array(1, 60), $this->element->seconds_to_unit(60));
|
||||
$this->assertEquals(array(3, 60), $this->element->seconds_to_unit(180));
|
||||
$this->assertEquals(array(1, 3600), $this->element->seconds_to_unit(3600));
|
||||
$this->assertEquals(array(2, 3600), $this->element->seconds_to_unit(7200));
|
||||
$this->assertEquals(array(1, 86400), $this->element->seconds_to_unit(86400));
|
||||
$this->assertEquals(array(25, 3600), $this->element->seconds_to_unit(90000));
|
||||
[$mform, $element] = $this->get_test_form_and_element();
|
||||
$this->assertEquals([0, MINSECS], $element->seconds_to_unit(0)); // Zero minutes, for a nice default unit.
|
||||
$this->assertEquals([1, 1], $element->seconds_to_unit(1));
|
||||
$this->assertEquals([3601, 1], $element->seconds_to_unit(3601));
|
||||
$this->assertEquals([1, MINSECS], $element->seconds_to_unit(60));
|
||||
$this->assertEquals([3, MINSECS], $element->seconds_to_unit(180));
|
||||
$this->assertEquals([1, HOURSECS], $element->seconds_to_unit(3600));
|
||||
$this->assertEquals([2, HOURSECS], $element->seconds_to_unit(7200));
|
||||
$this->assertEquals([1, DAYSECS], $element->seconds_to_unit(86400));
|
||||
$this->assertEquals([25, HOURSECS], $element->seconds_to_unit(90000));
|
||||
|
||||
$this->element = $this->mform->addElement('duration', 'testel', null, array('defaultunit' => 86400, 'optional' => false));
|
||||
$this->assertEquals(array(0, 86400), $this->element->seconds_to_unit(0)); // Zero minutes, for a nice default unit.
|
||||
$element = $mform->addElement('duration', 'testel', null,
|
||||
['defaultunit' => DAYSECS, 'optional' => false]);
|
||||
$this->assertEquals([0, DAYSECS], $element->seconds_to_unit(0)); // Zero minutes, for a nice default unit.
|
||||
}
|
||||
|
||||
/**
|
||||
* Testcase to check generated timestamp
|
||||
*/
|
||||
public function test_exportValue() {
|
||||
/** @var MoodleQuickForm_duration $el */
|
||||
$el = $this->mform->addElement('duration', 'testel');
|
||||
$values = array('testel' => array('number' => 10, 'timeunit' => 1));
|
||||
$this->assertEquals(array('testel' => 10), $el->exportValue($values, true));
|
||||
$mform = $this->get_test_form();
|
||||
$el = $mform->addElement('duration', 'testel');
|
||||
$values = ['testel' => ['number' => 10, 'timeunit' => 1]];
|
||||
$this->assertEquals(['testel' => 10], $el->exportValue($values, true));
|
||||
$this->assertEquals(10, $el->exportValue($values));
|
||||
$values = array('testel' => array('number' => 3, 'timeunit' => 60));
|
||||
$this->assertEquals(array('testel' => 180), $el->exportValue($values, true));
|
||||
$values = ['testel' => ['number' => 3, 'timeunit' => MINSECS]];
|
||||
$this->assertEquals(['testel' => 180], $el->exportValue($values, true));
|
||||
$this->assertEquals(180, $el->exportValue($values));
|
||||
$values = array('testel' => array('number' => 1.5, 'timeunit' => 60));
|
||||
$this->assertEquals(array('testel' => 90), $el->exportValue($values, true));
|
||||
$values = ['testel' => ['number' => 1.5, 'timeunit' => MINSECS]];
|
||||
$this->assertEquals(['testel' => 90], $el->exportValue($values, true));
|
||||
$this->assertEquals(90, $el->exportValue($values));
|
||||
$values = array('testel' => array('number' => 2, 'timeunit' => 3600));
|
||||
$this->assertEquals(array('testel' => 7200), $el->exportValue($values, true));
|
||||
$values = ['testel' => ['number' => 2, 'timeunit' => HOURSECS]];
|
||||
$this->assertEquals(['testel' => 7200], $el->exportValue($values, true));
|
||||
$this->assertEquals(7200, $el->exportValue($values));
|
||||
$values = array('testel' => array('number' => 1, 'timeunit' => 86400));
|
||||
$this->assertEquals(array('testel' => 86400), $el->exportValue($values, true));
|
||||
$values = ['testel' => ['number' => 1, 'timeunit' => DAYSECS]];
|
||||
$this->assertEquals(['testel' => 86400], $el->exportValue($values, true));
|
||||
$this->assertEquals(86400, $el->exportValue($values));
|
||||
$values = array('testel' => array('number' => 0, 'timeunit' => 3600));
|
||||
$this->assertEquals(array('testel' => 0), $el->exportValue($values, true));
|
||||
$values = ['testel' => ['number' => 0, 'timeunit' => HOURSECS]];
|
||||
$this->assertEquals(['testel' => 0], $el->exportValue($values, true));
|
||||
$this->assertEquals(0, $el->exportValue($values));
|
||||
|
||||
$el = $this->mform->addElement('duration', 'testel', null, array('optional' => true));
|
||||
$values = array('testel' => array('number' => 10, 'timeunit' => 1));
|
||||
$this->assertEquals(array('testel' => 0), $el->exportValue($values, true));
|
||||
$el = $mform->addElement('duration', 'testel', null, ['optional' => true]);
|
||||
$values = ['testel' => ['number' => 10, 'timeunit' => 1]];
|
||||
$this->assertEquals(['testel' => 0], $el->exportValue($values, true));
|
||||
$this->assertEquals(0, $el->exportValue($values));
|
||||
$values = array('testel' => array('number' => 20, 'timeunit' => 1, 'enabled' => 1));
|
||||
$this->assertEquals(array('testel' => 20), $el->exportValue($values, true));
|
||||
$values = ['testel' => ['number' => 20, 'timeunit' => 1, 'enabled' => 1]];
|
||||
$this->assertEquals(['testel' => 20], $el->exportValue($values, true));
|
||||
$this->assertEquals(20, $el->exportValue($values));
|
||||
|
||||
// Optional element.
|
||||
$el2 = $this->mform->addElement('duration', 'testel', '', ['optional' => true]);
|
||||
$values = array('testel' => array('number' => 10, 'timeunit' => 1, 'enabled' => 1));
|
||||
$this->assertEquals(array('testel' => 10), $el2->exportValue($values, true));
|
||||
$el2 = $mform->addElement('duration', 'testel', '', ['optional' => true]);
|
||||
$values = ['testel' => ['number' => 10, 'timeunit' => 1, 'enabled' => 1]];
|
||||
$this->assertEquals(['testel' => 10], $el2->exportValue($values, true));
|
||||
$this->assertEquals(10, $el2->exportValue($values));
|
||||
$values = array('testel' => array('number' => 10, 'timeunit' => 1, 'enabled' => 0));
|
||||
$this->assertEquals(array('testel' => 0), $el2->exportValue($values, true));
|
||||
$values = ['testel' => ['number' => 10, 'timeunit' => 1, 'enabled' => 0]];
|
||||
$this->assertEquals(['testel' => 0], $el2->exportValue($values, true));
|
||||
$this->assertEquals(null, $el2->exportValue($values));
|
||||
}
|
||||
}
|
||||
@ -158,6 +171,7 @@ class temp_form_duration extends moodleform {
|
||||
public function definition() {
|
||||
// No definition required.
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns form reference
|
||||
* @return MoodleQuickForm
|
||||
|
Loading…
x
Reference in New Issue
Block a user