1<?php 2namespace dokuwiki\plugin\struct\types; 3 4use dokuwiki\plugin\struct\meta\DateFormatConverter; 5use dokuwiki\plugin\struct\meta\QueryBuilder; 6use dokuwiki\plugin\struct\meta\QueryBuilderWhere; 7use dokuwiki\plugin\struct\meta\ValidationException; 8 9class DateTime extends Date { 10 11 protected $config = array( 12 'format' => '', // filled by constructor 13 'prefilltoday' => false 14 ); 15 16 /** 17 * DateTime constructor. 18 * 19 * @param array|null $config 20 * @param string $label 21 * @param bool $ismulti 22 * @param int $tid 23 */ 24 public function __construct($config = null, $label = '', $ismulti = false, $tid = 0) { 25 global $conf; 26 $this->config['format'] = DateFormatConverter::toDate($conf['dformat']); 27 28 parent::__construct($config, $label, $ismulti, $tid); 29 } 30 31 /** 32 * Return the editor to edit a single value 33 * 34 * @param string $name the form name where this has to be stored 35 * @param string $value the current value 36 * @param bool $isRaw ignored 37 * @return string html 38 */ 39 public function valueEditor($name, $value, $isRaw = false) { 40 if($this->config['prefilltoday'] && !$value) { 41 $value = date('Y-m-d H:i:s'); 42 } 43 return parent::valueEditor($name, $value); 44 } 45 46 /** 47 * Validate a single value 48 * 49 * This function needs to throw a validation exception when validation fails. 50 * The exception message will be prefixed by the appropriate field on output 51 * 52 * @param string|array $rawvalue 53 * @return string 54 * @throws ValidationException 55 */ 56 public function validate($rawvalue) { 57 $rawvalue = trim($rawvalue); 58 list($date, $time) = explode(' ', $rawvalue, 2); 59 $date = trim($date); 60 $time = trim($time); 61 62 list($year, $month, $day) = explode('-', $date, 3); 63 if(!checkdate((int) $month, (int) $day, (int) $year)) { 64 throw new ValidationException('invalid datetime format'); 65 } 66 67 list($h, $m, $s) = explode(':', $time, 3); 68 $h = (int) $h; 69 $m = (int) $m; 70 $s = (int) $s; 71 if($h < 0 || $h > 23 || $m < 0 || $m > 59 || $s < 0 || $s > 59) { 72 throw new ValidationException('invalid datetime format'); 73 } 74 75 return sprintf("%d-%02d-%02d %02d:%02d:%02d", $year, $month, $day, $h, $m, $s); 76 } 77 78 /** 79 * @param QueryBuilder $QB 80 * @param string $tablealias 81 * @param string $colname 82 * @param string $alias 83 */ 84 public function select(QueryBuilder $QB, $tablealias, $colname, $alias) { 85 // when accessing the revision column we need to convert from Unix timestamp 86 $col = "$tablealias.$colname"; 87 if($colname == 'rev') { 88 $col = "DATETIME($col, 'unixepoch')"; 89 } 90 91 $QB->addSelectStatement($col, $alias); 92 } 93 94 /** 95 * @param QueryBuilder $QB 96 * @param string $tablealias 97 * @param string $colname 98 * @param string $comp 99 * @param string|\string[] $value 100 * @param string $op 101 */ 102 public function filter(QueryBuilder $QB, $tablealias, $colname, $comp, $value, $op) { 103 // when accessing the revision column we need to convert from Unix timestamp 104 $col = "$tablealias.$colname"; 105 if($colname == 'rev') { 106 $col = "DATETIME($col, 'unixepoch')"; 107 } 108 109 /** @var QueryBuilderWhere $add Where additionional queries are added to*/ 110 if(is_array($value)) { 111 $add = $QB->filters()->where($op); // sub where group 112 $op = 'OR'; 113 } else { 114 $add = $QB->filters(); // main where clause 115 } 116 foreach((array) $value as $item) { 117 $pl = $QB->addValue($item); 118 $add->where($op, "$col $comp $pl"); 119 } 120 } 121 122} 123