Quentin Zervaas, author of the book "Web 2.0 Development," is a simple PHP data Access object mentioned in the book.
- /**
- * Databaseobject
- *
- * Abstract class used to easily manipulate data in a database table
- * Via Simple Load/save/delete methods
- */
- Abstract class Databaseobject
- {
- Const TYPE_TIMESTAMP = 1;
- Const Type_boolean = 2;
- protected static $types = Array (Self::type_timestamp, Self::type_boolean);
- Private $_id = null;
- Private $_properties = Array ();
- protected $_db = null;
- protected $_table = ";
- protected $_idfield = ";
- Public function __construct (zend_db_adapter_abstract $db, $table, $idField)
- {
- $this->_db = $db;
- $this->_table = $table;
- $this->_idfield = $idField;
- }
- Public function Load ($id, $field = null)
- {
- if (strlen ($field) = = 0)
- $field = $this->_idfield;
- if ($field = = $this->_idfield) {
- $id = (int) $id;
- if ($id <= 0)
- return false;
- }
- $query = sprintf (' Select%s from%s where%s =? ',
- Join (', ', $this->getselectfields ()),
- $this->_table,
- $field);
- $query = $this->_db->quoteinto ($query, $id);
- return $this->_load ($query);
- }
- protected function Getselectfields ($prefix = ")
- {
- $fields = Array ($prefix. $this->_idfield);
- foreach ($this->_properties as $k = $v)
- $fields [] = $prefix. $k;
- return $fields;
- }
- protected function _load ($query)
- {
- $result = $this->_db->query ($query);
- $row = $result->fetch ();
- if (! $row)
- return false;
- $this->_init ($row);
- $this->postload ();
- return true;
- }
- Public Function _init ($row)
- {
- foreach ($this->_properties as $k = + $v) {
- $val = $row [$k];
- Switch ($v [' type ']) {
- Case Self::type_timestamp:
- if (!is_null ($val))
- $val = Strtotime ($val);
- Break
- Case Self::type_boolean:
- $val = (bool) $val;
- Break
- }
- $this->_properties[$k [' value '] = $val;
- }
- $this->_id = (int) $row [$this->_idfield];
- }
- Public Function Save ($useTransactions = True)
- {
- $update = $this->issaved ();
- if ($useTransactions)
- $this->_db->begintransaction ();
- if ($update)
- $commit = $this->preupdate ();
- Else
- $commit = $this->preinsert ();
- if (! $commit) {
- if ($useTransactions)
- $this->_db->rollback ();
- return false;
- }
- $row = Array ();
- foreach ($this->_properties as $k = + $v) {
- if ($update &&! $v [' Updated '])
- Continue
- Switch ($v [' type ']) {
- Case Self::type_timestamp:
- if (!is_null ($v [' value ')]) {
- if ($this->_db instanceof Zend_db_adapter_pdo_pgsql)
- $v [' value '] = Date (' y-m-d h:i:so ', $v [' value ']);
- Else
- $v [' value '] = Date (' y-m-d h:i:s ', $v [' value ']);
- }
- Break
- Case Self::type_boolean:
- $v [' value '] = (int) ((bool) $v [' value ']);
- Break
- }
- $row [$k] = $v [' value '];
- }
- if (count ($row) > 0) {
- Perform insert/update
- if ($update) {
- $this->_db->update ($this->_table, $row, sprintf ('%s =%d ', $this->_idfield, $this->getid ()));
- }
- else {
- $this->_db->insert ($this->_table, $row);
- $this->_id = $this->_db->lastinsertid ($this->_table, $this->_idfield);
- }
- }
- Update Internal ID
- if ($commit) {
- if ($update)
- $commit = $this->postupdate ();
- Else
- $commit = $this->postinsert ();
- }
- if ($useTransactions) {
- if ($commit)
- $this->_db->commit ();
- Else
- $this->_db->rollback ();
- }
- return $commit;
- }
- Public Function Delete ($useTransactions = True)
- {
- if (! $this->issaved ())
- return false;
- if ($useTransactions)
- $this->_db->begintransaction ();
- $commit = $this->predelete ();
- if ($commit) {
- $this->_db->delete ($this->_table, sprintf ('%s =%d ', $this->_idfield, $this->getid ()));
- }
- else {
- if ($useTransactions)
- $this->_db->rollback ();
- return false;
- }
- $commit = $this->postdelete ();
- $this->_id = null;
- if ($useTransactions) {
- if ($commit)
- $this->_db->commit ();
- Else
- $this->_db->rollback ();
- }
- return $commit;
- }
- Public Function issaved ()
- {
- return $this->getid () > 0;
- }
- Public Function GetId ()
- {
- return (int) $this->_id;
- }
- Public Function Getdb ()
- {
- return $this->_db;
- }
- Public Function __set ($name, $value)
- {
- if (Array_key_exists ($name, $this->_properties)) {
- $this->_properties[$name [' value '] = $value;
- $this->_properties[$name [' updated '] = true;
- return true;
- }
- return false;
- }
- Public Function __get ($name)
- {
- Return array_key_exists ($name, $this->_properties)? $this->_properties[$name [' value ']: null;
- }
- protected function Add ($field, $default = null, $type = NULL)
- {
- $this->_properties[$field] = Array (' value ' = = $default,
- ' Type ' = In_array ($type, Self:: $types)? $type: null,
- ' Updated ' = false);
- }
- protected function Preinsert ()
- {
- return true;
- }
- protected function Postinsert ()
- {
- return true;
- }
- protected function Preupdate ()
- {
- return true;
- }
- protected function Postupdate ()
- {
- return true;
- }
- protected function Predelete ()
- {
- return true;
- }
- protected function Postdelete ()
- {
- return true;
- }
- protected function Postload ()
- {
- return true;
- }
- public static function Buildmultiple ($db, $class, $data)
- {
- $ret = Array ();
- if (!class_exists ($class))
- throw new Exception (' Undefined class specified: '. $class);
- $TESTOBJ = new $class ($DB);
- if (! $TESTOBJ instanceof Databaseobject)
- throw new Exception (' Class does not extend from databaseobject ');
- foreach ($data as $row) {
- $obj = new $class ($DB);
- $obj->_init ($row);
- $ret [$obj->getid ()] = $obj;
- }
- return $ret;
- }
- }
Copy Code
- Class Databaseobject_user extends Databaseobject
- {
- Static $userTypes = Array (' member ' = ' member ',
- ' Administrator ' = ' Administrator ');
- public $profile = null;
- public $_newpassword = null;
- Public function __construct ($DB)
- {
- Parent::__construct ($db, ' users ', ' user_id ');
- $this->add (' username ');
- $this->add (' password ');
- $this->add (' User_type ', ' member ');
- $this->add (' ts_created ', Time (), self::type_timestamp);
- $this->add (' Ts_last_login ', null, self::type_timestamp);
- $this->profile = new Profile_user ($DB);
- }
- protected function Preinsert ()
- {
- $this->_newpassword = text_password::create (8);
- $this->password = $this->_newpassword;
- return true;
- }
- protected function Postload ()
- {
- $this->profile->setuserid ($this->getid ());
- $this->profile->load ();
- }
- protected function Postinsert ()
- {
- $this->profile->setuserid ($this->getid ());
- $this->profile->save (FALSE);
- $this->sendemail (' User-register.tpl ');
- return true;
- }
- protected function Postupdate ()
- {
- $this->profile->save (FALSE);
- return true;
- }
- protected function Predelete ()
- {
- $this->profile->delete ();
- return true;
- }
- Public Function SendEmail ($TPL)
- {
- $templater = new Templater ();
- $templater->user = $this;
- Fetch the e-mail body
- $body = $templater->render (' email/'. $tpl);
- Extract the subject from the first line
- List ($subject, $body) = Preg_split ('/\r|\n/', $body, 2);
- Now set up and send the e-mail
- $mail = new Zend_mail ();
- Set the to address and the user's full name in the "to" line
- $mail->addto ($this->profile->email,
- Trim ($this->profile->first_name. ' ' .
- $this->profile->last_name));
- Get the admin ' from ' details from the Config
- $mail->setfrom (zend_registry::get (' config ')->email->from->email,
- Zend_registry::get (' config ')->email->from->name);
- Set the subject and body and send the mail
- $mail->setsubject (Trim ($subject));
- $mail->setbodytext (Trim ($body));
- $mail->send ();
- }
- Public Function createauthidentity ()
- {
- $identity = new StdClass;
- $identity->user_id = $this->getid ();
- $identity->username = $this->username;
- $identity->user_type = $this->user_type;
- $identity->first_name = $this->profile->first_name;
- $identity->last_name = $this->profile->last_name;
- $identity->email = $this->profile->email;
- return $identity;
- }
- Public Function loginsuccess ()
- {
- $this->ts_last_login = time ();
- unset ($this->profile->new_password);
- unset ($this->profile->new_password_ts);
- unset ($this->profile->new_password_key);
- $this->save ();
- $message = sprintf (' Successful login attempt from%s user%s ',
- $_server[' REMOTE_ADDR '),
- $this->username);
- $logger = Zend_registry::get (' logger ');
- $logger->notice ($message);
- }
- static public Function Loginfailure ($username, $code = ")
- {
- Switch ($code) {
- Case Zend_auth_result::failure_identity_not_found:
- $reason = ' Unknown username ';
- Break
- Case Zend_auth_result::failure_identity_ambiguous:
- $reason = ' Multiple users found with this username ';
- Break
- Case Zend_auth_result::failure_credential_invalid:
- $reason = ' Invalid password ';
- Break
- Default
- $reason = ";
- }
- $message = sprintf (' Failed login attempt from%s user%s ',
- $_server[' REMOTE_ADDR '),
- $username);
- if (strlen ($reason) > 0)
- $message. = sprintf (' (%s) ', $reason);
- $logger = Zend_registry::get (' logger ');
- $logger->warn ($message);
- }
- Public Function Fetchpassword ()
- {
- if (! $this->issaved ())
- return false;
- Generate New Password properties
- $this->_newpassword = text_password::create (8);
- $this->profile->new_password = MD5 ($this->_newpassword);
- $this->profile->new_password_ts = time ();
- $this->profile->new_password_key = MD5 (Uniqid ().
- $this->getid ().
- $this->_newpassword);
- Save new password to profile and send e-mail
- $this->profile->save ();
- $this->sendemail (' User-fetch-password.tpl ');
- return true;
- }
- Public Function Confirmnewpassword ($key)
- {
- Check that valid password reset data is set
- if (!isset ($this->profile->new_password)
- || !isset ($this->profile->new_password_ts)
- || !isset ($this->profile->new_password_key)) {
- return false;
- }
- Check if the password is being confirm within a day
- if (Time ()-$this->profile->new_password_ts > 86400)
- return false;
- Check the key is correct
- if ($this->profile->new_password_key! = $key)
- return false;
- Everything is valid, now update the account to use the new password
- Bypass the local setter as New_password is already an MD5
- Parent::__set (' Password ', $this->profile->new_password);
- unset ($this->profile->new_password);
- unset ($this->profile->new_password_ts);
- unset ($this->profile->new_password_key);
- Finally, save the updated user record and the updated profile
- return $this->save ();
- }
- Public Function usernameexists ($username)
- {
- $query = sprintf (' Select COUNT (*) as num from%s where username =? ',
- $this->_table);
- $result = $this->_db->fetchone ($query, $username);
- return $result > 0;
- }
- static public Function IsValidUserName ($username)
- {
- $validator = new Zend_validate_alnum ();
- Return $validator->isvalid ($username);
- }
- Public Function __set ($name, $value)
- {
- Switch ($name) {
- Case ' password ':
- $value = MD5 ($value);
- Break
- Case ' User_type ':
- if (!array_key_exists ($value, Self:: $userTypes))
- $value = ' member ';
- Break
- }
- Return Parent::__set ($name, $value);
- }
- }
- ?>
Copy Code |