Skip to content

Commit 97315d3

Browse files
Extrafield: Support duration extra field (hh:mm:ss)- refs #5634
1 parent fa7aabe commit 97315d3

File tree

2 files changed

+76
-9
lines changed

2 files changed

+76
-9
lines changed

public/main/inc/lib/extra_field.lib.php

Lines changed: 71 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ class ExtraField extends Model
3737
public const FIELD_TYPE_GEOLOCALIZATION_COORDINATES = 25;
3838
public const FIELD_TYPE_SELECT_WITH_TEXT_FIELD = 26;
3939
public const FIELD_TYPE_TRIPLE_SELECT = 27;
40+
public const FIELD_TYPE_DURATION = 28;
4041

4142
public $columns = [
4243
'id',
@@ -871,6 +872,9 @@ public function get_handler_extra_data($itemId)
871872
$extra_data["extra_$variable"]["extra_{$variable}_second"] = $level2;
872873
$extra_data["extra_$variable"]["extra_{$variable}_third"] = $level3;
873874
break;
875+
case self::FIELD_TYPE_DURATION:
876+
$extra_data['extra_'.$field['variable']] = self::formatDuration((int) $field_value);
877+
break;
874878
default:
875879
$extra_data['extra_'.$field['variable']] = $field_value;
876880
break;
@@ -889,6 +893,18 @@ public function get_handler_extra_data($itemId)
889893
return $extra_data;
890894
}
891895

896+
/**
897+
* Formats a duration in seconds into hh:mm:ss.
898+
*/
899+
private function formatDuration(int $seconds): string
900+
{
901+
$hours = floor($seconds / 3600);
902+
$minutes = floor(($seconds % 3600) / 60);
903+
$seconds = $seconds % 60;
904+
905+
return sprintf('%02d:%02d:%02d', $hours, $minutes, $seconds);
906+
}
907+
892908
/**
893909
* Get an array of all the values from the extra_field and extra_field_options tables
894910
* based on the current object's type.
@@ -1882,6 +1898,38 @@ public function set_extra_fields_in_form(
18821898
$freezeElement
18831899
);
18841900
break;
1901+
case self::FIELD_TYPE_DURATION:
1902+
$form->addElement(
1903+
'text',
1904+
'extra_'.$variable,
1905+
$field_details['display_text'],
1906+
['class' => 'span2', 'placeholder' => 'hh:mm:ss']
1907+
);
1908+
1909+
$form->addRule(
1910+
'extra_'.$variable,
1911+
get_lang('Invalid format'),
1912+
'callback',
1913+
'validate_duration_format'
1914+
);
1915+
1916+
$form->applyFilter('extra_'.$variable, function ($value) {
1917+
if (preg_match('/^(\d+):([0-5]?\d):([0-5]?\d)$/', $value, $matches)) {
1918+
return ($matches[1] * 3600) + ($matches[2] * 60) + $matches[3];
1919+
}
1920+
return 0;
1921+
});
1922+
1923+
if (isset($extraData['extra_'.$variable]) && is_numeric($extraData['extra_'.$variable])) {
1924+
$form->setDefaults([
1925+
'extra_'.$variable => self::formatDuration((int) $extraData['extra_'.$variable])
1926+
]);
1927+
}
1928+
1929+
if ($freezeElement) {
1930+
$form->freeze('extra_'.$variable);
1931+
}
1932+
break;
18851933
}
18861934
}
18871935
}
@@ -1892,6 +1940,14 @@ public function set_extra_fields_in_form(
18921940
return $return;
18931941
}
18941942

1943+
/**
1944+
* Validates if a string is in the hh:mm:ss duration format.
1945+
*/
1946+
function validate_duration_format($value): bool
1947+
{
1948+
return (bool) preg_match('/^(\d+):([0-5]?\d):([0-5]?\d)$/', $value);
1949+
}
1950+
18951951
/**
18961952
* @param array $options
18971953
*
@@ -2012,6 +2068,7 @@ public static function get_extra_fields_by_handler($handler)
20122068
$types[self::FIELD_TYPE_GEOLOCALIZATION_COORDINATES] = get_lang('Geolocalization by coordinates');
20132069
$types[self::FIELD_TYPE_SELECT_WITH_TEXT_FIELD] = get_lang('Select with text field');
20142070
$types[self::FIELD_TYPE_TRIPLE_SELECT] = get_lang('Triple select');
2071+
$types[self::FIELD_TYPE_DURATION] = get_lang('Duration (hh:mm:ss)');
20152072

20162073
switch ($handler) {
20172074
case 'course':
@@ -2540,11 +2597,20 @@ public function getRules(&$columns, &$column_model, $extraFields = [], $checkExt
25402597
foreach ($fields as $field) {
25412598
$search_options = [];
25422599
$type = 'text';
2543-
if (in_array($field['value_type'], [self::FIELD_TYPE_SELECT, self::FIELD_TYPE_DOUBLE_SELECT])) {
2544-
$type = 'select';
2545-
$search_options['sopt'] = ['eq', 'ne']; //equal not equal
2546-
} else {
2547-
$search_options['sopt'] = ['cn', 'nc']; //contains not contains
2600+
switch ($field['value_type']) {
2601+
case self::FIELD_TYPE_SELECT:
2602+
case self::FIELD_TYPE_DOUBLE_SELECT:
2603+
$type = 'select';
2604+
$search_options['sopt'] = ['eq', 'ne'];
2605+
break;
2606+
case self::FIELD_TYPE_DURATION:
2607+
$type = 'text';
2608+
$search_options['sopt'] = ['cn', 'nc'];
2609+
break;
2610+
default:
2611+
$type = 'text';
2612+
$search_options['sopt'] = ['cn', 'nc'];
2613+
break;
25482614
}
25492615

25502616
$search_options['searchhidden'] = 'true';

src/CoreBundle/Entity/ExtraField.php

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@ class ExtraField
8888
public const FIELD_TYPE_FILE = 18;
8989
public const FIELD_TYPE_GEOLOCALIZATION = 24;
9090
public const FIELD_TYPE_GEOLOCALIZATION_COORDINATES = 25;
91+
public const FIELD_TYPE_DURATION = 28;
9192

9293
#[Groups(['extra_field:read'])]
9394
#[ORM\Column(name: 'id', type: 'integer')]
@@ -253,7 +254,7 @@ public function setFieldOrder(int $fieldOrder): self
253254

254255
public function isChangeable(): ?bool
255256
{
256-
return $this->changeable;
257+
return (bool) $this->changeable;
257258
}
258259

259260
public function setChangeable(bool $changeable): self
@@ -265,7 +266,7 @@ public function setChangeable(bool $changeable): self
265266

266267
public function isFilter(): bool
267268
{
268-
return $this->filter;
269+
return (bool) $this->filter;
269270
}
270271

271272
public function setFilter(bool $filter): self
@@ -277,7 +278,7 @@ public function setFilter(bool $filter): self
277278

278279
public function isVisibleToSelf(): bool
279280
{
280-
return $this->visibleToSelf;
281+
return (bool) $this->visibleToSelf;
281282
}
282283

283284
public function setVisibleToSelf(bool $visibleToSelf): self
@@ -289,7 +290,7 @@ public function setVisibleToSelf(bool $visibleToSelf): self
289290

290291
public function isVisibleToOthers(): bool
291292
{
292-
return $this->visibleToOthers;
293+
return (bool) $this->visibleToOthers;
293294
}
294295

295296
public function setVisibleToOthers(bool $visibleToOthers): self

0 commit comments

Comments
 (0)