mirror of
https://github.com/silverstripe/silverstripe-framework
synced 2024-10-22 12:05:37 +00:00
API Create SeparatedDateField
API Restrict allowed values parsed via DBDate::setValue API Remove NumericField_Readonly API Remove DBTime::Nice12 / Nice24
This commit is contained in:
parent
029a8b9586
commit
014f0d23ed
7
admin/client/dist/styles/bundle.css
vendored
7
admin/client/dist/styles/bundle.css
vendored
@ -8859,11 +8859,16 @@ fieldset{
|
||||
height:18px;
|
||||
}
|
||||
|
||||
.field input.day,.field input.month,.field input.year{
|
||||
.field input.day,.field input.month{
|
||||
width:56px;
|
||||
display:inline;
|
||||
}
|
||||
|
||||
.field input.year{
|
||||
width:72px;
|
||||
display:inline;
|
||||
}
|
||||
|
||||
.field input.time{
|
||||
width:88px;
|
||||
}
|
||||
|
@ -295,8 +295,12 @@ form.small .field, .field.small {
|
||||
}
|
||||
|
||||
/* Date Fields */
|
||||
input.month, input.day, input.year {
|
||||
input.month, input.day {
|
||||
width: ($grid-x * 7);
|
||||
display: inline;
|
||||
}
|
||||
input.year {
|
||||
width: ($grid-x * 9);
|
||||
display: inline;
|
||||
}
|
||||
|
||||
|
@ -68,11 +68,6 @@ Subclasses of `FormField` can define their own version of `validate` to provide
|
||||
above example with the `Email` validation. The `validate` method on `FormField` takes a single argument of the current
|
||||
`Validator` instance.
|
||||
|
||||
<div class="notice" markdown="1">
|
||||
The data value of the `FormField` submitted is not passed into validate. It is stored in the `value` property through
|
||||
the `setValue` method.
|
||||
</div>
|
||||
|
||||
```php
|
||||
public function validate($validator)
|
||||
{
|
||||
|
@ -3,8 +3,8 @@ summary: How to format and use the DateField class.
|
||||
|
||||
# DateField
|
||||
|
||||
This `FormField` subclass lets you display an editable date, either in a single text input field, or in three separate
|
||||
fields for day, month and year. It also provides a calendar date picker.
|
||||
This `FormField` subclass lets you display an editable date, in a single text input field.
|
||||
It also provides a calendar date picker.
|
||||
|
||||
The following example will add a simple DateField to your Page, allowing you to enter a date manually.
|
||||
|
||||
@ -33,14 +33,14 @@ 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 `setConfig`.
|
||||
A custom date format for a [api:DateField] can be provided through `setDateFormat`.
|
||||
|
||||
:::php
|
||||
// will display a date in the following format: 31-06-2012
|
||||
DateField::create('MyDate')->setDateFormat('dd-MM-yyyy');
|
||||
|
||||
<div class="info" markdown="1">
|
||||
The formats are based on [Zend_Date constants](http://framework.zend.com/manual/1.12/en/zend.date.constants.html).
|
||||
The formats are based on [CLDR format](http://userguide.icu-project.org/formatparse/datetime).
|
||||
</div>
|
||||
|
||||
|
||||
@ -51,19 +51,16 @@ strtotime()).
|
||||
|
||||
:::php
|
||||
DateField::create('MyDate')
|
||||
->setConfig('min', '-7 days')
|
||||
->setConfig('max', '2012-12-31')
|
||||
->setMinDate('-7 days')
|
||||
->setMaxDate'2012-12-31')
|
||||
|
||||
## Separate Day / Month / Year Fields
|
||||
|
||||
The following setting will display your DateField as three input fields for day, month and year separately. HTML5
|
||||
placeholders 'day', 'month' and 'year' are enabled by default.
|
||||
To display separate input fields for day, month and year separately you can use the `DateFieldSeparated` subclass`.
|
||||
HTML5 placeholders 'day', 'month' and 'year' are enabled by default.
|
||||
|
||||
:::php
|
||||
DateField::create('MyDate')
|
||||
->setConfig('dmyfields', true)
|
||||
->setConfig('dmyseparator', '/') // set the separator
|
||||
->setConfig('dmyplaceholders', 'true'); // enable HTML 5 Placeholders
|
||||
DateFieldSeparated::create('MyDate');
|
||||
|
||||
<div class="alert" markdown="1">
|
||||
Any custom date format settings will be ignored.
|
||||
@ -75,10 +72,13 @@ The following setting will add a Calendar to a single DateField, using the jQuer
|
||||
|
||||
:::php
|
||||
DateField::create('MyDate')
|
||||
->setConfig('showcalendar', true);
|
||||
->setShowCalendar(true);
|
||||
|
||||
The jQuery DatePicker doesn't support every constant available for `Zend_Date`. If you choose to use the calendar, the
|
||||
following constants should at least be safe:
|
||||
The jQuery date picker will support most custom locale formats (if left as default).
|
||||
If setting an explicit date format via setDateFormat() then the below table of supported
|
||||
characters should be used.
|
||||
|
||||
It is recommended to use numeric format, as `MMM` or `MMMM` month names may not always pass validation.
|
||||
|
||||
Constant | xxxxx
|
||||
-------- | -----
|
||||
@ -94,15 +94,6 @@ y | year (4 digits)
|
||||
yy | year (2 digits)
|
||||
yyyy | year (4 digits)
|
||||
|
||||
Unfortunately the day- and monthname values in Zend Date do not always match those in the existing jQuery UI locale
|
||||
files, so constants like `EEE` or `MMM`, for day and month names could break validation. To fix this we had to slightly
|
||||
alter the jQuery locale files, situated in */framework/thirdparty/jquery-ui/datepicker/i18n/*, to match Zend_Date.
|
||||
|
||||
<div class="info">
|
||||
At this moment not all locale files may be present. If a locale file is missing, the DatePicker calendar will fallback
|
||||
to 'yyyy-MM-dd' whenever day - and/or monthnames are used. After saving, the correct format will be displayed.
|
||||
</div>
|
||||
|
||||
## Formatting Hints
|
||||
|
||||
It's often not immediate apparent which format a field accepts, and showing the technical format (e.g. `HH:mm:ss`) is
|
||||
@ -113,13 +104,14 @@ field description as an example.
|
||||
$dateField = DateField::create('MyDate');
|
||||
|
||||
// Show long format as text below the field
|
||||
$dateField->setDescription(sprintf(
|
||||
_t('FormField.Example', 'e.g. %s', 'Example format'),
|
||||
Convert::raw2xml(Zend_Date::now()->toString($dateField->getConfig('dateformat')))
|
||||
$dateField->setDescription(_t(
|
||||
'FormField.Example',
|
||||
'e.g. {format}',
|
||||
[ 'format' => $dateField->getDateFormat() ]
|
||||
));
|
||||
|
||||
// Alternatively, set short format as a placeholder in the field
|
||||
$dateField->setAttribute('placeholder', $dateField->getConfig('dateformat'));
|
||||
$dateField->setAttribute('placeholder', $dateField->getDateFormat());
|
||||
|
||||
<div class="notice" markdown="1">
|
||||
Fields scaffolded through [api:DataObject::scaffoldCMSFields()] automatically have a description attached to them.
|
||||
|
@ -942,6 +942,9 @@ specific functions.
|
||||
by the array key, or the `class` parameter value.
|
||||
* Uniqueness checks for `File.Name` is performed on write only (not in `setName()`)
|
||||
* Created `Resettable` interface to better declare objects which should be reset between tests.
|
||||
* Added a server requirement for the php-intl extension (shipped by default with most PHP distributions)
|
||||
* Replaced Zend_Date and Zend_Locale with the php-intl extension.
|
||||
* Consistently use CLDR date formats (rather than a mix of CLDR and date() formats)
|
||||
|
||||
#### <a name="overview-general-removed"></a>General and Core Removed API
|
||||
|
||||
@ -1052,17 +1055,23 @@ A very small number of methods were chosen for deprecation, and will be removed
|
||||
* `ChangeSet` and `ChangeSetItem` have been added for batch publishing of versioned dataobjects.
|
||||
* `DataObject.table_name` config can now be used to customise the database table for any record.
|
||||
* `DataObjectSchema` class added to assist with mapping between classes and tables.
|
||||
* `DBMoney` values are now treated as empty only Amount is null. Values without Currency
|
||||
will be formatted in the default locale.
|
||||
* `DBMoney` values are now treated as empty only if `Amount` field is null. If an `Amount` value
|
||||
is provided without a `Currency` specified, it will be formatted as per the current locale.
|
||||
|
||||
The below methods have been added or had their functionality updated to `DBDate`, `DBTime` and `DBDatetime`
|
||||
* `getTimestamp()` added to get the respective date / time as unix timestamp (seconds since 1970-01-01)
|
||||
* `Format()` method now use CLDR format strings, rather than PHP format strings.
|
||||
See http://userguide.icu-project.org/formatparse/datetime.
|
||||
* `Format()` method now use [CLDR format strings](http://userguide.icu-project.org/formatparse/datetime),
|
||||
rather than [PHP format string](http://php.net/manual/en/function.date.php).
|
||||
E.g. `d/m/Y H:i:s` (php format) should be replaced with to `dd/MM/y HH:mm:ss` (CLDR format).
|
||||
* getISOFormat() added which returns the standard date/time ISO 8601 pattern in CLDR format.
|
||||
* Dates passed in m/d/y format will now raise a notice but will be parsed.
|
||||
Dates passed to constructors should follow ISO 8601 (y-m-d).
|
||||
* 2-digit years will raise a notice.
|
||||
* `setValue` method is now a lot more restrictive, and expects dates and times to be passed in
|
||||
ISO 8601 format (y-MM-dd) or (HH:mm:ss). Certain date formats will attempt to parse with
|
||||
the below restrictions:
|
||||
- `/`, `.` or `-` are supported date separators, but will be replaced with `-` internally.
|
||||
- US date formats (m-d-y / y-d-m) will not be supported and may be parsed incorrectly.
|
||||
(Note: Date form fields will still support localised date formats).
|
||||
- `dd-MM-y` will be converted to `y-MM-dd` internally.
|
||||
- 2-digit values for year will now raise errors.
|
||||
* `FormatFromSettings` will default to `Nice()` format if no member is logged in.
|
||||
* `Nice`, `Long` and `Full` methods will now follow standard formatting rules for the
|
||||
current locale, rather than pre-defined formats.
|
||||
@ -1071,7 +1080,6 @@ The below methods have been added or had their functionality updated to `DBDate`
|
||||
|
||||
`DBTime` specific changes:
|
||||
* Added `DBTime::FormatFromSettings`
|
||||
* Added `DBTime::Nice12`
|
||||
|
||||
#### <a name="overview-orm-removed"></a>ORM Removed API
|
||||
|
||||
@ -1115,7 +1123,9 @@ The below methods have been added or had their functionality updated to `DBDate`
|
||||
- `days_between`
|
||||
* `nice_format` has been removed from `DBDate` / `DBTime` / `DBDatetime` has been removed in favour of
|
||||
locale-specific formatting for Nice()
|
||||
* Removed `DBTime::TwelveHour`
|
||||
* Removed several `DBTime` methods:
|
||||
- `TwelveHour`
|
||||
- `Nice24`
|
||||
* Removed some `DBMoney` methods due to lack of support in php-intl.
|
||||
- `NiceWithShortname`
|
||||
- `NiceWithName`
|
||||
@ -1235,6 +1245,9 @@ The following filesystem synchronisation methods and tasks are also removed
|
||||
* Introduced `AssetAdmin\Forms\UploadField` as a react-friendly version of UploadField. This may also
|
||||
be used in normal entwine forms for managing files in a similar way to UploadField. However, this
|
||||
does not support inline editing of files.
|
||||
* Added method `FormField::setSubmittedValue($value, $data)` to process input submitted from form
|
||||
submission, in contrast to `FormField::setValue($value, $data)` which is intended to load its
|
||||
value from the ORM. The second argument to setValue() has been added.
|
||||
|
||||
The following methods and properties on `Requirements_Backend` have been renamed:
|
||||
|
||||
@ -1320,6 +1333,7 @@ New `DatetimeField` methods replace `getConfig()` / `setConfig()`:
|
||||
* `getTimezone()` / `setTimezone()`
|
||||
* `getDateTimeOrder()` / `setDateTimeOrder()`
|
||||
* `getLocale()` / `setLocale()`
|
||||
* `datavaluefield` config is removed as internal data value is now fixed to ISO 8601 format
|
||||
|
||||
New `DateField` methods replace `getConfig()` / `setConfig()`:
|
||||
|
||||
@ -1328,9 +1342,9 @@ New `DateField` methods replace `getConfig()` / `setConfig()`:
|
||||
* `getMinDate()` / `setMinDate()`
|
||||
* `getMaxDate()` / `setMaxDate()`
|
||||
* `getPlaceholders()` / `setPlaceholders()`
|
||||
* `getSeparateDMYFields()` / `setSeparateDMYFields()`
|
||||
* `getClientLocale` / `setClientLocale`
|
||||
* `getLocale()` / `setLocale()`
|
||||
* option `dmyfields` is now superceded with an `SeparatedDateField` class
|
||||
|
||||
New `TimeField` methods replace `getConfig()` / `setConfig()`
|
||||
|
||||
@ -1370,6 +1384,7 @@ New `TimeField` methods replace `getConfig()` / `setConfig()`
|
||||
as they are obsolete.
|
||||
* Removed `DatetimeField`, `DateField` and `TimeField` methods `getConfig` and `setConfig`. Individual
|
||||
getters and setters for individual options are provided instead. See above for list of new methods.
|
||||
* Removed `NumericField_Readonly`. Use `setReadonly(true)` instead.
|
||||
|
||||
### <a name="overview-i18n"></a>i18n API
|
||||
|
||||
@ -1383,20 +1398,20 @@ New `TimeField` methods replace `getConfig()` / `setConfig()`
|
||||
for all DataObject subclasses, rather than just the basename without namespace.
|
||||
* i18n key for locale-respective pluralisation rules added as '.PLURALS'. These can be configured
|
||||
within yaml in array format as per [ruby i18n pluralization rules](http://guides.rubyonrails.org/i18n.html#pluralization).
|
||||
* `i18n.all_locales` config moved to `Locales.locales`
|
||||
* `i18n.common_languages` config moved to `Locales.languages`
|
||||
* `i18n.likely_subtags` config moved to `Locales.likely_subtags`
|
||||
* `i18n.tinymce_lang` config moved to `TinyMCEConfig.tinymce_lang`
|
||||
* `i18n::get_tinymce_lang()` moved to `TinyMCEConfig::get_tinymce_lang()`
|
||||
* `i18n::get_locale_from_lang()` moved to `Locales::localeFromLang()`
|
||||
* `i18n::get_lange_from_locale()` moved to `Locales::langFromLocale()`
|
||||
* `i18n::validate_locale()` moved to `Locales::validate()`
|
||||
* `i18n::get_common_languages()` moved to `Locales::getLanguages()`
|
||||
* `i18n::get_locale_name()` moved to `Locales::localeName()`
|
||||
* `i18n::get_language_name()` moved to `Locales::languageName()`
|
||||
* `i18n.module_priority` config moved to `Sources.module_priority`
|
||||
* `i18n::get_owner_module()` moved to `ClassManifest::getOwnerModule()`
|
||||
* `i18n::get_existing_translations()` moved to `Sources::getKnownLocales()`
|
||||
* `i18n.all_locales` config moved to `SilverStripe\i18n\Data\Locales.locales`
|
||||
* `i18n.common_languages` config moved to `SilverStripe\i18n\Data\Locales.languages`
|
||||
* `i18n.likely_subtags` config moved to `SilverStripe\i18n\Data\Locales.likely_subtags`
|
||||
* `i18n.tinymce_lang` config moved to `SilverStripe\Forms\HTMLEditor\TinyMCEConfig.tinymce_lang`
|
||||
* `i18n::get_tinymce_lang()` moved to `SilverStripe\Forms\HTMLEditor\TinyMCEConfig::get_tinymce_lang()`
|
||||
* `i18n::get_locale_from_lang()` moved to `SilverStripe\i18n\Data\Locales::localeFromLang()`
|
||||
* `i18n::get_lange_from_locale()` moved to `SilverStripe\i18n\Data\Locales::langFromLocale()`
|
||||
* `i18n::validate_locale()` moved to `SilverStripe\i18n\Data\Locales::validate()`
|
||||
* `i18n::get_common_languages()` moved to `SilverStripe\i18n\Data\Locales::getLanguages()`
|
||||
* `i18n::get_locale_name()` moved to `SilverStripe\i18n\Data\Locales::localeName()`
|
||||
* `i18n::get_language_name()` moved to `SilverStripe\i18n\Data\Locales::languageName()`
|
||||
* `i18n.module_priority` config moved to `SilverStripe\i18n\Data\Sources.module_priority`
|
||||
* `i18n::get_owner_module()` moved to `SilverStripe\Core\Manifest\ClassManifest::getOwnerModule()`
|
||||
* `i18n::get_existing_translations()` moved to `SilverStripe\i18n\Data\Sources::getKnownLocales()`
|
||||
|
||||
#### <a name="overview-i18n-removed"></a>i18n API Removed API
|
||||
|
||||
|
@ -8,9 +8,7 @@ use InvalidArgumentException;
|
||||
use SilverStripe\ORM\FieldType\DBDatetime;
|
||||
|
||||
/**
|
||||
* Form field to display an editable date string,
|
||||
* either in a single `<input type="text">` field,
|
||||
* or in three separate fields for day, month and year.
|
||||
* Form used for editing a date stirng
|
||||
*
|
||||
* Caution: The form field does not include any JavaScript or CSS when used outside of the CMS context,
|
||||
* since the required frontend dependencies are included through CMS bundling.
|
||||
@ -29,11 +27,10 @@ use SilverStripe\ORM\FieldType\DBDatetime;
|
||||
*
|
||||
* # Usage
|
||||
*
|
||||
* ## Example: German dates with separate fields for day, month, year
|
||||
* ## Example: Field localised with german date format
|
||||
*
|
||||
* $f = new DateField('MyDate');
|
||||
* $f->setLocale('de_DE');
|
||||
* $f->setSeparateDMYFields(true);
|
||||
*
|
||||
* # Validation
|
||||
*
|
||||
@ -95,14 +92,6 @@ class DateField extends TextField
|
||||
*/
|
||||
protected $placeholders = true;
|
||||
|
||||
/**
|
||||
* Declare whether D, M and Y fields should be separate inputs.
|
||||
* If set then only numeric values will be accepted.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
protected $separateDMYFields = false;
|
||||
|
||||
/**
|
||||
* Override locale for client side.
|
||||
*
|
||||
@ -145,16 +134,11 @@ class DateField extends TextField
|
||||
/**
|
||||
* Set if calendar should be shown on the frontend.
|
||||
*
|
||||
* If set to true, disables separate DMY fields
|
||||
*
|
||||
* @param bool $show
|
||||
* @return $this
|
||||
*/
|
||||
public function setShowCalendar($show)
|
||||
{
|
||||
if ($show && $this->getSeparateDMYFields()) {
|
||||
throw new InvalidArgumentException("Can't separate DMY fields and show calendar popup");
|
||||
}
|
||||
$this->showCalendar = $show;
|
||||
return $this;
|
||||
}
|
||||
@ -316,39 +300,6 @@ class DateField extends TextField
|
||||
return $attributes;
|
||||
}
|
||||
|
||||
public function Field($properties = array())
|
||||
{
|
||||
if (!$this->getSeparateDMYFields()) {
|
||||
return parent::Field($properties);
|
||||
}
|
||||
|
||||
// Three separate fields for day, month and year
|
||||
$valArr = $this->iso8601ToArray($this->Value());
|
||||
$fieldDay = NumericField::create($this->name . '[day]', false, $valArr ? $valArr['day'] : null)
|
||||
->addExtraClass('day')
|
||||
->setMaxLength(2);
|
||||
$fieldMonth = NumericField::create($this->name . '[month]', false, $valArr ? $valArr['month'] : null)
|
||||
->addExtraClass('month')
|
||||
->setMaxLength(2);
|
||||
$fieldYear = NumericField::create($this->name . '[year]', false, $valArr ? $valArr['year'] : null)
|
||||
->addExtraClass('year')
|
||||
->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'));
|
||||
}
|
||||
|
||||
// Join all fields
|
||||
// @todo custom ordering based on locale
|
||||
$sep = ' <span class="separator">/</span> ';
|
||||
return $fieldDay->Field() . $sep
|
||||
. $fieldMonth->Field() . $sep
|
||||
. $fieldYear->Field();
|
||||
}
|
||||
|
||||
public function Type()
|
||||
{
|
||||
return 'date text';
|
||||
@ -364,11 +315,7 @@ class DateField extends TextField
|
||||
public function setSubmittedValue($value, $data = null)
|
||||
{
|
||||
// Save raw value for later validation
|
||||
if ($this->isEmptyArray($value)) {
|
||||
$this->rawValue = null;
|
||||
} else {
|
||||
$this->rawValue = $value;
|
||||
}
|
||||
|
||||
// Null case
|
||||
if (!$value) {
|
||||
@ -376,12 +323,6 @@ class DateField extends TextField
|
||||
return $this;
|
||||
}
|
||||
|
||||
// If loading from array convert
|
||||
if (is_array($value)) {
|
||||
$this->value = $this->arrayToISO8601($value);
|
||||
return $this;
|
||||
}
|
||||
|
||||
// Parse from submitted value
|
||||
$this->value = $this->localisedToISO8601($value);
|
||||
return $this;
|
||||
@ -555,33 +496,6 @@ class DateField extends TextField
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Declare whether D, M and Y fields should be separate inputs.
|
||||
* If set then only numeric values will be accepted.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function getSeparateDMYFields()
|
||||
{
|
||||
return $this->separateDMYFields;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set if we should separate D M and Y fields. If set to true, disabled calendar
|
||||
* popup.
|
||||
*
|
||||
* @param bool $separate
|
||||
* @return $this
|
||||
*/
|
||||
public function setSeparateDMYFields($separate)
|
||||
{
|
||||
if ($separate && $this->getShowCalendar()) {
|
||||
throw new InvalidArgumentException("Can't separate DMY fields and show calendar popup");
|
||||
}
|
||||
$this->separateDMYFields = $separate;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
@ -647,62 +561,6 @@ class DateField extends TextField
|
||||
return $config;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 date localised in the current locale to ISO 8601 date
|
||||
*
|
||||
@ -776,15 +634,4 @@ class DateField extends TextField
|
||||
{
|
||||
return DateField_View_JQuery::create($this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if this array is empty
|
||||
*
|
||||
* @param $value
|
||||
* @return bool
|
||||
*/
|
||||
public function isEmptyArray($value)
|
||||
{
|
||||
return is_array($value) && !array_filter($value);
|
||||
}
|
||||
}
|
||||
|
@ -2,7 +2,6 @@
|
||||
|
||||
namespace SilverStripe\Forms\HTMLEditor;
|
||||
|
||||
use SilverStripe\Core\Config\Configurable;
|
||||
use SilverStripe\Core\Convert;
|
||||
use SilverStripe\Control\Controller;
|
||||
use SilverStripe\Control\Director;
|
||||
|
@ -159,7 +159,7 @@ class MemberDatetimeOptionsetField extends OptionsetField
|
||||
public function setValue($value, $data = null)
|
||||
{
|
||||
if (is_array($value)) {
|
||||
throw new InvalidArgumentException("Invalid value");
|
||||
throw new InvalidArgumentException("Invalid array value: Expected string");
|
||||
}
|
||||
return parent::setValue($value, $data);
|
||||
}
|
||||
|
@ -89,7 +89,7 @@ class MoneyField extends FormField
|
||||
$currencyValue = $this->fieldCurrency ? $this->fieldCurrency->dataValue() : null;
|
||||
$allowedCurrencies = $this->getAllowedCurrencies();
|
||||
if (count($allowedCurrencies) === 1) {
|
||||
// Dropdown field for multiple currencies
|
||||
// Hidden field for single currency
|
||||
$field = HiddenField::create("{$name}[Currency]");
|
||||
reset($allowedCurrencies);
|
||||
$currencyValue = key($allowedCurrencies);
|
||||
@ -164,7 +164,7 @@ class MoneyField extends FormField
|
||||
'Currency' => $value->getCurrency(),
|
||||
'Amount' => $value->getAmount(),
|
||||
];
|
||||
} else {
|
||||
} elseif (!is_array($value)) {
|
||||
throw new InvalidArgumentException("Invalid currency format");
|
||||
}
|
||||
|
||||
@ -232,8 +232,6 @@ class MoneyField extends FormField
|
||||
public function performReadonlyTransformation()
|
||||
{
|
||||
$clone = clone $this;
|
||||
$clone->fieldAmount = $clone->fieldAmount->performReadonlyTransformation();
|
||||
$clone->fieldCurrency = $clone->fieldCurrency->performReadonlyTransformation();
|
||||
$clone->setReadonly(true);
|
||||
return $clone;
|
||||
}
|
||||
|
@ -306,4 +306,11 @@ class NumericField extends TextField
|
||||
$this->scale = $scale;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function performReadonlyTransformation()
|
||||
{
|
||||
$field = clone $this;
|
||||
$field->setReadonly(true);
|
||||
return $field;
|
||||
}
|
||||
}
|
||||
|
@ -1,30 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace SilverStripe\Forms;
|
||||
|
||||
/**
|
||||
* Readonly version of a numeric field.
|
||||
*/
|
||||
class NumericField_Readonly extends ReadonlyField
|
||||
{
|
||||
/**
|
||||
* @return static
|
||||
*/
|
||||
public function performReadonlyTransformation()
|
||||
{
|
||||
return clone $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function Value()
|
||||
{
|
||||
return $this->value ?: '0';
|
||||
}
|
||||
|
||||
public function getValueCast()
|
||||
{
|
||||
return 'Decimal';
|
||||
}
|
||||
}
|
136
src/Forms/SeparatedDateField.php
Normal file
136
src/Forms/SeparatedDateField.php
Normal file
@ -0,0 +1,136 @@
|
||||
<?php
|
||||
|
||||
namespace SilverStripe\Forms;
|
||||
|
||||
use SilverStripe\i18n\i18n;
|
||||
|
||||
/**
|
||||
* Date field with separate inputs for d/m/y
|
||||
*/
|
||||
class SeparatedDateField extends DateField
|
||||
{
|
||||
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'));
|
||||
}
|
||||
|
||||
// Join all fields
|
||||
// @todo custom ordering based on locale
|
||||
$sep = ' <span class="separator">/</span> ';
|
||||
return $fieldDay->Field() . $sep
|
||||
. $fieldMonth->Field() . $sep
|
||||
. $fieldYear->Field();
|
||||
}
|
||||
|
||||
/**
|
||||
* 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);
|
||||
}
|
||||
}
|
@ -38,7 +38,7 @@ class DBDate extends DBField
|
||||
$value = $this->parseDate($value);
|
||||
if ($value === false) {
|
||||
throw new InvalidArgumentException(
|
||||
"Invalid date passed. Use " . self::ISO_DATE . " to prevent this error."
|
||||
"Invalid date: '$value'. Use " . self::ISO_DATE . " to prevent this error."
|
||||
);
|
||||
}
|
||||
$this->value = $value;
|
||||
@ -308,10 +308,7 @@ class DBDate extends DBField
|
||||
*/
|
||||
public function Rfc2822()
|
||||
{
|
||||
if ($this->value) {
|
||||
return date('Y-m-d H:i:s', $this->getTimestamp());
|
||||
}
|
||||
return null;
|
||||
return $this->Format('y-MM-dd HH:mm:ss');
|
||||
}
|
||||
|
||||
/**
|
||||
@ -321,15 +318,13 @@ class DBDate extends DBField
|
||||
*/
|
||||
public function Rfc3339()
|
||||
{
|
||||
if (!$this->value) {
|
||||
$date = $this->Format('y-MM-dd\\THH:mm:ss');
|
||||
if (!$date) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$timestamp = $this->getTimestamp();
|
||||
$date = date('Y-m-d\TH:i:s', $timestamp);
|
||||
|
||||
$matches = array();
|
||||
if (preg_match('/^([\-+])(\d{2})(\d{2})$/', date('O', $timestamp), $matches)) {
|
||||
if (preg_match('/^([\-+])(\d{2})(\d{2})$/', date('O', $this->getTimestamp()), $matches)) {
|
||||
$date .= $matches[1].$matches[2].':'.$matches[3];
|
||||
} else {
|
||||
$date .= 'Z';
|
||||
@ -541,23 +536,13 @@ class DBDate extends DBField
|
||||
protected function fixInputDate($value)
|
||||
{
|
||||
// split
|
||||
list($day, $month, $year, $time) = $this->explodeDateString($value);
|
||||
|
||||
// Detect invalid year order
|
||||
if (!checkdate($month, $day, $year) && checkdate($month, $year, $day)) {
|
||||
trigger_error(
|
||||
"Unexpected date order. Use " . self::ISO_DATE . " to prevent this notice.",
|
||||
E_USER_NOTICE
|
||||
);
|
||||
list($day, $year) = [$year, $day];
|
||||
}
|
||||
|
||||
// Fix y2k year
|
||||
$year = $this->guessY2kYear($year);
|
||||
list($year, $month, $day, $time) = $this->explodeDateString($value);
|
||||
|
||||
// Validate date
|
||||
if (!checkdate($month, $day, $year)) {
|
||||
throw new InvalidArgumentException("Invalid date passed. Use " . self::ISO_DATE . " to prevent this error.");
|
||||
throw new InvalidArgumentException(
|
||||
"Invalid date: '$value'. Use " . self::ISO_DATE . " to prevent this error."
|
||||
);
|
||||
}
|
||||
|
||||
// Convert to y-m-d
|
||||
@ -565,65 +550,39 @@ class DBDate extends DBField
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempt to split date string into day, month, year, and timestamp components.
|
||||
* Don't read this code without a drink in hand!
|
||||
* Attempt to split date string into year, month, day, and timestamp components.
|
||||
*
|
||||
* @param string $value
|
||||
* @return array
|
||||
*/
|
||||
protected function explodeDateString($value)
|
||||
{
|
||||
// US date format with 4-digit year first
|
||||
if (preg_match('#^(?<year>\\d{4})/(?<day>\\d+)/(?<month>\\d+)(?<time>.*)$#', $value, $matches)) {
|
||||
trigger_error(
|
||||
"Implicit y/d/m conversion. Use " . self::ISO_DATE . " to prevent this notice.",
|
||||
E_USER_NOTICE
|
||||
);
|
||||
return [$matches['day'], $matches['month'], $matches['year'], $matches['time']];
|
||||
}
|
||||
|
||||
// US date format without 4-digit year first: assume m/d/y
|
||||
if (preg_match('#^(?<month>\\d+)/(?<day>\\d+)/(?<year>\\d+)(?<time>.*)$#', $value, $matches)) {
|
||||
// Assume m/d/y
|
||||
trigger_error(
|
||||
"Implicit m/d/y conversion. Use " . self::ISO_DATE . " to prevent this notice.",
|
||||
E_USER_NOTICE
|
||||
);
|
||||
return [$matches['day'], $matches['month'], $matches['year'], $matches['time']];
|
||||
}
|
||||
|
||||
// check d.m.y
|
||||
if (preg_match('#^(?<day>\\d+)\\.(?<month>\\d+)\\.(?<year>\\d+)(?<time>.*)$#', $value, $matches)) {
|
||||
return [$matches['day'], $matches['month'], $matches['year'], $matches['time']];
|
||||
}
|
||||
|
||||
// check y-m-d
|
||||
if (preg_match('#^(?<year>\\d+)\\-(?<month>\\d+)\\-(?<day>\\d+)(?<time>.*)$#', $value, $matches)) {
|
||||
return [$matches['day'], $matches['month'], $matches['year'], $matches['time']];
|
||||
}
|
||||
|
||||
// split on known delimiters (. / -)
|
||||
if (!preg_match(
|
||||
'#^(?<first>\\d+)[-/\\.](?<second>\\d+)[-/\\.](?<third>\\d+)(?<time>.*)$#',
|
||||
$value,
|
||||
$matches
|
||||
)) {
|
||||
throw new InvalidArgumentException(
|
||||
"Invalid date passed. Use " . self::ISO_DATE . " to prevent this error."
|
||||
"Invalid date: '$value'. Use " . self::ISO_DATE . " to prevent this error."
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $year
|
||||
* @return int Fixed year
|
||||
*/
|
||||
protected function guessY2kYear($year)
|
||||
{
|
||||
// Fix y2k
|
||||
if ($year < 100) {
|
||||
trigger_error("Implicit y2k conversion. Please use full YYYY year for dates", E_USER_NOTICE);
|
||||
if ($year >= 70) {
|
||||
// 70 -> 99 converted to 19(x)
|
||||
$year += 1900;
|
||||
} else {
|
||||
// 0 -> 69 converted to 20(x)
|
||||
$year += 2000;
|
||||
$parts = [
|
||||
$matches['first'],
|
||||
$matches['second'],
|
||||
$matches['third']
|
||||
];
|
||||
// Flip d-m-y to y-m-d
|
||||
if ($parts[0] < 1000 && $parts[2] > 1000) {
|
||||
$parts = array_reverse($parts);
|
||||
}
|
||||
if ($parts[0] < 1000) {
|
||||
throw new InvalidArgumentException(
|
||||
"Invalid date: '$value'. Use " . self::ISO_DATE . " to prevent this error."
|
||||
);
|
||||
}
|
||||
return $year;
|
||||
$parts[] = $matches['time'];
|
||||
return $parts;
|
||||
}
|
||||
}
|
||||
|
@ -110,26 +110,6 @@ class DBTime extends DBField
|
||||
return $formatter->format($this->getTimestamp());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the time in 12-hour format using the format string 'h:mm a' e.g. '1:32 pm'.
|
||||
*
|
||||
* @return string Formatted time.
|
||||
*/
|
||||
public function Nice12()
|
||||
{
|
||||
return $this->Format('h:mm a');
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the time in 24-hour format using the format string 'H:mm' e.g. '13:32'.
|
||||
*
|
||||
* @return string Formatted time.
|
||||
*/
|
||||
public function Nice24()
|
||||
{
|
||||
return $this->Format('H:mm');
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the time using a particular formatting string.
|
||||
*
|
||||
|
@ -1606,8 +1606,8 @@ class IntlLocales implements Locales, Resettable
|
||||
return false;
|
||||
}
|
||||
return strcasecmp($lang, $region)
|
||||
* strcasecmp($lang, $locale)
|
||||
* strcasecmp($region, $locale) !== 0;
|
||||
&& strcasecmp($lang, $locale)
|
||||
&& strcasecmp($region, $locale);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -4,6 +4,7 @@ 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;
|
||||
@ -110,8 +111,7 @@ class DateFieldTest extends SapphireTest
|
||||
|
||||
public function testSetValueWithDateArray()
|
||||
{
|
||||
$f = new DateField('Date', 'Date');
|
||||
$f->setSeparateDMYFields(true);
|
||||
$f = new SeparatedDateField('Date', 'Date');
|
||||
$f->setSubmittedValue([
|
||||
'day' => 29,
|
||||
'month' => 03,
|
||||
@ -147,10 +147,8 @@ class DateFieldTest extends SapphireTest
|
||||
|
||||
public function testEmptyValueValidation()
|
||||
{
|
||||
$field = new DateField('Date');
|
||||
$validator = new RequiredFields();
|
||||
$this->assertTrue($field->validate($validator));
|
||||
$field->setSeparateDMYFields(true);
|
||||
$field = new SeparatedDateField('Date');
|
||||
$this->assertTrue($field->validate($validator));
|
||||
$field->setSubmittedValue([
|
||||
'day' => '',
|
||||
@ -162,8 +160,7 @@ class DateFieldTest extends SapphireTest
|
||||
|
||||
public function testValidateArray()
|
||||
{
|
||||
$f = new DateField('Date', 'Date');
|
||||
$f->setSeparateDMYFields(true);
|
||||
$f = new SeparatedDateField('Date', 'Date');
|
||||
$f->setSubmittedValue([
|
||||
'day' => 29,
|
||||
'month' => 03,
|
||||
@ -193,9 +190,7 @@ class DateFieldTest extends SapphireTest
|
||||
|
||||
public function testValidateEmptyArrayValuesSetsNullForValueObject()
|
||||
{
|
||||
$f = new DateField('Date', 'Date');
|
||||
$f->setSeparateDMYFields(true);
|
||||
|
||||
$f = new SeparatedDateField('Date', 'Date');
|
||||
$f->setSubmittedValue([
|
||||
'day' => '',
|
||||
'month' => '',
|
||||
@ -213,7 +208,7 @@ class DateFieldTest extends SapphireTest
|
||||
|
||||
public function testValidateArrayValue()
|
||||
{
|
||||
$f = new DateField('Date', 'Date');
|
||||
$f = new SeparatedDateField('Date', 'Date');
|
||||
$f->setSubmittedValue(['day' => 29, 'month' => 03, 'year' => 2003]);
|
||||
$this->assertTrue($f->validate(new RequiredFields()));
|
||||
|
||||
|
@ -7,6 +7,7 @@ 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;
|
||||
@ -107,7 +108,7 @@ class DatetimeFieldTest extends SapphireTest
|
||||
public function testSetValueWithDmyArray()
|
||||
{
|
||||
$f = new DatetimeField('Datetime', 'Datetime');
|
||||
$f->getDateField()->setSeparateDMYFields(true);
|
||||
$f->setDateField(new SeparatedDateField('Datetime[date]'));
|
||||
$f->setSubmittedValue([
|
||||
'date' => ['day' => 29, 'month' => 03, 'year' => 2003],
|
||||
'time' => '11:00:00 pm'
|
||||
|
@ -107,9 +107,13 @@ class NumericFieldTest extends SapphireTest
|
||||
|
||||
public function testReadonly()
|
||||
{
|
||||
i18n::set_locale('en_US');
|
||||
$field = new NumericField('Number');
|
||||
$this->assertRegExp("#<span[^>]+>\s*0\s*<\/span>#", "".$field->performReadonlyTransformation()->Field()."");
|
||||
$field->setLocale('de_DE');
|
||||
$field->setScale(2);
|
||||
$field->setValue(1001.3);
|
||||
$html = $field->performReadonlyTransformation()->Field()->forTemplate();
|
||||
$this->assertContains('value="1.001,30"', $html);
|
||||
$this->assertContains('readonly="readonly"', $html);
|
||||
}
|
||||
|
||||
public function testNumberTypeOnInputHtml()
|
||||
|
@ -94,96 +94,30 @@ class DBDateTest extends SapphireTest
|
||||
|
||||
public function testMDYConversion()
|
||||
{
|
||||
// Disable notices
|
||||
$this->suppressNotices();
|
||||
|
||||
$this->assertEquals(
|
||||
'4/03/2003',
|
||||
DBField::create_field('Date', '3/4/2003')->Nice(),
|
||||
"Date->Nice() works with M/D/YYYY format"
|
||||
);
|
||||
|
||||
$this->setExpectedException(
|
||||
PHPUnit_Framework_Error_Notice::class,
|
||||
"Implicit m/d/y conversion. Use " . DBDate::ISO_DATE . " to prevent this notice."
|
||||
\InvalidArgumentException::class,
|
||||
"Invalid date: '3/16/2003'. Use " . DBDate::ISO_DATE . " to prevent this error."
|
||||
);
|
||||
$this->restoreNotices();
|
||||
DBField::create_field('Date', '3/4/2003');
|
||||
}
|
||||
|
||||
public function testYDMConversion()
|
||||
{
|
||||
// Disable notices
|
||||
$this->suppressNotices();
|
||||
$this->assertEquals(
|
||||
'4/03/2003',
|
||||
DBField::create_field('Date', '2003/4/3')->Nice(),
|
||||
"Date->Nice() works with YYYY/D/M format"
|
||||
);
|
||||
|
||||
$this->setExpectedException(
|
||||
PHPUnit_Framework_Error_Notice::class,
|
||||
"Implicit y/d/m conversion. Use " . DBDate::ISO_DATE . " to prevent this notice."
|
||||
);
|
||||
$this->restoreNotices();
|
||||
DBField::create_field('Date', '2003/4/3');
|
||||
DBField::create_field('Date', '3/16/2003');
|
||||
}
|
||||
|
||||
public function testY2kCorrection()
|
||||
{
|
||||
$this->suppressNotices();
|
||||
|
||||
$this->assertEquals(
|
||||
'4/03/2003',
|
||||
DBField::create_field('Date', '4.3.03')->Nice(),
|
||||
"Date->Nice() works with D.M.YY format"
|
||||
);
|
||||
$this->assertEquals(
|
||||
'4/03/2003',
|
||||
DBField::create_field('Date', '04.03.03')->Nice(),
|
||||
"Date->Nice() works with DD.MM.YY format"
|
||||
);
|
||||
$this->assertEquals(
|
||||
'4/03/2003',
|
||||
DBField::create_field('Date', '4.3.03')->Nice(),
|
||||
"Date->Nice() works with D.M.YY format"
|
||||
);
|
||||
$this->assertEquals(
|
||||
'4/03/2003',
|
||||
DBField::create_field('Date', '4.03.03')->Nice(),
|
||||
"Date->Nice() works with D.M.YY format"
|
||||
);
|
||||
$this->assertEquals(
|
||||
'4/03/2003',
|
||||
DBField::create_field('Date', '03-03-04')->Nice(),
|
||||
"Date->Nice() works with Y-m-d format"
|
||||
);
|
||||
|
||||
$this->setExpectedException(
|
||||
PHPUnit_Framework_Error_Notice::class,
|
||||
"Implicit y2k conversion. Please use full YYYY year for dates"
|
||||
\InvalidArgumentException::class,
|
||||
"Invalid date: '03-03-04'. Use " . DBDate::ISO_DATE . " to prevent this error."
|
||||
);
|
||||
$this->restoreNotices();
|
||||
DBField::create_field('Date', '03-03-04');
|
||||
}
|
||||
|
||||
public function testInvertedYearCorrection()
|
||||
{
|
||||
$this->suppressNotices();
|
||||
|
||||
// iso8601 expects year first
|
||||
// iso8601 expects year first, but support year last
|
||||
$this->assertEquals(
|
||||
'4/03/2003',
|
||||
DBField::create_field('Date', '04-03-2003')->Nice(),
|
||||
"Date->Nice() works with DD-MM-YYYY format"
|
||||
);
|
||||
|
||||
$this->setExpectedException(
|
||||
PHPUnit_Framework_Error_Notice::class,
|
||||
"Unexpected date order. Use " . DBDate::ISO_DATE . " to prevent this notice."
|
||||
);
|
||||
$this->restoreNotices();
|
||||
DBField::create_field('Date', '04-03-2003');
|
||||
}
|
||||
|
||||
public function testYear()
|
||||
@ -400,7 +334,6 @@ class DBDateTest extends SapphireTest
|
||||
return [
|
||||
['2000-12-31', '31/12/2000'],
|
||||
['31-12-2000', '31/12/2000'],
|
||||
['12/31/2000', '31/12/2000'],
|
||||
['2014-04-01', '01/04/2014'],
|
||||
];
|
||||
}
|
||||
|
@ -57,18 +57,6 @@ class DBTimeTest extends SapphireTest
|
||||
$this->assertEquals('5:15 PM', $time->Short());
|
||||
}
|
||||
|
||||
public function testNice12()
|
||||
{
|
||||
$time = DBTime::create_field('Time', '17:15:55');
|
||||
$this->assertEquals('5:15 PM', $time->Nice12());
|
||||
}
|
||||
|
||||
public function testNice24()
|
||||
{
|
||||
$time = DBTime::create_field('Time', '17:15:55');
|
||||
$this->assertEquals('17:15', $time->Nice24());
|
||||
}
|
||||
|
||||
public function dataTestFormatFromSettings()
|
||||
{
|
||||
return [
|
||||
|
Loading…
x
Reference in New Issue
Block a user