const NETWORKING_IM = 0x020000;
const NETWORKING_SOCIAL = 0x040000;
+ const FETCH_ADDRESSES = 0x00001;
+ const FETCH_CORPS = 0x00002;
+ const FETCH_EDU = 0x00004;
+ const FETCH_JOBS = 0x00008;
+ const FETCH_MEDALS = 0x00010;
+ const FETCH_NETWORKING = 0x00020;
+ const FETCH_PHONES = 0x00040;
+ const FETCH_PHOTO = 0x00080;
+
private $pid;
private $hrpid;
private $data = array();
}
}
+ static private $contexts = array();
+
+ /** Returns the best visibility context toward $visibility
+ * @param $visibility A wished visibility level
+ * @return The closest allowed visibility level
+ *
+ * if $visibility is null, the best visibility is returned
+ */
+ static public function getVisibilityContext($visibility = null)
+ {
+ if (array_key_exists($visibility, self::$contexts)) {
+ return self::$contexts[$visibility];
+ }
+
+ $asked_vis = $visibility;
+
+ if (S::logged()) {
+ $minvis = self::VISIBILITY_PRIVATE;
+ } else {
+ $minvis = self::VISIBILITY_PUBLIC;
+ }
+ if ($visibility == null) {
+ $visibility = array($minvis);
+ }
+
+ if ($minvis == self::VISIBILITY_PUBLIC) {
+ $visibility = array(self::VISIBILITY_PUBLIC);
+ }
+
+ self::$contexts[$asked_vis] = $visibility;
+
+ return $visibility;
+ }
+
public function id()
{
return $this->pid;
return in_array($visibility, $this->visibility);
}
+ public static function getCompatibleVisibilities($visibility)
+ {
+ return self::$v_values[$visibility];
+ }
+
/* Photo
*/
+ private $photo = null;
+ public function setPhoto(ProfilePhoto $photo)
+ {
+ $this->photo = $photo;
+ }
+
public function getPhoto($fallback = true)
{
+ if ($this->photo != null) {
+ return $this->photo->pic;
+ } else if ($fallback) {
+ return PlImage::fromFile(dirname(__FILE__).'/../htdocs/images/none.png',
+ 'image/png');
+ }
+ return null;
+ }
+ /*
$cond = '';
if ($this->visibility) {
- $cond = XDB::format(' AND pub IN {?}', $this->visibility);
+ $cond = ' AND pub IN ' . XDB::formatArray($this->visibility);
}
$res = XDB::query("SELECT *
FROM profile_photos
}
return null;
}
-
+ */
/* Addresses
*/
public function getAddresses($flags, $limit = null)
$where .= ' AND FIND_IN_SET(\'mail\', pa.flags)';
}
if ($this->visibility) {
- $where .= XDB::format(' AND pa.pub IN {?}', $this->visibility);
+ $where .= ' AND pa.pub IN ' . XDB::formatArray($this->visibility);
}
$type = array();
if ($flags & self::ADDRESS_PRO) {
$type[] = 'home';
}
if (count($type) > 0) {
- $where .= XDB::format(' AND pa.type IN {?}', $type);
+ $where .= ' AND pa.type IN ' . XDB::formatArray($type);
}
$limit = is_null($limit) ? '' : XDB::format('LIMIT {?}', (int)$limit);
return XDB::iterator('SELECT pa.text, pa.postalCode, pa.type, pa.latitude, pa.longitude,
$where .= ' AND pn.network_type = 0'; // XXX hardcoded reference to web site index
}
if ($this->visibility) {
- $where .= XDB::format(' AND pn.pub IN {?}', $this->visibility);
+ $where .= ' AND pn.pub IN ' . XDB::formatArray($this->visibility);
}
$limit = is_null($limit) ? '' : XDB::format('LIMIT {?}', (int)$limit);
return XDB::iterator('SELECT pne.name, pne.icon,
$where = XDB::format('pj.pid = {?}', $this->id());
$cond = 'TRUE';
if ($this->visibility) {
- $where .= XDB::format(' AND pj.pub IN {?}', $this->visibility);
- $cond = XDB::format('pj.email_pub IN {?}', $this->visibility);
+ $where .= ' AND pj.pub IN ' . XDB::formatArray($this->visibility);
+ $cond = 'pj.email_pub IN ' . XDB::formatArray($this->visibility);
}
$limit = is_null($limit) ? '' : XDB::format('LIMIT {?}', (int)$limit);
return XDB::iterator('SELECT pje.name, pje.acronym, pje.url, pje.email, pje.NAF_code,
return ($isOk && ($maxlen > 2 || $maxlen == strlen($_lastname)));
}
- /**
- * Clears a profile.
- * *always deletes in: profile_addresses, profile_binets, profile_job,
- * profile_langskills, profile_mentor, profile_networking,
- * profile_phones, profile_skills, watch_profile
- * *always keeps in: profile_corps, profile_display, profile_education,
- * profile_medals, profile_name, profile_photos, search_name
- * *modifies: profiles
- */
- public function clear()
- {
- XDB::execute('DELETE FROM profile_job, profile_langskills, profile_mentor,
- profile_networking, profile_skills, watch_profile
- WHERE pid = {?}',
- $this->id());
- XDB::execute('DELETE FROM profile_addresses, profile_binets,
- profile_phones
- WHERE pid = {?}',
- $this->id());
- XDB::execute("UPDATE profiles
- SET cv = NULL, freetext = NULL, freetext_pub = 'private',
- medals_pub = 'private', alias_pub = 'private',
- email_directory = NULL
- WHERE pid = {?}",
- $this->id());
- }
-
- private static function fetchProfileData(array $pids, $respect_order = true)
+ private static function fetchProfileData(array $pids, $respect_order = true, $fields = 0x0000, $visibility = null)
{
if (count($pids) == 0) {
return array();
$order = '';
}
- return XDB::Iterator('SELECT p.*, p.sex = \'female\' AS sex, pe.entry_year, pe.grad_year,
- pn_f.name AS firstname, pn_l.name AS lastname, pn_n.name AS nickname,
- IF(pn_uf.name IS NULL, pn_f.name, pn_uf.name) AS firstname_ordinary,
- IF(pn_ul.name IS NULL, pn_l.name, pn_ul.name) AS lastname_ordinary,
- pd.promo AS promo, pd.short_name, pd.directory_name AS full_name,
- pd.directory_name, pp.display_tel AS mobile, pp.pub AS mobile_pub,
- ph.attach IS NOT NULL AS has_photo, ph.pub AS photo_pub,
- p.last_change < DATE_SUB(NOW(), INTERVAL 365 DAY) AS is_old,
- ap.uid AS owner_id
- FROM profiles AS p
- INNER JOIN profile_display AS pd ON (pd.pid = p.pid)
- INNER JOIN profile_education AS pe ON (pe.pid = p.pid AND FIND_IN_SET(\'primary\', pe.flags))
- INNER JOIN profile_name AS pn_f ON (pn_f.pid = p.pid AND pn_f.typeid = {?})
- INNER JOIN profile_name AS pn_l ON (pn_l.pid = p.pid AND pn_l.typeid = {?})
- LEFT JOIN profile_name AS pn_uf ON (pn_uf.pid = p.pid AND pn_uf.typeid = {?})
- LEFT JOIN profile_name AS pn_ul ON (pn_ul.pid = p.pid AND pn_ul.typeid = {?})
- LEFT JOIN profile_name AS pn_n ON (pn_n.pid = p.pid AND pn_n.typeid = {?})
- LEFT JOIN profile_phones AS pp ON (pp.pid = p.pid AND pp.link_type = \'user\' AND tel_type = \'mobile\')
- LEFT JOIN profile_photos AS ph ON (ph.pid = p.pid)
- LEFT JOIN account_profiles AS ap ON (ap.pid = p.pid AND FIND_IN_SET(\'owner\', ap.perms))
- WHERE p.pid IN {?}
- GROUP BY p.pid
- ' . $order,
- DirEnum::getID(DirEnum::NAMETYPES, 'firstname'),
- DirEnum::getID(DirEnum::NAMETYPES, 'lastname'),
- DirEnum::getID(DirEnum::NAMETYPES, 'firstname_ordinary'),
- DirEnum::getID(DirEnum::NAMETYPES, 'lastname_ordinary'),
- DirEnum::getID(DirEnum::NAMETYPES, 'nickname'), $pids);
+
+ $it = XDB::Iterator('SELECT p.*, p.sex = \'female\' AS sex, pe.entry_year, pe.grad_year,
+ pn_f.name AS firstname, pn_l.name AS lastname, pn_n.name AS nickname,
+ IF(pn_uf.name IS NULL, pn_f.name, pn_uf.name) AS firstname_ordinary,
+ IF(pn_ul.name IS NULL, pn_l.name, pn_ul.name) AS lastname_ordinary,
+ pd.promo AS promo, pd.short_name, pd.directory_name AS full_name,
+ pd.directory_name, pp.display_tel AS mobile, pp.pub AS mobile_pub,
+ ph.attach IS NOT NULL AS has_photo, ph.pub AS photo_pub,
+ p.last_change < DATE_SUB(NOW(), INTERVAL 365 DAY) AS is_old,
+ ap.uid AS owner_id
+ FROM profiles AS p
+ INNER JOIN profile_display AS pd ON (pd.pid = p.pid)
+ INNER JOIN profile_education AS pe ON (pe.pid = p.pid AND FIND_IN_SET(\'primary\', pe.flags))
+ INNER JOIN profile_name AS pn_f ON (pn_f.pid = p.pid
+ AND pn_f.typeid = ' . self::getNameTypeId('firstname', true) . ')
+ INNER JOIN profile_name AS pn_l ON (pn_l.pid = p.pid
+ AND pn_l.typeid = ' . self::getNameTypeId('lastname', true) . ')
+ LEFT JOIN profile_name AS pn_uf ON (pn_uf.pid = p.pid
+ AND pn_uf.typeid = ' . self::getNameTypeId('firstname_ordinary', true) . ')
+ LEFT JOIN profile_name AS pn_ul ON (pn_ul.pid = p.pid
+ AND pn_ul.typeid = ' . self::getNameTypeId('lastname_ordinary', true) . ')
+ LEFT JOIN profile_name AS pn_n ON (pn_n.pid = p.pid
+ AND pn_n.typeid = ' . self::getNameTypeId('nickname', true) . ')
+ LEFT JOIN profile_phones AS pp ON (pp.pid = p.pid AND pp.link_type = \'user\' AND tel_type = \'mobile\')
+ LEFT JOIN profile_photos AS ph ON (ph.pid = p.pid)
+ LEFT JOIN account_profiles AS ap ON (ap.pid = p.pid AND FIND_IN_SET(\'owner\', ap.perms))
+ WHERE p.pid IN ' . XDB::formatArray($pids) . '
+ GROUP BY p.pid
+ ' . $order);
+ return new ProfileDataIterator($it, $pids, $fields, $visibility);
}
public static function getPID($login)
FROM account_profiles
WHERE uid = {?} AND FIND_IN_SET(\'owner\', perms)',
$login->id());
- } else if (is_int($login) || ctype_digit($login)) {
+ } else if (ctype_digit($login)) {
return XDB::fetchOneCell('SELECT pid
FROM profiles
WHERE pid = {?}', $login);
return XDB::fetchAllAssoc('uid', 'SELECT ap.uid, ap.pid
FROM account_profiles AS ap
WHERE FIND_IN_SET(\'owner\', ap.perms)
- AND ap.uid IN {?}
- ' . $order, $uids);
+ AND ap.uid IN ' . XDB::formatArray($uids) .'
+ ' . $order);
}
/** Return the profile associated with the given login.
*/
- public static function get($login)
+ public static function get($login, $fields = 0x0000, $visibility = null)
{
if (is_array($login)) {
return new Profile($login);
}
$pid = self::getPID($login);
if (!is_null($pid)) {
- $it = self::iterOverPIDs(array($pid), false);
+ $it = self::iterOverPIDs(array($pid), false, $fields, $visibility);
return $it->next();
} else {
/* Let say we can identify a profile using the identifiers of its owner.
}
}
- public static function iterOverUIDs($uids, $respect_order = true)
+ public static function iterOverUIDs($uids, $respect_order = true, $fields = 0x0000, $visibility = null)
{
- return self::iterOverPIDs(self::getPIDsFromUIDs($uids), $respect_order);
+ return self::iterOverPIDs(self::getPIDsFromUIDs($uids), $respect_order, $fields, $visibility);
}
- public static function iterOverPIDs($pids, $respect_order = true)
+ public static function iterOverPIDs($pids, $respect_order = true, $fields = 0x0000, $visibility = null)
{
- return new ProfileIterator(self::fetchProfileData($pids, $respect_order));
+ return self::fetchProfileData($pids, $respect_order, $fields, $visibility);
}
/** Return profiles for the list of pids.
*/
- public static function getBulkProfilesWithPIDs(array $pids)
+ public static function getBulkProfilesWithPIDs(array $pids, $fields = 0x0000, $visibility = null)
{
if (count($pids) == 0) {
return array();
}
- $it = self::iterOverPIDs($pids);
+ $it = self::iterOverPIDs($pids, true, $fields, $visibility);
$profiles = array();
while ($p = $it->next()) {
$profiles[$p->id()] = $p;
/** Return profiles for uids.
*/
- public static function getBulkProfilesWithUIDS(array $uids)
+ public static function getBulkProfilesWithUIDS(array $uids, $fields = 0x000, $visibility = null)
{
if (count($uids) == 0) {
return array();
}
- return self::getBulkProfilesWithPIDs(self::getPIDsFromUIDs($uids));
+ return self::getBulkProfilesWithPIDs(self::getPIDsFromUIDs($uids), $fields, $visibility);
}
public static function isDisplayName($name)
|| $name == self::DN_SHORT || $name == self::DN_SORT;
}
+ public static function getNameTypeId($type, $for_sql = false)
+ {
+ if (!S::has('name_types')) {
+ $table = XDB::fetchAllAssoc('type', 'SELECT id, type
+ FROM profile_name_enum');
+ S::set('name_types', $table);
+ } else {
+ $table = S::v('name_types');
+ }
+ if ($for_sql) {
+ return XDB::escape($table[$type]);
+ } else {
+ return $table[$type];
+ }
+ }
+
public static function rebuildSearchTokens($pid)
{
XDB::execute('DELETE FROM search_name
}
}
+class ProfileDataIterator
+{
+ private $iterator = null;
+ private $fields;
+
+ public function __construct(PlIterator $it, array $pids, $fields = 0x0000, $visibility = null)
+ {
+ require_once 'profilefields.inc.php';
+ $visibility = Profile::getVisibilityContext($visibility);
+ $this->fields = $fields;
+
+ $subits = array();
+ $callbacks = array();
+
+ $subits[0] = $it;
+ $callbacks[0] = PlIteratorUtils::arrayValueCallback('pid');
+ $cb = PlIteratorUtils::objectPropertyCallback('pid');
+
+ if ($fields & Profile::FETCH_ADDRESSES) {
+ $callbacks[Profile::FETCH_ADDRESSES] = $cb;
+ $subits[Profile::FETCH_ADDRESSES] = new ProfileFieldIterator('ProfileAddresses', $pids, $visibility);
+ }
+
+ if ($fields & Profile::FETCH_CORPS) {
+ $callbacks[Profile::FETCH_CORPS] = $cb;
+ $subits[Profile::FETCH_CORPS] = new ProfileFieldIterator('ProfileCorps', $pids, $visibility);
+ }
+
+ if ($fields & Profile::FETCH_EDU) {
+ $callbacks[Profile::FETCH_EDU] = $cb;
+ $subits[Profile::FETCH_EDU] = new ProfileFieldIterator('ProfileEducation', $pids, $visibility);
+ }
+
+ if ($fields & Profile::FETCH_JOBS) {
+ $callbacks[Profile::FETCH_JOBS] = $cb;
+ $subits[Profile::FETCH_JOBS] = new ProfileFieldIterator('ProfileJobs', $pids, $visibility);
+ }
+
+ if ($fields & Profile::FETCH_MEDALS) {
+ $callbacks[Profile::FETCH_MEDALS] = $cb;
+ $subits[Profile::FETCH_MEDALS] = new ProfileFieldIterator('ProfileMedals', $pids, $visibility);
+ }
+
+ if ($fields & Profile::FETCH_NETWORKING) {
+ $callbacks[Profile::FETCH_NETWORKING] = $cb;
+ $subits[Profile::FETCH_NETWORKING] = new ProfileFieldIterator('ProfileNetworking', $pids, $visibility);
+ }
+
+ if ($fields & Profile::FETCH_PHONES) {
+ $callbacks[Profile::FETCH_PHONES] = $cb;
+ $subits[Profile::FETCH_PHONES] = new ProfileFieldIterator('ProfilePhones', $pids, $visibility);
+ }
+
+ if ($fields & Profile::FETCH_PHOTO) {
+ $callbacks[Profile::FETCH_PHOTO] = $cb;
+ $subits[Profile::FETCH_PHOTO] = new ProfileFieldIterator('ProfilePhoto', $pids, $visibility);
+ }
+
+ $this->iterator = PlIteratorUtils::parallelIterator($subits, $callbacks, 0);
+ }
+
+ private function consolidateFields(array $pf)
+ {
+ if ($this->fields & Profile::FETCH_PHONES) {
+ $phones = $pf[Profile::FETCH_PHONES];
+
+ if ($this->fields & Profile::FETCH_ADDRESSES) {
+ $pf[Profile::FETCH_ADDRESSES]->addPhones($phones);
+ }
+ if ($this->fields & Profile::FETCH_JOBS) {
+ $pf[Profile::FETCH_JOBS]->addPhones($phones);
+ }
+ }
+
+ if ($this->fields & Profile::FETCH_ADDRESSES) {
+ $addrs = $pf[Profile::FETCH_ADDRESSES];
+ if ($this->fields & Profile::FETCH_JOBS) {
+ $pf[Profile::FETCH_JOBS]->addAddresses($addrs);
+ }
+ }
+
+ return $pf;
+ }
+
+ private function fillProfile(array $vals)
+ {
+ $vals = $this->consolidateFields($vals);
+
+ $pf = Profile::get($vals[0]);
+ if ($this->fields & Profile::FETCH_ADDRESSES) {
+ $pf->setAddresses($vals[Profile::FETCH_ADDRESSES]);
+ }
+ if ($this->fields & Profile::FETCH_CORPS) {
+ $pf->setCorps($vals[Profile::FETCH_CORPS]);
+ }
+ if ($this->fields & Profile::FETCH_EDU) {
+ $pf->setEdu($vals[Profile::FETCH_EDU]);
+ }
+ if ($this->fields & Profile::FETCH_JOBS) {
+ $pf->setJobs($vals[Profile::FETCH_JOBS]);
+ }
+ if ($this->fields & Profile::FETCH_MEDALS) {
+ $pf->setMedals($vals[Profile::FETCH_MEDALS]);
+ }
+ if ($this->fields & Profile::FETCH_NETWORKING) {
+ $pf->setNetworking($vals[Profile::FETCH_NETWORKING]);
+ }
+ if ($this->fields & Profile::FETCH_PHONES) {
+ $pf->setPhones($vals[Profile::FETCH_PHONES]);
+ }
+ if ($this->fields & Profile::FETCH_PHOTO) {
+ if ($vals[Profile::FETCH_PHOTO] != null) {
+ $pf->setPhoto($vals[Profile::FETCH_PHOTO]);
+ }
+ }
+
+ return $pf;
+ }
+
+ public function next()
+ {
+ $vals = $this->iterator->next();
+ if ($vals == null) {
+ return null;
+ }
+ return $this->fillProfile($vals);
+ }
+
+ public function first()
+ {
+ return $this->iterator->first();
+ }
+
+ public function last()
+ {
+ return $this->iterator->last();
+ }
+
+ public function total()
+ {
+ return $this->iterator->total();
+ }
+}
+
/** Iterator over a set of Profiles
* @param an XDB::Iterator obtained from a Profile::fetchProfileData
*/
class ProfileIterator implements PlIterator
{
+ private $pdi;
private $dbiter;
- public function __construct($dbiter)
+ public function __construct(ProfileDataIterator &$pdi)
{
- $this->dbiter = $dbiter;
+ $this->pdi = $pdi;
+ $this->dbiter = $pdi->iterator();
}
public function next()
if ($data == null) {
return null;
} else {
- return Profile::get($data);
+ return $this->pdi->fillProfile(Profile::get($data));
}
}
--- /dev/null
+<?php
+/***************************************************************************
+ * Copyright (C) 2003-2010 Polytechnique.org *
+ * http://opensource.polytechnique.org/ *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the Free Software *
+ * Foundation, Inc., *
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA *
+ ***************************************************************************/
+
+// {{{ class ProfileField
+/** To store a "field" from the profile
+ * Provides functions for loading a batch of such data
+ */
+abstract class ProfileField
+{
+ /** The profile to which this field belongs
+ */
+ public $pid;
+
+ /** Fetches data from the database for the given pids, compatible with
+ * the visibility context.
+ * @param $pids An array of pids
+ * @param $visibility The level of visibility fetched fields must have
+ * @return a PlIterator yielding data suitable for a "new ProfileBlah($data)"
+ */
+ abstract public static function fetchData(array $pids, $visibility);
+
+ public static function buildForPID($cls, $pid, $visibility)
+ {
+ $res = self::buildFromPIDs($cls, array($pid), $visibility);
+ return array_pop($res);
+ }
+
+ /** Build a list of ProfileFields from a set of pids
+ * @param $cls The name of the field to create ('ProfileMedals', ...)
+ * @param $pids An array of pids
+ * @param $visibility An array of allowed visibility contexts
+ * @return An array of $pid => ProfileField
+ */
+ public static function buildFromPIDs($cls, array $pids, $visibility)
+ {
+ $it = new ProfileFieldIterator($cls, $pids, $visibility);
+ $res = array();
+ while ($pf = $it->next()) {
+ $res[$pf->pid] = $pf;
+ }
+ return $res;
+ }
+}
+// }}}
+
+// {{{ class ProfileFieldIterator
+class ProfileFieldIterator implements PlIterator
+{
+ private $data;
+ private $cls;
+
+ public function __construct($cls, array $pids, $visibility)
+ {
+ $this->data = call_user_func(array($cls, 'fetchData'), $pids, $visibility);
+ $this->cls = $cls;
+ }
+
+ public function next()
+ {
+ $d = $this->data->next();
+ if ($d == null) {
+ return null;
+ } else {
+ $cls = $this->cls;
+ return new $cls($d);
+ }
+ }
+
+ public function total()
+ {
+ return $this->data->total();
+ }
+
+ public function first()
+ {
+ return $this->data->first();
+ }
+
+ public function last()
+ {
+ return $this->data->last();
+ }
+}
+// }}}
+
+// {{{ class Phone
+class Phone
+{
+ const TYPE_FAX = 'fax';
+ const TYPE_FIXED = 'fixed';
+ const TYPE_MOBILE = 'mobile';
+ public $type;
+
+ public $search;
+ public $display;
+ public $comment = '';
+
+ const LINK_JOB = 'job';
+ const LINK_ADDRESS = 'address';
+ const LINK_PROFILE = 'user';
+ const LINK_COMPANY = 'hq';
+ public $link_type;
+ public $link_id;
+
+ /** Fields are :
+ * $type, $search, $display, $link_type, $link_id, $comment, $pid, $id
+ */
+ public function __construct($data)
+ {
+ foreach ($data as $key => $val) {
+ $this->$key = $val;
+ }
+ }
+}
+// }}}
+// {{{ class Company
+class Company
+{
+ public $id;
+ public $name;
+ public $acronym;
+ public $url;
+ public $phone = null;
+ public $address = null;
+
+ /** Fields are:
+ * $id, $name, $acronym, $url
+ */
+ public function __construct($date)
+ {
+ foreach ($data as $key => $val) {
+ $this->$key = $val;
+ }
+ }
+
+ public function setPhone(Phone &$phone)
+ {
+ if ($phone->link_type == Phone::LINK_COMPANY && $phone->link_id == $this->id) {
+ $this->phone = $phone;
+ }
+ }
+
+ public function setAddress(Address &$address)
+ {
+ if ($address->link_type == Address::LINK_COMPANY && $address->link_id == $this->id) {
+ $this->address = $address;
+ }
+ }
+
+}
+// }}}
+// {{{ class Job
+class Job
+{
+ public $pid;
+ public $id;
+
+ private $company = null;
+ private $phones = array();
+ private $address = null;
+
+ public $company_id;
+
+ public $description;
+ public $url;
+ public $email;
+
+ /** Fields are:
+ * pid, id, company_id, description, url, email
+ */
+ public function __construct($data)
+ {
+ foreach ($data as $key => $val) {
+ $this->$key = $val;
+ }
+ }
+
+ public function phones()
+ {
+ return $this->phones;
+ }
+
+ public function company()
+ {
+ return $this->company;
+ }
+
+ public function addPhone(Phone &$phone)
+ {
+ if ($phone->link_type == Phone::LINK_JOB && $phone->link_id == $this->id && $phone->pid == $this->pid) {
+ $this->phones[] = $phone;
+ }
+ }
+
+ public function setAddress(Address $address)
+ {
+ if ($address->link_id == Address::LINK_JOB && $address->link_id == $this->id && $address->pid == $this->pid) {
+ $this->address = $address;
+ }
+ }
+
+ public function setCompany(Company $company)
+ {
+ $this->company = $company;
+ }
+}
+// }}}
+// {{{ class Address
+class Address
+{
+ const LINK_JOB = 'job';
+ const LINK_COMPANY = 'hq';
+ const LINK_PROFILE = 'home';
+
+ public $link_id;
+ public $link_type;
+
+ public $flags;
+ public $text;
+ public $postcode;
+ public $country;
+
+ private $phones = array();
+
+ /** Fields are:
+ * pîd, id, link_id, link_type, flags, text, postcode, country
+ */
+ public function __construct($data)
+ {
+ foreach ($data as $key => $val) {
+ $this->$key = $val;
+ }
+ }
+
+ public function addPhone(Phone &$phone)
+ {
+ if ($phone->link_type == Phone::LINK_ADDRESS && $phone->link_id == $this->id && $phone->pid == $this->pid) {
+ $this->phones[] = $phone;
+ }
+ }
+
+ public function phones()
+ {
+ return $this->phones;
+ }
+}
+// }}}
+
+// {{{ class ProfileEducation [ Field ]
+class ProfileEducation extends ProfileField
+{
+ public $schools = array();
+
+ private function __construct(PlIterator $it)
+ {
+ $this->visibility = Profile::VISIBILITY_PUBLIC;
+ while ($edu = $it->next()) {
+ $this->schools[$edu['id']] = $edu;
+ }
+ }
+
+ public static function fetchData(array $pids, $visibility)
+ {
+ $data = XDB::iterator('SELECT *
+ FROM profile_education
+ WHERE pid IN {?}
+ ORDER BY ' . XDB::formatCustomOrder('pid', $pids),
+ $pids);
+
+ return PlIteratorUtils::subIterator($data, PlIteratorUtils::arrayValueCallback('pid'));
+ }
+}
+// }}}
+// {{{ class ProfileMedals [ Field ]
+class ProfileMedals extends ProfileField
+{
+ public $medals = array();
+
+ private function __construct(PlIterator $it)
+ {
+ while ($medal = $it->next()) {
+ $this->medals[$medal['mid']] = $medal['gid'];
+ }
+ }
+
+ public static function fetchData(array $pids, $visibility)
+ {
+ $data = XDB::iterator('SELECT pm.pid, pm.mid, pm.gid
+ FROM profile_medals AS pm
+ LEFT JOIN profiles AS p ON (pm.pid = p.pid)
+ WHERE pm.pid IN {?} AND p.medals_pub IN {?}
+ ORDER BY ' . XDB::formatCustomOrder('pm.pid', $pids),
+ XDB::formatArray($pids),
+ XDB::formatArray($visibility)
+ );
+
+ return PlIteratorUtils::subIterator($data, PlIteratorUtils::arrayValueCallback('pid'));
+ }
+}
+// }}}
+// {{{ class ProfileNetworking [ Field ]
+class ProfileNetworking extends ProfileField
+{
+ private $networks = array();
+ private $visibilities = array();
+
+ private function __construct(PlIterator $it)
+ {
+ while ($network = $it->next()) {
+ $this->networks[$network['nwid']] = $network['address'];
+ $this->visibilities[$network['nwid']] = $network['pub'];
+ }
+ }
+
+ public static function fetchData(array $pids, $visibility)
+ {
+ $data = XDB::iterator('SELECT pid, nwid, address, pub
+ FROM profile_networking
+ WHERE pid IN {?} AND pub IN {?}
+ ORDER BY ' . XDB::formatCustomOrder('pid', $pids),
+ XDB::formatArray($pids),
+ XDB::formatArray($visibility)
+ );
+
+ return PlIteratorUtils::subIterator($data, PlIteratorUtils::arrayValueCallback('pid'));
+ }
+
+ public function networks()
+ {
+ $nws = array();
+ foreach ($this->visibilities as $id => $vis) {
+ if ($this->profile->isVisible($vis)) {
+ $nws[$id] = $this->networks[$id];
+ }
+ }
+ return $nws;
+ }
+}
+// }}}
+// {{{ class ProfilePhoto [ Field ]
+class ProfilePhoto extends ProfileField
+{
+ public $pic;
+
+ public function __construct(array $data)
+ {
+ if ($data == null || count($data) == 0) {
+ $this->pic = null;
+ } else {
+ $this->pid = $data['pid'];
+ $this->pic = PlImage::fromDATA($data['attach'],
+ $data['attachmime'],
+ $data['x'],
+ $data['y']);
+ }
+ }
+
+ public static function fetchData(array $pids, $visibility)
+ {
+ $data = XDB::iterator('SELECT *
+ FROM profile_photos
+ WHERE pid IN {?} AND attachmime IN (\'jpeg\', \'png\') AND pub IN {?}
+ ORDER BY ' . XDB::formatCustomOrder('pid', $pids),
+ $pids,
+ $visibility
+ );
+
+ return $data;
+ }
+}
+// }}}
+// {{{ class ProfileCorps [ Field ]
+class ProfileCorps extends ProfileField
+{
+ public $original;
+ public $current;
+ public $rank;
+
+ private function __construct(array $data)
+ {
+ $this->original = $data['original_corpsid'];
+ $this->current = $data['current_corpsid'];
+ $this->rank = $data['rankid'];
+ $this->visibility = $data['corps_pub'];
+ }
+
+ public static function fetchData(array $pids, $visibility)
+ {
+ $data = XDB::iterator('SELECT pid, original_corpsid, current_corpsid,
+ rankid
+ FROM profile_corps
+ WHERE pid IN {?} AND corps_pub IN {?}
+ ORDER BY ' . XDB::formatCustomOrder('pid', $pids),
+ XDB::formatArray($pids),
+ XDB::formatArray($visibility)
+ );
+
+ return $data;
+ }
+}
+// }}}
+
+/** Loading of data for a Profile :
+ * 1) load jobs, addresses, phones
+ * 2) attach phones to addresses, jobs and profiles
+ * 3) attach addresses to jobs and profiles
+ */
+
+// {{{ class ProfileAddresses [ Field ]
+class ProfileAddresses extends ProfileField
+{
+ private $addresses = array();
+
+ private function __construct(PlIterator $addrs)
+ {
+ while ($addr = $it->next()) {
+ $this->addresses[] = Address::buildFromData($addr);
+ }
+ }
+
+ public static function fetchData(array $pids, $visibility)
+ {
+ $data = XDB::iterator('SELECT text, postalCode, type, latitude, longitude,
+ flags, type
+ FROM profile_addresses
+ WHERE pid in {?} AND pub IN {?}
+ ORDER BY ' . XDB::formatCustomOrder('pid', $pids),
+ XDB::formatArray($pids),
+ XDB::formatArray($visibility)
+ );
+
+ return PlIteratorUtils::subIterator($data, PlIteratorUtils::arrayValueCallback('pid'));
+ }
+
+ public static function addPhones(array $addresses, $phones)
+ {
+ foreach ($phones as $phone) {
+ if ($phone->link_type == Phone::LINK_ADDRESS) {
+ $addresses[$phone->link_id]->addPhone($phone);
+ }
+ }
+ return $addresses;
+ }
+}
+// }}}
+// {{{ class ProfilePhones [ Field ]
+class ProfilePhones extends ProfileField
+{
+ private $phones = array();
+
+ private function __construct(PlIterator $phones)
+ {
+ while ($phone = $it->next()) {
+ $this->phones[] = Phone::buildFromData($phone);
+ }
+ }
+
+ public static function fetchData(array $pids, $visibility)
+ {
+ $data = XDB::iterator('SELECT type, search, display, link_type, comment
+ FROM profile_phones
+ WHERE pid IN {?} AND pub IN {?}
+ ORDER BY ' . XDB::formatCustomOrder('pid', $pids),
+ XDB::formatArray($pids),
+ XDB::formatArray($visibility)
+ );
+ return PlIteratorUtils::subIterator($data, PlIteratorUtils::arrayValueCallback('pid'));
+ }
+}
+// }}}
+// {{{ class ProfileJobs [ Field ]
+class ProfileJobs extends ProfileField
+{
+ private $jobs = array();
+
+ private function __construct(PlIterator $jobs)
+ {
+ while ($job = $jobs->next()) {
+ $this->jobs[] = Jobs::buildFromData($job);
+ }
+ }
+
+ public static function fetchData(array $pids, $visibility)
+ {
+ $data = XDB::iterator('SELECT description, url, jobid, IF(email_pub IN {?}, email, NULL) AS email
+ FROM profile_job
+ WHERE pid IN {?} AND pub IN {?}
+ ORDER BY ' . XDB::formatCustomOrder('pid', $pids),
+ XDB::formatArray($visibility),
+ XDB::formatArray($pids),
+ XDB::formatArray($visibility)
+ );
+ return PlIteratorUtils::subIterator($data, PlIteratorUtils::arrayValueCallback('pid'));
+ }
+
+ public static function addPhones(array $jobs, array $phones)
+ {
+ foreach ($phones as $phone)
+ {
+ if ($phone->link_type == Phone::LINK_JOB) {
+ $jobs[$phone->link_id]->addPhones($phone);
+ }
+ }
+ return $jobs;
+ }
+
+ public static function addAddresses(array $jobs, array $addresses)
+ {
+ foreach ($addresses as $address)
+ {
+ if ($address->link_type == Address::LINK_JOB) {
+ $jobs[$address->link_id]->setAddress($address);
+ }
+ }
+ return $jobs;
+ }
+
+ public static function addCompanies(array $jobs, array $companies)
+ {
+ foreach ($jobs as $job)
+ {
+ $job->setCompany($companies[$job->company_id]);
+ }
+ return $jobs;
+ }
+}
+// }}}
+
+// {{{ class CompanyList
+class CompanyList
+{
+ static private $fullload = false;
+ static private $companies = array();
+
+ static public function preload($pids = array())
+ {
+ if (self::$fullload) {
+ return;
+ }
+ // Load raw data
+ if (count($pids)) {
+ $join = 'LEFT JOIN profile_jobs ON (profile_job.jobid = profile_job_enum.id)';
+ $where = 'profile_jobs.pid IN ' . XDB::formatArray($pids);
+ } else {
+ $join = '';
+ $where = '';
+ }
+
+ $it = XDB::iterator('SELECT pje.id, pje.name, pje.acronmy, pje.url,
+ pa.flags, pa.text, pa.postcode, pa.country,
+ pa.link_type, pa.pub
+ FROM profile_job_enum AS pje
+ LEFT JOIN profile_addresses AS pa ON (pje.id = pa.jobid AND pa.type = \'hq\')
+ ' . $join . '
+ ' . $where);
+ while ($row = $it->next()) {
+ $cp = Company::buildFromData($row);
+ $addr = Address::buildFromData($row);
+ $cp->setAddress($addr);
+ self::$companies[$row['id']] = $cp;
+ }
+
+ // TODO: add phones to addresses
+ if (count($pids) == 0) {
+ self::$fullload = true;
+ }
+ }
+
+ static public function getCompany($id)
+ {
+ if (!array_key_exists($id, self::$companies)) {
+ self::preload();
+ }
+ return self::$companies[$id];
+ }
+}
+
+// vim:set et sw=4 sts=4 sws=4 foldmethod=marker enc=utf-8:
+?>