- Update the copyright notices to use the correct year and not a non-ASCII symbol
[bugdar.git] / includes / api_user.php
1 <?php
2 /*=====================================================================*\
3 || ###################################################################
4 || # Bugdar
5 || # Copyright (c)2004-2008 Blue Static
6 || #
7 || # This program is free software; you can redistribute it and/or modify
8 || # it under the terms of the GNU General Public License as published by
9 || # the Free Software Foundation; version 2 of the License.
10 || #
11 || # This program is distributed in the hope that it will be useful, but
12 || # WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13 || # or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14 || # more details.
15 || #
16 || # You should have received a copy of the GNU General Public License along
17 || # with this program; if not, write to the Free Software Foundation, Inc.,
18 || # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
19 || ###################################################################
20 \*=====================================================================*/
21
22 require_once ISSO . '/Api.php';
23 require_once('./includes/functions_datastore.php');
24 require_once('./includes/class_sort.php');
25
26 /**
27 * API: User
28 *
29 * @author Blue Static
30 * @copyright Copyright (c)2004 - 2008, Blue Static
31 * @package Bugdar
32 *
33 */
34 class UserAPI extends BSApi
35 {
36 /**
37 * Database fields
38 * @var array
39 */
40 protected $fields = array(
41 'userid' => array(TYPE_UINT, REQ_AUTO),
42 'email' => array(TYPE_STR, REQ_YES),
43 'displayname' => array(TYPE_STR, REQ_YES),
44 'usergroupid' => array(TYPE_UINT, REQ_YES),
45 'groupids' => array(TYPE_STR, REQ_NO),
46 'password' => array(TYPE_STR, REQ_YES),
47 'salt' => array(TYPE_STR, REQ_SET),
48 'authkey' => array(TYPE_STR, REQ_SET),
49 'showemail' => array(TYPE_BOOL, REQ_NO),
50 'showcolors' => array(TYPE_BOOL, REQ_NO),
51 'languageid' => array(TYPE_UINT, REQ_NO),
52 'timezone' => array(TYPE_FLOAT,REQ_NO),
53 'usedst' => array(TYPE_BOOL, REQ_NO),
54 'hidestatuses' => array(TYPE_STR, REQ_NO),
55 'defaultsortkey' => array(TYPE_STR, REQ_NO),
56 'defaultsortas' => array(TYPE_STR, REQ_NO),
57 'columnoptions' => array(TYPE_STR, REQ_NO),
58 'authid' => array(TYPE_STR, REQ_NO)
59 );
60
61 /**
62 * Database table
63 * @var string
64 */
65 protected $table = 'user';
66
67 /**
68 * Table prefix
69 * @var string
70 */
71 protected $prefix = TABLE_PREFIX;
72
73 /**
74 * Set field: salt
75 */
76 protected function set_salt()
77 {
78 $this->set('salt', BSFunctions::random(rand(3, 15)));
79 }
80
81 /**
82 * Set field: authkey
83 */
84 protected function set_authkey()
85 {
86 $this->set('authkey', BSFunctions::random());
87 }
88
89 /**
90 * Pre-insert
91 */
92 protected function pre_insert()
93 {
94 $this->set('password', md5(md5($this->values['password']) . md5($this->values['salt'])));
95 }
96
97 /**
98 * Post-insert
99 */
100 protected function post_insert()
101 {
102 BSApp::$db->query("
103 INSERT INTO " . TABLE_PREFIX . "useremail
104 (userid, mask, relation)
105 VALUES
106 (" . $this->insertid . ", 32, 0),
107 (" . $this->insertid . ", 320, 1),
108 (" . $this->insertid . ", 1984, 2),
109 (" . $this->insertid . ", 64, 4),
110 (" . $this->insertid . ", 64, 8),
111 (" . $this->insertid . ", 256, 16
112 )
113 ");
114 build_assignedto();
115 }
116
117 /**
118 * Validate: email
119 */
120 protected function validate_email($field)
121 {
122 if (!$this->_verifyIsNotEmpty($field))
123 {
124 return false;
125 }
126
127 if (!BSFunctions::is_valid_email($this->values['email']))
128 {
129 $this->_error(new FieldException(T('The specified email is invalid.'), 'email'));
130 return false;
131 }
132 if (BSApp::$db->queryFirst("SELECT * FROM " . TABLE_PREFIX . "user WHERE email = '" . BSApp::$input->escape($this->values['email']) . "' AND userid <> " . BSApp::$input->clean($this->values['userid'], TYPE_UINT)))
133 {
134 $this->_error(new FieldException(T('The specified email is already in use.'), 'email'));
135 return false;
136 }
137 return true;
138 }
139
140 /**
141 * Validate: displayname
142 */
143 protected function validate_displayname($field)
144 {
145 if (!$this->_verifyIsNotEmpty($field))
146 {
147 return false;
148 }
149
150 if (BSApp::$db->queryFirst("SELECT * FROM " . TABLE_PREFIX . "user WHERE displayname = '" . BSApp::$input->escape($this->values['displayname']) . "' AND userid <> " . BSApp::$input->clean($this->values['userid'], TYPE_UINT)))
151 {
152 $this->_error(new FieldException(T('That display name is already in use by another user.'), 'displayname'));
153 return false;
154 }
155 return true;
156 }
157
158 /**
159 * Validate: usergroupid
160 */
161 protected function validate_usergroupid($field)
162 {
163 if (!isset(bugdar::$datastore['usergroup'][ $this->values['usergroupid'] ]))
164 {
165 $this->_error(new FieldException(L_INVALID_ID, $field));
166 return false;
167 }
168 return true;
169 }
170
171 /**
172 * Validate: groupids
173 */
174 protected function validate_groupids($field)
175 {
176 $groups = $this->values['groupids'];
177 if (!is_array($groups))
178 {
179 $groups = explode(',', $this->values['groupids']);
180 }
181 $groups = BSFunctions::array_strip_empty($groups);
182
183 foreach ($groups as $group)
184 {
185 if (!isset(bugdar::$datastore['usergroup']["$group"]))
186 {
187 $this->_error(new FieldException(L_INVALID_ID, $field));
188 return false;
189 }
190 }
191
192 $this->values['groupids'] = implode(',', $groups);
193
194 return true;
195 }
196
197 /**
198 * Pre-update
199 */
200 protected function pre_update()
201 {
202 $this->setCondition();
203 $this->fetch();
204
205 if ($this->values['password'] == '')
206 {
207 $this->set('password', $this->record['password']);
208 }
209 else
210 {
211 BSApp::debug("updating password = true");
212 $this->set('password', md5(md5($this->values['password']) . md5($this->record['salt'])));
213 }
214 }
215
216 /**
217 * Post-update
218 */
219 protected function post_update()
220 {
221 if (isset($this->values['displayname']))
222 {
223 $username = BSApp::$input->escape($this->values['displayname']);
224 $id = $this->values['userid'];
225
226 BSApp::$db->query("UPDATE " . TABLE_PREFIX . "bug SET username = '$username' WHERE userid = $id");
227 BSApp::$db->query("UPDATE " . TABLE_PREFIX . "bug SET lastpostbyname = '$username' WHERE lastpostby = $id");
228 BSApp::$db->query("UPDATE " . TABLE_PREFIX . "bug SET hiddenlastpostbyname = '$username' WHERE hiddenlastpostby = $id");
229 }
230
231 if (isset($this->values['displayname']) || isset($this->values['email']))
232 {
233 build_assignedto();
234 }
235 }
236
237 /**
238 * Pre-delete
239 */
240 protected function pre_delete()
241 {
242 if ($this->values['userid'] == bugdar::$userinfo['userid'])
243 {
244
245 $this->error(T('You cannot delete your own account!'));
246 }
247
248 if ($this->values['usergroupid'] == 6)
249 {
250 $count = BSApp::$db->queryFirst("SELECT COUNT(*) AS count FROM " . TABLE_PREFIX . "user WHERE usergroupid = 6 AND userid <> " . $this->values['userid']);
251 if ($count['count'] < 1)
252 {
253 $this->error(T('At least one other administrator needs to be present before you can delete this user'));
254 }
255 }
256 }
257
258 /**
259 * Post-delete
260 */
261 protected function post_delete()
262 {
263 BSApp::db->query("DELETE FROM " . TABLE_PREFIX . "user WHERE userid = " . $this->values['userid']);
264 BSApp::db->query("DELETE FROM " . TABLE_PREFIX . "favorite WHERE userid = " . $this->values['userid']);
265 BSApp::db->query("DELETE FROM " . TABLE_PREFIX . "useractivation WHERE userid = " . $this->values['userid']);
266 BSApp::db->query("DELETE FROM " . TABLE_PREFIX . "useremail WHERE userid = " . $this->values['userid']);
267 BSApp::db->query("DELETE FROM " . TABLE_PREFIX . "search WHERE userid = " . $this->values['userid']);
268
269 build_assignedto();
270 }
271
272 /**
273 * Validate: hidestatuses
274 */
275 protected function validate_hidestatuses($field)
276 {
277 if (is_array($this->values['hidestatuses']))
278 {
279 $this->set('hidestatuses', implode(',', $this->values['hidestatuses']));
280 }
281
282 return true;
283 }
284
285 /**
286 * Validate: defaultsortkey
287 */
288 protected function validate_defaultsortkey($field)
289 {
290 if (!ListSorter::fetch_by_text($this->values['defaultsortkey']))
291 {
292 $this->_error(new FieldException(L_INVALID_ID, $field));
293 return false;
294 }
295
296 return true;
297 }
298
299 /**
300 * Validate: defaultsortas
301 */
302 protected function validate_defaultsortas($field)
303 {
304 if (!ListSorter::fetch_as_text($this->values['defaultsortas']))
305 {
306 $this->_error(new FieldException(L_INVALID_ID, $field));
307 return false;
308 }
309
310 return true;
311 }
312
313 /**
314 * Validate: columnoptions
315 */
316 protected function validate_columnoptions($field)
317 {
318 if (is_array($this->values['columnoptions']))
319 {
320 $this->set('columnoptions', serialize($this->values['columnoptions']));
321 }
322 return true;
323 }
324 }
325
326 ?>