xref: /plugin/struct/types/Date.php (revision 1f4dc0b95bed5d54071e0a290886bc9ed1ba1d32)
1<?php
2namespace dokuwiki\plugin\struct\types;
3
4use dokuwiki\plugin\struct\meta\QueryBuilder;
5use dokuwiki\plugin\struct\meta\ValidationException;
6
7class Date extends AbstractBaseType {
8
9    protected $config = array(
10        'format' => 'Y/m/d',
11        'prefilltoday' => false
12    );
13
14    /**
15     * Output the stored data
16     *
17     * @param string|int $value the value stored in the database
18     * @param \Doku_Renderer $R the renderer currently used to render the data
19     * @param string $mode The mode the output is rendered in (eg. XHTML)
20     * @return bool true if $mode could be satisfied
21     */
22    public function renderValue($value, \Doku_Renderer $R, $mode) {
23        $date = date_create($value);
24        if($date !== false) {
25            $out = date_format($date, $this->config['format']);
26        } else {
27            $out = '';
28        }
29
30        $R->cdata($out);
31        return true;
32    }
33
34    /**
35     * Return the editor to edit a single value
36     *
37     * @param string $name the form name where this has to be stored
38     * @param string $rawvalue the current value
39     * @return string html
40     */
41    public function valueEditor($name, $rawvalue) {
42        $name = hsc($name);
43        $rawvalue = hsc($rawvalue);
44
45        if($this->config['prefilltoday'] && !$rawvalue) {
46            $rawvalue = date('Y-m-d');
47        }
48
49        $html = "<input class=\"struct_date\" name=\"$name\" value=\"$rawvalue\" />";
50        return "$html";
51    }
52
53    /**
54     * Validate a single value
55     *
56     * This function needs to throw a validation exception when validation fails.
57     * The exception message will be prefixed by the appropriate field on output
58     *
59     * @param string|int $rawvalue
60     * @return int|string
61     * @throws ValidationException
62     */
63    public function validate($rawvalue) {
64        $rawvalue = parent::validate($rawvalue);
65        list($rawvalue) = explode(' ', $rawvalue, 2); // strip off time if there is any
66
67        list($year, $month, $day) = explode('-', $rawvalue, 3);
68        if(!checkdate((int) $month, (int) $day, (int) $year)) {
69            throw new ValidationException('invalid date format');
70        }
71        return sprintf('%d-%02d-%02d', $year, $month, $day);
72    }
73
74    /**
75     * When handling `%lastupdated%` get the data from the `titles` table instead the `data_` table.
76     *
77     * @param QueryBuilder $QB
78     * @param string $tablealias
79     * @param string $colname
80     * @param string $alias
81     */
82    public function select(QueryBuilder $QB, $tablealias, $colname, $alias) {
83        if(is_a($this->context,'dokuwiki\plugin\struct\meta\RevisionColumn')) {
84            $rightalias = $QB->generateTableAlias();
85            $QB->addLeftJoin($tablealias, 'titles', $rightalias, "$tablealias.pid = $rightalias.pid");
86            $QB->addSelectStatement("$rightalias.lastrev", $alias);
87            return;
88        }
89
90        parent::select($QB, $tablealias, $colname, $alias);
91    }
92
93    /**
94     * When sorting `%lastupdated%`, then sort the data from the `titles` table instead the `data_` table.
95     *
96     * @param QueryBuilder $QB
97     * @param string $tablealias
98     * @param string $colname
99     * @param string $order
100     */
101    public function sort(QueryBuilder $QB, $tablealias, $colname, $order) {
102        if(is_a($this->context,'dokuwiki\plugin\struct\meta\RevisionColumn')) {
103            $rightalias = $QB->generateTableAlias();
104            $QB->addLeftJoin($tablealias, 'titles', $rightalias, "$tablealias.pid = $rightalias.pid");
105            $QB->addOrderBy("$rightalias.lastrev $order");
106            return;
107        }
108
109        $QB->addOrderBy("$tablealias.$colname $order");
110    }
111
112    /**
113     * When using `%lastupdated%`, we need to compare against the `title` table.
114     *
115     * @param QueryBuilder $QB
116     * @param string $tablealias
117     * @param string $colname
118     * @param string $comp
119     * @param string|\string[] $value
120     * @param string $op
121     */
122    public function filter(QueryBuilder $QB, $tablealias, $colname, $comp, $value, $op) {
123        if(is_a($this->context,'dokuwiki\plugin\struct\meta\RevisionColumn')) {
124            $rightalias = $QB->generateTableAlias();
125            $QB->addLeftJoin($tablealias, 'titles', $rightalias, "$tablealias.pid = $rightalias.pid");
126
127            // compare against page and title
128            $sub = $QB->filters()->where($op);
129            $pl = $QB->addValue($value);
130            $sub->whereOr("$rightalias.lastrev $comp $pl");
131            return;
132        }
133
134        parent::filter($QB, $tablealias, $colname, $comp, $value, $op);
135    }
136
137}
138