2007-07-19 12:40:28 +02:00
|
|
|
<?php
|
2015-08-30 07:02:55 +02:00
|
|
|
|
2016-08-19 00:51:35 +02:00
|
|
|
namespace SilverStripe\Forms;
|
2016-06-15 06:03:16 +02:00
|
|
|
|
2017-01-26 05:20:08 +01:00
|
|
|
use IntlDateFormatter;
|
2016-08-19 00:51:35 +02:00
|
|
|
use SilverStripe\i18n\i18n;
|
|
|
|
use InvalidArgumentException;
|
2017-01-26 05:20:08 +01:00
|
|
|
use SilverStripe\ORM\FieldType\DBDatetime;
|
FEATURE New DatetimeField class (form field wrapper composed of DateField andTimeField)
FEATURE New DateField and TimeField form classes with more consistent API and easier localization
API CHANGE Date/time parsing in DateField, TimeField and DatetimeField defaults to i18n::get_locale() ('en_US') instead of using en_NZ/en_GB specific parsing. Use i18n::set_locale('en_NZ') in mysite/_config.php to revert to old behaviour.
API CHANGE constructor parameter in TimeField needs to be in ISO date notation (not PHP's date())
API CHANGE TimeField, DateField and related subclasses use Zend_Date for date parsing, meaning they're stricer than the previously used strtotime()
API CHANGE Removed DMYCalendarDateField and CalendarDateField, use DateField with setConfig('showcalendar')
API CHANGE Removed CompositeDateField, DMYDateField, use DateField with setConfig('dmyfields')
API CHANGE Removed DropdownTimeField, use TimeField with setConfig('showdropdown')
API CHANGE Removed PopupDateTimeField, use DatetimeField
API CHANGE Changed 'date', 'month' and 'year' HTML field names to lowercase in DMYDateField
API CHANGE Removed support for ambiguous date formats in DateField, e.g. '06/03/03'. Use DateField->setConfig('dateformat', '<format>') to revert to this behaviour.
API CHANGE Removed flag from DateField, CalendarDateField etc., use DateField->setConfig('min') and DateField->setConfig('max')
ENHANCEMENT Using Zend_Date for DateField and TimeField, with more robust date handling, starting localization support. Set globally via i18n::set_locale(), or for a field instance through setLocale(). Note: Javascript validation is not localized yet. (from r99360)
git-svn-id: svn://svn.silverstripe.com/silverstripe/open/modules/sapphire/trunk@102859 467b73ca-7a2a-4603-9d3b-597d59a354a9
2010-04-14 06:38:40 +02:00
|
|
|
|
2007-07-19 12:40:28 +02:00
|
|
|
/**
|
2017-02-14 06:19:09 +01:00
|
|
|
* Form used for editing a date stirng
|
2014-08-15 08:53:05 +02:00
|
|
|
*
|
2016-09-15 04:48:38 +02:00
|
|
|
* 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.
|
|
|
|
*
|
FEATURE New DatetimeField class (form field wrapper composed of DateField andTimeField)
FEATURE New DateField and TimeField form classes with more consistent API and easier localization
API CHANGE Date/time parsing in DateField, TimeField and DatetimeField defaults to i18n::get_locale() ('en_US') instead of using en_NZ/en_GB specific parsing. Use i18n::set_locale('en_NZ') in mysite/_config.php to revert to old behaviour.
API CHANGE constructor parameter in TimeField needs to be in ISO date notation (not PHP's date())
API CHANGE TimeField, DateField and related subclasses use Zend_Date for date parsing, meaning they're stricer than the previously used strtotime()
API CHANGE Removed DMYCalendarDateField and CalendarDateField, use DateField with setConfig('showcalendar')
API CHANGE Removed CompositeDateField, DMYDateField, use DateField with setConfig('dmyfields')
API CHANGE Removed DropdownTimeField, use TimeField with setConfig('showdropdown')
API CHANGE Removed PopupDateTimeField, use DatetimeField
API CHANGE Changed 'date', 'month' and 'year' HTML field names to lowercase in DMYDateField
API CHANGE Removed support for ambiguous date formats in DateField, e.g. '06/03/03'. Use DateField->setConfig('dateformat', '<format>') to revert to this behaviour.
API CHANGE Removed flag from DateField, CalendarDateField etc., use DateField->setConfig('min') and DateField->setConfig('max')
ENHANCEMENT Using Zend_Date for DateField and TimeField, with more robust date handling, starting localization support. Set globally via i18n::set_locale(), or for a field instance through setLocale(). Note: Javascript validation is not localized yet. (from r99360)
git-svn-id: svn://svn.silverstripe.com/silverstripe/open/modules/sapphire/trunk@102859 467b73ca-7a2a-4603-9d3b-597d59a354a9
2010-04-14 06:38:40 +02:00
|
|
|
* # Localization
|
2014-08-15 08:53:05 +02:00
|
|
|
*
|
2017-01-26 05:20:08 +01:00
|
|
|
* Date formatting can be controlled in the below order of priority:
|
|
|
|
* - Format set via setDateFormat()
|
|
|
|
* - Format generated from current locale set by setLocale() and setDateLength()
|
|
|
|
* - Format generated from current locale in i18n
|
|
|
|
*
|
|
|
|
* You can also specify a setClientLocale() to set the javascript to a specific locale
|
|
|
|
* on the frontend. However, this will not override the date format string.
|
2014-08-15 08:53:05 +02:00
|
|
|
*
|
2012-10-05 06:00:39 +02:00
|
|
|
* See http://doc.silverstripe.org/framework/en/topics/i18n for more information about localizing form fields.
|
2014-08-15 08:53:05 +02:00
|
|
|
*
|
FEATURE New DatetimeField class (form field wrapper composed of DateField andTimeField)
FEATURE New DateField and TimeField form classes with more consistent API and easier localization
API CHANGE Date/time parsing in DateField, TimeField and DatetimeField defaults to i18n::get_locale() ('en_US') instead of using en_NZ/en_GB specific parsing. Use i18n::set_locale('en_NZ') in mysite/_config.php to revert to old behaviour.
API CHANGE constructor parameter in TimeField needs to be in ISO date notation (not PHP's date())
API CHANGE TimeField, DateField and related subclasses use Zend_Date for date parsing, meaning they're stricer than the previously used strtotime()
API CHANGE Removed DMYCalendarDateField and CalendarDateField, use DateField with setConfig('showcalendar')
API CHANGE Removed CompositeDateField, DMYDateField, use DateField with setConfig('dmyfields')
API CHANGE Removed DropdownTimeField, use TimeField with setConfig('showdropdown')
API CHANGE Removed PopupDateTimeField, use DatetimeField
API CHANGE Changed 'date', 'month' and 'year' HTML field names to lowercase in DMYDateField
API CHANGE Removed support for ambiguous date formats in DateField, e.g. '06/03/03'. Use DateField->setConfig('dateformat', '<format>') to revert to this behaviour.
API CHANGE Removed flag from DateField, CalendarDateField etc., use DateField->setConfig('min') and DateField->setConfig('max')
ENHANCEMENT Using Zend_Date for DateField and TimeField, with more robust date handling, starting localization support. Set globally via i18n::set_locale(), or for a field instance through setLocale(). Note: Javascript validation is not localized yet. (from r99360)
git-svn-id: svn://svn.silverstripe.com/silverstripe/open/modules/sapphire/trunk@102859 467b73ca-7a2a-4603-9d3b-597d59a354a9
2010-04-14 06:38:40 +02:00
|
|
|
* # Usage
|
2014-08-15 08:53:05 +02:00
|
|
|
*
|
2017-02-14 06:19:09 +01:00
|
|
|
* ## Example: Field localised with german date format
|
2014-08-15 08:53:05 +02:00
|
|
|
*
|
2012-12-08 12:20:20 +01:00
|
|
|
* $f = new DateField('MyDate');
|
|
|
|
* $f->setLocale('de_DE');
|
2014-08-15 08:53:05 +02:00
|
|
|
*
|
2010-10-04 06:29:13 +02:00
|
|
|
* # Validation
|
2014-08-15 08:53:05 +02:00
|
|
|
*
|
2010-10-04 06:29:13 +02:00
|
|
|
* Caution: JavaScript validation is only supported for the 'en_NZ' locale at the moment,
|
|
|
|
* it will be disabled automatically for all other locales.
|
2017-01-26 05:20:08 +01:00
|
|
|
*
|
|
|
|
* # Formats
|
|
|
|
*
|
|
|
|
* All format strings should follow the CLDR standard as per
|
|
|
|
* http://userguide.icu-project.org/formatparse/datetime. These will be converted
|
|
|
|
* automatically to jquery UI format.
|
|
|
|
*
|
|
|
|
* The value of this field in PHP will be ISO 8601 standard (e.g. 2004-02-12), and
|
|
|
|
* stores this as a timestamp internally.
|
|
|
|
*
|
|
|
|
* Note: Do NOT use php date format strings. Date format strings follow the date
|
|
|
|
* field symbol table as below.
|
|
|
|
*
|
|
|
|
* @see http://userguide.icu-project.org/formatparse/datetime
|
|
|
|
* @see http://api.jqueryui.com/datepicker/#utility-formatDate
|
2007-07-19 12:40:28 +02:00
|
|
|
*/
|
2016-11-29 00:31:16 +01:00
|
|
|
class DateField extends TextField
|
|
|
|
{
|
|
|
|
protected $schemaDataType = FormField::SCHEMA_DATA_TYPE_DATE;
|
|
|
|
|
|
|
|
/**
|
2017-01-26 05:20:08 +01:00
|
|
|
* Override locale. If empty will default to current locale
|
|
|
|
*
|
|
|
|
* @var string
|
|
|
|
*/
|
|
|
|
protected $locale = null;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Override date format. If empty will default to that used by the current locale.
|
|
|
|
*
|
|
|
|
* @var null
|
2016-11-29 00:31:16 +01:00
|
|
|
*/
|
2017-01-26 05:20:08 +01:00
|
|
|
protected $dateFormat = null;
|
2016-11-29 00:31:16 +01:00
|
|
|
|
|
|
|
/**
|
2017-01-26 05:20:08 +01:00
|
|
|
* Set if js calendar should popup
|
|
|
|
*
|
|
|
|
* @var bool
|
2016-11-29 00:31:16 +01:00
|
|
|
*/
|
2017-01-26 05:20:08 +01:00
|
|
|
protected $showCalendar = false;
|
2016-11-29 00:31:16 +01:00
|
|
|
|
|
|
|
/**
|
2017-01-26 05:20:08 +01:00
|
|
|
* Length of this date (full, short, etc).
|
|
|
|
*
|
|
|
|
* @see http://php.net/manual/en/class.intldateformatter.php#intl.intldateformatter-constants
|
|
|
|
* @var int
|
2016-11-29 00:31:16 +01:00
|
|
|
*/
|
2017-01-26 05:20:08 +01:00
|
|
|
protected $dateLength = null;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Set whether to show placeholders
|
|
|
|
*
|
|
|
|
* @var bool
|
|
|
|
*/
|
|
|
|
protected $placeholders = true;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Override locale for client side.
|
|
|
|
*
|
|
|
|
* @var string
|
|
|
|
*/
|
|
|
|
protected $clientLocale = null;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Min date
|
|
|
|
*
|
|
|
|
* @var string ISO 8601 date for min date
|
|
|
|
*/
|
|
|
|
protected $minDate = null;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Max date
|
|
|
|
*
|
|
|
|
* @var string ISO 860 date for max date
|
|
|
|
*/
|
|
|
|
protected $maxDate = null;
|
2016-11-29 00:31:16 +01:00
|
|
|
|
|
|
|
/**
|
2017-01-26 05:20:08 +01:00
|
|
|
* Unparsed value, used exclusively for comparing with internal value
|
|
|
|
* to detect invalid values.
|
|
|
|
*
|
|
|
|
* @var mixed
|
2016-11-29 00:31:16 +01:00
|
|
|
*/
|
2017-01-26 05:20:08 +01:00
|
|
|
protected $rawValue = null;
|
2016-11-29 00:31:16 +01:00
|
|
|
|
2017-01-26 05:20:08 +01:00
|
|
|
/**
|
|
|
|
* Check if calendar should be shown on the frontend
|
|
|
|
*
|
|
|
|
* @return bool
|
|
|
|
*/
|
|
|
|
public function getShowCalendar()
|
2016-11-29 00:31:16 +01:00
|
|
|
{
|
2017-01-26 05:20:08 +01:00
|
|
|
return $this->showCalendar;
|
|
|
|
}
|
2016-11-29 00:31:16 +01:00
|
|
|
|
2017-01-26 05:20:08 +01:00
|
|
|
/**
|
|
|
|
* Set if calendar should be shown on the frontend.
|
|
|
|
*
|
|
|
|
* @param bool $show
|
|
|
|
* @return $this
|
|
|
|
*/
|
|
|
|
public function setShowCalendar($show)
|
|
|
|
{
|
|
|
|
$this->showCalendar = $show;
|
|
|
|
return $this;
|
|
|
|
}
|
2016-11-29 00:31:16 +01:00
|
|
|
|
2017-01-26 05:20:08 +01:00
|
|
|
/**
|
|
|
|
* Get length of the date format to use. One of:
|
|
|
|
*
|
|
|
|
* - IntlDateFormatter::SHORT
|
|
|
|
* - IntlDateFormatter::MEDIUM
|
|
|
|
* - IntlDateFormatter::LONG
|
|
|
|
* - IntlDateFormatter::FULL
|
|
|
|
*
|
|
|
|
* @see http://php.net/manual/en/class.intldateformatter.php#intl.intldateformatter-constants
|
|
|
|
* @return int
|
|
|
|
*/
|
|
|
|
public function getDateLength()
|
|
|
|
{
|
|
|
|
if ($this->dateLength) {
|
|
|
|
return $this->dateLength;
|
2016-11-29 00:31:16 +01:00
|
|
|
}
|
2017-01-26 05:20:08 +01:00
|
|
|
return IntlDateFormatter::MEDIUM;
|
|
|
|
}
|
2016-11-29 00:31:16 +01:00
|
|
|
|
2017-01-26 05:20:08 +01:00
|
|
|
/**
|
|
|
|
* Get length of the date format to use. One of:
|
|
|
|
*
|
|
|
|
* - IntlDateFormatter::SHORT
|
|
|
|
* - IntlDateFormatter::MEDIUM
|
|
|
|
* - IntlDateFormatter::LONG
|
|
|
|
* - IntlDateFormatter::FULL
|
|
|
|
*
|
|
|
|
* @see http://php.net/manual/en/class.intldateformatter.php#intl.intldateformatter-constants
|
|
|
|
*
|
|
|
|
* @param int $length
|
|
|
|
* @return $this
|
|
|
|
*/
|
|
|
|
public function setDateLength($length)
|
|
|
|
{
|
|
|
|
$this->dateLength = $length;
|
|
|
|
return $this;
|
2016-11-29 00:31:16 +01:00
|
|
|
}
|
|
|
|
|
2017-01-26 05:20:08 +01:00
|
|
|
/**
|
|
|
|
* Get date format in CLDR standard format
|
|
|
|
*
|
|
|
|
* This can be set explicitly. If not, this will be generated from the current locale
|
|
|
|
* with the current date length.
|
|
|
|
*
|
|
|
|
* @see http://userguide.icu-project.org/formatparse/datetime#TOC-Date-Field-Symbol-Table
|
|
|
|
*/
|
|
|
|
public function getDateFormat()
|
2016-11-29 00:31:16 +01:00
|
|
|
{
|
2017-01-26 05:20:08 +01:00
|
|
|
if ($this->dateFormat) {
|
|
|
|
return $this->dateFormat;
|
2016-11-29 00:31:16 +01:00
|
|
|
}
|
|
|
|
|
2017-01-26 05:20:08 +01:00
|
|
|
// Get from locale
|
|
|
|
return $this->getFormatter()->getPattern();
|
2016-11-29 00:31:16 +01:00
|
|
|
}
|
|
|
|
|
2017-01-26 05:20:08 +01:00
|
|
|
/**
|
|
|
|
* Set date format in CLDR standard format.
|
|
|
|
*
|
|
|
|
* @see http://userguide.icu-project.org/formatparse/datetime#TOC-Date-Field-Symbol-Table
|
|
|
|
* @param string $format
|
|
|
|
* @return $this
|
|
|
|
*/
|
|
|
|
public function setDateFormat($format)
|
2016-11-29 00:31:16 +01:00
|
|
|
{
|
2017-01-26 05:20:08 +01:00
|
|
|
$this->dateFormat = $format;
|
|
|
|
return $this;
|
2016-11-29 00:31:16 +01:00
|
|
|
}
|
|
|
|
|
2017-01-26 05:20:08 +01:00
|
|
|
/**
|
|
|
|
* Get date formatter with the standard locale / date format
|
|
|
|
*
|
|
|
|
* @return IntlDateFormatter
|
|
|
|
*/
|
|
|
|
protected function getFormatter()
|
2016-11-29 00:31:16 +01:00
|
|
|
{
|
2017-01-26 05:20:08 +01:00
|
|
|
$formatter = IntlDateFormatter::create(
|
|
|
|
$this->getLocale(),
|
|
|
|
$this->getDateLength(),
|
|
|
|
IntlDateFormatter::NONE
|
2016-11-29 00:31:16 +01:00
|
|
|
);
|
|
|
|
|
2017-01-26 05:20:08 +01:00
|
|
|
// Don't invoke getDateFormat() directly to avoid infinite loop
|
|
|
|
if ($this->dateFormat) {
|
|
|
|
$ok = $formatter->setPattern($this->dateFormat);
|
|
|
|
if (!$ok) {
|
|
|
|
throw new InvalidArgumentException("Invalid date format {$this->dateFormat}");
|
2016-11-29 00:31:16 +01:00
|
|
|
}
|
|
|
|
}
|
2017-01-26 05:20:08 +01:00
|
|
|
return $formatter;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Get a date formatter for the ISO 8601 format
|
|
|
|
*
|
|
|
|
* @return IntlDateFormatter
|
|
|
|
*/
|
|
|
|
protected function getISO8601Formatter()
|
|
|
|
{
|
|
|
|
$formatter = IntlDateFormatter::create(
|
|
|
|
i18n::config()->get('default_locale'),
|
|
|
|
IntlDateFormatter::MEDIUM,
|
|
|
|
IntlDateFormatter::NONE
|
|
|
|
);
|
|
|
|
$formatter->setLenient(false);
|
|
|
|
// CLDR iso8601 date.
|
|
|
|
$formatter->setPattern('y-MM-dd');
|
|
|
|
return $formatter;
|
|
|
|
}
|
|
|
|
|
|
|
|
public function FieldHolder($properties = array())
|
|
|
|
{
|
|
|
|
return $this->renderWithClientView(function () use ($properties) {
|
|
|
|
return parent::FieldHolder($properties);
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
public function SmallFieldHolder($properties = array())
|
|
|
|
{
|
|
|
|
return $this->renderWithClientView(function () use ($properties) {
|
|
|
|
return parent::SmallFieldHolder($properties);
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Generate field with client view enabled
|
|
|
|
*
|
|
|
|
* @param callable $callback
|
|
|
|
* @return string
|
|
|
|
*/
|
|
|
|
protected function renderWithClientView($callback)
|
|
|
|
{
|
|
|
|
$clientView = null;
|
|
|
|
if ($this->getShowCalendar()) {
|
|
|
|
$clientView = $this->getClientView();
|
|
|
|
$clientView->onBeforeRender();
|
|
|
|
}
|
|
|
|
$html = $callback();
|
|
|
|
if ($clientView) {
|
|
|
|
$html = $clientView->onAfterRender($html);
|
2016-11-29 00:31:16 +01:00
|
|
|
}
|
2017-01-26 05:20:08 +01:00
|
|
|
return $html;
|
|
|
|
}
|
|
|
|
|
|
|
|
public function getAttributes()
|
|
|
|
{
|
|
|
|
$attributes = parent::getAttributes();
|
|
|
|
|
|
|
|
// Merge with client config
|
|
|
|
$config = $this->getClientConfig();
|
|
|
|
foreach ($config as $key => $value) {
|
|
|
|
$attributes["data-{$key}"] = $value;
|
|
|
|
}
|
|
|
|
|
|
|
|
return $attributes;
|
|
|
|
}
|
|
|
|
|
2016-11-29 00:31:16 +01:00
|
|
|
public function Type()
|
|
|
|
{
|
|
|
|
return 'date text';
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2017-01-26 05:20:08 +01:00
|
|
|
* Assign value posted from form submission
|
2016-11-29 00:31:16 +01:00
|
|
|
*
|
2017-01-26 05:20:08 +01:00
|
|
|
* @param mixed $value
|
|
|
|
* @param mixed $data
|
2016-11-29 00:31:16 +01:00
|
|
|
* @return $this
|
|
|
|
*/
|
2017-01-26 05:20:08 +01:00
|
|
|
public function setSubmittedValue($value, $data = null)
|
2016-11-29 00:31:16 +01:00
|
|
|
{
|
2017-01-26 05:20:08 +01:00
|
|
|
// Save raw value for later validation
|
2017-02-14 06:19:09 +01:00
|
|
|
$this->rawValue = $value;
|
2016-11-29 00:31:16 +01:00
|
|
|
|
2017-01-26 05:20:08 +01:00
|
|
|
// Null case
|
|
|
|
if (!$value) {
|
2016-11-29 00:31:16 +01:00
|
|
|
$this->value = null;
|
2017-01-26 05:20:08 +01:00
|
|
|
return $this;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Parse from submitted value
|
|
|
|
$this->value = $this->localisedToISO8601($value);
|
2016-11-29 00:31:16 +01:00
|
|
|
return $this;
|
|
|
|
}
|
|
|
|
|
2017-01-26 05:20:08 +01:00
|
|
|
public function setValue($value, $data = null)
|
2016-11-29 00:31:16 +01:00
|
|
|
{
|
2017-01-26 05:20:08 +01:00
|
|
|
// Save raw value for later validation
|
|
|
|
$this->rawValue = $value;
|
|
|
|
|
|
|
|
// Null case
|
|
|
|
if (!$value) {
|
|
|
|
$this->value = null;
|
|
|
|
return $this;
|
2016-11-29 00:31:16 +01:00
|
|
|
}
|
|
|
|
|
2017-01-26 05:20:08 +01:00
|
|
|
if (is_array($value)) {
|
|
|
|
throw new InvalidArgumentException("Use setSubmittedValue to assign by array");
|
|
|
|
}
|
2016-11-29 00:31:16 +01:00
|
|
|
|
2017-01-26 05:20:08 +01:00
|
|
|
// Re-run through formatter to tidy up (e.g. remove time component)
|
|
|
|
$this->value = $this->tidyISO8601($value);
|
|
|
|
return $this;
|
2016-11-29 00:31:16 +01:00
|
|
|
}
|
|
|
|
|
2017-01-26 05:20:08 +01:00
|
|
|
public function Value()
|
2016-11-29 00:31:16 +01:00
|
|
|
{
|
2017-01-26 05:20:08 +01:00
|
|
|
return $this->iso8601ToLocalised($this->value);
|
2016-11-29 00:31:16 +01:00
|
|
|
}
|
|
|
|
|
2017-01-26 05:20:08 +01:00
|
|
|
public function performReadonlyTransformation()
|
2016-11-29 00:31:16 +01:00
|
|
|
{
|
2017-01-26 05:20:08 +01:00
|
|
|
$field = $this->castedCopy(DateField_Disabled::class);
|
|
|
|
$field->setValue($this->dataValue());
|
|
|
|
$field->setReadonly(true);
|
|
|
|
return $field;
|
2016-11-29 00:31:16 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @param Validator $validator
|
|
|
|
* @return bool
|
|
|
|
*/
|
|
|
|
public function validate($validator)
|
|
|
|
{
|
|
|
|
// Don't validate empty fields
|
2017-01-26 05:20:08 +01:00
|
|
|
if (empty($this->rawValue)) {
|
2016-11-29 00:31:16 +01:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2017-01-26 05:20:08 +01:00
|
|
|
// We submitted a value, but it couldn't be parsed
|
|
|
|
if (empty($this->value)) {
|
2016-11-29 00:31:16 +01:00
|
|
|
$validator->validationError(
|
|
|
|
$this->name,
|
|
|
|
_t(
|
|
|
|
'DateField.VALIDDATEFORMAT2',
|
|
|
|
"Please enter a valid date format ({format})",
|
2017-01-26 05:20:08 +01:00
|
|
|
['format' => $this->getDateFormat()]
|
|
|
|
)
|
2016-11-29 00:31:16 +01:00
|
|
|
);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2017-01-26 05:20:08 +01:00
|
|
|
// Check min date
|
|
|
|
$min = $this->getMinDate();
|
|
|
|
if ($min) {
|
|
|
|
$oops = strtotime($this->value) < strtotime($min);
|
|
|
|
if ($oops) {
|
2016-11-29 00:31:16 +01:00
|
|
|
$validator->validationError(
|
|
|
|
$this->name,
|
|
|
|
_t(
|
|
|
|
'DateField.VALIDDATEMINDATE',
|
|
|
|
"Your date has to be newer or matching the minimum allowed date ({date})",
|
2017-01-26 05:20:08 +01:00
|
|
|
['date' => $this->iso8601ToLocalised($min)]
|
|
|
|
)
|
2016-11-29 00:31:16 +01:00
|
|
|
);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
2017-01-26 05:20:08 +01:00
|
|
|
|
|
|
|
// Check max date
|
|
|
|
$max = $this->getMaxDate();
|
|
|
|
if ($max) {
|
|
|
|
$oops = strtotime($this->value) > strtotime($max);
|
|
|
|
if ($oops) {
|
2016-11-29 00:31:16 +01:00
|
|
|
$validator->validationError(
|
|
|
|
$this->name,
|
|
|
|
_t(
|
|
|
|
'DateField.VALIDDATEMAXDATE',
|
|
|
|
"Your date has to be older or matching the maximum allowed date ({date})",
|
2017-01-26 05:20:08 +01:00
|
|
|
['date' => $this->iso8601ToLocalised($max)]
|
|
|
|
)
|
2016-11-29 00:31:16 +01:00
|
|
|
);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2017-01-26 05:20:08 +01:00
|
|
|
* Get locale to use for this field
|
|
|
|
*
|
2016-11-29 00:31:16 +01:00
|
|
|
* @return string
|
|
|
|
*/
|
|
|
|
public function getLocale()
|
|
|
|
{
|
2017-01-26 05:20:08 +01:00
|
|
|
return $this->locale ?: i18n::get_locale();
|
2016-11-29 00:31:16 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Caution: Will not update the 'dateformat' config value.
|
|
|
|
*
|
|
|
|
* @param string $locale
|
|
|
|
* @return $this
|
|
|
|
*/
|
|
|
|
public function setLocale($locale)
|
|
|
|
{
|
|
|
|
$this->locale = $locale;
|
|
|
|
return $this;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2017-01-26 05:20:08 +01:00
|
|
|
* Get locale code for client-side. Will default to getLocale() if omitted.
|
|
|
|
*
|
|
|
|
* @return string
|
2016-11-29 00:31:16 +01:00
|
|
|
*/
|
2017-01-26 05:20:08 +01:00
|
|
|
public function getClientLocale()
|
|
|
|
{
|
|
|
|
if ($this->clientLocale) {
|
|
|
|
return $this->clientLocale;
|
|
|
|
}
|
|
|
|
return $this->getLocale();
|
2016-11-29 00:31:16 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2017-01-26 05:20:08 +01:00
|
|
|
* @param string $clientLocale
|
|
|
|
* @return DateField
|
2016-11-29 00:31:16 +01:00
|
|
|
*/
|
2017-01-26 05:20:08 +01:00
|
|
|
public function setClientLocale($clientLocale)
|
2016-11-29 00:31:16 +01:00
|
|
|
{
|
2017-01-26 05:20:08 +01:00
|
|
|
$this->clientLocale = $clientLocale;
|
|
|
|
return $this;
|
2016-11-29 00:31:16 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
public function getSchemaValidation()
|
|
|
|
{
|
|
|
|
$rules = parent::getSchemaValidation();
|
|
|
|
$rules['date'] = true;
|
|
|
|
return $rules;
|
|
|
|
}
|
2017-01-26 05:20:08 +01:00
|
|
|
|
|
|
|
/**
|
|
|
|
* 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;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @return string
|
|
|
|
*/
|
|
|
|
public function getMinDate()
|
|
|
|
{
|
|
|
|
return $this->minDate;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @param string $minDate
|
|
|
|
* @return $this
|
|
|
|
*/
|
|
|
|
public function setMinDate($minDate)
|
|
|
|
{
|
|
|
|
$this->minDate = $this->tidyISO8601($minDate);
|
|
|
|
return $this;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @return string
|
|
|
|
*/
|
|
|
|
public function getMaxDate()
|
|
|
|
{
|
|
|
|
return $this->maxDate;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @param string $maxDate
|
|
|
|
* @return $this
|
|
|
|
*/
|
|
|
|
public function setMaxDate($maxDate)
|
|
|
|
{
|
|
|
|
$this->maxDate = $this->tidyISO8601($maxDate);
|
|
|
|
return $this;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Get client data properties for this field
|
|
|
|
*
|
|
|
|
* @return array
|
|
|
|
*/
|
|
|
|
public function getClientConfig()
|
|
|
|
{
|
|
|
|
$view = $this->getClientView();
|
|
|
|
$config = [
|
|
|
|
'showcalendar' => $this->getShowCalendar() ? 'true' : null,
|
|
|
|
'date-format' => $view->getDateFormat(), // https://api.jqueryui.com/datepicker/#option-dateFormat
|
|
|
|
'locale' => $view->getLocale(),
|
|
|
|
];
|
|
|
|
|
|
|
|
// Format min/maxDate in format expected by jquery datepicker
|
|
|
|
$min = $this->getMinDate();
|
|
|
|
if ($min) {
|
|
|
|
// https://api.jqueryui.com/datepicker/#option-minDate
|
|
|
|
$config['min-date'] = $this->iso8601ToLocalised($min);
|
|
|
|
}
|
|
|
|
$max = $this->getMaxDate();
|
|
|
|
if ($max) {
|
|
|
|
// https://api.jqueryui.com/datepicker/#option-maxDate
|
|
|
|
$config['max-date'] = $this->iso8601ToLocalised($max);
|
|
|
|
}
|
|
|
|
|
|
|
|
return $config;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Convert date localised in the current locale to ISO 8601 date
|
|
|
|
*
|
|
|
|
* @param string $date
|
|
|
|
* @return string The formatted date, or null if not a valid date
|
|
|
|
*/
|
|
|
|
public function localisedToISO8601($date)
|
|
|
|
{
|
|
|
|
if (!$date) {
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
$fromFormatter = $this->getFormatter();
|
|
|
|
$toFormatter = $this->getISO8601Formatter();
|
|
|
|
$timestamp = $fromFormatter->parse($date);
|
|
|
|
if ($timestamp === false) {
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
return $toFormatter->format($timestamp) ?: null;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Convert an ISO 8601 localised date into the format specified by the
|
|
|
|
* current date format.
|
|
|
|
*
|
|
|
|
* @param string $date
|
|
|
|
* @return string The formatted date, or null if not a valid date
|
|
|
|
*/
|
|
|
|
public function iso8601ToLocalised($date)
|
|
|
|
{
|
|
|
|
$date = $this->tidyISO8601($date);
|
|
|
|
if (!$date) {
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
$fromFormatter = $this->getISO8601Formatter();
|
|
|
|
$toFormatter = $this->getFormatter();
|
|
|
|
$timestamp = $fromFormatter->parse($date);
|
|
|
|
if ($timestamp === false) {
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
return $toFormatter->format($timestamp) ?: null;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Tidy up iso8601-ish date, or approximation
|
|
|
|
*
|
|
|
|
* @param string $date Date in iso8601 or approximate form
|
|
|
|
* @return string iso8601 date, or null if not valid
|
|
|
|
*/
|
|
|
|
public function tidyISO8601($date)
|
|
|
|
{
|
|
|
|
if (!$date) {
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
// Re-run through formatter to tidy up (e.g. remove time component)
|
|
|
|
$formatter = $this->getISO8601Formatter();
|
|
|
|
$timestamp = $formatter->parse($date);
|
|
|
|
if ($timestamp === false) {
|
|
|
|
// Fallback to strtotime
|
|
|
|
$timestamp = strtotime($date, DBDatetime::now()->getTimestamp());
|
|
|
|
if ($timestamp === false) {
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return $formatter->format($timestamp);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @return DateField_View_JQuery
|
|
|
|
*/
|
|
|
|
protected function getClientView()
|
|
|
|
{
|
|
|
|
return DateField_View_JQuery::create($this);
|
|
|
|
}
|
2007-07-19 12:40:28 +02:00
|
|
|
}
|