Search:

# CWIS Developers Documentation

- Main Page
- Classes
- Files

- File List
- File Members

# Axis--User.php

Go to the documentation of this file.

    00001 <?PHP
    00002
    00003 #
    00004 #   Axis--User.php
    00005 #   An Object for Handling User Information
    00006 #
    00007 #   Copyright 1999-2001 Axis Data
    00008 #   This code is free software that can be used or redistributed under the
    00009 #   terms of Version 2 of the GNU General Public License, as published by the
    00010 #   Free Software Foundation (http://www.fsf.org).
    00011 #
    00012 #   Author:  Edward Almasy (almasy@axisdata.com)
    00013 #
    00014 #   Part of the AxisPHP library v1.2.4
    00015 #   For more information see http://www.axisdata.com/AxisPHP/
    00016 #
    00017
    00018 # status values (error codes)
    00019 define("U_OKAY",                0);
    00020 define("U_ERROR",               1);
    00021 define("U_BADPASSWORD",         2);
    00022 define("U_NOSUCHUSER",          3);
    00023 define("U_PASSWORDSDONTMATCH",  4);
    00024 define("U_EMAILSDONTMATCH",     5);
    00025 define("U_DUPLICATEUSERNAME",   6);
    00026 define("U_ILLEGALUSERNAME",     7);
    00027 define("U_EMPTYUSERNAME",       8);
    00028 define("U_ILLEGALPASSWORD",     9);
    00029 define("U_ILLEGALPASSWORDAGAIN",10);
    00030 define("U_EMPTYPASSWORD",       11);
    00031 define("U_EMPTYPASSWORDAGAIN",  12);
    00032 define("U_ILLEGALEMAIL",        13);
    00033 define("U_ILLEGALEMAILAGAIN",   14);
    00034 define("U_EMPTYEMAIL",          15);
    00035 define("U_EMPTYEMAILAGAIN",     16);
    00036 define("U_NOTLOGGEDIN",         17);
    00037 define("U_MAILINGERROR",        18);
    00038 define("U_TEMPLATENOTFOUND",    19);
    00039 define("U_DUPLICATEEMAIL",      20);
    00040
    00041
    00042 class User {
    00043
    00044     # ---- PUBLIC INTERFACE --------------------------------------------------
    00045
    00046     function User(&$SessionOrDb, $UserInfo=NULL)
    00047     {
    00048         # assume constructor will succeed and user is not logged in
    00049         $this->Result = U_OKAY;
    00050         $this->LoggedIn = FALSE;
    00051
    00052         # if a session was passed in
    00053         if (is_object($SessionOrDb) && method_exists($SessionOrDb, "Session"))
    00054         {
    00055             # save pointer to session
    00056             $this->Session =& $SessionOrDb;
    00057
    00058             # swipe database handle from session
    00059             $this->DB =& $this->Session->DB;
    00060
    00061             # if user ID is available from session
    00062             if ($this->Session->Get("APUserId") !== NULL)
    00063             {
    00064                 # save user ID
    00065                 $this->UserId = $this->Session->Get("APUserId");
    00066
    00067                 # set flag indicating user is currently logged in
    00068                 $this->LoggedIn = TRUE;
    00069             }
    00070         }
    00071         # else if database handle was passed in
    00072         elseif (is_object($SessionOrDb)
    00073                 && method_exists($SessionOrDb, "Database"))
    00074         {
    00075             # save database handle
    00076             $this->DB =& $SessionOrDb;
    00077
    00078             # if user ID was passed in
    00079             if (is_int($UserInfo))
    00080             {
    00081                 # save user ID
    00082                 $this->UserId = $UserInfo;
    00083             }
    00084             # else if user name was passed in
    00085             elseif (is_string($UserInfo))
    00086             {
    00087                 # look up user ID in database
    00088                 $this->DB->Query("SELECT UserId FROM APUsers"
    00089                         ." WHERE UserName='".addslashes($UserInfo)."'");
    00090
    00091                 # if user ID was found
    00092                 if ($this->DB->NumRowsSelected() > 0)
    00093                 {
    00094                     $this->UserId = $this->DB->FetchField("UserId");
    00095                 }
    00096                 else
    00097                 {
    00098                     # if name looks like it could actually be a user ID
    00099                     if (preg_match("/^[-]*[0-9]+$/", $UserInfo))
    00100                     {
    00101                         # assume name was user ID
    00102                         $this->UserId = $UserInfo;
    00103                     }
    00104                     else
    00105                     {
    00106                         # set code indicating no user found
    00107                         $this->Result = U_NOSUCHUSER;
    00108                     }
    00109                 }
    00110             }
    00111         }
    00112         else
    00113         {
    00114             # error out
    00115             $this->Result = U_ERROR;
    00116             exit("ERROR: User object creation attempted without DB or session");
    00117         }
    00118     }
    00119
    00120     function Status()
    00121     {
    00122         return $this->Result;
    00123     }
    00124
    00125     # return text message corresponding to current (or specified) status code
    00126     function StatusMessage($StatusCode = NULL)
    00127     {
    00128         $APUserStatusMessages = array(
    00129                 U_OKAY                => "The operation was successful.",
    00130                 U_ERROR               => "There has been an error.",
    00131                 U_BADPASSWORD         => "The password you entered was"
    00132                                             ." incorrect.",
    00133                 U_NOSUCHUSER          => "No such user name was found.",
    00134                 U_PASSWORDSDONTMATCH  => "The new passwords you entered do"
    00135                                             ." not match.",
    00136                 U_EMAILSDONTMATCH     => "The e-mail addresses you entered"
    00137                                             ." do not match.",
    00138                 U_DUPLICATEUSERNAME   => "The user name you requested is"
    00139                                             ." already in use.",
    00140                 U_ILLEGALUSERNAME     => "The user name you requested is too"
    00141                                             ." short, too long, or contains"
    00142                                             ." illegal characters.",
    00143                 U_ILLEGALPASSWORD     => "The new password you requested is"
    00144                                             ." too short, too long, or"
    00145                                             ." contains illegal characters.",
    00146                 U_ILLEGALEMAIL        => "The e-mail address you entered"
    00147                                             ." appears to be invalid.",
    00148                 U_NOTLOGGEDIN         => "The user is not logged in.",
    00149                 U_MAILINGERROR        => "An error occurred while attempting"
    00150                                             ." to send e-mail.  Please notify"
    00151                                             ." the system administrator.",
    00152                 U_TEMPLATENOTFOUND    => "An error occurred while attempting"
    00153                                             ." to generate e-mail.  Please"
    00154                                             ." notify the system administrator.",
    00155                 U_DUPLICATEEMAIL      => "The e-mail address you supplied already"
    00156                                             ." has an account associated with it.",
    00157                 );
    00158
    00159         return ($StatusCode === NULL) ? $APUserStatusMessages[$this->Result]
    00160                 : $APUserStatusMessages[$StatusCode];
    00161     }
    00162
    00163     function Delete()
    00164     {
    00165         # clear priv list values
    00166         $this->DB->Query("DELETE FROM APUserPrivileges WHERE UserId = '".$this->UserId."'");
    00167
    00168         # delete user record from database
    00169         $this->DB->Query("DELETE FROM APUsers WHERE UserId = '".$this->UserId."'");
    00170
    00171         # report to caller that everything succeeded
    00172         $this->Result = U_OKAY;
    00173         return $this->Result;
    00174     }
    00175
    00176
    00177     # ---- Getting/Setting Values --------------------------------------------
    00178
    00179     function Id()
    00180     {
    00181         return $this->UserId;
    00182     }
    00183     function Name()
    00184     {
    00185         return $this->Get("UserName");
    00186     }
    00187     function LastLocation($NewLocation = NULL)
    00188     {
    00189         if ($NewLocation)
    00190         {
    00191             $this->DB->Query("UPDATE APUsers SET"
    00192                     ." LastLocation = '".addslashes($NewLocation)."',"
    00193                     ." LastActiveDate = NOW(),"
    00194                     ." LastIPAddress = '".$_SERVER["REMOTE_ADDR"]."'"
    00195                     ." WHERE UserId = '".addslashes($this->UserId)."'");
    00196             if (isset($this->DBFields))
    00197             {
    00198                 $this->DBFields["LastLocation"] = $NewLocation;
    00199                 $this->DBFields["LastActiveDate"] = date("Y-m-d H:i:s");
    00200             }
    00201         }
    00202         return $this->Get("LastLocation");
    00203     }
    00204     function LastActiveDate()
    00205     {
    00206         return $this->Get("LastActiveDate");
    00207     }
    00208     function LastIPAddress()
    00209     {
    00210         return $this->Get("LastIPAddress");
    00211     }
    00212
    00213     # get value from specified field
    00214     function Get($FieldName)
    00215     {
    00216         return $this->UpdateValue($FieldName);
    00217     }
    00218
    00219     # get value (formatted as a date) from specified field
    00220     function GetDate($FieldName, $Format = "")
    00221     {
    00222         # retrieve specified value from database
    00223         if (strlen($Format) > 0)
    00224         {
    00225             $this->DB->Query("SELECT DATE_FORMAT(`".addslashes($FieldName)."`, '".addslashes($Format)."') AS `".addslashes($FieldName)."` FROM APUsers WHERE UserId='".$this->UserId."'");
    00226         }
    00227         else
    00228         {
    00229             $this->DB->Query("SELECT `".addslashes($FieldName)."` FROM APUsers WHERE UserId='".$this->UserId."'");
    00230         }
    00231         $Record = $this->DB->FetchRow();
    00232
    00233         # return value to caller
    00234         return $Record[$FieldName];
    00235     }
    00236
    00237     # set value in specified field
    00238     function Set($FieldName, $NewValue)
    00239     {
    00240         $this->UpdateValue($FieldName, $NewValue);
    00241         $this->Result = U_OKAY;
    00242         return $this->Result;
    00243     }
    00244
    00245
    00246     # ---- Login Functions ---------------------------------------------------
    00247
    00248     function Login($UserName, $Password, $IgnorePassword = FALSE)
    00249     {
    00250         global $APUserId;
    00251
    00252         # error out if we are not part of a session
    00253         if (!isset($this->Session))
    00254         {
    00255             exit("ERROR: User->Login() called on object without session");
    00256         }
    00257
    00258         # if user not found in DB
    00259         $this->DB->Query("SELECT * FROM APUsers"
    00260                 ." WHERE UserName = '"
    00261                         .addslashes(self::NormalizeUserName($UserName))."'");
    00262         if ($this->DB->NumRowsSelected() < 1)
    00263         {
    00264             # result is no user by that name
    00265             $this->Result = U_NOSUCHUSER;
    00266         }
    00267         else
    00268         {
    00269             # grab password from DB
    00270             $Record = $this->DB->FetchRow();
    00271             $StoredPassword = $Record["UserPassword"];
    00272
    00273             if (isset($Password[0]) && $Password[0] == " ")
    00274             {
    00275                 $Challenge = md5(date("Ymd").$_SERVER["REMOTE_ADDR"]);
    00276                 $StoredPassword = md5( $Challenge . $StoredPassword );
    00277
    00278                 $EncryptedPassword = trim($Password);
    00279             }
    00280             else
    00281             {
    00282                 # if supplied password matches encrypted password
    00283                 $EncryptedPassword = crypt($Password, $StoredPassword);
    00284             }
    00285
    00286             if (($EncryptedPassword == $StoredPassword) || $IgnorePassword)
    00287             {
    00288                 # result is success
    00289                 $this->Result = U_OKAY;
    00290
    00291                 # store user ID for session
    00292                 $this->UserId = $Record["UserId"];
    00293                 $APUserId = $this->UserId;
    00294                 $this->Session->RegisterVariable("APUserId");
    00295
    00296                 # update last login date
    00297                 $this->DB->Query("UPDATE APUsers SET LastLoginDate = NOW() "
    00298                         ."WHERE UserId = '".$this->UserId."'");
    00299
    00300                 # Check for old format hashes, and rehash if possible
    00301                 if ($EncryptedPassword === $StoredPassword &&
    00302                     substr($StoredPassword,0,3) !== "$1$" &&
    00303                     $Password[0] !== " " &&
    00304                     CRYPT_MD5 )
    00305                 {
    00306                     $NewPassword = crypt($Password);
    00307                     $this->DB->Query(
    00308                         "UPDATE APUsers SET UserPassword='".addslashes($NewPassword)."' "
    00309                         ."WHERE UserId='".$this->UserId."'");
    00310                 }
    00311
    00312                 # since self::DBFields might already have been set to false if
    00313                 # the  user wasn't logged in when this is called, populate it
    00314                 # with user data so that a call to self::UpdateValue will be
    00315                 # able to properly fetch the data associated with the user
    00316                 $this->DBFields = $Record;
    00317
    00318                 # set flag to indicate we are logged in
    00319                 $this->LoggedIn = TRUE;
    00320             }
    00321             else
    00322             {
    00323                 # result is bad password
    00324                 $this->Result = U_BADPASSWORD;
    00325             }
    00326         }
    00327
    00328         # return result to caller
    00329         return $this->Result;
    00330     }
    00331
    00332     # log this user out
    00333     function Logout()
    00334     {
    00335         # if we are part of a session
    00336         if (isset($this->Session))
    00337         {
    00338             # clear user ID for session
    00339             $this->Session->UnregisterVariable("APUserId");
    00340         }
    00341
    00342         # set flag to indicate user is no longer logged in
    00343         $this->LoggedIn = FALSE;
    00344     }
    00345
    00346     function GetPasswordSalt($UserName)
    00347     {
    00348         $this->DB->Query(
    00349             "SELECT * FROM APUsers WHERE UserName = '"
    00350             .addslashes(self::NormalizeUserName($UserName))."'");
    00351
    00352         if ($this->DB->NumRowsSelected() < 1)
    00353         {
    00354             # result is no user by that name, generate a fake salt
    00355             # to discourage user enumeration. Make it be an old-format
    00356             # crypt() salt so that it's harder.
    00357             $SaltString = $_SERVER["SERVER_ADDR"].$UserName;
    00358             $Result = substr(base64_encode(md5($SaltString)),0,2);
    00359         }
    00360         else
    00361         {
    00362             # grab password from DB
    00363             # Assumes that we used php's crypt() for the passowrd
    00364             # management stuff, and will need to be changed if we
    00365             # go to something else.
    00366             $Record = $this->DB->FetchRow();
    00367             $StoredPassword = $Record["UserPassword"];
    00368
    00369             if (substr($StoredPassword,0,3)==="$1$")
    00370             {
    00371                 $Result = substr($StoredPassword, 0,12);
    00372             }
    00373             else
    00374             {
    00375                 $Result = substr($StoredPassword, 0,2);
    00376             }
    00377         }
    00378
    00379         return $Result;
    00380     }
    00381
    00382     # report whether this user is or is not currently logged in
    00383     function IsLoggedIn() {  return $this->LoggedIn;  }
    00384     function IsNotLoggedIn() {  return !$this->LoggedIn;  }
    00385
    00386
    00387     # ---- Password Functions ------------------------------------------------
    00388
    00389     # set new password (with checks against old password)
    00390     function ChangePassword($OldPassword, $NewPassword, $NewPasswordAgain)
    00391     {
    00392         # if we are part of a session make sure a user is logged in
    00393         if (isset($this->Session) && ($this->IsLoggedIn() == FALSE))
    00394         {
    00395             $this->Result = U_NOTLOGGEDIN;
    00396             return $this->Result;
    00397         }
    00398
    00399         # if old password is not correct
    00400         $StoredPassword = $this->DB->Query("SELECT UserPassword FROM APUsers"
    00401                 ." WHERE UserId='".$this->UserId."'", "UserPassword");
    00402         $EncryptedPassword = crypt($OldPassword, $StoredPassword);
    00403         if ($EncryptedPassword != $StoredPassword)
    00404         {
    00405             # set status to indicate error
    00406             $this->Result = U_BADPASSWORD;
    00407         }
    00408         # else if new password is not legal
    00409         elseif (!$this->IsValidPassword($NewPassword))
    00410         {
    00411             # set status to indicate error
    00412             $this->Result = U_ILLEGALPASSWORD;
    00413         }
    00414         # else if both instances of new password do not match
    00415         elseif (self::NormalizePassword($NewPassword)
    00416                 != self::NormalizePassword($NewPasswordAgain))
    00417         {
    00418             # set status to indicate error
    00419             $this->Result = U_PASSWORDSDONTMATCH;
    00420         }
    00421         else
    00422         {
    00423             # set new password
    00424             $this->SetPassword($NewPassword);
    00425
    00426             # set status to indicate password successfully changed
    00427             $this->Result = U_OKAY;
    00428         }
    00429
    00430         # report to caller that everything succeeded
    00431         return $this->Result;
    00432     }
    00433
    00434     # set new password
    00435     function SetPassword($NewPassword)
    00436     {
    00437         # generate encrypted password
    00438         $EncryptedPassword = crypt(self::NormalizePassword($NewPassword));
    00439
    00440         # save encrypted password
    00441         $this->UpdateValue("UserPassword", $EncryptedPassword);
    00442     }
    00443
    00444     function CreateNewUserWithEMailedPassword(
    00445             $UserName, $EMail, $EMailAgain,
    00446             $TemplateFile = "Axis--User--EMailTemplate.txt")
    00447     {
    00448         return CreateNewUserAndMailPasswordFromFile(
    00449                 $UserName, $EMail, $EMailAgain, $TemplateFile);
    00450     }
    00451
    00452     function CreateNewUserAndMailPasswordFromFile(
    00453             $UserName, $EMail, $EMailAgain,
    00454             $TemplateFile = "Axis--User--EMailTemplate.txt")
    00455     {
    00456         # load e-mail template from file (first line is subject)
    00457         $Template = file($TemplateFile, 1);
    00458         $EMailSubject = array_shift($Template);
    00459         $EMailBody = join("", $Template);
    00460
    00461         return CreateNewUserAndMailPassword(
    00462                 $UserName, $EMail, $EMailAgain, $EMailSubject, $EMailBody);
    00463     }
    00464
    00465     function CreateNewUserAndMailPassword(
    00466             $UserName, $EMail, $EMailAgain, $EMailSubject, $EMailBody)
    00467     {
    00468         # make sure e-mail addresses match
    00469         if ($EMail != $EMailAgain)
    00470         {
    00471             $this->Result = U_EMAILSDONTMATCH;
    00472             return $this->Result;
    00473         }
    00474
    00475         # make sure e-mail address looks valid
    00476         if ($this->IsValidLookingEMailAddress($EMail) == FALSE)
    00477         {
    00478             $this->Result = U_ILLEGALEMAIL;
    00479             return $this->Result;
    00480         }
    00481
    00482         # generate random password
    00483         $Password = $this->GetRandomPassword();
    00484
    00485         # attempt to create new user with password
    00486         $Result = $this->CreateNewUser($UserName, $Password, $Password);
    00487
    00488         # if user creation failed
    00489         if ($Result != U_OKAY)
    00490         {
    00491             # report error result to caller
    00492             return $Result;
    00493         }
    00494         # else
    00495         else
    00496         {
    00497             # set e-mail address in user record
    00498             $this->Set("EMail", $EMail);
    00499
    00500             # plug appropriate values into subject and body of e-mail message
    00501             $EMailSubject = str_replace("X-USERNAME-X", $UserName, $EMailSubject);
    00502             $EMailBody = str_replace("X-USERNAME-X", $UserName, $EMailBody);
    00503             $EMailBody = str_replace("X-PASSWORD-X", $Password, $EMailBody);
    00504
    00505             # send out e-mail message with new account info
    00506             $Result = mail($EMail, $EMailSubject, $EMailBody,
    00507                 "Auto-Submitted: auto-generated");
    00508
    00509             # if mailing attempt failed
    00510             if ($Result != TRUE)
    00511             {
    00512                 # report error to caller
    00513                 $this->Result = U_MAILINGERROR;
    00514                 return $this->Result;
    00515             }
    00516             # else
    00517             else
    00518             {
    00519                 # report success to caller
    00520                 $this->Result = U_OKAY;
    00521                 return $this->Result;
    00522             }
    00523         }
    00524     }
    00525
    00526     # get code for user to submit to confirm registration
    00527     function GetActivationCode()
    00528     {
    00529         # code is MD5 sum based on user name and encrypted password
    00530         $ActivationCodeLength = 6;
    00531         return $this->GetUniqueCode("Activation", $ActivationCodeLength);
    00532     }
    00533
    00534     # check whether confirmation code is valid
    00535     function IsActivationCodeGood($Code)
    00536     {
    00537         return (strtoupper(trim($Code)) == $this->GetActivationCode())
    00538                 ? TRUE : FALSE;
    00539     }
    00540
    00541     # get/set whether user registration has been confirmed
    00542     function IsActivated($NewValue = DB_NOVALUE)
    00543     {
    00544         return $this->UpdateValue("RegistrationConfirmed", $NewValue);
    00545     }
    00546
    00547     # get code for user to submit to confirm password reset
    00548     function GetResetCode()
    00549     {
    00550         # code is MD5 sum based on user name and encrypted password
    00551         $ResetCodeLength = 10;
    00552         return $this->GetUniqueCode("Reset", $ResetCodeLength);
    00553     }
    00554
    00555     # check whether password reset code is valid
    00556     function IsResetCodeGood($Code)
    00557     {
    00558         return (strtoupper(trim($Code)) == $this->GetResetCode())
    00559                 ? TRUE : FALSE;
    00560     }
    00561
    00562     # get code for user to submit to confirm mail change request
    00563     function GetMailChangeCode()
    00564     {
    00565       $ResetCodeLength = 10;
    00566
    00567       return $this->GetUniqueCode("MailChange".$this->Get("EMail").$this->Get("NewEMail"),
    00568                                   $ResetCodeLength);
    00569     }
    00570
    00571     function IsMailChangeCodeGood($Code)
    00572     {
    00573       return (strtoupper(trim($Code)) == $this->GetMailChangeCode())
    00574         ? TRUE : FALSE;
    00575     }
    00576
    00577     # send e-mail to user (returns TRUE on success)
    00578     function SendEMail(
    00579                   $TemplateTextOrFileName, $FromAddress = NULL, $MoreSubstitutions = NULL,
    00580                   $ToAddress = NULL)
    00581     {
    00582         # if template is file name
    00583         if (@is_file($TemplateTextOrFileName))
    00584         {
    00585             # load in template from file
    00586             $Template = file($TemplateTextOrFileName, 1);
    00587
    00588             # report error to caller if template load failed
    00589             if ($Template == FALSE)
    00590             {
    00591                 $this->Status = U_TEMPLATENOTFOUND;
    00592                 return $this->Status;
    00593             }
    00594
    00595             # join into one text block
    00596             $TemplateTextOrFileName = join("", $Template);
    00597         }
    00598
    00599         # split template into lines
    00600         $Template = explode("\n", $TemplateTextOrFileName);
    00601
    00602         # strip any comments out of template
    00603         $FilteredTemplate = array();
    00604         foreach ($Template as $Line)
    00605         {
    00606             if (!preg_match("/^[\\s]*#/", $Line))
    00607             {
    00608                 $FilteredTemplate[] = $Line;
    00609             }
    00610         }
    00611
    00612         # split subject line out of template (first non-comment line in file)
    00613         $EMailSubject = array_shift($FilteredTemplate);
    00614         $EMailBody = join("\n", $FilteredTemplate);
    00615
    00616         # set up our substitutions
    00617         $Substitutions = array(
    00618                 "X-USERNAME-X" => $this->Get("UserName"),
    00619                 "X-EMAILADDRESS-X" =>  $this->Get("EMail"),
    00620                 "X-ACTIVATIONCODE-X" => $this->GetActivationCode(),
    00621                 "X-RESETCODE-X" => $this->GetResetCode(),
    00622                 "X-CHANGECODE-X" => $this->GetMailChangeCode(),
    00623                 "X-IPADDRESS-X" => @$_SERVER["REMOTE_ADDR"],
    00624                 );
    00625
    00626         # if caller provided additional substitutions
    00627         if (is_array($MoreSubstitutions))
    00628         {
    00629             # add in entries from caller to substitution list
    00630             $Substitutions = array_merge(
    00631                     $Substitutions, $MoreSubstitutions);
    00632         }
    00633
    00634         # perform substitutions on subject and body of message
    00635         $EMailSubject = str_replace(array_keys($Substitutions),
    00636                 array_values($Substitutions), $EMailSubject);
    00637         $EMailBody = str_replace(array_keys($Substitutions),
    00638                 array_values($Substitutions), $EMailBody);
    00639
    00640         $AdditionalHeaders = "Auto-Submitted: auto-generated";
    00641
    00642         # if caller provided "From" address
    00643         if ($FromAddress)
    00644         {
    00645             # prepend "From" address onto message
    00646             $AdditionalHeaders .= "\r\nFrom: ".$FromAddress;
    00647         }
    00648
    00649         # send out mail message
    00650         $Result = mail(is_null($ToAddress)?$this->Get("EMail"):$ToAddress,
    00651                        $EMailSubject,
    00652                        $EMailBody, $AdditionalHeaders);
    00653
    00654         # report result of mailing attempt to caller
    00655         $this->Status = ($Result == TRUE) ? U_OKAY : U_MAILINGERROR;
    00656         return ($this->Status == U_OKAY);
    00657     }
    00658
    00659
    00660     # ---- Privilege Functions -----------------------------------------------
    00661
    00670     function HasPriv($Privilege)
    00671     {
    00672         # make sure a user is logged in (no privileges if not logged in)
    00673         if ($this->IsLoggedIn() == FALSE) {  return FALSE;  }
    00674
    00675         # set up beginning of database query
    00676         $Query = "SELECT COUNT(*) AS PrivCount FROM APUserPrivileges "
    00677                         ."WHERE UserId='".$this->UserId."' AND (";
    00678
    00679         # add first privilege(s) to query (first arg may be single value or array)
    00680         if (is_array($Privilege))
    00681         {
    00682             $Sep = "";
    00683             foreach ($Privilege as $Priv)
    00684             {
    00685                 $Query .= $Sep."Privilege='".addslashes($Priv)."'";
    00686                 $Sep = " OR ";
    00687             }
    00688         }
    00689         else
    00690         {
    00691             $Query .= "Privilege='".$Privilege."'";
    00692             $Sep = " OR ";
    00693         }
    00694
    00695         # add any privileges from additional args to query
    00696         $Args = func_get_args();
    00697         array_shift($Args);
    00698         foreach ($Args as $Arg)
    00699         {
    00700             $Query .= $Sep."Privilege='".$Arg."'";
    00701             $Sep = " OR ";
    00702         }
    00703
    00704         # close out query
    00705         $Query .= ")";
    00706
    00707         # look for privilege in database
    00708         $PrivCount = $this->DB->Query($Query, "PrivCount");
    00709
    00710         # return value to caller
    00711         return ($PrivCount > 0) ? TRUE : FALSE;
    00712     }
    00713
    00722     static function GetSqlQueryForUsersWithPriv($Privilege)
    00723     {
    00724         # set up beginning of database query
    00725         $Query = "SELECT UserId FROM APUserPrivileges "
    00726                         ."WHERE ";
    00727
    00728         # add first privilege(s) to query (first arg may be single value or array)
    00729         if (is_array($Privilege))
    00730         {
    00731             $Sep = "";
    00732             foreach ($Privilege as $Priv)
    00733             {
    00734                 $Query .= $Sep."Privilege='".addslashes($Priv)."'";
    00735                 $Sep = " OR ";
    00736             }
    00737         }
    00738         else
    00739         {
    00740             $Query .= "Privilege='".$Privilege."'";
    00741             $Sep = " OR ";
    00742         }
    00743
    00744         # add any privileges from additional args to query
    00745         $Args = func_get_args();
    00746         array_shift($Args);
    00747         foreach ($Args as $Arg)
    00748         {
    00749             $Query .= $Sep."Privilege='".$Arg."'";
    00750             $Sep = " OR ";
    00751         }
    00752
    00753         # return query to caller
    00754         return $Query;
    00755     }
    00756
    00757     function GrantPriv($Privilege)
    00758     {
    00759         # if privilege value is invalid
    00760         if (intval($Privilege) != trim($Privilege))
    00761         {
    00762             # set code to indicate error
    00763             $this->Result = U_ERROR;
    00764         }
    00765         else
    00766         {
    00767             # if user does not already have privilege
    00768             $PrivCount = $this->DB->Query("SELECT COUNT(*) AS PrivCount"
    00769                     ." FROM APUserPrivileges"
    00770                     ." WHERE UserId='".$this->UserId."'"
    00771                     ." AND Privilege='".$Privilege."'",
    00772                     "PrivCount");
    00773             if ($PrivCount == 0)
    00774             {
    00775                 # add privilege for this user to database
    00776                 $this->DB->Query("INSERT INTO APUserPrivileges"
    00777                         ." (UserId, Privilege) VALUES"
    00778                         ." ('".$this->UserId."', ".$Privilege.")");
    00779             }
    00780
    00781             # set code to indicate success
    00782             $this->Result = U_OKAY;
    00783         }
    00784
    00785         # report result to caller
    00786         return $this->Result;
    00787     }
    00788
    00789     function RevokePriv($Privilege)
    00790     {
    00791         # remove privilege from database (if present)
    00792         $this->DB->Query("DELETE FROM APUserPrivileges"
    00793                          ." WHERE UserId = '".$this->UserId."'"
    00794                          ." AND Privilege = '".$Privilege."'");
    00795
    00796         # report success to caller
    00797         $this->Result = U_OKAY;
    00798         return $this->Result;
    00799     }
    00800
    00801     function GetPrivList()
    00802     {
    00803         # read privileges from database and return array to caller
    00804         $this->DB->Query("SELECT Privilege FROM APUserPrivileges"
    00805                 ." WHERE UserId='".$this->UserId."'");
    00806         return $this->DB->FetchColumn("Privilege");
    00807     }
    00808
    00809     function SetPrivList($NewPrivileges)
    00810     {
    00811         # clear old priv list values
    00812         $this->DB->Query("DELETE FROM APUserPrivileges"
    00813                 ." WHERE UserId='".$this->UserId."'");
    00814
    00815         # for each priv value passed in
    00816         foreach ($NewPrivileges as $Privilege)
    00817         {
    00818             # set priv for user
    00819             $this->GrantPriv($Privilege);
    00820         }
    00821     }
    00822
    00823
    00824     # ---- Miscellaneous Functions -------------------------------------------
    00825
    00826     # get unique alphanumeric code for user
    00827     function GetUniqueCode($SeedString, $CodeLength)
    00828     {
    00829         return substr(strtoupper(md5(
    00830                 $this->Get("UserName").$this->Get("UserPassword").$SeedString)),
    00831                 0, $CodeLength);
    00832     }
    00833
    00834
    00835     # ---- PRIVATE INTERFACE -------------------------------------------------
    00836
    00837     var $DB;        # handle to SQL database we use to store user information
    00838     var $Session;   # session to use in storing persistent information
    00839     var $UserId;    # user ID number for reference into database
    00840     var $Result;    # result of last operation
    00841     var $LoggedIn;  # flag indicating whether user is logged in
    00842     var $DBFields;  # used for caching user values
    00843
    00844     # check whether a user name is valid  (alphanumeric string of 2-24 chars)
    00845     static function IsValidUserName($UserName)
    00846     {
    00847         if (preg_match("/^[a-zA-Z0-9]{2,24}$/", $UserName)) {  return TRUE;  } else {  return FALSE;  }
    00848     }
    00849
    00850     # check whether a password is valid  (at least 6 characters)
    00851     static function IsValidPassword($Password)
    00852     {
    00853         if (strlen(self::NormalizePassword($Password)) < 6)
    00854                 {  return FALSE;  } else {  return TRUE;  }
    00855     }
    00856
    00857     # check whether an e-mail address looks valid
    00858     static function IsValidLookingEMailAddress($EMail)
    00859     {
    00860         if (preg_match("/^[a-zA-Z0-9._\-]+@[a-zA-Z0-9._\-]+\.[a-zA-Z]{2,3}$/", $EMail)) {  return TRUE;  } else {  return FALSE;  }
    00861     }
    00862
    00863     # get normalized version of e-mail address
    00864     static function NormalizeEMailAddress($EMailAddress)
    00865     {
    00866         return strtolower(trim($EMailAddress));
    00867     }
    00868
    00869     # get normalized version of user name
    00870     static function NormalizeUserName($UserName)
    00871     {
    00872         return trim($UserName);
    00873     }
    00874
    00875     # get normalized version of password
    00876     static function NormalizePassword($Password)
    00877     {
    00878         return trim($Password);
    00879     }
    00880
    00881     # generate random password
    00882     function GetRandomPassword($PasswordMinLength = 6, $PasswordMaxLength = 8)
    00883     {
    00884         # seed random number generator
    00885         mt_srand((double)microtime() * 1000000);
    00886
    00887         # generate password of requested length
    00888         return sprintf("%06d", mt_rand(pow(10, ($PasswordMinLength - 1)),
    00889                 (pow(10, $PasswordMaxLength) - 1)));
    00890     }
    00891
    00892     # convenience function to supply parameters to Database->UpdateValue()
    00893     function UpdateValue($FieldName, $NewValue = DB_NOVALUE)
    00894     {
    00895         return $this->DB->UpdateValue("APUsers", $FieldName, $NewValue,
    00896                 "UserId = '".$this->UserId."'", $this->DBFields);
    00897     }
    00898
    00899     # methods for backward compatibility with earlier versions of User
    00900     function GivePriv($Privilege) {  $this->GrantPriv($Privilege);  }
    00901
    00902 }