1<?php 2namespace dokuwiki\plugin\struct\types; 3 4use dokuwiki\plugin\struct\meta\QueryBuilder; 5use dokuwiki\plugin\struct\meta\StructException; 6use dokuwiki\plugin\struct\meta\ValidationException; 7 8class User extends AbstractMultiBaseType { 9 10 protected $config = array( 11 'existingonly' => true, 12 'autocomplete' => array( 13 'fullname' => true, 14 'mininput' => 2, 15 'maxresult' => 5, 16 ), 17 ); 18 19 /** 20 * @param string $rawvalue the user to validate 21 * @return int|string|void 22 */ 23 public function validate($rawvalue) { 24 $rawvalue = parent::validate($rawvalue); 25 26 if($this->config['existingonly']) { 27 /** @var \DokuWiki_Auth_Plugin $auth */ 28 global $auth; 29 $info = $auth->getUserData($rawvalue, false); 30 if($info === false) throw new ValidationException('User not found', $rawvalue); 31 } 32 33 return $rawvalue; 34 } 35 36 /** 37 * @param string $value the user to display 38 * @param \Doku_Renderer $R 39 * @param string $mode 40 * @return bool 41 */ 42 public function renderValue($value, \Doku_Renderer $R, $mode) { 43 if($mode == 'xhtml') { 44 $name = userlink($value); 45 $R->doc .= $name; 46 } else { 47 $name = userlink($value, true); 48 $R->cdata($name); 49 } 50 return true; 51 } 52 53 /** 54 * Autocompletion for user names 55 * 56 * @todo should we have any security mechanism? Currently everybody can look up users 57 * @return array 58 */ 59 public function handleAjax() { 60 /** @var \DokuWiki_Auth_Plugin $auth */ 61 global $auth; 62 global $INPUT; 63 64 if(!$auth->canDo('getUsers')) { 65 throw new StructException('The user backend can not search for users'); 66 } 67 68 // check minimum length 69 $lookup = trim($INPUT->str('search')); 70 if(utf8_strlen($lookup) < $this->config['autocomplete']['mininput']) return array(); 71 72 // results wanted? 73 $max = $this->config['autocomplete']['maxresult']; 74 if($max <= 0) return array(); 75 76 // find users by login, fill up with names if wanted 77 $logins = (array) $auth->retrieveUsers(0, $max, array('user' => $lookup)); 78 if((count($logins) < $max) && $this->config['autocomplete']['fullname']) { 79 $logins = array_merge($logins, (array) $auth->retrieveUsers(0, $max, array('name' => $lookup))); 80 } 81 82 // reformat result for jQuery UI Autocomplete 83 $users = array(); 84 foreach($logins as $login => $info) { 85 $users[] = array( 86 'label' => $info['name'] . ' [' . $login . ']', 87 'value' => $login 88 ); 89 } 90 91 return $users; 92 } 93 94 /** 95 * When handling `%lasteditor%` get the data from the `titles` table instead the `data_` table. 96 * 97 * @param QueryBuilder $QB 98 * @param string $tablealias 99 * @param string $colname 100 * @param string $alias 101 */ 102 public function select(QueryBuilder $QB, $tablealias, $colname, $alias) { 103 if(is_a($this->context,'dokuwiki\plugin\struct\meta\UserColumn')) { 104 $rightalias = $QB->generateTableAlias(); 105 $QB->addLeftJoin($tablealias, 'titles', $rightalias, "$tablealias.pid = $rightalias.pid"); 106 $QB->addSelectStatement("$rightalias.lasteditor", $alias); 107 return; 108 } 109 110 parent::select($QB, $tablealias, $colname, $alias); 111 } 112 113 /** 114 * When sorting `%lasteditor%`, then sort the data from the `titles` table instead the `data_` table. 115 * 116 * @param QueryBuilder $QB 117 * @param string $tablealias 118 * @param string $colname 119 * @param string $order 120 */ 121 public function sort(QueryBuilder $QB, $tablealias, $colname, $order) { 122 if(is_a($this->context,'dokuwiki\plugin\struct\meta\UserColumn')) { 123 $rightalias = $QB->generateTableAlias(); 124 $QB->addLeftJoin($tablealias, 'titles', $rightalias, "$tablealias.pid = $rightalias.pid"); 125 $QB->addOrderBy("$rightalias.lasteditor $order"); 126 return; 127 } 128 129 $QB->addOrderBy("$tablealias.$colname $order"); 130 } 131 132 /** 133 * When using `%lasteditor%`, we need to compare against the `title` table. 134 * 135 * @param QueryBuilder $QB 136 * @param string $tablealias 137 * @param string $colname 138 * @param string $comp 139 * @param string|\string[] $value 140 * @param string $op 141 */ 142 public function filter(QueryBuilder $QB, $tablealias, $colname, $comp, $value, $op) { 143 if(is_a($this->context,'dokuwiki\plugin\struct\meta\UserColumn')) { 144 $rightalias = $QB->generateTableAlias(); 145 $QB->addLeftJoin($tablealias, 'titles', $rightalias, "$tablealias.pid = $rightalias.pid"); 146 147 // compare against page and title 148 $sub = $QB->filters()->where($op); 149 $pl = $QB->addValue($value); 150 $sub->whereOr("$rightalias.lasteditor $comp $pl"); 151 return; 152 } 153 154 parent::filter($QB, $tablealias, $colname, $comp, $value, $op); 155 } 156 157} 158