root/trunk/wifidog-auth/wifidog/classes/User.php @ 1179

Revision 1179, 36.3 KB (checked in by drazzib, 6 years ago)

Real fix this time :
2007-02-05 Damien Raude-Morvan <drazzib@…>

  • ... and remove unnecessary include of Avatar content type in User.php : All contents types are included by Content.php getAvailableContentTypes() call.
  • Property svn:eol-style set to native
  • Property svn:executable set to *
  • Property svn:keywords set to Author Date Id Revision
Line 
1<?php
2
3
4/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
5
6// +-------------------------------------------------------------------+
7// | WiFiDog Authentication Server                                     |
8// | =============================                                     |
9// |                                                                   |
10// | The WiFiDog Authentication Server is part of the WiFiDog captive  |
11// | portal suite.                                                     |
12// +-------------------------------------------------------------------+
13// | PHP version 5 required.                                           |
14// +-------------------------------------------------------------------+
15// | Homepage:     http://www.wifidog.org/                             |
16// | Source Forge: http://sourceforge.net/projects/wifidog/            |
17// +-------------------------------------------------------------------+
18// | This program is free software; you can redistribute it and/or     |
19// | modify it under the terms of the GNU General Public License as    |
20// | published by the Free Software Foundation; either version 2 of    |
21// | the License, or (at your option) any later version.               |
22// |                                                                   |
23// | This program is distributed in the hope that it will be useful,   |
24// | but WITHOUT ANY WARRANTY; without even the implied warranty of    |
25// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the     |
26// | GNU General Public License for more details.                      |
27// |                                                                   |
28// | You should have received a copy of the GNU General Public License |
29// | along with this program; if not, contact:                         |
30// |                                                                   |
31// | Free Software Foundation           Voice:  +1-617-542-5942        |
32// | 59 Temple Place - Suite 330        Fax:    +1-617-542-2652        |
33// | Boston, MA  02111-1307,  USA       gnu@gnu.org                    |
34// |                                                                   |
35// +-------------------------------------------------------------------+
36
37/**
38 * @package    WiFiDogAuthServer
39 * @author     Benoit Grégoire <bock@step.polymtl.ca>
40 * @copyright  2005-2006 Benoit Grégoire, Technologies Coeus inc.
41 * @version    Subversion $Id$
42 * @link       http://www.wifidog.org/
43 */
44
45/**
46 * Load required classes
47 */
48require_once ('classes/Network.php');
49require_once ('classes/Mail.php');
50require_once ('classes/InterfaceElements.php');
51require_once ('classes/ProfileTemplate.php');
52require_once ('classes/Profile.php');
53
54/**
55 * Abstract a User
56 *
57 * @package    WiFiDogAuthServer
58 * @author     Benoit Grégoire <bock@step.polymtl.ca>
59 * @copyright  2005-2006 Benoit Grégoire, Technologies Coeus inc.
60 */
61class User implements GenericObject {
62    private $mRow;
63    private $id;
64    /** Object cache for the object factory (getObject())*/
65    private static $instanceArray = array();
66
67    /** Instantiate a user object
68     * @param $id The user id of the requested user
69     * @return a User object, or null if there was an error
70     */
71    public static function getObject($id) {
72        if(!isset(self::$instanceArray[$id]))
73        {
74            self::$instanceArray[$id] = new self($id);
75        }
76        return self::$instanceArray[$id];
77    }
78
79    static function createNewObject() {
80        echo "<h1>Use User::createUser() instead</h1>";
81    }
82    /** Get an interface to create a new object.
83    * @return html markup
84    */
85    public static function getCreateNewObjectUI() {
86        return null;
87    }
88
89    /** Process the new object interface.
90     *  Will       return the new object if the user has the credentials
91     * necessary (Else an exception is thrown) and and the form was fully
92     * filled (Else the object returns null).
93     * @return the node object or null if no new node was created.
94     */
95    static function processCreateNewObjectUI() {
96        return self :: createNewObject();
97    }
98    /**
99     * Instantiate the current user
100     *
101     * @return mixed A User object, or null if there was an error
102   
103     */
104    public static function getCurrentUser() {
105        require_once ('classes/Session.php');
106        $session = Session::getObject();
107        $user = null;
108        try {
109            $user = self :: getObject($session->get(SESS_USER_ID_VAR));
110            //$user = new User($session->get(SESS_USER_ID_VAR));
111        } catch (Exception $e) {
112            /**If any problem occurs, the user should be considered logged out*/
113            $session->set(SESS_USER_ID_VAR, null);
114        }
115        return $user;
116    }
117
118    /**
119     * Associates the user passed in parameter with the session
120     *
121     * This should NOT be called by anything except the Authenticators
122     *
123     * @param object $user User a user object
124     *
125     * @return bool True if everything went well setting the session
126   
127     */
128    public static function setCurrentUser(User $user) {
129        try {
130            $session = Session::getObject();
131            $session->set(SESS_USER_ID_VAR, $user->getId());
132            $session->set(SESS_PASSWORD_HASH_VAR, $user->getPasswordHash());
133            return true;
134        } catch (Exception $e) {
135            return false;
136        }
137    }
138
139    /**
140     * Returns the server the user is connected to
141     *
142     * @return string Hostname of server
143   
144     */
145    public static function getCurrentServer() {
146        return $_SERVER['SERVER_NAME'];
147    }
148
149    /** Instantiate a user object
150     * @param $username The username of the user
151     * @param $account_origin Network:  The account origin
152     * @return a User object, or null if there was an error
153     */
154    public static function getUserByUsernameAndOrigin($username, Network $account_origin) {
155        $db = AbstractDb::getObject();
156        $object = null;
157
158        $username_str = $db->escapeString($username);
159        $account_origin_str = $db->escapeString($account_origin->getId());
160        $db->execSqlUniqueRes("SELECT user_id FROM users WHERE username = '$username_str' AND account_origin = '$account_origin_str'", $user_info, false);
161
162        if ($user_info != null)
163        $object = self::getObject($user_info['user_id']);
164        return $object;
165    }
166
167    /** Instantiate a user object
168     * @param $email The email of the user
169     * @param $account_origin Network:  The account origin
170     * @return a User object, or null if there was an error
171     */
172    public static function getUserByEmailAndOrigin($email, Network $account_origin) {
173        $db = AbstractDb::getObject();
174        $object = null;
175
176        $email_str = $db->escapeString($email);
177        $account_origin_str = $db->escapeString($account_origin->getId());
178        $db->execSqlUniqueRes("SELECT user_id FROM users WHERE email = '$email_str' AND account_origin = '$account_origin_str'", $user_info, false);
179
180        if ($user_info != null)
181        $object = self::getObject($user_info['user_id']);
182        return $object;
183    }
184
185    /** Returns the hash of the password suitable for storing or comparing in the database.  This hash is the same one as used in NoCat
186     * @return The 32 character hash.
187     */
188    public static function passwordHash($password) {
189        /**
190         * utf8_decode is used for backward compatibility with old passwords
191         * containing special characters.
192         * Conversion from UTF-8 to ISO-8859-1 is done to match the MD5 hash
193         */
194        return base64_encode(pack("H*", md5(utf8_decode($password))));
195    }
196
197    /** Create a new User in the database
198     * @param $id The id to be given to the new user
199     * @return the newly created User object, or null if there was an error
200     */
201    static function createUser($id, $username, Network $account_origin, $email, $password) {
202        $db = AbstractDb::getObject();
203
204        $object = null;
205        $id_str = $db->escapeString($id);
206        $username_str = $db->escapeString($username);
207        $account_origin_str = $db->escapeString($account_origin->getId());
208        $email_str = $db->escapeString($email);
209
210        $password_hash = $db->escapeString(User :: passwordHash($password));
211        $status = ACCOUNT_STATUS_VALIDATION;
212        $token = User :: generateToken();
213
214        $db->execSqlUpdate("INSERT INTO users (user_id,username, account_origin,email,pass,account_status,validation_token,reg_date) VALUES ('$id_str','$username_str','$account_origin_str','$email_str','$password_hash','$status','$token',CURRENT_TIMESTAMP)");
215
216        $object = self::getObject($id);
217        return $object;
218    }
219
220    /*    public static function purgeUnvalidatedUsers($days_since_creation)
221     {
222     $db = AbstractDb::getObject();
223     $days_since_creation = $db->escapeString($days_since_creation);
224
225     //$db->execSqlUpdate("INSERT INTO users (user_id,username, account_origin,email,pass,account_status,validation_token,reg_date) VALUES ('$id_str','$username_str','$account_origin_str','$email_str','$password_hash','$status','$token',CURRENT_TIMESTAMP)");
226     }*/
227
228    /** @param $object_id The id of the user */
229    function __construct($object_id) {
230        $db = AbstractDb::getObject();
231        $this->mDb = & $db;
232        $object_id_str = $db->escapeString($object_id);
233        $sql = "SELECT * FROM users WHERE user_id='{$object_id_str}'";
234        $db->execSqlUniqueRes($sql, $row, false);
235        if ($row == null) {
236            throw new Exception(sprintf(_("User id: %s could not be found in the database"), $object_id_str));
237        }
238        $this->mRow = $row;
239        $this->id = $row['user_id'];
240    } //End class
241
242    function getId() {
243        return $this->id;
244    }
245
246    /** Gets the Network to which the user belongs
247     * @return Network object (never returns null)
248     */
249    public function getNetwork() {
250        return Network :: getObject($this->mRow['account_origin']);
251    }
252
253    /** Get a user display suitable for a user list.  Will include link to the user profile. */
254    function getListUI() {
255        /*   
256        $roles = array ();
257
258        if ($current_node->isOwner($online_user)) {
259        $roles[] = _("owner");
260        }
261
262        if ($current_node->isTechnicalOfficer($online_user)) {
263        $roles[] = _("technical officer");
264        }
265
266        if ($roles) {
267        $rolenames = join($roles, ",");
268        }*/
269        $html = '';
270        if ($this->isSplashOnlyUser()) {
271            $html .= _("Guest");
272        }
273        else {
274                $nickname = null;
275                $avatar = null;
276                $profile = $this->getAllProfiles();
277                if(!empty($profile)) {
278                        // Use the first profile for now
279                        $profile = $profile[0];
280                       
281                        $nickname_fields = $profile->getFieldsBySemanticId("foaf:nick");
282                        // Try using the first nickname available
283                        if(!empty($nickname_fields)) {
284                                $nickname_content = $nickname_fields[0]->getContentField();
285                                if(!empty($nickname_content)) {
286                                        // Force non-verbose output
287                                        $str = $nickname_content->__toString(false);
288                                        if(!empty($str))
289                                                $nickname = $str;
290                                }
291                        }
292                       
293                        $avatar_fields = $profile->getFieldsBySemanticId("foaf:img");
294                        // Try using the first avatar available
295                        if(!empty($avatar_fields)) {
296                                $avatar_content = $avatar_fields[0]->getContentField();
297                                if(!empty($avatar_content)) {
298                                        $avatar = $avatar_content->getUserUI();
299                                }
300                        }
301                }
302               
303               
304               
305                // Display the avatar
306                $html .= "<a href='".BASE_URL_PATH."profile/?profile_user_id=".$this->getId()."' title='".htmlentities(_("View this user's profile."), ENT_QUOTES)."'>\n";
307                if(empty($avatar))
308                        $html .= Avatar::getDefaultUserUI();
309                else
310                        $html .= $avatar;
311                $html .= "</a>\n";
312               
313                // Display the nickname or the username
314                $html .= "<a href='".BASE_URL_PATH."profile/?profile_user_id=".$this->getId()."' title='".htmlentities(_("View this user's profile."), ENT_QUOTES)."' class='user_nickname'>\n";
315                if(empty($nickname))
316                $html .= $this->getUserName();
317            else
318                $html .= $nickname;
319            $html .= "</a>\n";
320           
321        }
322        return $html;
323    }
324
325    function getUsername() {
326        return $this->mRow['username'];
327    }
328
329    /** Set the user's username
330    * @param $value The new value
331    * @return true on success, false on failure
332    * @throws exception if the user tries to set a duplicate username
333    */
334    function setUsername($value) {
335        $retval = true;
336        if ($value != $this->getUsername()) {
337            $db = AbstractDb::getObject();
338            $value = $db->escapeString($value);
339            $retval = @ $db->execSqlUpdate("UPDATE users SET username = '{$value}' WHERE user_id='{$this->id}'", false);
340            if (!$retval) {
341                throw new exception(sprintf(_("Sorry, the username %s is not available"), $value));
342            }
343            $this->refresh();
344        }
345        return $retval;
346    }
347   
348    /** Add profile template to this user */
349    public function addProfile(Profile $profile) {
350        $db = AbstractDb::getObject();
351        $profile_id = $db->escapeString($profile->getId());
352        $sql = "INSERT INTO user_has_profiles (user_id, profile_id) VALUES ('$this->id','$profile_id')";
353        return $db->execSqlUpdate($sql, false);
354    }
355
356    /** Remove profile template from this user */
357    public function removeProfile(Profile $profile) {
358        $db = AbstractDb::getObject();
359        $profile_id = $db->escapeString($profile->getId());
360        $sql = "DELETE FROM user_has_profiles WHERE user_id='$this->id' AND profile_id='$profile_id'";
361        return $db->execSqlUpdate($sql, false);
362    }
363   
364    /**Get an array of all Profiles linked to this user
365    * @return an array of Profile or an empty arrray */
366    public function getAllProfiles() {
367        $db = AbstractDb::getObject();
368        $retval = array ();
369        $profile_rows = null;
370        $sql = "SELECT profile_id FROM user_has_profiles NATURAL JOIN profiles WHERE user_id='$this->id' ORDER BY creation_date";
371        $db->execSql($sql, $profile_rows, false);
372        if ($profile_rows != null) {
373            foreach ($profile_rows as $profile_row) {
374                $retval[] = Profile :: getObject($profile_row['profile_id']);
375            }
376        }
377        return $retval;
378    }
379
380    public function getEmail() {
381        return $this->mRow['email'];
382    }
383
384    public function setEmail($email) {
385        $email_str = $this->mDb->escapeString($email);
386        if (!($update = $this->mDb->execSqlUpdate("UPDATE users SET email='{$email_str}' WHERE user_id='{$this->id}'"))) {
387            throw new Exception(_("Could not update email address."));
388        }
389        $this->mRow['email'] = $email; // unescaped
390    }
391
392    function setIsInvisible($value) {
393        $retval = true;
394        if ($value != $this->isAdvertised()) {
395            $db = AbstractDb::getObject();
396            $value ? $value = 'TRUE' : $value = 'FALSE';
397            $retval = $db->execSqlUpdate("UPDATE users SET is_invisible = {$value} WHERE user_id = '{$this->getId()}'", false);
398            $this->refresh();
399        }
400        return $retval;
401    }
402
403    public function isInvisible() {
404        return (($this->mRow['is_invisible'] == 't') ? true : false);
405    }
406
407    /**What locale (language) does the user prefer? */
408    public function getPreferedLocale() {
409        $session = Session::getObject();
410        $locale = $this->mRow['prefered_locale'];
411        if (empty ($locale) && !empty ($session))
412        $locale = $session->get(SESS_LANGUAGE_VAR);
413        if (empty ($locale))
414        $locale = DEFAULT_LANG;
415        return $locale;
416    }
417
418    public function setPreferedLocale($locale) {
419        $locale_str = $this->mDb->escapeString($locale);
420        if (!($update = $this->mDb->execSqlUpdate("UPDATE users SET prefered_locale='{$locale_str}' WHERE user_id='{$this->id}'"))) {
421            throw new Exception(_("Could not update username locale."));
422        }
423        $this->mRow['prefered_locale'] = $locale;
424    }
425
426    /** get the hashed password stored in the database */
427    public function getPasswordHash() {
428        return $this->mRow['pass'];
429    }
430
431    /** Get the account status.
432     * @return Possible values are listed in common.php
433    */
434    function getAccountStatus() {
435        return $this->mRow['account_status'];
436    }
437
438    function setAccountStatus($status) {
439        $db = AbstractDb::getObject();
440        if($status != $this->getAccountStatus()) {
441            $status_str = $db->escapeString($status);
442            if (!($update = $db->execSqlUpdate("UPDATE users SET account_status='{$status_str}' WHERE user_id='{$this->id}'"))) {
443                throw new Exception(_("Could not update status."));
444            }
445            $this->mRow['account_status'] = $status;
446        }
447    }
448
449    /** Is the user valid?  Valid means that the account is validated or hasn't exhausted it's validation period.
450     $errmsg: Returs the reason why the account is or isn't valid */
451    function isUserValid(& $errmsg = null) {
452        $db = AbstractDb::getObject();
453        $retval = false;
454        $account_status = $this->getAccountStatus();
455        if ($account_status == ACCOUNT_STATUS_ALLOWED) {
456            $retval = true;
457        } else
458        if ($account_status == ACCOUNT_STATUS_VALIDATION) {
459            $sql = "SELECT CASE WHEN ((CURRENT_TIMESTAMP - reg_date) > networks.validation_grace_time) THEN true ELSE false END AS validation_grace_time_expired, EXTRACT(EPOCH FROM networks.validation_grace_time) as validation_grace_time FROM users  JOIN networks ON (users.account_origin = networks.network_id) WHERE (user_id='{$this->id}')";
460            $db->execSqlUniqueRes($sql, $user_info, false);
461
462            if ($user_info['validation_grace_time_expired'] == 't') {
463                $errmsg = sprintf(_("Sorry, your %.0f minutes grace period to retrieve your email and validate your account has now expired. You will have to connect to the internet and validate your account from another location. For more help, please %s click here %s."), $user_info['validation_grace_time']/60, '<a href="' . BASE_URL_PATH . 'faq.php' . '">', '</a>');
464                $retval = false;
465            } else {
466                $errmsg = _("Your account is currently valid.");
467                $retval = true;
468            }
469        } else {
470            $errmsg = _("Sorry, your account is not valid: ") . $account_status_to_text[$account_status];
471            $retval = false;
472        }
473        return $retval;
474    }
475
476    public function isSuperAdmin() {
477        $db = AbstractDb::getObject();
478        //$this->session->dump();
479
480        $db->execSqlUniqueRes("SELECT * FROM users NATURAL JOIN administrators WHERE (users.user_id='$this->id')", $user_info, false);
481        if (!empty ($user_info)) {
482            return true;
483        } else {
484            return false;
485        }
486
487    }
488
489    /**
490     * Tells if the current user is owner of at least one hotspot.
491     */
492    public function isOwner() {
493        $db = AbstractDb::getObject();
494        $db->execSql("SELECT * FROM node_stakeholders WHERE is_owner = true AND user_id='{$this->getId()}'", $row, false);
495        if ($row != null)
496        return true;
497        return false;
498
499    }
500
501    public function isNobody() {
502        $db = AbstractDb::getObject();
503        $db->execSqlUniqueRes("SELECT DISTINCT user_id FROM (SELECT user_id FROM network_stakeholders WHERE user_id='{$this->getId()}' UNION SELECT user_id FROM node_stakeholders WHERE user_id='{$this->getId()}' UNION SELECT user_id FROM administrators WHERE user_id='{$this->getId()}') as tmp", $row, false);
504        if ($row == null)
505        return true;
506        return false;
507    }
508
509    /** Is this user the Splash Only User() */
510    public function isSplashOnlyUser() {
511        if ($this->mRow['username'] == "SPLASH_ONLY_USER") {
512            return true;
513        } else {
514            return false;
515        }
516    }
517
518    function getValidationToken() {
519        return $this->mRow['validation_token'];
520    }
521
522    /** Generate a token in the connection table so the user can actually use the internet
523    @return true on success, false on failure
524    */
525    function generateConnectionToken() {
526        if ($this->isUserValid()) {
527            $db = AbstractDb::getObject();
528            $session = Session::getObject();
529
530            $token = self :: generateToken();
531            if ($_SERVER['REMOTE_ADDR']) {
532                $node_ip = $db->escapeString($_SERVER['REMOTE_ADDR']);
533            }
534            if ($session && $node_ip && $session->get(SESS_NODE_ID_VAR)) {
535                //echo "$session && $node_ip && {$session->get(SESS_NODE_ID_VAR)}";
536                $node_id = $db->escapeString($session->get(SESS_NODE_ID_VAR));
537                $db->execSqlUpdate("INSERT INTO connections (user_id, token, token_status, timestamp_in, node_id, node_ip, last_updated) VALUES ('" . $this->getId() . "', '$token', '" . TOKEN_UNUSED . "', CURRENT_TIMESTAMP, '$node_id', '$node_ip', CURRENT_TIMESTAMP)", false);
538                $retval = $token;
539            } else
540            $retval = false;
541        } else {
542            $retval = false;
543        }
544        return $retval;
545    }
546
547    function setPassword($password) {
548        $db = AbstractDb::getObject();
549
550        $new_password_hash = User :: passwordHash($password);
551        if (empty($password)) {
552            throw new Exception(_("Password cannot be empty."));
553        }
554
555        if (!($update = $db->execSqlUpdate("UPDATE users SET pass='$new_password_hash' WHERE user_id='{$this->id}'"))) {
556            throw new Exception(_("Could not change user's password."));
557        }
558        $this->mRow['pass'] = $password;
559    }
560
561    function getAccountOrigin() {
562        return $this->mRow['account_origin'];
563    }
564
565    /** Return all the users
566     */
567    static function getAllUsers() {
568        $db = AbstractDb::getObject();
569
570        $db->execSql("SELECT * FROM users", $objects, false);
571        if ($objects == null) {
572            throw new Exception(_("No users could not be found in the database"));
573        }
574        return $objects;
575    }
576
577    function sendLostUsername() {
578        $network = $this->getNetwork();
579        $mail = new Mail();
580        $mail->setSenderName(_("Registration system"));
581        $mail->setSenderEmail($network->getValidationEmailFromAddress());
582        $mail->setRecipientEmail($this->getEmail());
583        $mail->setMessageSubject($network->getName() . _(" lost username request"));
584        $mail->setMessageBody(_("Hello,\nYou have requested that the authentication server send you your username:\nUsername: ") . $this->getUsername() . _("\n\nHave a nice day,\nThe Team"));
585        $mail->send();
586    }
587
588    function sendValidationEmail() {
589        if ($this->getAccountStatus() != ACCOUNT_STATUS_VALIDATION) {
590            throw new Exception(_("The user is not in validation period."));
591        } else {
592            if ($this->getValidationToken() == "") {
593                throw new Exception(_("The validation token is empty."));
594            } else {
595                $network = $this->getNetwork();
596
597                $mail = new Mail();
598                $mail->setSenderName(_("Registration system"));
599                $mail->setSenderEmail($network->getValidationEmailFromAddress());
600                $mail->setRecipientEmail($this->getEmail());
601                $mail->setMessageSubject($network->getName() . _(" new user validation"));
602                $url = BASE_SSL_PATH . "validate.php?user_id=" . $this->getId() . "&token=" . $this->getValidationToken();
603                $mail->setMessageBody(_("Hello,\nPlease follow the link below to validate your account.\n") . $url . _("\n\nThank you,\nThe Team."));
604                $mail->send();
605            }
606        }
607    }
608
609    function sendLostPasswordEmail() {
610        $network = $this->getNetwork();
611        $new_password = $this->randomPass();
612        $this->setPassword($new_password);
613
614        $mail = new Mail();
615        $mail->setSenderName(_("Registration system"));
616        $mail->setSenderEmail($network->getValidationEmailFromAddress());
617        $mail->setRecipientEmail($this->getEmail());
618        $mail->setMessageSubject($network->getName() . _(" new password request"));
619        $mail->setMessageBody(_("Hello,\nYou have requested that the authentication server send you a new password:\nUsername: ") . $this->getUsername() . _("\nPassword: ") . $new_password . _("\n\nHave a nice day,\nThe Team"));
620        $mail->send();
621    }
622
623    public static function emailExists($id) {
624        $db = AbstractDb::getObject();
625        $id_str = $db->escapeString($id);
626        $sql = "SELECT * FROM users WHERE email='{$id_str}'";
627        $db->execSqlUniqueRes($sql, $row, false);
628        return $row;
629    }
630
631    public static function randomPass() {
632        $rand_pass = ''; // makes sure the $pass var is empty.
633        for ($j = 0; $j < 3; $j++) {
634            $startnend = array (
635                'b',
636                'c',
637                'd',
638                'f',
639                'g',
640                'h',
641                'j',
642                'k',
643                'l',
644                'm',
645                'n',
646                'p',
647                'q',
648                'r',
649                's',
650                't',
651                'v',
652                'w',
653                'x',
654                'y',
655                'z',
656
657                );
658                $id = array (
659                'a',
660                'e',
661                'i',
662                'o',
663                'u',
664                'y',
665
666                );
667                $count1 = count($startnend) - 1;
668                $count2 = count($id) - 1;
669
670                for ($i = 0; $i < 3; $i++) {
671                    if ($i != 1) {
672                        $rand_pass .= $startnend[rand(0, $count1)];
673                    } else {
674                        $rand_pass .= $id[rand(0, $count2)];
675                    }
676                }
677        }
678        return $rand_pass;
679    }
680
681    public static function generateToken() {
682        return md5(uniqid(rand(), 1));
683    }
684
685    /**
686     * Get an interface to add a user to a list
687     *
688     * @param string $user_prefix      A identifier provided by the programmer
689     *                                 to recognise it's generated HTML form
690     * @param string $add_button_name  Name of optional "add" button
691     * @param string $add_button_value Value of optional "add" button
692     *
693     * @return string HTML markup
694   
695     */
696    public static function getSelectUserUI($user_prefix, $add_button_name = null, $add_button_value = null) {
697
698        $db = AbstractDb::getObject();
699
700        $networkSelector = Network :: getSelectNetworkUI($user_prefix);
701
702        // Check if we need to add an "add" button
703        if ($add_button_name && $add_button_value) {
704            $userSelector = _("Username") . ": " . InterfaceElements :: generateInputText("select_user_" . $user_prefix . "_username", "", "", "input_text", array (
705                "onkeypress" => "if ((event.which ? event.which : event.keyCode) == 13) {form.$add_button_name.click() }"
706                ));
707                $userSelector .= InterfaceElements :: generateInputSubmit($add_button_name, $add_button_value);
708        } else {
709            $userSelector = _("Username") . ": " . InterfaceElements :: generateInputText("select_user_" . $user_prefix . "_username");
710        }
711        $html = "<div class='user_select_user_ui_container'>".$networkSelector . $userSelector . "</div>\n";
712        return $html;
713    }
714
715    /** Get the selected user, IF one was selected and is valid
716     * @param $user_prefix A identifier provided by the programmer to recognise it's generated form
717     * @return the User object, or null if the user is invalid or none was selected
718     */
719    static function processSelectUserUI($user_prefix) {
720        $object = null;
721        try {
722            $network = Network :: processSelectNetworkUI($user_prefix);
723            $name = "select_user_{$user_prefix}_username";
724            if (!empty ($_REQUEST[$name])) {
725                $username = $_REQUEST[$name];
726                return self :: getUserByUsernameAndOrigin($username, $network);
727            } else
728            return null;
729        } catch (Exception $e) {
730            return null;
731        }
732    }
733
734    public function getAdminUI() {
735        $db = AbstractDb::getObject();
736        $currentUser = self :: getCurrentUser();
737        $userPreferencesItems = array();
738        $finalHtml = '';
739        if($this->getNetwork()->hasAdminAccess($currentUser)) {
740            /* Statistics */
741            $content = "<a href='".BASE_SSL_PATH."admin/stats.php?Statistics=".$this->getNetwork()->getId()."&distinguish_users_by=user_id&stats_selected_users=".$this->getUsername()."&UserReport=on&user_id=".$this->getId()."&action=generate'>"._("Get user statistics")."</a>\n";
742            $administrationItems[] = InterfaceElements::genSectionItem($content);
743
744            /* Account status */
745            $title = _("Account Status");
746            $help = _("Note that Error is for internal use only");
747            $name = "user_" . $this->getId() . "_accountstatus";
748            global $account_status_to_text;
749            $content = FormSelectGenerator::generateFromKeyLabelArray($account_status_to_text, $this->getAccountStatus(), $name, null, false);
750            $administrationItems[] = InterfaceElements::genSectionItem($content, $title, $help);
751
752            $finalHtml .= InterfaceElements::genSection($administrationItems, _("Administrative options"));
753        }
754
755        if (($this == $currentUser && !$this->isSplashOnlyUser() )|| $this->getNetwork()->hasAdminAccess($currentUser)) {
756            /* Username */
757            $title = _("Username");
758            $name = "user_" . $this->getId() . "_username";
759            $content = "<input type='text' name='$name' value='" . htmlentities($this->getUsername()) . "' size=30><br/>\n";
760            $content .= _("Be carefull when changing this: it's the username you use to log in!");
761            $userPreferencesItems[] = InterfaceElements::genSectionItem($content, $title);
762           
763            /* Change password */
764                $changePasswordItems=array();
765                if($this == $currentUser) {//Don't enter the old password if changing password for another user
766                    $title = _("Your current password");
767                    $name = "user_" . $this->getId() . "_oldpassword";
768                    $content = "<input type='password' name='$name' size='20'>\n";
769                    $changePasswordItems[] = InterfaceElements::genSectionItem($content, $title);
770                }
771       
772                $title = _("Your new password");
773                $name = "user_" . $this->getId() . "_newpassword";
774                $content = "<input type='password' name='$name' size='20'>\n";
775                $changePasswordItems[] = InterfaceElements::genSectionItem($content, $title);
776       
777                $title = _("Your new password (again)");
778                $name = "user_" . $this->getId() . "_newpassword_again";
779                $content = "<input type='password' name='$name' size='20'>\n";
780                $changePasswordItems[] = InterfaceElements::genSectionItem($content, $title);
781       
782                $userPreferencesItems[] = InterfaceElements::genSection($changePasswordItems, _("Change my password"));
783       
784                $finalHtml .= InterfaceElements::genSection($userPreferencesItems, _("User preferences"), false, false, get_class($this));
785           
786            //N.B: For now, let pretend we have only one profile per use...
787            $profiles = $this->getAllProfiles();
788            $current_profile = null;
789            if(empty($profiles)) {
790                // Get the list of profile templates for the users' network
791                $profile_templates = ProfileTemplate::getAllProfileTemplates($this->getNetwork());
792                if(!empty($profile_templates)) {
793                        // Create a blank profile and link it to the user
794                        $current_profile = Profile::createNewObject(null, $profile_templates[0]);
795                        $this->addProfile($current_profile);
796                }
797            } else {
798                $current_profile = $profiles[0];
799            }
800           
801            if($current_profile != null) {
802                    $finalHtml .= $current_profile->getAdminUI();
803            }
804        }
805
806        return $finalHtml;
807    }
808
809    public function processAdminUI() {
810        $db = AbstractDb::getObject();
811        $currentUser = self :: getCurrentUser();
812        if ($this->getNetwork()->hasAdminAccess($currentUser)) {
813            /* Account status */
814            $name = "user_" . $this->getId() . "_accountstatus";
815            $status = FormSelectGenerator::getResult($name, null);
816            $this->setAccountStatus($status);
817        }
818
819        if ($this == $currentUser || $this->getNetwork()->hasAdminAccess($currentUser)) {
820            /* Username */
821            $name = "user_" . $this->getId() . "_username";
822            $this->setUsername($_REQUEST[$name]);
823           
824            /* Change password */
825            $nameOldpassword = "user_" . $this->getId() . "_oldpassword";
826            $nameNewpassword = "user_" . $this->getId() . "_newpassword";
827            $nameNewpasswordAgain = "user_" . $this->getId() . "_newpassword_again";
828            if($_REQUEST[$nameNewpassword]!=null){
829                if ($this == $currentUser && $this->getPasswordHash() != User::passwordHash($_REQUEST[$nameOldpassword])) {
830                    throw new Exception(_("Wrong password."));
831                }
832                if ($_REQUEST[$nameNewpassword] != $_REQUEST[$nameNewpasswordAgain]){
833                    throw new Exception(_("Passwords do not match."));
834                }
835                $this->setPassword($_REQUEST[$nameNewpassword]);
836            }
837
838            // Pretend there is only one
839            $profiles = $this->getAllProfiles();
840            if(!empty($profiles))
841                $profiles[0]->processAdminUI();
842
843        }
844    }
845
846    public function delete(& $errmsg) {
847    }
848
849    public function getUserUI() {
850        $html = "";
851        $html .= $this->getRealName();
852
853        return $html;
854    }
855
856    /** Add content to this user ( subscription ) */
857    public function addContent(Content $content) {
858        $db = AbstractDb::getObject();
859        $content_id = $db->escapeString($content->getId());
860        $sql = "INSERT INTO user_has_content (user_id, content_id) VALUES ('$this->id','$content_id')";
861        $db->execSqlUpdate($sql, false);
862        return true;
863    }
864
865    /** Remove content from this node */
866    public function removeContent(Content $content) {
867        $db = AbstractDb::getObject();
868        $content_id = $db->escapeString($content->getId());
869        $sql = "DELETE FROM user_has_content WHERE user_id='$this->id' AND content_id='$content_id'";
870        $db->execSqlUpdate($sql, false);
871        return true;
872    }
873
874    /**Get an array of all Content linked to this node
875     * @return an array of Content or an empty arrray */
876    function getAllContent() {
877        $db = AbstractDb::getObject();
878        $retval = array ();
879        $content_rows = null;
880        $sql = "SELECT * FROM user_has_content WHERE user_id='$this->id' ORDER BY subscribe_timestamp";
881        $db->execSql($sql, $content_rows, false);
882        if ($content_rows != null) {
883            foreach ($content_rows as $content_row) {
884                $retval[] = Content :: getObject($content_row['content_id']);
885            }
886        }
887        return $retval;
888    }
889
890    /** Reloads the object from the database.  Should normally be called after a set operation */
891    protected function refresh() {
892        $this->__construct($this->id);
893    }
894
895    /** Set Smarty template values.  Standardization routine. */
896    public static function assignSmartyValues($smarty, $user = null) {
897        if (!$user)
898        $user = User :: getCurrentUser();
899        $smarty->assign('userId', $user ? $user->getId() : '');
900        $smarty->assign('userName', $user ? $user->getListUI() : '');
901        /**
902         * Define user security levels for the template
903         *
904         * These values are used in the default template of WiFoDog but could be
905         * used in a customized template to restrict certain links to specific
906         * user access levels.
907         */
908        $smarty->assign('userIsValid', $user && !$user->isSplashOnlyUser() ? true : false);
909        $smarty->assign('userIsSuperAdmin', $user && $user->isSuperAdmin());
910        $smarty->assign('userIsANodeOwner', $user && $user->isOwner());
911
912        if (isset ($_REQUEST['debug_request']) && ($user && $user->isSuperAdmin())) {
913            // Tell Smarty everything it needs to know
914            $smarty->assign('debugRequested', true);
915            $smarty->assign('debugOutput', print_r($_REQUEST, true));
916        }
917    }
918}
919
920/*
921 * Local variables:
922 * tab-width: 4
923 * c-basic-offset: 4
924 * c-hanging-comment-ender-p: nil
925 * End:
926 */
Note: See TracBrowser for help on using the browser.