Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Class Members | File Members | Related Pages

base-user.inc.php

Go to the documentation of this file.
00001 <?
00012 abstract class BaseUser extends MyObject
00013 {
00018     public $their;
00019     
00024     public $pronoun;
00025 
00029     public $profileImage = null;
00030 
00034     public static $authCacheLife = 86400;
00035     
00041     public function __construct($data = null, $table = 'users')
00042     {
00043         $this->hasAuthor = false;
00044         $this->profileImage = new Image();
00045         
00046         parent::__construct($data, $table);
00047         
00048         //setup some pronouns and shite.
00049         $this->pronoun = 'them';
00050         $this->their = 'their';
00051         if ($this->gender == 'female')
00052         {
00053             $this->pronoun = 'her';
00054             $this->their = 'her';
00055         }
00056         else if ($this->gender == 'male')
00057         {
00058             $this->pronoun = 'him';
00059             $this->their = 'his';
00060         }
00061 
00062         //is our auth_secret not defined?
00063         if (!Config::get('auth_secret'))
00064             throw new Exception('You must Config::set(\'auth_secret\').');
00065 
00066         //add in fulltext fields
00067         $this->fullTextFields[] = 'first_name';
00068         $this->fullTextFields[] = 'last_name';
00069     }
00070     
00076     public function isAdmin()
00077     {
00078         return (bool)$this->is_admin;
00079     }
00080 
00084     public function initLoginPage()
00085     {
00086         global $me;
00087         
00088         $this->pageTitle = 'Login';
00089         
00090         if ($this->params('status'))
00091             $this->addStatus($this->params('status'));
00092 
00093         if ($me->id)
00094             throw new PageError('You cannot login if you are already logged in.  Please log our first.');
00095     }
00096 
00100     public function initViewPage()
00101     {
00102         global $me;
00103         
00104         //are we viewing our own profile?
00105         if (!$this->params('id'))
00106         {
00107             if ($me->id)
00108                 $this->setParam('id', $me->id);
00109             //ya gotta log in fool
00110             else
00111                 $this->assertLogin();
00112         }
00113         
00114         //call our parent
00115         parent::initViewPage();
00116     }
00117 
00121     public function drawLoginPage()
00122     { 
00123         //create and process our login form.
00124         $form = $this->createLoginForm($this->redir);
00125         $this->processLoginForm($form);
00126         $email = $form->getData('username');
00127         
00128         //draw our form!!!
00129         $form->drawIfNeeded();
00130 
00131         //draw our links
00132         echo "<br/>\n";
00133         echo $this->getLink(".register?email=$email", 'Register') . " | ";
00134         echo $this->getLink(".lostpass?email=$email", 'Lost Password');
00135     }
00136 
00141     public function processLoginForm($form)
00142     {
00143         if ($form->isSubmittedAndValid())
00144         {
00145             if ($this->authenticate($form->getData('username'), $form->getData('password'), $form->getData('remember_me')))
00146             {
00147                 if ($form->getData('redirect'))
00148                     Util::redirect(base64_decode($form->getData('redirect')));
00149                 else
00150                     Util::redirect($this->getUrl('main'));
00151             }
00152             else
00153             {
00154                 $email = $form->getData('username');
00155                 $userId = $this->accountExists($email);
00156                 if ($userId)
00157                 {
00158                     $this->id = $userId;
00159                     if (Config::get("users_must_activate") && $this->activation_key != '')
00160                         $form->setError('username', "
00161                             Login failed.<br/>
00162                             You must " . 
00163                             $this->getLink(".activatehelp?email=$email", 'activate') . 
00164                             ' your account first.'
00165                         );
00166                     else
00167                         $form->setError('password', "
00168                         Login failed, please try again.
00169                         Remember: passwords are case sensitive.
00170                     ");
00171                 }
00172                 else
00173                     $form->setError('username', "
00174                         Account does not exist<br>
00175                         You may " . $this->getLink(".register?email=$email", 'register') . ' it.'
00176                     );
00177             }
00178         }
00179     } 
00180 
00188     public function createLoginForm($redirect = null)
00189     {
00190         $form = new Form(new OneColumnTableLayout());
00191         $form->action = $this->getUrl(".login");
00192         $form->name = 'loginForm';
00193         
00194         $form->add('HiddenField', 'redirect', array(
00195             'value' => $redirect
00196         ));
00197     
00198         //add username field
00199         $this->loginFormAddUsernameField($form);
00200         
00201         $form->add('PasswordField', 'password', array(
00202             'required' => true,
00203             'width' => '100%',
00204             'maxlength' => 255,
00205             'title' => 'Password'
00206         ));
00207         
00208         $form->add('CheckboxField', 'remember_me', array(
00209             'label' => 'Remember Me',
00210             'value' => 1
00211         ));
00212         
00213         $form->addSubmit('Login');
00214 
00215         return $form;
00216     }
00217 
00223     protected function loginFormAddUsernameField($form)
00224     {
00225         $form->add('TextField', 'username', array(
00226             'required' => true,
00227             'width' => '100%',
00228             'maxlength' => 255,
00229             'title' => 'Email'
00230         ));
00231     }
00232     
00238     static public function makePassword($len = 8)
00239     {
00240         //our vowel/consonant arrays
00241         $letter = array(
00242            array("b","c","d","f","g","h","j","k","l","m","n","p","q","r","s","t","v","w","x","y","z"),
00243            array("a","e","i","o","u")
00244         );
00245         
00246         //blank pass
00247         $pass = "";
00248         
00249         //vowels or consonants?
00250         $set = round(rand(0,1));
00251         for ($i=0; $i<$len; $i++)
00252         {
00253             //alternate
00254             $set = !$set;
00255 
00256             //get a random key...
00257             $idx = floor(rand(0, count($letter[$set])-1));
00258 
00259             //add it to the pass
00260             $pass .= $letter[$set][$idx];
00261         }
00262 
00263         return $pass;
00264     }
00265 
00269     function initLogoutPage()
00270     {
00271         global $me;
00272 
00273         if ($me->id)
00274             $me->logoutProcess();
00275 
00276         Util::redirect($this->baseUrl);
00277     }
00278     
00282     function drawLogoutPage()
00283     {
00284         echo 'You have been logged out.';
00285     }
00286 
00290     function initRegisterPage()
00291     {
00292         global $me;
00293         
00294         $this->pageTitle = 'Register New Account';
00295 
00296         if ($me->id)
00297             throw new PageError('You are logged in, you don\'t need another account. Please log out first.');
00298     }
00299 
00305     function createRegisterForm()
00306     {
00307         $form = new Form();
00308         $form->action = $this->getUrl(".register");
00309     
00310         //add oru fields in
00311         $this->registerFormAddFields($form);
00312 
00313         return $form;
00314     }
00315 
00323     protected function registerFormAddFields($form)
00324     {
00325         $form->add('EmailField', 'email', array(
00326             'required' => true,
00327         ));
00328         $form->add('TextField', 'username', array(
00329             'required' => true,
00330             'size' => 50
00331         ));
00332         $form->add('PasswordField', 'password1', array(
00333             'required' => true,
00334             'title' => 'Password',
00335         ));
00336         $form->add('PasswordField', 'password2', array(
00337             'required' => true,
00338             'title' => 'Password Again',
00339         ));
00340 
00341         if ($this->hasField('birthday'))
00342             $form->add('DateField', 'birthday', array(
00343                 'required' => true,
00344                 'beginYear' => 1900,
00345                 'endYear' => date('Y')
00346             ));
00347         
00348         $form->add('CheckboxField', 'read_tos', array(
00349             'title' => '',
00350             'label' => 'I have read the <a href=\'' . $this->getUrl(array('module' => 'main', 'page' => 'tos')) .
00351                 '\' target=\'_blank\'>Terms of Service</a>.'
00352         ));
00353         $form->add('CheckboxField', 'am_of_age', array(
00354             'title' => '',
00355             'label' => 'I am at least <b>' . Config::get('minimum_age') . ' years</b> of age.'
00356         ));
00357 
00358         $form->addSubmit("Register");
00359 
00360         return $form;
00361     }
00362 
00366     function drawRegisterPage()
00367     {
00368         $form = $this->createRegisterForm();
00369         
00370         if ($form->isSubmitted())
00371         {
00372             $this->validateRegistration($form);
00373             
00374             if (!$form->hasError())
00375                 $this->registrationPostSuccess($form);
00376         }
00377         else
00378         {
00379             $email = $this->params('email');
00380             if ($email)
00381                 $form->setData(array('email' => $email));
00382         }
00383         
00384         //finally draw the form if needed
00385         if ($form->needsDrawn())
00386             $form->drawAll();
00387     }
00388 
00394     protected function validateRegistration($form)
00395     {
00396         //validate oru form.
00397         $form->validate();
00398         
00399         //make them agree to the TOS
00400         if (!$form->getData('read_tos'))
00401             $form->setError('read_tos', 'You must read and agree to the Terms of Service');
00402 
00403         //check our passwords
00404         if ($form->getData('password1') != $form->getData('password2'))
00405             $form->setError('password2', 'Your passwords must match.');
00406 
00407         //handle age stuff...
00408         $parentPerm = $form->getData('am_of_age');
00409         if (!$parentPerm)
00410             $form->setError('am_of_age', 'By law, we cannot allow
00411             people under ' . Config::get('minimum_age') . '  to access the site. You must
00412             agree that you are able to access this site.');
00413 
00414         //setup the minimum age date.
00415         $year = date("Y") - Config::get('minimum_age');
00416         $month = date("m");
00417         $day = date("d");
00418         $time = strtotime("$year-$month-$day");
00419         
00420         //get their birthday
00421         $bday = $form->getData('birthday');
00422         $bdayTime = strtotime($bday);
00423 
00424         //do our error...
00425         if ($bdayTime > $time)
00426             $form->setError('birthday', 'You are not old enough to access this site.');
00427 
00428         //check for duplicates
00429         if ($this->accountExists($form->getData('email')))
00430             $form->setError('email',
00431                 'That email has already been registered.  If it is yours, <br/>you may <a href="' .
00432                 $this->getUrl(".login") . '">login</a> or if you forgot it, <a href="' . 
00433                 $this->getUrl(".lostpass?email=" . $form->getData("email")) . '">reset your password.</a>');
00434 
00435         //want to make sure we can check on username.
00436         if ($form->hasField('username'))
00437             if ($this->usernameExists($form->getData('username')))
00438                 $form->setError('username', 'That username already exists.');
00439     }
00440 
00447     protected function usernameExists($username)
00448     {
00449         return (bool)dbGetNumRows(dbQuery("
00450             SELECT id
00451             FROM users
00452             WHERE username = '$username'
00453         "));
00454     }
00455 
00461     protected function registrationPostSuccess($form)
00462     {
00463         global $me;
00464         
00465         //hash our pass
00466         $pass = $form->getData('password1');
00467         $encPass = sha1($pass);
00468         $this->password = $encPass;
00469 
00470         //save our stuff.
00471         $this->editPagePostSaveSync($form);
00472 
00473         //send our activation email
00474         if (Config::get('users_must_activate'))
00475             $this->sendActivationEmail();
00476         //or just log them in...
00477         else
00478         {
00479             $this->doLogin();
00480             Util::redirect($this->getUrl('.main'));
00481         }
00482     }
00483     
00490     function accountExists($email)
00491     {
00492         if ($ar = dbFetchAssoc(dbQuery("
00493             SELECT id
00494             FROM $this->tableName
00495             WHERE email = '$email'
00496         ")))
00497             return $ar['id'];
00498         else
00499             return false;
00500     }
00501 
00505     function initEditPage()
00506     {
00507         global $me;
00508         
00509         //must be logged in.
00510         $this->assertLogin();
00511     
00512         //get our id...
00513         $this->id = $this->params('id');
00514     
00515         //no id?... no problem.
00516         if (!$this->id)
00517             $this->id = $me->id;
00518         
00519         //can we edit?
00520         if (!$this->canEdit())
00521             throw new PageError('You do not have permission to edit this profile.');
00522         else
00523             $this->pageTitle = 'Edit Profile';
00524     }
00525 
00534     function editFormValidate($form)
00535     {
00536         parent::editFormValidate($form);
00537         
00538         $email = trim($form->getData('email'));
00539         if (strlen($email) && $email != $this->email)
00540         {
00541             if ($this->accountExists($email))
00542                 $form->setError('email', 'That email is already in use.');
00543         }
00544     }
00545 
00554     function editFormAddFields($form)
00555     {
00556         global $me;
00557 
00558         if ($me->isAdmin() && $this->hasField('is_admin'))
00559             $form->add('CheckboxField', 'is_admin');
00560     
00561         if ($this->hasField('first_name') && $this->hasField('last_name'))
00562             $form->add('NameField', 'name', array(
00563                 'required' => true
00564             ));
00565             
00566         if ($this->hasField('email'))
00567             $form->add('EmailField', 'email', array(
00568                 'required' => true,
00569                 'size' => 45,
00570                 'maxlength' => 255
00571             ));
00572         
00573         if ($this->hasField('birthday'))
00574         {
00575             $form->add('DateField', 'birthday', array(
00576                 'beginYear' => 1900,
00577                 'endYear' => date('Y')
00578             ));
00579         }
00580 
00581         if ($this->hasField('gender'))
00582             $form->add('GenderField', 'gender', array());
00583 
00584         if ($this->hasField('website'))
00585             $form->add('TextField', 'website', array(
00586                 'size' => 45,
00587                 'maxlength' => 255
00588             ));
00589         
00590         if ($this->hasField('phone_number'))
00591             $form->add('PhoneField', 'phone_number', array(
00592             ));
00593     
00594         if ($this->hasField('cell_number'))
00595             $form->add('PhoneField', 'cell_number', array(
00596                 'title' => 'Cellphone Number'
00597             ));
00598     
00599         if ($this->hasField('street'))
00600             $form->add('TextField', 'street', array(
00601                 'size' => 45,
00602                 'maxlength' => 255,
00603                 'title' => 'Street Address'
00604             ));
00605     
00606         if ($this->hasField('city') && $this->hasField('state') && $this->hasField('zip'))
00607             $form->add('CityStateZipField', 'citystzip', array(
00608                 'title' => 'City / State / Zip'
00609             ));
00610     
00611         if ($this->hasField('about_me'))
00612             $form->add('EditorField', 'about_me', array(
00613                 "width" => '100%',
00614                 "height" => '300px',
00615                 "title" => 'About Me'
00616             ));
00617     }
00618 
00626     function editPagePostSaveSync($form)
00627     {
00628         global $me;
00629         
00630         //save the first name?
00631         if ($form->hasField('name') && $this->hasField('first_name') && $this->hasField('last_name'))
00632         {
00633             $name = $form->getData('name');
00634             $this->first_name = $name['first_name'];
00635             $this->last_name = $name['last_name'];
00636         }
00637         
00638         //save it!!
00639         parent::editPagePostSaveSync($form);
00640         
00641         //create our session?
00642         if ($this->id == $me->id)
00643             $me->createSession();
00644     }
00645 
00649     function canEdit()
00650     {
00651         global $me;
00652 
00653         if ($me->isAdmin() || $this->isMe())
00654             return true;
00655         return false;
00656     }
00657     
00661     function initLostPassPage()
00662     {
00663         global $me;
00664 
00665         $this->pageTitle = 'Lost Password Retrieval';
00666     
00667         if ($me->id)
00668             throw new PageError("You're already logged in, if you want to change your password, you can do so via your profile.");
00669     }
00670 
00676     function createLostPassForm()
00677     {
00678         $form = new Form();
00679         $form->action = $this->getUrl('.lostpass');
00680 
00681         $form->add('EmailField', 'email', array(
00682             'title' => 'Email Address',
00683             'required' => true,
00684             'size' => 50,
00685             'maxlength' => 255
00686         ));
00687         $form->addSubmit("Request Password Reset");
00688 
00689         return $form;
00690     }
00691     
00697     function drawLostpassPage()
00698     {
00699         if (!$this->id)
00700         {
00701             $form = $this->createLostPassForm();
00702 
00703             if ($form->isSubmitted())
00704             {
00705                 $form->validate();
00706 
00707                 if (!$form->hasError())
00708                 {
00709                     $email = $form->getData('email');
00710                     if ($this->requestPassReset($email))
00711                         echo "<p>We have emailed your password request to $email.</p>";
00712                     else
00713                         $form->setError('email', 'We did not find that email, you may ' .
00714                         $this->getLink(".register?email=$email", 'register') . ' it if you like.');
00715                 }
00716             }
00717             else
00718                 $form->setData($this->params());
00719 
00720             //finally draw the form if needed
00721             if ($form->needsDrawn())
00722                 $form->drawAll();
00723         }
00724         else
00725             echo 'If you are already logged in, you do not need to request a new password.';
00726     }
00727     
00733     function createEditPassForm()
00734     {
00735         $form = new Form();
00736         $form->action = $this->getUrl('.editpass');
00737 
00738         $form->add('PasswordField', 'password1', array(
00739             'required' => true,
00740             'title' => 'Password',
00741         ));
00742         $form->add('PasswordField', 'password2', array(
00743             'required' => true,
00744             'title' => 'Password Again',
00745         ));
00746         $form->addSubmit("Edit Password");
00747         
00748         return $form;
00749     }
00750 
00754     function initEditPassPage()
00755     {
00756         $this->pageTitle = 'Edit Password';
00757     
00758         $this->id = $this->assertLogin();
00759     }
00760 
00764     function drawEditPassPage()
00765     {
00766         $form = $this->createEditPassForm();
00767         
00768         if ($form->isSubmitted())
00769         {
00770             $form->validate();
00771 
00772             if (!$form->hasError())
00773             {
00774                 $this->password = sha1($form->getData('password1'));
00775 
00776                 //mark the pass set if we can.
00777                 if ($this->hasField('pass_changed'))
00778                     $this->pass_changed = 1;
00779                     
00780                 $this->save();
00781 
00782                 //update our session
00783                 $this->doLogin(true, false);
00784 
00785                 //let them know their password changed.
00786                 $this->emailPassChanged();
00787 
00788                 echo 'You password has been changed.';
00789             }
00790         }
00791 
00792         //finally draw the form if needed
00793         if ($form->needsDrawn())
00794             $form->drawAll();
00795     }
00796 
00800     function emailPassChanged()
00801     {
00802         $subject = 'Password Change Notice';
00803         
00804         $body = 'Dear ' . $this->getName() . "\n\n";
00805         $body .= "This is just a notification that you (or someone using your account) has changed your password on " . Config::get('site_name') . ". ";
00806         $body .= "No action is required on  your part, unless you did not do this, in which case contact " . Config::get('site_admin') . ".\n\n";
00807         $body .= "Thank you,\nHappy " . Config::get('site_name') . " Password Protection Robot";
00808 
00809         //send her off!
00810         $this->mail($subject, $body);
00811     }
00812 
00827     public function authenticate($username = null, $password = null, $rememberMe = null)
00828     {
00829         //if we got a username and pass... log them in.
00830         if ($username !== null && $password !== null)
00831         {
00832             //give it a try.
00833             if ($this->loginProcess($username, $password, $rememberMe))
00834                 return true;
00835         }
00836         
00837         //okay this is the 'remember me stuff'
00838         if (isset($_COOKIE['auth']))
00839         {
00840             //try our auth code
00841             if ($this->tryAuthCode($_COOKIE['auth']))
00842                 return true;
00843         }
00844         
00845         //nope, we failed!
00846         return false;
00847     }
00848 
00858     public function tryAuthCode($code, $checkCache = true)
00859     {
00860         global $me;
00861         
00862         //get our stuff...
00863         $authAr = explode("-", $code);
00864         
00865         //get our vars...
00866         $userId = $authAr[0];
00867     
00868         //if the id they are attempting is us... let them in.
00869         if ($me->id != $userId)
00870         {
00871             //passwords gotta match
00872             $user = new User($userId);
00873             $goodHash = $user->generateHash();
00874             
00875             //does it match with our secret hash?
00876             if ($code == $goodHash)
00877             {
00878                 //try and get our user from the cache.
00879                 if ($checkCache)
00880                     if ($this->checkAuthCache($code))
00881                         return true;
00882         
00883                 //log us in!
00884                 $user->doLogin(true, false);
00885                 return true;
00886             }
00887         }
00888         //its us... but we're already legit.
00889         else
00890             return true;
00891         
00892         return false;
00893     }
00894         
00905     protected function checkAuthCache($code)
00906     {
00907         global $me;
00908         
00909         //find our user.
00910         if ($code)
00911         {
00912             $user = CacheBot::get("BaseJumper:auth:$code", self::$authCacheLife);
00913             
00914             //did we get a user?
00915             if ($user instanceOf User)
00916             {
00917                 //yup, save them!
00918                 $me = $user;
00919                 return true;
00920             }
00921             return false;
00922         }
00923         else
00924             throw new Exception("Authcode was blank.");
00925     }
00926 
00937     public function generateHash()
00938     {
00939         $hash = '';
00940 
00941         //should we make one?
00942         if ($this->id)
00943             $hash = $this->id . "-" . sha1($this->id . "-" . $this->password . "-" . Config::get('auth_secret'));
00944         
00945         return $hash;
00946     }
00947 
00957     function loginProcess($user, $pass, $rememberMe = true)
00958     {
00959         //get our auth sql.
00960         $where = $this->getAuthWhereSql($user, $pass);
00961         $userRs = dbQuery("
00962             SELECT id
00963             FROM $this->tableName
00964             $where
00965         ");
00966 
00967         //did we get 1 and only 1 user?
00968         if ($userAr = dbFetchAssoc($userRs))
00969         {
00970             $user = new User($userAr['id']);
00971             $user->doLogin($rememberMe);
00972             
00973             return true;
00974         }
00975         else
00976             return false;
00977     }
00978 
00984     public function doLogin($rememberMe = true, $login = true)
00985     {
00986         //create our session!
00987         $this->createSession($login);
00988         
00989         //do we want to let them get remembered?
00990         if ($rememberMe)
00991             $time = 31556926;  // one year
00992         else
00993             $time = 86400; // one day
00994             
00995         //create our hash..
00996         $hash = $this->generateHash();
00997 
00998         //cookie set for 1 year
00999         setcookie('auth', $hash, time() + $time, '/', Config::get('site_hostname'));
01000         $_COOKIE['auth'] = $hash;
01001     }
01002 
01013     protected function getAuthWhereSql($user, $pass)
01014     {
01015         $pass = sha1($pass);
01016 
01017         $sql = "WHERE email = '$user' AND password = '$pass' ";
01018 
01019         if (Config::get('users_must_activate'))
01020             $sql .= " AND activation_key = '' ";
01021         
01022         return $sql;
01023     }
01024 
01037     function createSession($login = false)
01038     {
01039         if ($this->id)
01040         {
01041             //lookup our data
01042             $this->lookupData(false);
01043 
01044             //do we update the login stuff
01045             if ($login)
01046             {
01047                 //argh... relying on get and set... fuckers.  we cant do ++
01048                 if ($this->hasField('login_count'))
01049                     $this->login_count = $this->login_count + 1;
01050 
01051                 //save our previous login tithis...
01052                 if ($this->hasField('previous_login'))
01053                     $this->previous_login = $this->last_login;
01054 
01055                 //save our newest login tithis
01056                 if ($this->hasField('last_login'))
01057                     $this->last_login = date('Y-m-d H:i:s');
01058              }
01059 
01060             //call our update stub.
01061             $this->updateSession();
01062             
01063             //save our dater.
01064             $this->save();
01065 
01066             //save our user session.
01067             $this->saveSession();
01068             
01069             return $this;
01070         }
01071         else
01072             throw new Exception('You cannot create a session for a non user.');
01073     }
01074 
01079     protected function updateSession()
01080     {
01081     }
01082 
01088     protected function saveSession()
01089     {
01090         //save it with cachebot.
01091         if ($this->id)
01092             CacheBot::set("BaseJumper:auth:" . $this->generateHash(), $this, self::$authCacheLife);
01093         else
01094             throw new Exception('You cannot save a session for a non user.');
01095     }
01096 
01100     public function logoutProcess()
01101     {
01102         //delete our cache.
01103         CacheBot::delete("BaseJumper:auth:" . $this->generateHash());
01104         
01105         //delete our cookie.
01106         setcookie('auth', '', time()-42000, '/', Config::get('site_hostname'));
01107     }
01108 
01116     function confirmUser()
01117     {
01118         global $me;
01119         
01120         //get our data
01121         $code = $_REQUEST['code'];
01122         $userId = $_REQUEST['id'];
01123 
01124         //find the unapproved user that matches
01125         $userRs = dbQuery("
01126             SELECT *
01127             FROM users
01128             WHERE id = '$userId'
01129                 AND code = '$code'
01130                 AND approved = 0
01131         ");
01132         //did we get them?
01133         if (dbGetNumRows($userRs))
01134         {
01135             //create the object
01136             $me = new User(dbFetchAssoc($userRs));
01137 
01138             //mark them as approved
01139             $me->code = md5(mt_rand());
01140             $me->approved = 1;
01141             $me->save();
01142             
01143             //log them in...
01144             $_SESSION['user'] = $me;
01145             
01146             return true;
01147         }
01148         //return an error here eventually
01149         else
01150             return false;
01151     }
01152 
01160     function mail($subject, $body, $html = null)
01161     {
01162         Mail::send($this->email, $subject, $body, $html);
01163     }
01164     
01171     public function addAlert($url, $text)
01172     {
01173         //do we have it?
01174         if (!class_exists(Alert))
01175             throw new Exception('You need to add the Alert class or define User::addAlert and make it blank.');
01176 
01177         //add alert!
01178         $alert = new Alert();
01179         $alert->user_id = $this->id;
01180         $alert->url = $url;
01181         $alert->text = $text;
01182         $alert->save();
01183     }
01184 
01192     function requestPassReset($email)
01193     {
01194         $this->id = $this->accountExists($email);
01195         if ($this->id)
01196         {
01197             //update our code
01198             $this->reset_pass_code = substr(md5(mt_rand()), 1, 6);
01199             $this->save();
01200 
01201             //get our email to the forgetter.
01202             $subject = "Lost Password Request";
01203             $body .= "You have recently asked to have your " . Config::get('site_name') . " password reset.\n\n";
01204             $body .= "You may now do this at:\n";
01205             $body .= $this->getTicket(array(
01206                 'page' => 'editpass',
01207             )) . "\n\n";
01208             $body .= "Thank you,\nHappy " . Config::get('site_name') . " Password Reset Robot";
01209             $body .= "\n\nPS. For your convenience, this link will automatically log you in too!";
01210 
01211             //our html email!
01212             $html .= "You have recently asked to have your " . Config::get('site_name') . " password reset.<br/><br/>";
01213             $html .= "You may now do this " . $this->getTicket(array(
01214                 'page' => 'editpass',
01215             ), 'here') . ".<br/><br/>";
01216             $html .= "Thank you,<br/>Happy " . Config::get('site_name') . " Password Reset Robot";
01217             $html .= "<br/><br/>PS. For your convenience, this link will automatically log you in too!";
01218 
01219             //mail the user the url to update.
01220             $this->mail($subject, $body, $html);
01221 
01222             return true;
01223         }
01224         else
01225             return false;
01226     }
01227 
01233     function tryPassReset()
01234     {
01235         if ($this->id)
01236         {
01237             $code = $_REQUEST['code'];
01238             $pass = $_REQUEST['pass'];
01239 
01240             if (dbGetNumRows(dbQuery("
01241                 SELECT *
01242                 FROM $this->tableName
01243                 WHERE code = '$code'
01244                     AND id = '$this-id'
01245             ")))
01246             {
01247                 $this->password = md5($pass);
01248                 $this->code = md5(mt_rand());
01249 
01250                 //return a true
01251             }
01252             //else return an erro
01253         }
01254         //else return an erro
01255     }
01256 
01262     function isMe()
01263     {
01264         global $me;
01265         if ($this->id == $me->id)
01266             return true;
01267         else
01268             return false;
01269     }
01270 
01289     function getPagesXml()
01290     {
01291         $xml = parent::getPagesXml();
01292         $xml .= <<<XML
01293 <page name="register" desc="register a new user">       
01294     <param name="email" desc="your email"/>
01295     <param name="password" desc="plaintext password"/>
01296     <param name="first_name" desc="your name" />
01297     <param name="last_name" desc="your name" />
01298 </page>
01299 <page name="activate" desc="activate your user account">
01300     <param name="id" value="id of the user" required="true"/>
01301     <param name="code" value="code to activate" required="true"/>
01302 </page>
01303 <page name="activatehelp">
01304     <param name="email" value="email of account"/>
01305 </page>
01306 <page name="lostpass" desc="request a pass change via email">
01307     <param name="email" desc="email of forgotten account"/>
01308 </page>
01309 <page name="editpass" desc="edit your password">
01310     <param name="password1" />
01311     <param name="password2" />
01312 </page>
01313 <page name="login" desc="the login process page" type="xml">
01314     <param name="redirect" value="url to redirect to" />
01315     <param name="status" value="status message." />
01316 </page>
01317 <page name="logout" desc="the logout process page"/>
01318 <page name="prefs" desc="manage your site preferences"/>
01319 <page name="emailprefs" desc="edit your email preferences" />
01320 <page name="deleteme">
01321     <param name="id" value="your id" required="1" type="int"/>
01322 </page>
01323 XML;
01324         return $xml;
01325     }
01326 
01330     function initPrefsPage()
01331     {
01332         $this->assertLogin();
01333 
01334         $this->pageTitle = 'Account Preferences';
01335     }
01336 
01341     function drawPrefsPage()
01342     {
01343         global $me;
01344 
01345         echo "\t<h3>" . $me->getLink(array('page' => 'edit'), 'Edit My Profile') . "</h3>\n";
01346         echo "<p>This is where you can change various things like your
01347         name, birthday, zipcode, biography, and so forth. Most of the
01348         information is shared on your profile.  Don't put anything in here
01349         you would like to keep private.</p>";
01350         
01351         echo "\t<h3>" . $me->getLink(array('page' => 'editpass'), 'Change My Password') . "</h3>\n";
01352         echo "<p>Here you can change your password.</p>";
01353         
01354         echo "\t<h3>" . $me->getLink(array('page' => 'emailprefs'), 'Email Preferences') . "</h3>\n";
01355         echo "<p>On this page, you can modify your email preferences.  By
01356         default we notify you via email whenever something cool
01357         happens.</p>";
01358     }
01359 
01363     function initEmailPrefsPage()
01364     {
01365         $this->pageTitle = 'Email me whenever:';
01366         $this->id = $this->assertLogin();
01367     }
01368     
01372     function drawEmailPrefsPage()
01373     {
01374         $form = $this->createEmailPrefsForm();
01375         
01376         if ($form->isSubmitted())
01377         {
01378             $form->validate();
01379 
01380             if (!$form->hasError())
01381             {
01382                 $this->saveEmailPrefs($form);
01383                 echo 'You email preferences have been saved.';
01384             }
01385         }
01386 
01387         $form->setData($this->data);
01388 
01389         //finally draw the form if needed
01390         if ($form->needsDrawn())
01391             $form->drawAll();
01392     }
01393     
01399     function createEmailPrefsForm()
01400     {
01401         //set it up..
01402         $form = new Form();
01403         $form->action = $this->getUrl('.emailprefs');
01404 
01405         //add our fields.
01406         $form = $this->emailPrefsFormAddFields($form);
01407     
01408         //our submit button
01409         $form->addSubmit('Save Preferences');
01410 
01411         //preload!
01412         $form->setData($this->getData(false));
01413 
01414         return $form;
01415     }
01416 
01424     function emailPrefsFormAddFields($form)
01425     {
01426         if ($this->hasField('email_comments'))
01427             $form->add('CheckboxField', 'email_comments', array(
01428                 'title' => '',
01429                 'label' => 'Someone posts a comment on something I\'ve posted.',
01430                 'value' => 1
01431             ));
01432 
01433         if ($this->hasField('email_comment_replies'))
01434             $form->add('CheckboxField', 'email_comment_replies', array(
01435                 'title' => '',
01436                 'label' => 'Someone replies to one of my comments.',
01437                 'value' => 1
01438             ));
01439         
01440         if ($this->hasField('birthday'))
01441             $form->add('CheckboxField', 'email_happy_birthday', array(
01442                 'title' => '',
01443                 'label' => 'It\'s my birthday.',
01444                 'value' => 1
01445             ));
01446 
01447         return $form;
01448     }
01449     
01455     function saveEmailPrefs($form)
01456     {
01457         $this->email_happy_birthday = (int)$form->getData('email_happy_birthday');
01458         $this->email_comment_replies = (int)$form->getData('email_comment_replies');
01459         $this->email_comments = (int)$form->getData('email_comments');
01460 
01461         $this->save();
01462     }
01463 
01469     function getLastLogin()
01470     {
01471         global $me;
01472 
01473         return $me->formatDateTime($this->last_login);
01474     }
01475     
01481     function getMemberSince()
01482     {
01483         global $me;
01484 
01485         return $me->formatDateTime($this->member_since);
01486     }
01487 
01491     function drawActivatePage()
01492     {
01493         global $me;
01494         
01495         //create our first session!
01496         $me = new User($this->params('id'));
01497         $me->doLogin();
01498 
01499         //make it so we dont have to log in again.
01500         $me->activation_key = '';
01501         $me->save();
01502 
01503         //take me to your leader!
01504         Util::redirect($this->getUrl('.main')); 
01505     }
01506 
01510     function initActivateHelpPage()
01511     {
01512         $this->pageTitle = 'Account Activation Help';
01513     }
01514 
01518     function drawActivateHelpPage()
01519     {
01520         $form = $this->createActivateHelpForm();
01521 
01522         if ($form->isSubmitted())
01523         {
01524             //finally, validate
01525             $form->validate();
01526             
01527             //get our info
01528             $user = new User();
01529             $email = $form->getData('email');
01530             $userId = $user->accountExists($email);
01531 
01532             //did we get a user?
01533             if ($userId)
01534             {
01535                 $user->id = $userId;
01536 
01537                 //what if they already activated?
01538                 if (!$user->activation_key)
01539                     $form->setError('email', 'That account has already been activated, please log in normally.');
01540             }
01541             //nope, let them reg.
01542             else if ($email)
01543                 $form->setError('email', 'That username does not exist, you may ' . 
01544                 $user->getLink(".register?email=$email", 'register') . " it.");
01545 
01546             //okay send the email.
01547             if (!$form->hasError())
01548             {
01549                 $user->sendActivationEmail();
01550                 echo "<p>This new activation code overrides the old one, so
01551                 make sure you have the right email. (It's the newest
01552                 one.)</p>";
01553             }
01554         }
01555         else
01556             $form->setData($this->params());
01557 
01558         if ($form->needsDrawn())
01559         {
01560 ?>
01561 <p>When you register a new account, before you can log in you must first
01562 activate your account.  This can be done by following the link contained in
01563 an email titled 'New User Confirmation' that is sent when you register.</p>
01564 
01565 <p>If for some reason, you lost the activation email, you can have the
01566 email re-sent to you via the form below.  Simply enter your email and click
01567 the button.</p>
01568 <?
01569             $form->drawAll();
01570         }
01571     }
01572 
01578     function createActivateHelpForm()
01579     {
01580         $form = new Form();
01581         $form->action = $this->getUrl('.activatehelp');
01582 
01583         $form->add('EmailField', 'email', array(
01584             'required' => true,
01585             'size' => 45
01586         ));
01587         $form->addSubmit('Resend Activation Email');
01588 
01589         return $form;
01590     }
01591 
01595     function sendActivationEmail()
01596     {
01597         //our activation code...
01598         $this->activation_key = substr(sha1(time()), 0, 8);
01599         $this->save();
01600         
01601         //create and send our registration email.
01602         $subject = "New Account Confirmation";
01603         $body .= "You recently registered an account at " . Config::get('site_name') . ".  Before you can start using this account, you must activate your account by visiting the following url:\n\n";
01604         $body .= $this->getUrl(array('page' => 'activate', 'id' => $this->id, 'code' => $this->activation_key), null, true) . "\n\n";
01605         $body .= "The entire url must be entered.  If your mail client breaks the url into two lines, be sure to copy and paste both of them into your web browser.\n\n";
01606         $body .= "Once you have activated your account, you are free to start using the site.\n\n";
01607         $body .= "Thank you,\nThe " . Config::get('site_name') . " Happy Account Activation Robot\n\n";
01608         $body .= "PS. We really hope you like our website and if there is anything we can do, please contact us.";
01609         
01610         //html email
01611         $html .= "You recently registered an account at " . Config::get('site_name') . ".  Before you can start using this account, you must activate your account by ";
01612         $html .= $this->getLink(".activate?id=$this->id&code=$this->activation_key", 'clicking here', null, true) . "<br/><br/>";
01613         $html .= "Once you have activated your account, you are free to start using the site.<br/><br/>";
01614         $html .= "Thank you,<br/>The " . Config::get('site_name') . " Happy Account Activation Robot<br/><br/>";
01615         $html .= "PS. We really hope you like our website and if there is anything we can do, please contact us.";
01616 
01617         //actually mail it now...
01618         $this->mail($subject, $body, $html);
01619 
01620         //let them know we're done.
01621         echo "<p>Thank you, " . $this->getName() . ", we have emailed <b>$this->email</b> a confirmation email.</p>\n";
01622         echo "<p>Follow the instructions it contains to activate your account.</p>";
01623 
01624         echo "<p>If it doesn't show up within a few minutes, email " . Linkify::email(Config::get('site_admin')) . " and he'll help you.</p>";
01625 
01626         
01627         if (preg_match('/(@hotmail|@msn|@aol)/', $this->email))
01628             echo "<p><b>Hotmail, AOL, or MSN may be blocking our emails.  Check
01629             your Junk E-Mail folder.<br/><br/>If the email is in there, mark it
01630             as 'Not Junk Mail'.</b>";
01631     }
01632 
01637     function drawDeletePage()
01638     {
01639         global $me;
01640 
01641         $form = $this->createDeleteForm();
01642 
01643         if ($form->isSubmitted())
01644         {
01645             $form->validate();
01646 
01647             if (!$form->getData('acknowledge'))
01648                 $form->setError('acknowledge', 'Since this is dangerous, you have to acknowledge that you really want to delete your account.');
01649 
01650             if (!$form->hasError())
01651                 $this->deletePost();
01652         }
01653 
01654         if ($form->needsDrawn())
01655             $form->drawAll();
01656     }
01657     
01666     protected function deletePost()
01667     {
01668         if ($this->isMe())
01669         {
01670             $this->emailDeleteConfirmation();
01671             echo "<p>In order to protect the safety of your account, we have
01672             emailed a delete confirmation email to you.</p><p>Follow the link inside
01673             and your account will be permanently deleted.</p>";
01674         }
01675         else
01676         {
01677             $this->delete();
01678             echo '<p>' . $this->getName() . ' has been deleted.</p>';
01679         }
01680     }
01681     
01687     public function createDeleteForm()
01688     {
01689         $form = new Form();
01690         $form->action = $this->getUrl(".delete?id=$this->id");
01691         
01692         $form->add('StaticField', 'warning', array(
01693             'text' => '<b>Warning:</b> Deleting your account is permanent.  We
01694             cannot recover your account after we delete it.  That means you
01695             should carefully consider whether you really want to delete
01696             your account or not.'
01697         ));
01698         $form->add('CheckboxField', 'acknowledge', array(
01699             'title' => '',
01700             'label' => 'I really do want to delete this account.'
01701         ));
01702         $form->addSubmit('Delete Account');
01703 
01704         return $form;
01705     }
01706 
01713     public function initDeleteMePage()
01714     {
01715         $this->assertLogin();
01716 
01717         $this->initDeletePage();
01718 
01719         $this->pageTitle = 'Account Deleted';
01720 
01721         if (!$this->isMe())
01722             throw new PageError('You cannot delete other people with this page.');
01723     }
01724 
01732     public function drawDeleteMePage()
01733     {
01734         global $me;
01735         
01736         $me->delete();
01737         $me->logoutProcess();
01738     
01739         echo '<p>Your account has been deleted.We\'re sorry to see you
01740         go.</p><p>If there\'s anything we can do to get you to come back,
01741         please email ' . Linkify::email(Config::get('site_admin')) . '</p>';
01742     }
01743 
01747     protected function emailDeleteConfirmation()
01748     {
01749         $subject = 'Delete Account Confirmation';
01750 
01751         $body = "Dear $this->first_name,\n\n";
01752         $body .= "Recently, someone using this account (probably you) requested that it be deleted.\n\n";
01753         $body .= "In order to protect your account and confirm that you really wanted to do this you must follow the link below.\n\n";
01754         $body .= "*** If this is not what you want, delete this email and nothing will happen. ***\n\n";
01755         $body .= "Follow this link to delete your account:\n";
01756         $body .= $this->getUrl(".deleteme?id=$this->id", null, true) . "\n\n";
01757         $body .= "Thank you,\nThe Sad " . Config::get('site_name') . " Account Deletion Robot\n\n";
01758         $body .= "PS. Please dont go!  If you have problems with our site, email " . Config::get('site_admin') . " and we will try to fix them.";
01759         
01760         $html = "Dear $this->first_name,<br/><br/>";
01761         $html .= "Recently, someone using this account (probably you) requested that it be deleted.<br/><br/>";
01762         $html .= "In order to protect your account and confirm that you really wanted to do this you must follow the link below.<br/><br/>";
01763         $html .= "*** <b>If this is not what you want, delete this email and nothing will happen.</b> ***<br/><br/>";
01764         $html .= $this->getLink(".deleteme?id=$this->id", "Follow this link to delete your account.", null, true) . "<br/><br/>";
01765         $html .= "Thank you,<br/>The Sad " . Config::get('site_name') . " Account Deletion Robot<br/><br/>";
01766         $html .= "PS. Please dont go!  If you have problems with our site, email " . Config::get('site_admin') . " and we will try to fix them.";
01767 
01768         $this->mail($subject, $body, $html);
01769     }
01770 
01776     function canDelete()
01777     {
01778         global $me;
01779 
01780         if (($me->id == $this->id || $me->isAdmin()) && $this->id)
01781             return true;
01782         return false;
01783     }
01784 
01793     function getTicket($url, $html = null)
01794     {
01795         $redirUrl = $this->getUrl($url);
01796     
01797         if ($this->id)
01798         {
01799             //create our ticket...
01800             $ticket = new Ticket();
01801             $ticket->generate($redirUrl, $this);
01802             
01803             //return our ticket.
01804             $redirUrl = $ticket->url();
01805         }
01806 
01807         //what kind of links?
01808         if ($html !== null)
01809             return "<a href=\"$redirUrl\">$html</a>";
01810         else
01811             return $redirUrl;
01812     }
01813 
01821     function formatDate($date)
01822     {
01823         if (!$this->date_format)
01824             $date_format = 'F d, Y';
01825         else
01826             $date_format = $this->date_format;
01827 
01828         if (!$date)
01829             $date = 0;
01830         $time = strtotime($date);
01831     
01832         return date($date_format, $time);
01833     }
01834     
01842     function formatDateTime($date)
01843     {
01844         if (!$this->datetime_format)
01845             $datetime_format = 'F d, Y g:ia';
01846         else
01847             $datetime_format = $this->datetime_format;
01848         
01849         if (!$date)
01850             $date = 0;
01851     
01852         $time = strtotime($date);
01853         
01854         if ($time)
01855             return date($datetime_format, $time);
01856         else
01857             return '???';
01858     }
01859 
01864     function getPublicData()
01865     {
01866         global $me;
01867         
01868         $data = parent::getPublicData();
01869 
01870         $data['last_login'] = $me->formatDateTime($this->last_login);
01871         $data['login_count'] = $this->login_count;
01872 
01873         return $data;
01874     }
01875 
01884     function getName($link = false, $icon = null)
01885     {
01886         global $me;
01887         
01888         $rval = "";
01889 
01890         if ($this->hasField('image_id') && $icon != null)
01891                 $rval = $this->getIcon($icon) . " ";
01892 
01893         //name?
01894         $rval .= $this->getTextName(); 
01895 
01896         return parent::getName($link, $rval);
01897     }
01898 
01902     function getTextName()
01903     {
01904         return $this->first_name . ' ' . $this->last_name;
01905     }
01906 
01914     function getIcon($type = 'tiny')
01915     {
01916         return $this->profileImage->getImage($type, false, false);
01917     }
01918 
01924     public function lookupData($deep = true)
01925     {
01926         parent::lookupData($deep);
01927         
01928         $this->profileImage = new Image();
01929         $this->profileImage->load($this->image_id, false);
01930     } 
01931     
01942     public function getDataToCache($deep = true)
01943     {
01944         $data = parent::getDataToCache($deep);
01945 
01946         $data['profileimage'] = $this->profileImage->getDataToCache(false);
01947 
01948         return $data;
01949     }
01950 
01961     public function setDataFromCache($data, $deep = true)
01962     {
01963         parent::setDataFromCache($data, $deep);
01964 
01965         //load our image back in.
01966         $this->profileImage = new Image();
01967         $this->profileImage->load($data['profileimage'], false);
01968     }
01969 
01975     function setProfileImage($imageId)
01976     {
01977         global $me;
01978         
01979         //can we do it?
01980         $this->profileImage = new Image($imageId);
01981         if ($this->profileImage->canView())
01982         {
01983             $this->image_id = $imageId;
01984             $this->save();
01985 
01986             return true;
01987         }
01988         else
01989             return false;
01990     }
01991 
01995     function initSetImagePage()
01996     {
01997         $this->assertLogin();
01998 
01999         $this->pageTitle = 'Set Profile Image';
02000     }
02001 
02005     function drawSetImagePage()
02006     {
02007         global $me;
02008         
02009         if ($me->setProfileImage($this->params('image_id')))
02010         {
02011             $me->createSession();
02012             echo "<p>Your profile image has been updated.  You may " . $this->getLink(".view?id=$me->id", "continue to your profile") . ".</p>";
02013         }
02014         else
02015             echo "<p>You must be able to view an image to set it as your profile image.</p>";
02016     }
02017 
02023     public function getCreateFieldsArray()
02024     {
02025         $fields = parent::getCreateFieldsArray();
02026 
02027         $fields['email'] = "email varchar(255) default '' not null";
02028         $fields['first_name'] = "first_name varchar(255) default '' not null";
02029         $fields['last_name'] = "last_name varchar(255) default '' not null";
02030         $fields['password'] = "password char(40) default '' not null";
02031         $fields['birthday'] = "birthday date not null";
02032         $fields['last_login'] = "last_login datetime not null";
02033         $fields['previous_login'] = "previous_login datetime not null";
02034         $fields['login_count'] = "login_count int(11) default 0 not null";
02035         $fields['activation_key'] = "activation_key char(8) default '' not null";
02036         $fields['is_admin'] = "is_admin tinyint(1) default 0 not null";
02037     
02038         return $fields;
02039     }
02040 
02046     public function getCreateIndexesArray()
02047     {
02048         $fields = parent::getCreateIndexesArray();
02049 
02050         $fields['email'] = 'key (email)';
02051         $fields['password'] = 'key (password)';
02052 
02053         return $fields;
02054     }
02055 }
02056 ?>

Generated on Fri Oct 27 12:26:40 2006 for BaseJumper by doxygen 1.3.9.1