Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions .horde.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ authors:
-
name: Dmitry Petrov
user: dpetrov
email: ''
email:
active: true
role: lead
-
Expand Down Expand Up @@ -38,10 +38,10 @@ authors:
active: false
role: lead
version:
release: 3.0.0-beta8
release: 3.0.0-RC1
api: 3.0.0alpha1
state:
release: beta
release: RC
api: alpha
license:
identifier: LGPL-2.1-only
Expand Down
16 changes: 15 additions & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,20 @@
"homepage": "https://www.horde.org/libraries/Horde_Form",
"license": "LGPL-2.1-only",
"authors": [
{
"name": "Dmitry Petrov",
"role": "lead"
},
{
"name": "Torben Dannhauber",
"email": "torben@dannhauer.de",
"role": "releasemanager"
},
{
"name": "Ralf Lang",
"email": "ralf.lang@ralf-lang.de",
"role": "contributor"
},
{
"name": "Jan Schneider",
"email": "jan@horde.org",
Expand All @@ -21,7 +35,7 @@
"validation",
"crud"
],
"time": "2026-04-13",
"time": "2026-05-18",
"repositories": [],
"require": {
"php": "^7.4 || ^8",
Expand Down
35 changes: 35 additions & 0 deletions doc/changelog.yml
Original file line number Diff line number Diff line change
Expand Up @@ -271,6 +271,41 @@
Original version string was 3.0.0alpha1
[mjr] SECURITY: Prevent ability to specify temporary filename (CVE-2020-8866, Reported By: Andrea Cardaci working with Trend Micro Zero Day Initiative).
|+
3.0.0-RC1:
api: 3.0.0-RC1
state:
release: RC
api: RC
date: 2026-05-18
license:
identifier: LGPL-2.1-only
uri: https://spdx.org/licenses/LGPL-2.1-only.html
notes: |-
fix: Allow Horde\Util\Variables class in isValid() method
fix: Add Delegators - 866aa1af commit "Refactor variable method calls in Html.php" broke trean config menu
feat: add __call magic method to delegate undefined methods to $type
fix(v3): Reproduce legacy type names in getTypeName()
refactor: Improve createVariable() logic
fix: Make unused $info parameter in Horde_Form_Variable::getInfo() optional
Fix prompt check and update getInfo call
Merge pull request #26 from horde6/FRAMEWORK_6_0
refactor: use getFieldParts() in _getInfoFromVariables()
refactor: simplify _getUpload and getUploadedFileType() - use getFieldParts() instead of getArrayParts() in 'image' type - utilize extra parameter in getElement/setElement to simplify the code - make getUploadedFileType() static
refactor: use array_splice in removeVariable()
fix: initialize $_img variable
refactor(Form): modernise _currentSection handling and variable insertion
Initialize _img property to null
Merge pull request #24 from horde6/V3
feat: Implement transitional support to V3 classes
docs: Add an "old-style entrypoint" and a PSR controller demonstrating all form types
test: Add regression test against the File behaviour change
fix: Restore original behavior of getInfo() for 'file" variable type
chore: Add Dmitry as the primary maintainer
fix: Type safety issue in PHP 8.5
docs: Add V3 UPGRADING.md which supersedes the previous migration guide
docs: Reference CSS for the V3 form model
test: Add test cases for V3 FieldGroups (replacing nested forms)
feat: Flesh out V3 forms and migrations
2.0.19:
api: 1.1.0
state:
Expand Down
18 changes: 9 additions & 9 deletions lib/Horde/Form/Type.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,11 @@
* @package Form
*/

use Horde\Date\Format;
use Horde\Date\FormatterInterface;
use Horde\Date\Formatter\IcuFormatter;
use Horde\Util\ArrayUtils;

use function PHP81_BC\strftime;

/**
* Horde_Form_Type Class
*
Expand Down Expand Up @@ -3099,8 +3099,8 @@ public function getFormattedTime($timestamp, $format = null, $showago = true)
$locale = $this->_resolveLocale();
$formatted = $this->_formatter->format($timestamp, $format, $locale, $this->_timezone);
} else {
// strftime mode (default, backward compatible)
$formatted = strftime($format, $timestamp);
// ICU format mode (default)
$formatted = Format::formatDate($timestamp, $format, $GLOBALS['language'] ?? 'en_US');
}
return $formatted . ($showago ? Horde_Form_Type_date::getAgo($timestamp) : '');
} else {
Expand Down Expand Up @@ -3598,8 +3598,8 @@ public function formatDate($date)
$locale = $this->_resolveLocale();
return $date->format($this->_format_out, $this->_formatter, $locale);
} else {
// strftime mode (default)
return $date->strftime($this->_format_out);
// ICU format mode (default)
return $date->format($this->_format_out, new IcuFormatter(), $GLOBALS['language'] ?? 'en_US');
}
}

Expand Down Expand Up @@ -3688,8 +3688,8 @@ public function _validateAndFormat($value, $var)
// Formatter mode
return $date->format($this->_format_in, $this->_formatter, $this->_locale);
} else {
// strftime mode
return $date->strftime($this->_format_in);
// ICU format mode
return $date->format($this->_format_in, new IcuFormatter(), $GLOBALS['language'] ?? 'en_US');
}
}
}
Expand Down Expand Up @@ -3827,7 +3827,7 @@ private function _getInfo($value)
if ($this->getProperty('format_in') === null) {
$info = $date->timestamp();
} else {
$info = $date->strftime($this->getProperty('format_in'));
$info = $date->format($this->getProperty('format_in'), new IcuFormatter(), $GLOBALS['language'] ?? 'en_US');
}
return $info;
}
Expand Down
9 changes: 5 additions & 4 deletions src/V3/DateVariable.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

namespace Horde\Form\V3;

use Horde\Date\Format;
use Horde\Util\Variables;
use Horde_Variables;
use Horde_Date;
Expand All @@ -11,7 +12,7 @@
/**
* DateVariable type for date input fields.
*
* @property string $format The date format string
* @property string $format The ICU date format pattern

*
* PSR-4 implementation.
Expand All @@ -26,13 +27,13 @@ class DateVariable extends BaseVariable
* Initialize a date field.
*
* @param array $params Variable arguments:
* - $params[0]: string $format - The date format string (default: '%a %d %B')
* - $params[0]: string $format - ICU date format pattern (default: 'EEE dd MMMM')
*
* @api
*/
public function init(...$params)
{
$this->_format = $params[0] ?? '%a %d %B';
$this->_format = $params[0] ?? 'EEE dd MMMM';
}

protected function isValid(Horde_Variables|array $vars, $value): bool
Expand Down Expand Up @@ -97,7 +98,7 @@ public function getFormattedTime($timestamp, $format = null, $showago = true)
$format = $this->_format;
}

return strftime($format, $timestamp) . ($showago ? $this::getAgo($timestamp) : '');
return Format::formatDate($timestamp, $format, $GLOBALS['language'] ?? 'en_US') . ($showago ? $this::getAgo($timestamp) : '');
}

/**
Expand Down
13 changes: 7 additions & 6 deletions src/V3/DatetimeVariable.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

namespace Horde\Form\V3;

use Horde\Date\Formatter\IcuFormatter;
use Horde\Util\Variables;
use Horde_Variables;
use Horde_Form_Translation;
Expand All @@ -12,8 +13,8 @@
* @property int $start_year The first available year for input
* @property int $end_year The last available year for input
* @property bool $picker Do we show the DHTML calendar
* @property string|null $format_in The format to use when sending the date for storage
* @property string $format_out The format to use when displaying the date
* @property string|null $format_in The ICU format to use when sending the date for storage
* @property string $format_out The ICU format to use when displaying the date
* @property bool $show_seconds Include a form input for seconds

*
Expand All @@ -33,8 +34,8 @@ class DatetimeVariable extends BaseVariable
* - $params[0]: int $start_year - The first available year for input (default: '')
* - $params[1]: int $end_year - The last available year for input (default: '')
* - $params[2]: bool $picker - Do we show the DHTML calendar (default: true)
* - $params[3]: string|null $format_in - The format to use when sending the date for storage. Defaults to Unix epoch. Similar to the strftime() function. (default: null)
* - $params[4]: string $format_out - The format to use when displaying the date. Similar to the strftime() function. (default: '%x')
* - $params[3]: string|null $format_in - ICU format for storage. Defaults to Unix epoch. (default: null)
* - $params[4]: string $format_out - ICU format for display (default: 'short')
* - $params[5]: bool $show_seconds - Include a form input for seconds (default: false)
*
* @api
Expand All @@ -45,7 +46,7 @@ public function init(...$params)
$end_year = $params[1] ?? '';
$picker = $params[2] ?? true;
$format_in = $params[3] ?? null;
$format_out = $params[4] ?? '%x';
$format_out = $params[4] ?? 'short';
$show_seconds = $params[5] ?? false;

$this->_mdy = new MonthdayyearVariable('', '', true);
Expand Down Expand Up @@ -100,7 +101,7 @@ private function _getInfo($value)
if ($this->getProperty('format_in') === null) {
$info = $date->timestamp();
} else {
$info = $date->strftime($this->getProperty('format_in'));
$info = $date->format($this->getProperty('format_in'), new IcuFormatter(), $GLOBALS['language'] ?? 'en_US');
}

return $info;
Expand Down
17 changes: 9 additions & 8 deletions src/V3/MonthdayyearVariable.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

namespace Horde\Form\V3;

use Horde\Date\Formatter\IcuFormatter;
use Horde\Util\Variables;
use Horde_Variables;
use Horde_Date;
Expand All @@ -13,8 +14,8 @@
* @property int $start_year The first available year for input
* @property int $end_year The last available year for input
* @property bool $picker Do we show the DHTML calendar
* @property string|null $format_in The format to use when sending the date for storage
* @property string $format_out The format to use when displaying the date
* @property string|null $format_in The ICU format to use when sending the date for storage
* @property string $format_out The ICU format to use when displaying the date

*
* PSR-4 implementation.
Expand All @@ -27,7 +28,7 @@ class MonthdayyearVariable extends BaseVariable
public $_end_year;
public $_picker;
public $_format_in = null;
public $_format_out = '%x';
public $_format_out = 'short';

/**
* Initialize a date selection field.
Expand All @@ -36,8 +37,8 @@ class MonthdayyearVariable extends BaseVariable
* - $params[0]: int $start_year - The first available year for input (default: current year)
* - $params[1]: int $end_year - The last available year for input (default: current year + 10)
* - $params[2]: bool $picker - Do we show the DHTML calendar (default: true)
* - $params[3]: string|null $format_in - The format to use when sending the date for storage. Defaults to Unix epoch. Similar to the strftime() function. (default: null)
* - $params[4]: string $format_out - The format to use when displaying the date. Similar to the strftime() function. (default: '%x')
* - $params[3]: string|null $format_in - ICU format for storage. Defaults to Unix epoch. (default: null)
* - $params[4]: string $format_out - ICU format for display (default: 'short')
*
* @api
*/
Expand All @@ -47,7 +48,7 @@ public function init(...$params)
$end_year = $params[1] ?? '';
$picker = $params[2] ?? true;
$format_in = $params[3] ?? null;
$format_out = $params[4] ?? '%x';
$format_out = $params[4] ?? 'short';

if (empty($start_year)) {
$start_year = date('Y');
Expand Down Expand Up @@ -211,7 +212,7 @@ public function formatDate($date)
$date = $this->getDateOb($date);
}

return $date->strftime($this->_format_out);
return $date->format($this->_format_out, new IcuFormatter(), $GLOBALS['language'] ?? 'en_US');
}

/**
Expand Down Expand Up @@ -246,7 +247,7 @@ public function _validateAndFormat($value)
return $date->timestamp();
}

return $date->strftime($this->_format_in);
return $date->format($this->_format_in, new IcuFormatter(), $GLOBALS['language'] ?? 'en_US');
}

/**
Expand Down
11 changes: 11 additions & 0 deletions var/config/horde/registry.d/00-horde.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<?php

/**
* AUTOGENERATED ONLY IF ABSENT
* Edit this file to match your needs
* To reset from defaults, run `composer horde:reconfigure --force --mode=proxy`
*/
$deployment_webroot = '/';
$deployment_fileroot = '/home/i567442/php/git/horde/Form/web';
$app_fileroot = '/home/i567442/php/git/horde/Form/web/horde';
$app_webroot = '/horde';
7 changes: 7 additions & 0 deletions var/config/horde/registry.d/03-override-webroots.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<?php

/**
* AUTOGENERATED ONLY IF ABSENT
* If you activate at least one of these lines, please also set a full https URL for the default webroot where the remaining apps and the assets (js, themes, static) are located
* Run `composer horde:reconfigure --mode=proxy --webroot="https://assets.example.com/"`
*/
1 change: 1 addition & 0 deletions web/js/horde/accesskeys.js
1 change: 1 addition & 0 deletions web/js/horde/addressbooksprefs.js
1 change: 1 addition & 0 deletions web/js/horde/alarmprefs.js
1 change: 1 addition & 0 deletions web/js/horde/autocomplete.js
1 change: 1 addition & 0 deletions web/js/horde/calendar.js
1 change: 1 addition & 0 deletions web/js/horde/colorpicker.js
1 change: 1 addition & 0 deletions web/js/horde/date
1 change: 1 addition & 0 deletions web/js/horde/dialog.js
1 change: 1 addition & 0 deletions web/js/horde/excanvas
1 change: 1 addition & 0 deletions web/js/horde/flotr2
1 change: 1 addition & 0 deletions web/js/horde/form_assign.js
1 change: 1 addition & 0 deletions web/js/horde/form_helpers.js
1 change: 1 addition & 0 deletions web/js/horde/growler-jquery.js
1 change: 1 addition & 0 deletions web/js/horde/growler.js
1 change: 1 addition & 0 deletions web/js/horde/horde-jquery-init.js
1 change: 1 addition & 0 deletions web/js/horde/horde-jquery.js
1 change: 1 addition & 0 deletions web/js/horde/horde.js
1 change: 1 addition & 0 deletions web/js/horde/hordeblocks.js
1 change: 1 addition & 0 deletions web/js/horde/hordecore.js
1 change: 1 addition & 0 deletions web/js/horde/hordetree.js
1 change: 1 addition & 0 deletions web/js/horde/identityselect.js
1 change: 1 addition & 0 deletions web/js/horde/image.js
1 change: 1 addition & 0 deletions web/js/horde/imple.js
1 change: 1 addition & 0 deletions web/js/horde/inplaceeditor.js
Loading
Loading