Version: current

      1 <?php
      2 /**
      3  * A composite field for date and time entry,
      4  * based on {@link DateField} and {@link TimeField}.
      5  * Usually saves into a single {@link SS_Datetime} database column.
      6  * If you want to save into {@link Date} or {@link Time} columns,
      7  * please instanciate the fields separately.
      8  *
      9  * # Configuration
     10  *
     11  * All options in {@link setConfig()} are passed through to {@link DateField} and {@link TimeField}.
     12  *
     13  * @package sapphire
     14  * @subpackage forms
     15  */
     16 class DatetimeField extends FormField {
     17
     18     /**
     19      * @var DateField
     20      */
     21     protected $dateField = null;
     22
     23     /**
     24      * @var TimeField
     25      */
     26     protected $timeField = null;
     27
     28     /**
     29      * @var array
     30      */
     31     protected $config = array(
     32         'datavalueformat' => 'YYYY-MM-dd HH:mm:ss'
     33     );
     34
     35     function __construct($name, $title = null, $value = ""){
     36         $this->dateField = new DateField($name . '[date]', false);
     37         $this->timeField = new TimeField($name . '[time]', false);
     38
     39         parent::__construct($name, $title, $value);
     40     }
     41
     42     function setForm($form) {
     43         parent::setForm($form);
     44
     45         $this->dateField->setForm($form);
     46         $this->timeField->setForm($form);
     47     }
     48
     49     function Field() {
     50         $attributes = array(
     51             'class' => 'datetimefield'
     52         );
     53         $this->dateField->addExtraClass('datetimefield');
     54         $this->timeField->addExtraClass('datetimefield');
     55         $this->dateField->addExtraClass('datetimefield__date');
     56         $this->timeField->addExtraClass('datetimefield__time');
     57         if ($this->Required() && ($validator = $this->form->Validator)) {
     58             $validator->addRequiredField($this->name . '[date]');
     59             $validator->addRequiredField($this->name . '[time]');
     60         }
     61
     62         return $this->createTag('', $attributes);
     63     }
     64
     65     /**
     66      * Sets the internal value to ISO date format.
     67      *
     68      * @param string|array $val String expects an ISO date format. Array notation with 'date' and 'time'
     69      *  keys can contain localized strings. If the 'dmyfields' option is used for {@link DateField},
     70      *  the 'date' value may contain array notation was well (see {@link DateField->setValue()}).
     71      */
     72     function setValue($val) {
     73         if(empty($val)) {
     74             $this->dateField->setValue(null);
     75             $this->timeField->setValue(null);
     76         } else {
     77             // String setting is only possible from the database, so we don't allow anything but ISO format
     78             if(is_string($val) && Zend_Date::isDate($val, $this->getConfig('datavalueformat'), $this->locale)) {
     79                 // split up in date and time string values.
     80                 $valueObj = new Zend_Date($val, $this->getConfig('datavalueformat'), $this->locale);
     81                 // set date either as array, or as string
     82                 $this->dateField->setValue($valueObj->get($this->dateField->getConfig('dateformat')));
     83                 // set time
     84                 $this->timeField->setValue($valueObj->get($this->timeField->getConfig('timeformat')));
     85             }
     86             // Setting from form submission
     87             elseif(is_array($val) && array_key_exists('date', $val) && array_key_exists('time', $val)) {
     88                 $this->dateField->setValue($val['date']);
     89                 $this->timeField->setValue($val['time']);
     90             } else {
     91                 $this->dateField->setValue($val);
     92                 $this->timeField->setValue($val);
     93             }
     94         }
     95     }
     96
     97     function dataValue() {
     98         $valDate = $this->dateField->dataValue();
     99         $valTime = $this->timeField->dataValue();
    100
    101         if($valDate && $valTime) {
    102             return $valDate . ' ' . $valTime;
    103         } else {
    104             // TODO
    105             return null;
    106         }
    107     }
    108
    109     /**
    110      * @return DateField
    111      */
    112     function getDateField() {
    113         return $this->dateField;
    114     }
    115
    116     /**
    117      * @return TimeField
    118      */
    119     function getTimeField() {
    120         return $this->timeField;
    121     }
    122
    123     function setLocale($locale) {
    124         $this->dateField->setLocale($locale);
    125         $this->timeField->setLocale($locale);
    126     }
    127
    128     function getLocale() {
    129         return $this->dateField->getLocale();
    130     }
    131
    132     /**
    133      * Note: Use {@link getDateField()} and {@link getTimeField()}
    134      * to set field-specific config options.
    135      *
    136      * @param string $name
    137      * @param mixed $val
    138      */
    139     function setConfig($name, $val) {
    140         $this->config[$name] = $val;
    141         $this->dateField->setConfig($name, $val);
    142         $this->timeField->setConfig($name, $val);
    143     }
    144
    145     /**
    146      * Note: Use {@link getDateField()} and {@link getTimeField()}
    147      * to get field-specific config options.
    148      *
    149      * @param String $name
    150      * @return mixed
    151      */
    152     function getConfig($name) {
    153         return $this->config[$name];
    154     }
    155
    156     function validate($validator) {
    157         $dateValid = $this->dateField->validate($validator);
    158         $timeValid = $this->timeField->validate($validator);
    159
    160         return ($dateValid && $timeValid);
    161     }
    162
    163     function jsValidation() {
    164         return $this->dateField->jsValidation() . $this->timeField->jsValidation();
    165     }
    166
    167     function performReadonlyTransformation() {
    168         $field = new DatetimeField_Readonly($this->name, $this->title, $this->dataValue());
    169         $field->setForm($this->form);
    170
    171         return $field;
    172     }
    173 }
    174
    175 /**
    176  * The readonly class for our {@link DatetimeField}.
    177  *
    178  * @package forms
    179  * @subpackage fields-datetime
    180  */
    181 class DatetimeField_Readonly extends DatetimeField {
    182
    183     protected $readonly = true;
    184
    185     function Field() {
    186         $valDate = $this->dateField->dataValue();
    187         $valTime = $this->timeField->dataValue();
    188         if($valDate && $valTime) {
    189             $format = $this->dateField->getConfig('dateformat') . ' ' . $this->timeField->getConfig('timeformat');
    190             $valueObj = new Zend_Date(
    191                 $valDate . ' ' . $valTime,
    192                 $this->getConfig('datavalueformat'),
    193                 $this->dateField->getLocale()
    194             );
    195             $val = $valueObj->toString($format);
    196         } else {
    197             // TODO Localization
    198             $val = '<i>(not set)</i>';
    199         }
    200
    201         return "<span class=\"readonly\" id=\"" . $this->id() . "\">$val</span>";
    202     }
    203
    204     function jsValidation() {
    205         return null;
    206     }
    207
    208     function validate($validator) {
    209         return true;
    210     }
    211 }
    212 ?>

[Raise a SilverStripe Framework issue/bug](https://github.com/silverstripe/silverstripe-framework/issues/new)
- [Raise a SilverStripe CMS issue/bug](https://github.com/silverstripe/silverstripe-cms/issues/new)
- Please use the Silverstripe Forums to ask development related questions. -