xref: /plugin/struct/types/DateTime.php (revision 0cf47abb6db28bbf3d77ca6aac45c23b3c46a200)
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 $value
53     * @return string
54     * @throws ValidationException
55     */
56    public function validate($value) {
57        $value = trim($value);
58        list($date, $time) = explode(' ', $value, 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