Merge branch '2.0'
[GitHub/WoltLab/WCF.git] / wcfsetup / install / files / lib / form / UserSearchForm.class.php
1 <?php
2 namespace wcf\form;
3 use wcf\acp\form\UserOptionListForm;
4 use wcf\data\search\SearchEditor;
5 use wcf\system\breadcrumb\Breadcrumb;
6 use wcf\system\dashboard\DashboardHandler;
7 use wcf\system\database\util\PreparedStatementConditionBuilder;
8 use wcf\system\exception\UserInputException;
9 use wcf\system\request\LinkHandler;
10 use wcf\system\user\collapsible\content\UserCollapsibleContentHandler;
11 use wcf\system\WCF;
12 use wcf\util\HeaderUtil;
13 use wcf\util\StringUtil;
14
15 /**
16 * Shows the user search form.
17 *
18 * @author Marcel Werk
19 * @copyright 2001-2014 WoltLab GmbH
20 * @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
21 * @package com.woltlab.wcf
22 * @subpackage form
23 * @category Community Framework
24 */
25 class UserSearchForm extends UserOptionListForm {
26 /**
27 * @see \wcf\page\AbstractPage::$activeMenuItem
28 */
29 public $activeMenuItem = 'wcf.user.search';
30
31 /**
32 * @see \wcf\page\AbstractPage::$neededModules
33 */
34 public $neededModules = array('MODULE_MEMBERS_LIST');
35
36 /**
37 * username
38 * @var string
39 */
40 public $username = '';
41
42 /**
43 * matches
44 * @var array<integer>
45 */
46 public $matches = array();
47
48 /**
49 * condtion builder object
50 * @var \wcf\system\database\condition\PreparedStatementConditionBuilder
51 */
52 public $conditions = null;
53
54 /**
55 * search id
56 * @var integer
57 */
58 public $searchID = 0;
59
60 /**
61 * number of results
62 * @var integer
63 */
64 public $maxResults = 1000;
65
66 /**
67 * @see \wcf\form\IForm::readFormParameters()
68 */
69 public function readFormParameters() {
70 parent::readFormParameters();
71
72 if (isset($_POST['username'])) $this->username = StringUtil::trim($_POST['username']);
73 }
74
75 /**
76 * @see \wcf\acp\form\AbstractOptionListForm::initOptionHandler()
77 */
78 protected function initOptionHandler() {
79 $this->optionHandler->enableSearchMode();
80 $this->optionHandler->init();
81 }
82
83 /**
84 * @see \wcf\page\IPage::readData()
85 */
86 public function readData() {
87 parent::readData();
88
89 $this->readOptionTree();
90
91 // add breadcrumbs
92 WCF::getBreadcrumbs()->add(new Breadcrumb(WCF::getLanguage()->get('wcf.user.members'), LinkHandler::getInstance()->getLink('MembersList')));
93 }
94
95 /**
96 * Reads option tree on page init.
97 */
98 protected function readOptionTree() {
99 $this->optionTree = $this->optionHandler->getOptionTree();
100 }
101
102 /**
103 * @see \wcf\page\IPage::assignVariables()
104 */
105 public function assignVariables() {
106 parent::assignVariables();
107
108 DashboardHandler::getInstance()->loadBoxes('com.woltlab.wcf.user.MembersListPage', $this);
109
110 WCF::getTPL()->assign(array(
111 'username' => $this->username,
112 'optionTree' => $this->optionTree,
113 'sidebarCollapsed' => UserCollapsibleContentHandler::getInstance()->isCollapsed('com.woltlab.wcf.collapsibleSidebar', 'com.woltlab.wcf.user.MembersListPage'),
114 'sidebarName' => 'com.woltlab.wcf.user.MembersListPage'
115 ));
116 }
117
118 /**
119 * @see \wcf\form\IForm::save()
120 */
121 public function save() {
122 parent::save();
123
124 // store search result in database
125 $search = SearchEditor::create(array(
126 'userID' => WCF::getUser()->userID ?: null,
127 'searchData' => serialize(array('matches' => $this->matches)),
128 'searchTime' => TIME_NOW,
129 'searchType' => 'users'
130 ));
131
132 // get new search id
133 $this->searchID = $search->searchID;
134 $this->saved();
135
136 // forward to result page
137 $url = LinkHandler::getInstance()->getLink('MembersList', array('id' => $this->searchID));
138 HeaderUtil::redirect($url);
139 exit;
140 }
141
142 /**
143 * @see \wcf\form\IForm::validate()
144 */
145 public function validate() {
146 AbstractForm::validate();
147
148 // do search
149 $this->search();
150
151 if (empty($this->matches)) {
152 throw new UserInputException('search', 'noMatches');
153 }
154 }
155
156 /**
157 * Search for users which fit to the search values.
158 */
159 protected function search() {
160 $this->matches = array();
161 $sql = "SELECT user_table.userID
162 FROM wcf".WCF_N."_user user_table
163 LEFT JOIN wcf".WCF_N."_user_option_value option_value
164 ON (option_value.userID = user_table.userID)";
165
166 // build search condition
167 $this->conditions = new PreparedStatementConditionBuilder();
168
169 // static fields
170 $this->buildStaticConditions();
171
172 // dynamic fields
173 $this->buildDynamicConditions();
174
175 // if no conditions exists, no need to send query
176 if (!count($this->conditions->getParameters())) {
177 return;
178 }
179
180 // do search
181 $statement = WCF::getDB()->prepareStatement($sql.$this->conditions, $this->maxResults);
182 $statement->execute($this->conditions->getParameters());
183 while ($row = $statement->fetchArray()) {
184 $this->matches[] = $row['userID'];
185 }
186 }
187
188 /**
189 * Builds the static conditions.
190 */
191 protected function buildStaticConditions() {
192 if (!empty($this->username)) {
193 $this->conditions->add("user_table.username LIKE ?", array('%'.addcslashes($this->username, '_%').'%'));
194 }
195 }
196
197 /**
198 * Builds the dynamic conditions.
199 */
200 protected function buildDynamicConditions() {
201 foreach ($this->optionHandler->getCategoryOptions('profile') as $option) {
202 $option = $option['object'];
203
204 $value = isset($this->optionHandler->optionValues[$option->optionName]) ? $this->optionHandler->optionValues[$option->optionName] : null;
205 $this->optionHandler->getTypeObject($option->optionType)->getCondition($this->conditions, $option, $value);
206 }
207 }
208 }