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