1: <?php
2:
3: /**
4: * database.php
5: *
6: * PHP version 8
7: *
8: * LICENSE: This program is free software: you can redistribute it and/or modify
9: * it under the terms of the GNU Affero General Public License as
10: * published by the Free Software Foundation, either version 3 of the
11: * License, or (at your option) any later version.
12: * This program is distributed in the hope that it will be useful,
13: * but WITHOUT ANY WARRANTY; without even the implied warranty of
14: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15: * GNU Affero General Public License for more details.
16: * You should have received a copy of the GNU Affero General Public License
17: * along with this program. If not, see <http://www.gnu.org/licenses/>.
18: *
19: * @category Login
20: * @package UserDB
21: * @author Jpmaster77 a.k.a. The Grandmaster of C++ (GMC)
22: * @author Henri Schumacher <henri.hulski@gazeta.pl>
23: * @copyright 2007-2014 Henri Schumacher
24: * @license http://www.gnu.org/licenses/agpl.html GNU Affero General Public License v3
25: * @version 1.0
26: * @link https://research.openhomeo.info/download/OpenHomeopath_1.0.2.tar.gz
27: * @see login.php
28: */
29:
30: require_once("include/classes/login/constants.php");
31: require_once("include/classes/db/openhomeo_db.php");
32:
33: /**
34: * The Database class is meant to simplify the task of accessing
35: * information from the website's database.
36: *
37: * @category Login
38: * @package UserDB
39: * @author Jpmaster77 a.k.a. The Grandmaster of C++ (GMC)
40: * @author Henri Schumacher <henri.hulski@gazeta.pl>
41: * @copyright 2007-2014 Henri Schumacher
42: * @license http://www.gnu.org/licenses/agpl.html GNU Affero General Public License v3
43: */
44: class UserDB extends OpenHomeoDB {
45:
46: /**
47: * Number of active users viewing site
48: * @var integer
49: * @access public
50: */
51: public $num_active_users;
52:
53:
54: /**
55: * Number of active guests viewing site
56: * @var integer
57: * @access public
58: */
59: public $num_active_guests;
60:
61:
62: /**
63: * Number of signed-up users
64: * @var integer
65: * @access public
66: */
67: public $num_members;
68: /* Note: call getNumMembers() to access $num_members! */
69:
70: /**
71: * Only query database to find out number of members
72: * when getNumMembers() is called for the first time,
73: * until then, default value set.
74: *
75: * @return void
76: * @access public
77: */
78: function get_num_visitors() {
79: $this->num_members = -1;
80:
81: if (TRACK_VISITORS) {
82: /* Calculate number of users at site */
83: $this->calcNumActiveUsers();
84:
85: /* Calculate number of guests at site */
86: $this->calcNumActiveGuests();
87: }
88: }
89:
90: /**
91: * confirmUserPass - Checks whether or not the given
92: * username is in the database, if so it checks if the
93: * given password is the same password in the database
94: * for that user. If the user doesn't exist or if the
95: * passwords don't match up, it returns an error code
96: * (1 or 2). On success it returns 0.
97: *
98: * @param string $username username
99: * @param string $password password
100: * @return integer 0 | 1 | 2
101: * @access public
102: */
103: function confirmUserPass($username, $password) {
104: /* Add slashes if necessary (for query) */
105: if (!get_magic_quotes_gpc()) {
106: $username = addslashes($username);
107: }
108:
109: /* Verify that user is in database */
110: $query = "SELECT password FROM " . TBL_USERS . " WHERE username = '$username'";
111:
112: $this->send_query($query);
113: if ($this->db_num_rows() < 1) {
114: return 1; // Indicates username failure
115: }
116:
117: /* Retrieve password from result, strip slashes */
118: $dbarray = $this->db_fetch_row();
119: $this->free_result();
120:
121: $dbarray[0] = stripslashes($dbarray[0]);
122: $password = stripslashes($password);
123:
124: /* Validate that password is correct */
125: if ($password == $dbarray[0]) {
126: return 0; // Success! Username and password confirmed
127: } else {
128: return 2; // Indicates password failure
129: }
130: }
131:
132: /**
133: * confirmUserID - Checks whether or not the given
134: * username is in the database, if so it checks if the
135: * given userid is the same userid in the database
136: * for that user. If the user doesn't exist or if the
137: * userids don't match up, it returns an error code
138: * (1 or 2). On success it returns 0.
139: *
140: * @param string $username username
141: * @param string $userid user-ID
142: * @return integer 0 | 1 | 2
143: * @access public
144: */
145: function confirmUserID($username, $userid) {
146: /* Add slashes if necessary (for query) */
147: if (!get_magic_quotes_gpc()) {
148: $username = addslashes($username);
149: }
150:
151: /* Verify that user is in database */
152: $query = "SELECT userid FROM " . TBL_USERS . " WHERE username = '$username'";
153:
154: $this->send_query($query);
155: if ($this->db_num_rows() < 1) {
156: return 1; //Indicates username failure
157: }
158:
159: /* Retrieve userid from result, strip slashes */
160: $dbarray = $this->db_fetch_row();
161: $this->free_result();
162:
163: $dbarray[0] = stripslashes($dbarray[0]);
164: $userid = stripslashes($userid);
165:
166: /* Validate that userid is correct */
167: if ($userid == $dbarray[0]) {
168: return 0; //Success! Username and userid confirmed
169: }
170: else {
171: return 2; //Indicates userid invalid
172: }
173: }
174:
175: /**
176: * usernameTaken - Returns true if the username has
177: * been taken by another user, false otherwise.
178: *
179: * @param string $username username
180: * @return boolean
181: * @access public
182: */
183: function usernameTaken($username) {
184: if (!get_magic_quotes_gpc()) {
185: $username = addslashes($username);
186: }
187: $query = "SELECT username FROM " . TBL_USERS . " WHERE username = '$username'";
188: $this->send_query($query);
189: $username_exists = false;
190: if ($this->db_num_rows() > 0) {
191: $username_exists = true;
192: }
193: $this->free_result();
194:
195: return ($username_exists);
196: }
197:
198: /**
199: * usernameBanned - Returns true if the username has
200: * been banned by the administrator.
201: *
202: * @param string $username username
203: * @return boolean
204: * @access public
205: */
206: function usernameBanned($username) {
207: if (!get_magic_quotes_gpc()) {
208: $username = addslashes($username);
209: }
210: $query = "SELECT username FROM " . TBL_BANNED_USERS . " WHERE username = '$username'";
211: $this->send_query($query);
212: $username_banned = false;
213: if ($this->db_num_rows() > 0) {
214: $username_banned = true;
215: }
216: $this->free_result();
217: return ($username_banned);
218: }
219:
220: /**
221: * addNewUser - Inserts the given (username, password, email)
222: * info into the database. Appropriate user level is set.
223: * Returns true on success, false otherwise.
224: *
225: * @param string $username username
226: * @param string $password password
227: * @param string $email e-mail
228: * @return boolean true on success
229: * @access public
230: */
231: function addNewUser($username, $password, $email) {
232: /* If admin sign up, give admin user level */
233: if (strcasecmp($username, ADMIN_NAME) == 0 || strcasecmp($username, ADMIN_NAME_2) == 0) {
234: $ulevel = ADMIN_LEVEL;
235: } else {
236: $ulevel = USER_LEVEL;
237: }
238: $query = "INSERT INTO " . TBL_USERS . " (username, password, userid, userlevel, email, email_registered, registration) VALUES ('$username', '$password', '0', $ulevel, '$email', '$email', NOW())";
239: $result = $this->send_query($query);
240: return $result;
241: }
242:
243: /**
244: * updateUserField - Updates a field, specified by the field
245: * parameter, in the user's row of the database.
246: *
247: * @param string $username username
248: * @param string $field form field
249: * @param string $value field value
250: * @return boolean true on success
251: * @access public
252: */
253: function updateUserField($username, $field, $value) {
254: $query = "UPDATE " . TBL_USERS . " SET " . $field . " = '$value' WHERE username = '$username'";
255: $result = $this->send_query($query);
256: return $result;
257: }
258:
259: /**
260: * getUserInfo - Returns the result array from a database
261: * query asking for all information stored regarding
262: * the given username. If query fails, NULL is returned.
263: *
264: * @param string $username username
265: * @param string $column column(s) of user table to query - comma seperated
266: * @return boolean true on success
267: * @access public
268: */
269: function getUserInfo($username, $column) {
270: $query = "SELECT $column FROM " . TBL_USERS . " WHERE username = '$username'";
271: $this->send_query($query);
272: /* Error occurred, return given name by default */
273: if ($this->db_num_rows() < 1) {
274: $this->free_result();
275: return NULL;
276: }
277: /* Return result array */
278: $dbarray = $this->db_fetch_row();
279: $this->free_result();
280: return $dbarray;
281: }
282:
283: /**
284: * getNumMembers - Returns the number of signed-up users
285: * of the website, banned members not included. The first
286: * time the function is called on page load, the database
287: * is queried, on subsequent calls, the stored result
288: * is returned. This is to improve efficiency, effectively
289: * not querying the database when no call is made.
290: *
291: * @return integer
292: * @access public
293: */
294: function getNumMembers() {
295: if ($this->num_members < 0) {
296: $query = "SELECT COUNT(*) FROM " . TBL_USERS;
297: $this->send_query($query);
298: list($this->num_members) = $this->db_fetch_row();
299: $this->free_result();
300: }
301: return $this->num_members;
302: }
303:
304: /**
305: * calcNumActiveUsers - Finds out how many active users
306: * are viewing site and sets class variable accordingly.
307: *
308: * @return integer
309: * @access private
310: */
311: private function calcNumActiveUsers() {
312: /* Calculate number of users at site */
313: $query = "SELECT COUNT(*) FROM " . TBL_ACTIVE_USERS;
314: $this->send_query($query);
315: list($this->num_active_users) = $this->db_fetch_row();
316: $this->free_result();
317: }
318:
319: /**
320: * calcNumActiveGuests - Finds out how many active guests
321: * are viewing site and sets class variable accordingly.
322: *
323: * @return integer
324: * @access private
325: */
326: private function calcNumActiveGuests() {
327: /* Calculate number of guests at site */
328: $query = "SELECT COUNT(*) FROM " . TBL_ACTIVE_GUESTS;
329: $this->send_query($query);
330: list($this->num_active_guests) = $this->db_fetch_row();
331: $this->free_result();
332: }
333:
334: /**
335: * addActiveUser - Updates username's last activity
336: * in the database, and also adds him to the table of
337: * active users, or updates timestamp if already there.
338: *
339: * @param string $username username
340: * @return void
341: * @access public
342: */
343: function addActiveUser($username) {
344: $query = "UPDATE " . TBL_USERS . " SET `last_activity` = NOW() WHERE username = '$username'";
345: $this->send_query($query);
346: if (!TRACK_VISITORS) {
347: return;
348: }
349: $query = "REPLACE INTO " . TBL_ACTIVE_USERS . " (username) VALUES ('$username')";
350: $this->send_query($query);
351: $this->calcNumActiveUsers();
352: }
353:
354: /**
355: * addActiveGuest - Adds guest to active guests table
356: *
357: * @param string $ip IP-address
358: * @return void
359: * @access public
360: */
361: function addActiveGuest($ip) {
362: if (!TRACK_VISITORS) {
363: return;
364: }
365: $query = "REPLACE INTO " . TBL_ACTIVE_GUESTS . " (ip) VALUES ('$ip')";
366: $this->send_query($query);
367: $this->calcNumActiveGuests();
368: }
369:
370: /**
371: * removeActiveUser - removes user with given username
372: * from active_users table
373: *
374: * @param string $username username
375: * @return void
376: * @access public
377: */
378: function removeActiveUser($username) {
379: if (!TRACK_VISITORS) {
380: return;
381: }
382: $query = "DELETE FROM " . TBL_ACTIVE_USERS . " WHERE username = '$username'";
383: $this->send_query($query);
384: $this->calcNumActiveUsers();
385: }
386:
387: /**
388: * removeActiveGuest - removes guest with given IP
389: * from active_guests table
390: *
391: * @param string $ip IP-address
392: * @return void
393: * @access public
394: */
395: function removeActiveGuest($ip) {
396: if (!TRACK_VISITORS) {
397: return;
398: }
399: $query = "DELETE FROM " . TBL_ACTIVE_GUESTS . " WHERE ip = '$ip'";
400: $this->send_query($query);
401: $this->calcNumActiveGuests();
402: }
403:
404: /**
405: * removeInctiveUsers - removes users after inactivity of USER_TIMEOUT
406: * from active_users table
407: *
408: * @return void
409: * @access public
410: */
411: function removeInactiveUsers() {
412: if (!TRACK_VISITORS) {
413: return;
414: }
415: $query = "DELETE FROM " . TBL_ACTIVE_USERS . " WHERE TIMESTAMPDIFF(MINUTE, `timestamp`, NOW()) > " . USER_TIMEOUT;
416: $this->send_query($query);
417: $this->calcNumActiveUsers();
418: }
419:
420: /**
421: * removeInactiveGuest - removes guests after inactivity of GUEST_TIMEOUT
422: * from active_guests table
423: *
424: * @return void
425: * @access public
426: */
427: function removeInactiveGuests() {
428: if (!TRACK_VISITORS) {
429: return;
430: }
431: $query = "DELETE FROM " . TBL_ACTIVE_GUESTS . " WHERE TIMESTAMPDIFF(MINUTE, `timestamp`, NOW()) > " . GUEST_TIMEOUT;
432: $this->send_query($query);
433: $this->calcNumActiveGuests();
434: }
435:
436: }
437: // end of class UserDB
438: