mirror of
https://github.com/silverstripe/silverstripe-framework
synced 2024-10-22 12:05:37 +00:00
MERGE
This commit is contained in:
parent
326aa37ea4
commit
3b94d14e42
@ -4,7 +4,11 @@ summary: How to format and use the DateField class.
|
||||
# DateField
|
||||
|
||||
This `FormField` subclass lets you display an editable date, in a single text input field.
|
||||
It also provides a calendar date picker.
|
||||
It implements the [HTML5 input date type](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/date)
|
||||
(with `type=date`). In supported browsers, this will cause a localised date picker to appear for users.
|
||||
HTML5 date fields present and save ISO 8601 date formats (`y-MM-dd`),
|
||||
since the browser takes care of converting to/from a localised presentation.
|
||||
Browsers without support receive an `<input type=text>` based polyfill.
|
||||
|
||||
The following example will add a simple DateField to your Page, allowing you to enter a date manually.
|
||||
|
||||
@ -34,10 +38,13 @@ The following example will add a simple DateField to your Page, allowing you to
|
||||
## Custom Date Format
|
||||
|
||||
A custom date format for a [api:DateField] can be provided through `setDateFormat`.
|
||||
This is only necessary if you want to opt-out of the built-in browser localisation via `type=date`.
|
||||
|
||||
:::php
|
||||
// will display a date in the following format: 31-06-2012
|
||||
DateField::create('MyDate')->setDateFormat('dd-MM-yyyy');
|
||||
// will display a date in the following format: 31/06/2012
|
||||
DateField::create('MyDate')
|
||||
->setHTML5(false)
|
||||
->setDateFormat('dd/MM/yyyy');
|
||||
|
||||
<div class="info" markdown="1">
|
||||
The formats are based on [ICU format](http://www.icu-project.org/apiref/icu4c/classSimpleDateFormat.html#details).
|
||||
@ -53,34 +60,6 @@ Sets the minimum and maximum allowed date values using the `min` and `max` confi
|
||||
DateField::create('MyDate')
|
||||
->setMinDate('-7 days')
|
||||
->setMaxDate('2012-12-31')
|
||||
|
||||
## Separate Day / Month / Year Fields
|
||||
|
||||
To display separate input fields for day, month and year separately you can use the `SeparatedDateField` subclass`.
|
||||
HTML5 placeholders 'day', 'month' and 'year' are enabled by default.
|
||||
|
||||
:::php
|
||||
SeparatedDateField::create('MyDate');
|
||||
|
||||
<div class="alert" markdown="1">
|
||||
Any custom date format settings will be ignored.
|
||||
</div>
|
||||
|
||||
## Date Picker and HTML5 support
|
||||
|
||||
The field can be used as a [HTML5 input date type](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/date)
|
||||
(with `type=date`) by calling `setHTML5(true)`.
|
||||
|
||||
:::php
|
||||
DateField::create('MyDate')
|
||||
->setHTML5(true);
|
||||
|
||||
In browsers [supporting HTML5 date inputs](caniuse.com/#feat=input-datetime),
|
||||
this will cause a localised date picker to appear for users.
|
||||
In this mode, the field will be forced to present and save ISO 8601 date formats (`y-MM-dd`),
|
||||
since the browser takes care of converting to/from a localised presentation.
|
||||
|
||||
Browsers without support receive an `<input type=text>` based polyfill.
|
||||
|
||||
## Formatting Hints
|
||||
|
||||
|
@ -405,6 +405,7 @@ in `DateField` and `TimeField` now ([discussion](https://github.com/silverstripe
|
||||
where the browser localises the output based on the browser/system preferences.
|
||||
In this context it no longer makes sense to give users control over their own
|
||||
date and time formats in their CMS profile.
|
||||
Consequently, we've also removed `MemberDatetimeOptionsetField`.
|
||||
|
||||
`Member->getDateFormat()` and `Member->getTimeFormat()` still exist, and default to
|
||||
the [IntlDateFormatter defaults](http://php.net/manual/en/class.intldateformatter.php) for the selected locale.
|
||||
@ -1514,13 +1515,11 @@ New `DateField` methods replace `getConfig()` / `setConfig()`:
|
||||
|
||||
The `DateField` has changed behavior:
|
||||
|
||||
* `DateField` no longer provides a jQuery UI date picker,
|
||||
and uses [HTML5 date pickers](https://www.wufoo.com/html5/types/4-date.html) instead.
|
||||
Use `setUseHTML()` to activate this mode (instead of `setConfig('showcalendar', true)`).
|
||||
* `DateField` no longer provides a jQuery UI date picker (`showcalendar` option),
|
||||
and uses [HTML5 date pickers](https://www.wufoo.com/html5/types/4-date.html) by default instead.
|
||||
* `DateField` provides an optional polyfill for
|
||||
[browsers without HTML5 date picker support](http://caniuse.com/#feat=input-datetime)
|
||||
* The `dmyfields` option is now superceded with an `SeparatedDateField` class.
|
||||
* `getPlaceholders()` / `setPlaceholders()` moved to a new `SeparatedDateField` class
|
||||
* The `dmyfields` option has been replced with native HTML5 behaviour (as one single `<input type=date>`).
|
||||
* `getClientLocale` / `setClientLocale` have been removed (handled by `DateField->locale` and browser settings)
|
||||
|
||||
New `TimeField` methods replace `getConfig()` / `setConfig()`
|
||||
@ -1569,7 +1568,9 @@ New `TimeField` methods replace `getConfig()` / `setConfig()`
|
||||
* `set_source_file_comments()`
|
||||
* `get_source_file_comments()`
|
||||
* `getOption`
|
||||
* `setOption`
|
||||
* `setOption`
|
||||
* Removed `MemberDatetimeOptionsetField` (no replacement)
|
||||
* Removed `DateField_View_JQuery` (replaced with native HTML5 support in `DateField`)
|
||||
|
||||
### <a name="overview-i18n"></a>i18n API
|
||||
|
||||
|
@ -5,6 +5,7 @@ namespace SilverStripe\Forms;
|
||||
use IntlDateFormatter;
|
||||
use SilverStripe\i18n\i18n;
|
||||
use InvalidArgumentException;
|
||||
use SilverStripe\ORM\FieldType\DBDate;
|
||||
use SilverStripe\ORM\FieldType\DBDatetime;
|
||||
|
||||
/**
|
||||
@ -119,7 +120,7 @@ class DateField extends TextField
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
protected $html5 = false;
|
||||
protected $html5 = true;
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
@ -159,12 +160,8 @@ class DateField extends TextField
|
||||
}
|
||||
|
||||
/**
|
||||
* Get length of the date format to use. One of:
|
||||
*
|
||||
* - IntlDateFormatter::SHORT
|
||||
* - IntlDateFormatter::MEDIUM
|
||||
* - IntlDateFormatter::LONG
|
||||
* - IntlDateFormatter::FULL
|
||||
* Get length of the date format to use.
|
||||
* Only applicable with {@link setHTML5(false)}.
|
||||
*
|
||||
* @see http://php.net/manual/en/class.intldateformatter.php#intl.intldateformatter-constants
|
||||
*
|
||||
@ -187,6 +184,11 @@ class DateField extends TextField
|
||||
*/
|
||||
public function getDateFormat()
|
||||
{
|
||||
if ($this->getHTML5()) {
|
||||
// Browsers expect ISO 8601 dates, localisation is handled on the client
|
||||
$this->setDateFormat(DBDate::ISO_DATE);
|
||||
}
|
||||
|
||||
if ($this->dateFormat) {
|
||||
return $this->dateFormat;
|
||||
}
|
||||
@ -197,6 +199,7 @@ class DateField extends TextField
|
||||
|
||||
/**
|
||||
* Set date format in CLDR standard format.
|
||||
* Only applicable with {@link setHTML5(false)}.
|
||||
*
|
||||
* @see http://userguide.icu-project.org/formatparse/datetime#TOC-Date-Field-Symbol-Table
|
||||
* @param string $format
|
||||
@ -216,24 +219,33 @@ class DateField extends TextField
|
||||
*/
|
||||
protected function getFormatter()
|
||||
{
|
||||
if ($this->getHTML5() && $this->dateFormat && $this->dateFormat !== DBDate::ISO_DATE) {
|
||||
throw new \LogicException(
|
||||
'Please opt-out of HTML5 processing of ISO 8601 dates via setHTML5(false) if using setDateFormat()'
|
||||
);
|
||||
}
|
||||
|
||||
if ($this->getHTML5() && $this->dateLength) {
|
||||
throw new \LogicException(
|
||||
'Please opt-out of HTML5 processing of ISO 8601 dates via setHTML5(false) if using setDateLength()'
|
||||
);
|
||||
}
|
||||
|
||||
if ($this->getHTML5() && $this->locale) {
|
||||
throw new \LogicException(
|
||||
'Please opt-out of HTML5 processing of ISO 8601 dates via setHTML5(false) if using setLocale()'
|
||||
);
|
||||
}
|
||||
|
||||
$formatter = IntlDateFormatter::create(
|
||||
$this->getLocale(),
|
||||
$this->getDateLength(),
|
||||
IntlDateFormatter::NONE
|
||||
);
|
||||
|
||||
$isoFormat = 'y-MM-dd';
|
||||
|
||||
if ($this->dateFormat && $this->getHTML5() && $this->dateFormat !== $isoFormat) {
|
||||
throw new \LogicException(sprintf(
|
||||
'Can\'t use a custom dateFormat value with $html5=true (needs to be %s)',
|
||||
$isoFormat
|
||||
));
|
||||
}
|
||||
|
||||
if ($this->getHTML5()) {
|
||||
// Browsers expect ISO 8601 dates, localisation is handled on the client
|
||||
$formatter->setPattern($isoFormat);
|
||||
$formatter->setPattern(DBDate::ISO_DATE);
|
||||
} elseif ($this->dateFormat) {
|
||||
// Don't invoke getDateFormat() directly to avoid infinite loop
|
||||
$ok = $formatter->setPattern($this->dateFormat);
|
||||
@ -259,20 +271,10 @@ class DateField extends TextField
|
||||
);
|
||||
$formatter->setLenient(false);
|
||||
// CLDR ISO 8601 date.
|
||||
$formatter->setPattern('y-MM-dd');
|
||||
$formatter->setPattern(DBDate::ISO_DATE);
|
||||
return $formatter;
|
||||
}
|
||||
|
||||
public function FieldHolder($properties = array())
|
||||
{
|
||||
if ($this->getHTML5()) {
|
||||
// Browsers expect ISO 8601 dates, localisation is handled on the client
|
||||
$this->setDateFormat('y-MM-dd');
|
||||
}
|
||||
|
||||
return parent::FieldHolder($properties);
|
||||
}
|
||||
|
||||
public function getAttributes()
|
||||
{
|
||||
$attributes = parent::getAttributes();
|
||||
@ -421,7 +423,9 @@ class DateField extends TextField
|
||||
}
|
||||
|
||||
/**
|
||||
* Caution: Will not update the 'dateformat' config value.
|
||||
* Determines the presented/processed format based on locale defaults,
|
||||
* instead of explicitly setting {@link setDateFormat()}.
|
||||
* Only applicable with {@link setHTML5(false)}.
|
||||
*
|
||||
* @param string $locale
|
||||
* @return $this
|
||||
|
@ -1,206 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace SilverStripe\Forms;
|
||||
|
||||
use SilverStripe\i18n\i18n;
|
||||
|
||||
/**
|
||||
* Date field with separate inputs for d/m/y
|
||||
*/
|
||||
class SeparatedDateField extends DateField
|
||||
{
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $separator = '/';
|
||||
|
||||
/**
|
||||
* Set whether to show placeholders
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
protected $placeholders = true;
|
||||
|
||||
public function Field($properties = array())
|
||||
{
|
||||
// Three separate fields for day, month and year
|
||||
$valArr = $this->iso8601ToArray($this->dataValue());
|
||||
$fieldDay = NumericField::create($this->name . '[day]', false, $valArr ? $valArr['day'] : null)
|
||||
->addExtraClass('day')
|
||||
->setHTML5(true)
|
||||
->setMaxLength(2);
|
||||
$fieldMonth = NumericField::create($this->name . '[month]', false, $valArr ? $valArr['month'] : null)
|
||||
->addExtraClass('month')
|
||||
->setHTML5(true)
|
||||
->setMaxLength(2);
|
||||
$fieldYear = NumericField::create($this->name . '[year]', false, $valArr ? $valArr['year'] : null)
|
||||
->addExtraClass('year')
|
||||
->setHTML5(true)
|
||||
->setMaxLength(4);
|
||||
|
||||
// Set placeholders
|
||||
if ($this->getPlaceholders()) {
|
||||
$fieldDay->setAttribute('placeholder', _t(__CLASS__ . '.DAY', 'Day'));
|
||||
$fieldMonth->setAttribute('placeholder', _t(__CLASS__ . '.MONTH', 'Month'));
|
||||
$fieldYear->setAttribute('placeholder', _t(__CLASS__ . '.YEAR', 'Year'));
|
||||
}
|
||||
|
||||
$format = $this->getDateFormat();
|
||||
$validFormat = (
|
||||
stripos($format, 'd') !== false
|
||||
&& stripos($format, 'm') !== false
|
||||
&& stripos($format, 'y') !== false
|
||||
);
|
||||
if (!$validFormat) {
|
||||
throw new \InvalidArgumentException(
|
||||
'Invalid date format for field ordering: ' . $format
|
||||
. '. Requires "d", "m", and "y" values to determine order'
|
||||
);
|
||||
}
|
||||
|
||||
$fields = array();
|
||||
$fields[stripos($format, 'd')] = $fieldDay->Field();
|
||||
$fields[stripos($format, 'm')] = $fieldMonth->Field();
|
||||
$fields[stripos($format, 'y')] = $fieldYear->Field();
|
||||
ksort($fields);
|
||||
|
||||
|
||||
// Join all fields
|
||||
$sep = ' <span class="separator">' . $this->getSeparator() . '</span> ';
|
||||
return implode($sep, $fields);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $string
|
||||
* @return self
|
||||
*/
|
||||
public function setSeparator($separator)
|
||||
{
|
||||
$this->separator = $separator;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getSeparator()
|
||||
{
|
||||
return $this->separator;
|
||||
}
|
||||
|
||||
/**
|
||||
* If placeholders are shown
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function getPlaceholders()
|
||||
{
|
||||
return $this->placeholders;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set if placeholders are shown
|
||||
*
|
||||
* @param bool $placeholders
|
||||
* @return $this
|
||||
*/
|
||||
public function setPlaceholders($placeholders)
|
||||
{
|
||||
$this->placeholders = $placeholders;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert array to timestamp
|
||||
*
|
||||
* @param array $value
|
||||
* @return string
|
||||
*/
|
||||
public function arrayToISO8601($value)
|
||||
{
|
||||
if ($this->isEmptyArray($value)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// ensure all keys are specified
|
||||
if (!isset($value['month']) || !isset($value['day']) || !isset($value['year'])) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Ensure valid range
|
||||
if (!checkdate($value['month'], $value['day'], $value['year'])) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Note: Set formatter to strict for array input
|
||||
$formatter = $this->getISO8601Formatter();
|
||||
$timestamp = mktime(0, 0, 0, $value['month'], $value['day'], $value['year']);
|
||||
if ($timestamp === false) {
|
||||
return null;
|
||||
}
|
||||
return $formatter->format($timestamp);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert iso 8601 date to array (day / month / year)
|
||||
*
|
||||
* @param string $date
|
||||
* @return array|null Array form, or null if not valid
|
||||
*/
|
||||
public function iso8601ToArray($date)
|
||||
{
|
||||
if (!$date) {
|
||||
return null;
|
||||
}
|
||||
$formatter = $this->getISO8601Formatter();
|
||||
$timestamp = $formatter->parse($date);
|
||||
if ($timestamp === false) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Format time manually into an array
|
||||
return [
|
||||
'day' => date('j', $timestamp),
|
||||
'month' => date('n', $timestamp),
|
||||
'year' => date('Y', $timestamp),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Assign value posted from form submission
|
||||
*
|
||||
* @param mixed $value
|
||||
* @param mixed $data
|
||||
* @return $this
|
||||
*/
|
||||
public function setSubmittedValue($value, $data = null)
|
||||
{
|
||||
// Filter out empty arrays
|
||||
if ($this->isEmptyArray($value)) {
|
||||
$value = null;
|
||||
}
|
||||
$this->rawValue = $value;
|
||||
|
||||
// Null case
|
||||
if (!$value || !is_array($value)) {
|
||||
$this->value = null;
|
||||
return $this;
|
||||
}
|
||||
|
||||
// Parse
|
||||
$this->value = $this->arrayToISO8601($value);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if this array is empty
|
||||
*
|
||||
* @param $value
|
||||
* @return bool
|
||||
*/
|
||||
public function isEmptyArray($value)
|
||||
{
|
||||
return is_array($value) && !array_filter($value);
|
||||
}
|
||||
}
|
@ -6,6 +6,7 @@ use IntlDateFormatter;
|
||||
use InvalidArgumentException;
|
||||
use SilverStripe\i18n\i18n;
|
||||
use SilverStripe\ORM\FieldType\DBDatetime;
|
||||
use SilverStripe\ORM\FieldType\DBTime;
|
||||
|
||||
/**
|
||||
* Form field to display editable time values in an <input type="text"> field.
|
||||
@ -58,11 +59,11 @@ class TimeField extends TextField
|
||||
protected $timezone = null;
|
||||
|
||||
/**
|
||||
* Use HTML5-based input fields (and force ISO 8601 date formats).
|
||||
* Use HTML5-based input fields (and force ISO 8601 time formats).
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
protected $html5 = false;
|
||||
protected $html5 = true;
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
@ -92,6 +93,11 @@ class TimeField extends TextField
|
||||
*/
|
||||
public function getTimeFormat()
|
||||
{
|
||||
if ($this->getHTML5()) {
|
||||
// Browsers expect ISO 8601 times, localisation is handled on the client
|
||||
$this->setTimeFormat(DBTime::ISO_TIME);
|
||||
}
|
||||
|
||||
if ($this->timeFormat) {
|
||||
return $this->timeFormat;
|
||||
}
|
||||
@ -102,6 +108,7 @@ class TimeField extends TextField
|
||||
|
||||
/**
|
||||
* Set time format in CLDR standard format.
|
||||
* Only applicable with {@link setHTML5(false)}.
|
||||
*
|
||||
* @see http://userguide.icu-project.org/formatparse/datetime#TOC-Date-Field-Symbol-Table
|
||||
* @param string $format
|
||||
@ -133,12 +140,8 @@ class TimeField extends TextField
|
||||
}
|
||||
|
||||
/**
|
||||
* Get length of the time format to use. One of:
|
||||
*
|
||||
* - IntlDateFormatter::SHORT E.g. '6:31 PM'
|
||||
* - IntlDateFormatter::MEDIUM E.g. '6:30:48 PM'
|
||||
* - IntlDateFormatter::LONG E.g. '6:32:09 PM NZDT'
|
||||
* - IntlDateFormatter::FULL E.g. '6:32:24 PM New Zealand Daylight Time'
|
||||
* Get length of the time format to use.
|
||||
* Only applicable with {@link setHTML5(false)}.
|
||||
*
|
||||
* @see http://php.net/manual/en/class.intldateformatter.php#intl.intldateformatter-constants
|
||||
*
|
||||
@ -158,6 +161,24 @@ class TimeField extends TextField
|
||||
*/
|
||||
protected function getFormatter()
|
||||
{
|
||||
if ($this->getHTML5() && $this->timeFormat && $this->timeFormat !== DBTime::ISO_TIME) {
|
||||
throw new \LogicException(
|
||||
'Please opt-out of HTML5 processing of ISO 8601 times via setHTML5(false) if using setTimeFormat()'
|
||||
);
|
||||
}
|
||||
|
||||
if ($this->getHTML5() && $this->timeLength) {
|
||||
throw new \LogicException(
|
||||
'Please opt-out of HTML5 processing of ISO 8601 times via setHTML5(false) if using setTimeLength()'
|
||||
);
|
||||
}
|
||||
|
||||
if ($this->getHTML5() && $this->locale) {
|
||||
throw new \LogicException(
|
||||
'Please opt-out of HTML5 processing of ISO 8601 times via setHTML5(false) if using setLocale()'
|
||||
);
|
||||
}
|
||||
|
||||
$formatter = IntlDateFormatter::create(
|
||||
$this->getLocale(),
|
||||
IntlDateFormatter::NONE,
|
||||
@ -165,18 +186,9 @@ class TimeField extends TextField
|
||||
$this->getTimezone()
|
||||
);
|
||||
|
||||
$isoFormat = 'HH:mm:ss';
|
||||
|
||||
if ($this->timeFormat && $this->getHTML5() && $this->timeFormat !== $isoFormat) {
|
||||
throw new \LogicException(sprintf(
|
||||
'Can\'t use a custom timeFormat value with $html5=true (needs to be %s)',
|
||||
$isoFormat
|
||||
));
|
||||
}
|
||||
|
||||
if ($this->getHTML5()) {
|
||||
// Browsers expect ISO 8601 times, localisation is handled on the client
|
||||
$formatter->setPattern($isoFormat);
|
||||
$formatter->setPattern(DBTime::ISO_TIME);
|
||||
// Don't invoke getTimeFormat() directly to avoid infinite loop
|
||||
} elseif ($this->timeFormat) {
|
||||
$ok = $formatter->setPattern($this->timeFormat);
|
||||
@ -201,9 +213,10 @@ class TimeField extends TextField
|
||||
date_default_timezone_get() // Default to server timezone
|
||||
);
|
||||
$formatter->setLenient(false);
|
||||
// ISO 8601 time
|
||||
|
||||
// Note we omit timezone from this format, and we assume server TZ always.
|
||||
$formatter->setPattern('HH:mm:ss');
|
||||
$formatter->setPattern(DBTime::ISO_TIME);
|
||||
|
||||
return $formatter;
|
||||
}
|
||||
|
||||
@ -325,6 +338,10 @@ class TimeField extends TextField
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines the presented/processed format based on locale defaults,
|
||||
* instead of explicitly setting {@link setTimeFormat()}.
|
||||
* Only applicable with {@link setHTML5(false)}.
|
||||
*
|
||||
* @param string $locale
|
||||
* @return $this
|
||||
*/
|
||||
@ -363,7 +380,7 @@ class TimeField extends TextField
|
||||
|
||||
// Try to parse time without seconds, since that's a valid HTML5 submission format
|
||||
// See https://html.spec.whatwg.org/multipage/infrastructure.html#times
|
||||
if ($timestamp === false && $this->setHTML5(true)) {
|
||||
if ($timestamp === false && $this->getHTML5()) {
|
||||
$fromFormatter->setPattern('HH:mm');
|
||||
$timestamp = $fromFormatter->parse($time);
|
||||
}
|
||||
|
@ -141,10 +141,7 @@ class DBTime extends DBField
|
||||
|
||||
public function scaffoldFormField($title = null, $params = null)
|
||||
{
|
||||
$field = TimeField::create($this->name, $title);
|
||||
$field->setHTML5(true);
|
||||
|
||||
return $field;
|
||||
return TimeField::create($this->name, $title);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1318,8 +1318,15 @@ class Member extends DataObject implements TemplateGlobalProvider
|
||||
*/
|
||||
public function getDateFormat()
|
||||
{
|
||||
$format = $this->getDefaultDateFormat();
|
||||
$formatter = new IntlDateFormatter(
|
||||
$this->getLocale(),
|
||||
IntlDateFormatter::MEDIUM,
|
||||
IntlDateFormatter::NONE
|
||||
);
|
||||
$format = $formatter->getPattern();
|
||||
|
||||
$this->extend('updateDateFormat', $format);
|
||||
|
||||
return $format;
|
||||
}
|
||||
|
||||
@ -1343,7 +1350,13 @@ class Member extends DataObject implements TemplateGlobalProvider
|
||||
*/
|
||||
public function getTimeFormat()
|
||||
{
|
||||
$format = $this->getDefaultTimeFormat();
|
||||
$formatter = new IntlDateFormatter(
|
||||
$this->getLocale(),
|
||||
IntlDateFormatter::NONE,
|
||||
IntlDateFormatter::MEDIUM
|
||||
);
|
||||
$format = $formatter->getPattern();
|
||||
|
||||
$this->extend('updateTimeFormat', $format);
|
||||
|
||||
return $format;
|
||||
@ -1588,33 +1601,6 @@ class Member extends DataObject implements TemplateGlobalProvider
|
||||
return parent::getCMSFields();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getDefaultDateFormat()
|
||||
{
|
||||
$formatter = new IntlDateFormatter(
|
||||
$this->getLocale(),
|
||||
IntlDateFormatter::MEDIUM,
|
||||
IntlDateFormatter::NONE
|
||||
);
|
||||
return $formatter->getPattern();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getDefaultTimeFormat()
|
||||
{
|
||||
$formatter = new IntlDateFormatter(
|
||||
$this->getLocale(),
|
||||
IntlDateFormatter::NONE,
|
||||
IntlDateFormatter::MEDIUM
|
||||
);
|
||||
$defaultTimeFormat = $formatter->getPattern();
|
||||
return $defaultTimeFormat;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool $includerelations Indicate if the labels returned include relation fields
|
||||
* @return array
|
||||
|
@ -2,9 +2,9 @@
|
||||
|
||||
namespace SilverStripe\Forms\Tests;
|
||||
|
||||
use IntlDateFormatter;
|
||||
use SilverStripe\Dev\SapphireTest;
|
||||
use SilverStripe\Forms\DateField;
|
||||
use SilverStripe\Forms\SeparatedDateField;
|
||||
use SilverStripe\Forms\RequiredFields;
|
||||
use SilverStripe\i18n\i18n;
|
||||
use SilverStripe\ORM\FieldType\DBDatetime;
|
||||
@ -105,21 +105,11 @@ class DateFieldTest extends SapphireTest
|
||||
public function testSetValueWithDateString()
|
||||
{
|
||||
$f = new DateField('Date', 'Date');
|
||||
$f->setHTML5(false);
|
||||
$f->setSubmittedValue('29/03/2003');
|
||||
$this->assertEquals($f->dataValue(), '2003-03-29');
|
||||
}
|
||||
|
||||
public function testSetValueWithDateArray()
|
||||
{
|
||||
$f = new SeparatedDateField('Date', 'Date');
|
||||
$f->setSubmittedValue([
|
||||
'day' => 29,
|
||||
'month' => 03,
|
||||
'year' => 2003
|
||||
]);
|
||||
$this->assertEquals($f->dataValue(), '2003-03-29');
|
||||
}
|
||||
|
||||
public function testConstructorWithIsoDate()
|
||||
{
|
||||
// used by Form->loadDataFrom()
|
||||
@ -145,84 +135,11 @@ class DateFieldTest extends SapphireTest
|
||||
$this->assertFalse($f->validate(new RequiredFields()));
|
||||
}
|
||||
|
||||
public function testEmptyValueValidation()
|
||||
{
|
||||
$validator = new RequiredFields();
|
||||
$field = new SeparatedDateField('Date');
|
||||
$this->assertTrue($field->validate($validator));
|
||||
$field->setSubmittedValue([
|
||||
'day' => '',
|
||||
'month' => '',
|
||||
'year' => '',
|
||||
]);
|
||||
$this->assertTrue($field->validate($validator));
|
||||
}
|
||||
|
||||
public function testValidateArray()
|
||||
{
|
||||
$f = new SeparatedDateField('Date', 'Date');
|
||||
$f->setSubmittedValue([
|
||||
'day' => 29,
|
||||
'month' => 03,
|
||||
'year' => 2003
|
||||
]);
|
||||
$this->assertTrue($f->validate(new RequiredFields()));
|
||||
|
||||
$f->setValue(null);
|
||||
$this->assertTrue($f->validate(new RequiredFields()), 'NULL values are validating TRUE');
|
||||
|
||||
$f->setSubmittedValue(array());
|
||||
$this->assertTrue($f->validate(new RequiredFields()), 'Empty array values are validating TRUE');
|
||||
|
||||
$f->setSubmittedValue([
|
||||
'day' => null,
|
||||
'month' => null,
|
||||
'year' => null
|
||||
]);
|
||||
$this->assertTrue($f->validate(new RequiredFields()), 'Empty array values with keys are validating TRUE');
|
||||
$f->setSubmittedValue([
|
||||
'day' => 9999,
|
||||
'month' => 9999,
|
||||
'year' => 9999
|
||||
]);
|
||||
$this->assertFalse($f->validate(new RequiredFields()));
|
||||
}
|
||||
|
||||
public function testValidateEmptyArrayValuesSetsNullForValueObject()
|
||||
{
|
||||
$f = new SeparatedDateField('Date', 'Date');
|
||||
$f->setSubmittedValue([
|
||||
'day' => '',
|
||||
'month' => '',
|
||||
'year' => ''
|
||||
]);
|
||||
$this->assertNull($f->dataValue());
|
||||
|
||||
$f->setSubmittedValue([
|
||||
'day' => null,
|
||||
'month' => null,
|
||||
'year' => null
|
||||
]);
|
||||
$this->assertNull($f->dataValue());
|
||||
}
|
||||
|
||||
public function testValidateArrayValue()
|
||||
{
|
||||
$f = new SeparatedDateField('Date', 'Date');
|
||||
$f->setSubmittedValue(['day' => 29, 'month' => 03, 'year' => 2003]);
|
||||
$this->assertTrue($f->validate(new RequiredFields()));
|
||||
|
||||
$f->setSubmittedValue(['month' => 03, 'year' => 2003]);
|
||||
$this->assertFalse($f->validate(new RequiredFields()));
|
||||
|
||||
$f->setSubmittedValue(array('day' => 99, 'month' => 99, 'year' => 2003));
|
||||
$this->assertFalse($f->validate(new RequiredFields()));
|
||||
}
|
||||
|
||||
public function testFormatEnNz()
|
||||
{
|
||||
/* We get YYYY-MM-DD format as the data value for DD/MM/YYYY input value */
|
||||
$f = new DateField('Date', 'Date');
|
||||
$f->setHTML5(false);
|
||||
$f->setSubmittedValue('29/03/2003');
|
||||
$this->assertEquals($f->dataValue(), '2003-03-29');
|
||||
}
|
||||
@ -232,6 +149,7 @@ class DateFieldTest extends SapphireTest
|
||||
// should get en_NZ by default through setUp()
|
||||
i18n::set_locale('de_DE');
|
||||
$f = new DateField('Date', 'Date', '29/03/2003');
|
||||
$f->setHTML5(false);
|
||||
$f->setValue('29.06.2006');
|
||||
$this->assertEquals($f->dataValue(), '2006-06-29');
|
||||
}
|
||||
@ -242,6 +160,7 @@ class DateFieldTest extends SapphireTest
|
||||
public function testMDYFormat()
|
||||
{
|
||||
$dateField = new DateField('Date', 'Date');
|
||||
$dateField->setHTML5(false);
|
||||
$dateField->setDateFormat('d/M/y');
|
||||
$dateField->setSubmittedValue('31/03/2003');
|
||||
$this->assertEquals(
|
||||
@ -251,6 +170,7 @@ class DateFieldTest extends SapphireTest
|
||||
);
|
||||
|
||||
$dateField2 = new DateField('Date', 'Date');
|
||||
$dateField2->setHTML5(false);
|
||||
$dateField2->setDateFormat('d/M/y');
|
||||
$dateField2->setSubmittedValue('04/3/03');
|
||||
$this->assertEquals(
|
||||
@ -262,13 +182,37 @@ class DateFieldTest extends SapphireTest
|
||||
|
||||
/**
|
||||
* @expectedException \LogicException
|
||||
* @expectedExceptionMessageRegExp /Please opt-out .* if using setDateFormat/
|
||||
*/
|
||||
public function testHtml5WithCustomFormatThrowsException()
|
||||
{
|
||||
$dateField = new DateField('Date', 'Date');
|
||||
$dateField->setValue('2010-03-31');
|
||||
$dateField->setHTML5(true);
|
||||
$dateField->setDateFormat('d/M/y');
|
||||
$dateField->Value();
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \LogicException
|
||||
* @expectedExceptionMessageRegExp /Please opt-out .* if using setDateLength/
|
||||
*/
|
||||
public function testHtml5WithCustomDateLengthThrowsException()
|
||||
{
|
||||
$dateField = new DateField('Date', 'Date');
|
||||
$dateField->setValue('2010-03-31');
|
||||
$dateField->setDateLength(IntlDateFormatter::MEDIUM);
|
||||
$dateField->Value();
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \LogicException
|
||||
* @expectedExceptionMessageRegExp /Please opt-out .* if using setLocale/
|
||||
*/
|
||||
public function testHtml5WithCustomLocaleThrowsException()
|
||||
{
|
||||
$dateField = new DateField('Date', 'Date');
|
||||
$dateField->setValue('2010-03-31');
|
||||
$dateField->setLocale('de_DE');
|
||||
$dateField->Value();
|
||||
}
|
||||
}
|
||||
|
@ -7,7 +7,6 @@ use SilverStripe\Control\Controller;
|
||||
use SilverStripe\Forms\DatetimeField;
|
||||
use SilverStripe\Forms\RequiredFields;
|
||||
use SilverStripe\Forms\DateField;
|
||||
use SilverStripe\Forms\SeparatedDateField;
|
||||
use SilverStripe\Forms\Tests\DatetimeFieldTest\Model;
|
||||
use SilverStripe\Forms\TimeField;
|
||||
use SilverStripe\Forms\FieldList;
|
||||
@ -105,17 +104,6 @@ class DatetimeFieldTest extends SapphireTest
|
||||
$this->assertEquals($datetimeField->dataValue(), '2003-03-29 23:00:00');
|
||||
}
|
||||
|
||||
public function testSetValueWithDmyArray()
|
||||
{
|
||||
$f = new DatetimeField('Datetime', 'Datetime');
|
||||
$f->setDateField(new SeparatedDateField('Datetime[date]'));
|
||||
$f->setSubmittedValue([
|
||||
'date' => ['day' => 29, 'month' => 03, 'year' => 2003],
|
||||
'time' => '11:00:00 pm'
|
||||
]);
|
||||
$this->assertEquals($f->dataValue(), '2003-03-29 23:00:00');
|
||||
}
|
||||
|
||||
public function testValidate()
|
||||
{
|
||||
$f = new DatetimeField('Datetime', 'Datetime', '2003-03-29 23:59:38');
|
||||
|
@ -1,53 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace SilverStripe\Forms\Tests;
|
||||
|
||||
use SilverStripe\Dev\SapphireTest;
|
||||
use SilverStripe\Forms\DateField;
|
||||
use SilverStripe\Forms\SeparatedDateField;
|
||||
use SilverStripe\Forms\RequiredFields;
|
||||
use SilverStripe\i18n\i18n;
|
||||
use SilverStripe\ORM\FieldType\DBDatetime;
|
||||
|
||||
class SeparatedDateFieldTest extends SapphireTest
|
||||
{
|
||||
protected function setUp()
|
||||
{
|
||||
parent::setUp();
|
||||
i18n::set_locale('en_NZ');
|
||||
DBDatetime::set_mock_now('2011-02-01 8:34:00');
|
||||
}
|
||||
|
||||
public function testFieldOrderingBasedOnLocale()
|
||||
{
|
||||
$dateField = new SeparatedDateField('Date');
|
||||
$dateField->setLocale('en_NZ');
|
||||
$this->assertRegExp('/.*[day].*[month].*[year]/', $dateField->Field());
|
||||
}
|
||||
|
||||
public function testFieldOrderingBasedOnDateFormat()
|
||||
{
|
||||
$dateField = new SeparatedDateField('Date');
|
||||
$dateField->setDateFormat('y/MM/dd');
|
||||
$this->assertRegExp('/.*[year].*[month].*[day]/', $dateField->Field());
|
||||
}
|
||||
|
||||
public function testCustomSeparator()
|
||||
{
|
||||
$dateField = new SeparatedDateField('Date');
|
||||
$dateField->setDateFormat('dd/MM/y');
|
||||
$dateField->setSeparator('###');
|
||||
$this->assertRegExp('/.*[day].*###.*[month].*###.*[day]/', $dateField->Field());
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \InvalidArgumentException
|
||||
* @expectedExceptionMessage Invalid date format
|
||||
*/
|
||||
public function testInvalidDateFormat()
|
||||
{
|
||||
$dateField = new SeparatedDateField('Date');
|
||||
$dateField->setDateFormat('y/MM');
|
||||
$dateField->Field();
|
||||
}
|
||||
}
|
@ -2,6 +2,7 @@
|
||||
|
||||
namespace SilverStripe\Forms\Tests;
|
||||
|
||||
use IntlDateFormatter;
|
||||
use SilverStripe\Core\Config\Config;
|
||||
use SilverStripe\Dev\SapphireTest;
|
||||
use SilverStripe\Forms\TimeField;
|
||||
@ -55,7 +56,8 @@ class TimeFieldTest extends SapphireTest
|
||||
{
|
||||
// should get en_NZ by default through setUp()
|
||||
$f = new TimeField('Time', 'Time');
|
||||
$f->setLocale('de_DE');
|
||||
$f->setHTML5(false);
|
||||
$f->setLocale('fr_FR');
|
||||
// TODO Find a hour format thats actually different
|
||||
$f->setValue('23:59');
|
||||
$this->assertEquals($f->dataValue(), '23:59:00');
|
||||
@ -96,8 +98,7 @@ class TimeFieldTest extends SapphireTest
|
||||
public function testOverrideWithNull()
|
||||
{
|
||||
$field = new TimeField('Time', 'Time');
|
||||
|
||||
$field->setValue('11:00pm');
|
||||
$field->setValue('11:00:00');
|
||||
$field->setValue('');
|
||||
$this->assertEquals($field->dataValue(), '');
|
||||
}
|
||||
@ -105,31 +106,35 @@ class TimeFieldTest extends SapphireTest
|
||||
/**
|
||||
* Test that AM/PM is preserved correctly in various situations
|
||||
*/
|
||||
public function testPreserveAMPM()
|
||||
public function testSetTimeFormat()
|
||||
{
|
||||
|
||||
// Test with timeformat that includes hour
|
||||
|
||||
// Check pm
|
||||
$f = new TimeField('Time', 'Time');
|
||||
$f->setHTML5(false);
|
||||
$f->setTimeFormat('h:mm:ss a');
|
||||
$f->setValue('3:59 pm');
|
||||
$this->assertEquals($f->dataValue(), '15:59:00');
|
||||
|
||||
// Check am
|
||||
$f = new TimeField('Time', 'Time');
|
||||
$f->setHTML5(false);
|
||||
$f->setTimeFormat('h:mm:ss a');
|
||||
$f->setValue('3:59 am');
|
||||
$this->assertEquals($f->dataValue(), '03:59:00');
|
||||
|
||||
// Check with ISO date/time
|
||||
$f = new TimeField('Time', 'Time');
|
||||
$f->setHTML5(false);
|
||||
$f->setTimeFormat('h:mm:ss a');
|
||||
$f->setValue('15:59:00');
|
||||
$this->assertEquals($f->dataValue(), '15:59:00');
|
||||
|
||||
// ISO am
|
||||
$f = new TimeField('Time', 'Time');
|
||||
$f->setHTML5(false);
|
||||
$f->setTimeFormat('h:mm:ss a');
|
||||
$f->setValue('03:59:00');
|
||||
$this->assertEquals($f->dataValue(), '03:59:00');
|
||||
@ -138,20 +143,43 @@ class TimeFieldTest extends SapphireTest
|
||||
public function testLenientSubmissionParseWithoutSecondsOnHtml5()
|
||||
{
|
||||
$f = new TimeField('Time', 'Time');
|
||||
$f->setHTML5(true);
|
||||
$f->setSubmittedValue('23:59');
|
||||
$this->assertEquals($f->Value(), '23:59:00');
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \LogicException
|
||||
* @expectedExceptionMessageRegExp /Please opt-out .* if using setTimeFormat/
|
||||
*/
|
||||
public function testHtml5WithCustomFormatThrowsException()
|
||||
{
|
||||
$f = new TimeField('Time', 'Time');
|
||||
$f->setValue('15:59:00');
|
||||
$f->setHTML5(true);
|
||||
$f->setTimeFormat('mm:HH');
|
||||
$f->Value();
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \LogicException
|
||||
* @expectedExceptionMessageRegExp /Please opt-out .* if using setTimeLength/
|
||||
*/
|
||||
public function testHtml5WithCustomDateLengthThrowsException()
|
||||
{
|
||||
$f = new TimeField('Time', 'Time');
|
||||
$f->setValue('15:59:00');
|
||||
$f->setTimeLength(IntlDateFormatter::MEDIUM);
|
||||
$f->Value();
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \LogicException
|
||||
* @expectedExceptionMessageRegExp /Please opt-out .* if using setLocale/
|
||||
*/
|
||||
public function testHtml5WithCustomLocaleThrowsException()
|
||||
{
|
||||
$f = new TimeField('Time', 'Time');
|
||||
$f->setValue('15:59:00');
|
||||
$f->setLocale('de_DE');
|
||||
$f->Value();
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user