From: Vincent Zanotti Date: Sat, 19 Jul 2008 13:56:33 +0000 (+0200) Subject: Adds a common abstraction object for plat/al's users. X-Git-Tag: core/1.0.0~58 X-Git-Url: http://git.polytechnique.org/?a=commitdiff_plain;h=5421ab0971fa76a0ae98afbeffe899318c07780e;p=platal.git Adds a common abstraction object for plat/al's users. Signed-off-by: Vincent Zanotti --- diff --git a/classes/pluser.php b/classes/pluser.php new file mode 100644 index 0000000..5b36897 --- /dev/null +++ b/classes/pluser.php @@ -0,0 +1,256 @@ +results = $results; + parent::__construct(); + } +} + +/** + * Represents an user of plat/al (without any further assumption), with a + * special focus on always-used properties (identification fields, display name, + * forlife/bestalias emails, ...). + * NOTE: each implementation of plat/al-code MUST subclass PlUser, and name it + * 'User'. + */ +abstract class PlUser +{ + /** + * User data storage. + * By convention, null means the information hasn't been fetched yet, and + * false means the information is not available. + */ + protected $user_id = null; + protected $hruid = null; + + // User main email aliases (forlife is the for-life email address, bestalias + // is user-chosen preferred email address). + protected $forlife = null; + protected $bestalias = null; + + // Display name is user-chosen name to display (eg. in "Welcome + // !"), while full name is the official full name. + protected $display_name = null; + protected $full_name = null; + protected $promo = null; + + // Other properties are listed in this key-value hash map. + protected $data = array(); + + /** + * Constructs the PlUser object from an identifier (any identifier which is + * understood by getLogin() implementation). + * + * @param $login An user login. + * @param $values List of known user properties. + */ + public function __construct($login, $values = array()) + { + $this->fillFromArray($values); + + // If the user id was not part of the known values, determines it from + // the login. + if (!$this->user_id) { + $this->user_id = $this->getLogin($login); + } + + // Preloads main properties (assumes the loader will lazily get them + // from variables already set in the object). + $this->loadMainFields(); + } + + /** + * Get the canonical user id for the @p login. + * + * @param $login An user login. + * @return The canonical user id. + * @throws UserNotFoundException when login is not found. + */ + abstract protected function getLogin($login); + + /** + * Loads the main properties (hruid, forlife, bestalias, ...) from the + * database. Should return immediately when the properties are already + * available. + */ + abstract protected function loadMainFields(); + + /** + * Accessors to the main properties, ie. those available as top level + * object variables. + */ + public function id() { return $this->user_id; } + public function login() { return $this->hruid; } + + public function bestEmail() { return $this->bestalias; } + public function forlifeEmail() { return $this->forlife; } + + public function displayName() { return $this->display_name; } + public function fullName() { return $this->full_name; } + + /** + * Other properties are available directly through the $data array, or as + * standard object variables, using a getter. + */ + public function data() { return $this->data; } + + public function __get($name) + { + if (isset($this->$name)) { + return $this->$name; + } + + if (isset($this->data[$name])) { + return $this->data[$name]; + } + + return null; + } + + public function __isset($name) + { + return isset($this->$name) || isset($this->data[$name]); + } + + /** + * Fills the object properties using the @p associative array; the intended + * user case is to fill the object using SQL obtained arrays. + * + * @param $values Key-value array of user properties. + */ + protected function fillFromArray(array $values) + { + // Merge main properties with existing ones. + unset($values['data']); + foreach ($values as $key => $value) { + if (property_exists($this, $key) && !isset($this->$key)) { + $this->$key = $value; + } + } + + // Merge all value into the $this->data placeholder. + $this->data = array_merge($this->data, $values); + } + + + /** + * Returns a valid User object built from the @p id and optionnal @p values, + * or returns false and calls the callback if the @p id is not valid. + */ + public static function get($login, $callback = false) + { + return User::getWithValues($login, array(), $callback); + } + + public static function getWithValues($login, $values, $callback = false) + { + if (!$callback) { + $callback = array('User', '_default_user_callback'); + } + + try { + return new User($login, $values); + } catch (UserNotFoundException $e) { + return call_user_func($callback, $login, $e->results); + } + } + + // Same as above, but using the silent callback as default. + public static function getSilent($login) + { + return User::getWithValues($login, array(), array('User', '_silent_user_callback')); + } + + public static function getSilentWithValues($login, $values) + { + return User::getWithValues($login, $values, array('User', '_silent_user_callback')); + } + + /** + * Returns forlife emails corresponding to the @p logins. If @p strict mode + * is disabled, it also includes login for which no forlife was found (but + * still call the callback for them). + * In all cases, email addresses which are not from the local domains are + * kept. + * + * @param $logins Array of user logins. + * @param $strict Should unvalidated logins be returned as-is or discarded ? + * @param $callback Callback to call when a login is unknown to the system. + * @return Array of validated user forlife emails. + */ + public static function getBulkForlifeEmails($logins, $strict = true, $callback = false) + { + if (!is_array($logins)) { + if (strlen(trim($logins)) == 0) { + return null; + } + $logins = split("[; ,\r\n\|]+", $logins); + } + + if ($logins) { + $list = array(); + foreach ($logins as $i => $login) { + $login = trim($login); + if (empty($login)) { + continue; + } + + if (($user = User::get($login, $callback))) { + $list[$i] = $user->forlifeEmail(); + } else if (!$strict || User::isForeignEmailAddress($login)) { + $list[$i] = $login; + } + } + return $list; + } + return null; + } + + /** + * Predefined callbacks for the user lookup; they are called when a given + * login is found not to be associated with any valid user. Silent callback + * does nothing; default callback is supposed to display an error message, + * using the Platal::page() hook. + */ + public static function _silent_user_callback($login, $results) + { + return; + } + + abstract public static function _default_user_callback($login, $results); + + /** + * Determines if the @p login is an email address, and an email address not + * served locally by plat/al. + */ + abstract public static function isForeignEmailAddress($email); +} + +// vim:set et sw=4 sts=4 sws=4 foldmethod=marker enc=utf-8: +?>