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