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