public $shortname;
private $data = array();
- private $members = null;
- private $admins = null;
-
private function __construct(array $data)
{
foreach ($data as $key=>$value) {
return property_exists($this, $name) || isset($this->data[$name]);
}
- public function getMemberUIDs()
- {
- if (is_null($this->members)) {
- $this->members = XDB::fetchColumn('SELECT uid
- FROM groupex.membres
- WHERE asso_id = {?}', $this->id);
- }
- return $this->members;
- }
-
- public function getMembers($sortby = null, $count = null, $offset = null)
- {
- return User::getBuildUsersWithUIDs($this->getMemberUIDs(), $sortby, $count, $offset);
- }
-
- public function getMemberCount()
- {
- return count($this->getMemberUIDs());
- }
-
- public function getAdminUIDs()
+ private function getUF($admin = false, $extra_cond = null, $sort = null)
{
- if (is_null($this->admins)) {
- $this->admins = XDB::fetchColumn('SELECT uid
- FROM groupex.membres
- WHERE asso_id = {?} AND perms = \'admin\'', $this->id);
+ $cond = new UFC_Group($this->id, $admin);
+ if (!is_null($extra_cond)) {
+ $cond = new UFC_And($cond, $extra_cond);
}
- return $this->admins;
+ return new UserFilter($cond, $sort);
}
- public function getAdmins($sortby = null, $count = null, $offset = null)
+ public function getMembers($extra_cond = null, $sort = null)
{
- return User::getBuildUsersWithUIDs($this->getAdminUIDs(), $sortby, $count, $offset);
+ return $this->getUF(false, $extra_cond, $sort);
}
- public function getAdminCount()
+ public function getAdmins($extra_cond = null, $sort = null)
{
- return count($this->getAdminUIDs());
+ return $this->getUF(true, $extra_cond, $sort);
}
static public function get($id)
throw new UserNotFoundException($res->fetchColumn(1));
}
- protected static function loadMainFieldsFromUIDs(array $uids, $sorted = null, $count = null, $offset = null)
+ protected static function loadMainFieldsFromUIDs(array $uids)
{
global $globals;
$joins = '';
- $orderby = '';
$fields = array();
- if (!is_null($sorted)) {
- $order = array();
- $with_ap = false;
- $with_pd = false;
- foreach (explode(',', $sorted) as $part) {
- $desc = ($part[0] == '-');
- if ($desc) {
- $part = substr($part, 1);
- }
- switch ($part) {
- case 'promo':
- $with_pd = true;
- $with_ap = true;
- $part = 'IF (pd.promo IS NULL, \'ext\', pd.promo)';
- break;
- case 'full_name':
- $part = 'a.full_name';
- break;
- case 'display_name':
- $part = 'a.display_name';
- break;
- case 'directory_name':
- $part = 'pd.directory_name';
- $with_pd = true;
- $with_ap = true;
- break;
- default:
- $part = null;
- }
- if (!is_null($part)) {
- if ($desc) {
- $part .= ' DESC';
- }
- $order[] = $part;
- }
- }
- if (count($order) > 0) {
- if ($with_ap) {
- $joins .= "LEFT JOIN account_profiles AS ap ON (ap.uid = a.uid AND FIND_IN_SET('owner', ap.perms))\n";
- }
- if ($with_pd) {
- $joins .= "LEFT JOIN profile_display AS pd ON (pd.pid = ap.pid)\n";
- }
- $orderby = 'ORDER BY ' . implode(', ', $order);
- }
- }
if ($globals->asso('id')) {
$joins .= XDB::format("LEFT JOIN groupex.membres AS gpm ON (gpm.uid = a.uid AND gpm.asso_id = {?})\n", $globals->asso('id'));
$fields[] = 'gpm.perms AS group_perms';
} else {
$fields = '';
}
- $limit = '';
- if (!is_null($count)) {
- if (!is_null($offset)) {
- $limit = ' LIMIT ' . $offset . ', ' . $count;
- } else {
- $limit = ' LIMIT ' . $count;
- }
- }
$uids = array_map(array('XDB', 'escape'), $uids);
return XDB::iterator('SELECT a.uid, a.hruid, a.registration_date,
CONCAT(af.alias, \'@' . $globals->mail->domain . '\') AS forlife,
INNER JOIN account_types AS at ON (at.type = a.type)
LEFT JOIN aliases AS af ON (af.id = a.uid AND af.type = \'a_vie\')
LEFT JOIN aliases AS ab ON (ab.id = a.uid AND FIND_IN_SET(\'bestalias\', ab.flags))
- ' . $joins . '
+ ' . $joins . '
WHERE a.uid IN (' . implode(', ', $uids) . ')
- ' . $orderby . $limit);
+ GROUP BY a.uid');
}
// Implementation of the data loader.
}
// Fetch a set of users from a list of UIDs
- public static function getBuildUsersWithUIDs(array $uids, $sortby = null, $count = null, $offset = null)
+ public static function getBulkUsersWithUIDs(array $uids)
{
- $fields = self::loadMainFieldsFromUIDs($uids, $sortby, $count, $offset);
- $users = array();
+ $fields = self::loadMainFieldsFromUIDs($uids);
+ $table = array();
while (($list = $fields->next())) {
- $users[] = User::getSilentWithValues(null, $list);
+ $table[$list['uid']] = User::getSilentWithValues(null, $list);
+ }
+ $users = array();
+ foreach ($uids as $uid) {
+ $users[] = $table[$uid];
}
return $users;
}
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA *
***************************************************************************/
+
+/******************
+ * CONDITIONS
+ ******************/
+
interface UserFilterCondition
{
const COND_TRUE = 'TRUE';
public function buildCondition(UserFilter &$uf)
{
- // XXX: Definition of promotion for phds and masters might change in near future.
- if ($this->grade == UserFilter::GRADE_ING) {
- $promo_year = 'entry_year';
- } else {
- $promo_year = 'grad_year';
- }
$sub = $uf->addEducationFilter(true, $this->grade);
- $field = 'pe' . $sub . '.' . $promo_year;
+ $field = 'pe' . $sub . '.' . UserFilter::promoYear($this->grade);
return $field . ' IS NOT NULL AND ' . $field . ' ' . $this->comparison . ' ' . XDB::format('{?}', $this->promo);
}
}
}
$cond = $left . $op . $right;
$conds = array($this->buildNameQuery($this->type, null, $cond, $uf));
- if (($this->mode & self::VARIANTS) != 0) {
+ if (($this->mode & self::VARIANTS) != 0 && isset(UserFilter::$name_variants[$this->type])) {
foreach (UserFilter::$name_variants[$this->type] as $var) {
$conds[] = $this->buildNameQuery($this->type, $var, $cond, $uf);
}
}
}
+
+
+/******************
+ * ORDERS
+ ******************/
+
+abstract class UserFilterOrder
+{
+ protected $desc = false;
+
+ public function buildSort(UserFilter &$uf)
+ {
+ $sel = $this->getSortTokens($uf);
+ if (!is_array($sel)) {
+ $sel = array($sel);
+ }
+ if ($this->desc) {
+ foreach ($sel as $k=>$s) {
+ $sel[$k] = $s . ' DESC';
+ }
+ }
+ return $sel;
+ }
+
+ abstract protected function getSortTokens(UserFilter &$uf);
+}
+
+class UFO_Promo extends UserFilterOrder
+{
+ private $grade;
+
+ public function __construct($grade = null, $desc = false)
+ {
+ $this->grade = $grade;
+ $this->desc = $desc;
+ }
+
+ protected function getSortTokens(UserFilter &$uf)
+ {
+ if (UserFilter::isGrade($this->grade)) {
+ $sub = $uf->addEducationFilter($this->grade);
+ return 'pe' . $sub . '.' . UserFilter::promoYear($this->grade);
+ } else {
+ $sub = $uf->addDisplayFilter();
+ return 'pd' . $sub . '.promo';
+ }
+ }
+}
+
+class UFO_Name extends UserFilterOrder
+{
+ private $type;
+ private $variant;
+ private $particle;
+
+ public function __construct($type, $variant = null, $particle = false, $desc = false)
+ {
+ $this->type = $type;
+ $this->variant = $variant;
+ $this->particle = $particle;
+ $this->desc = $desc;
+ }
+
+ protected function getSortTokens(UserFilter &$uf)
+ {
+ if (UserFilter::isDisplayName($this->type)) {
+ $sub = $uf->addDisplayFilter();
+ return 'pd' . $sub . '.' . $this->type;
+ } else {
+ $sub = $uf->addNameFilter($this->type, $this->variant);
+ if ($this->particle) {
+ return 'CONCAT(pn' . $sub . '.particle, \' \', pn' . $sub . '.name)';
+ } else {
+ return 'pn' . $sub . '.name';
+ }
+ }
+ }
+}
+
+/***********************************
+ *********************************
+ USER FILTER CLASS
+ *********************************
+ ***********************************/
+
class UserFilter
{
+ static private $joinMethods = array();
+
private $root;
private $sort = array();
private $query = null;
private $orderby = null;
+ private $lastcount = 0;
+
public function __construct($cond = null, $sort = null)
{
+ if (empty(self::$joinMethods)) {
+ $class = new ReflectionClass('UserFilter');
+ foreach ($class->getMethods() as $method) {
+ $name = $method->getName();
+ if (substr($name, -5) == 'Joins' && $name != 'buildJoins') {
+ self::$joinMethods[] = $name;
+ }
+ }
+ }
if (!is_null($cond)) {
if ($cond instanceof UserFilterCondition) {
$this->setCondition($cond);
if (!is_null($sort)) {
if ($sort instanceof UserFilterOrder) {
$this->addSort($sort);
+ } else if (is_array($sort)) {
+ foreach ($sort as $s) {
+ $this->addSort($s);
+ }
}
}
}
private function buildQuery()
{
+ if (is_null($this->orderby)) {
+ $orders = array();
+ foreach ($this->sort as $sort) {
+ $orders = array_merge($orders, $sort->buildSort($this));
+ }
+ if (count($orders) == 0) {
+ $this->orderby = '';
+ } else {
+ $this->orderby = 'ORDER BY ' . implode(', ', $orders);
+ }
+ }
if (is_null($this->query)) {
$where = $this->root->buildCondition($this);
$joins = $this->buildJoins();
' . $joins . '
WHERE (' . $where . ')';
}
- if (is_null($this->sortby)) {
- $this->sortby = '';
- }
}
private function formatJoin(array $joins)
private function buildJoins()
{
- $joins = $this->educationJoins() + $this->nameJoins() + $this->groupJoins();
+ $joins = array();
+ foreach (self::$joinMethods as $method) {
+ $joins = array_merge($joins, $this->$method());
+ }
return $this->formatJoin($joins);
}
+ private function getUIDList($uids = null, $count = null, $offset = null)
+ {
+ $this->buildQuery();
+ $limit = '';
+ if (!is_null($count)) {
+ if (!is_null($offset)) {
+ $limit = XDB::format('LIMIT {?}, {?}', $offset, $count);
+ } else {
+ $limit = XDB::format('LIMIT {?}', $count);
+ }
+ }
+ $cond = '';
+ if (!is_null($uids)) {
+ $cond = ' AND a.uid IN (' . implode(', ', $uids) . ')';
+ }
+ $fetched = XDB::fetchColumn('SELECT SQL_CALC_FOUND_ROWS a.uid
+ ' . $this->query . $cond . '
+ GROUP BY a.uid
+ ' . $this->orderby . '
+ ' . $limit);
+ $this->lastcount = (int)XDB::fetchOneCell('SELECT FOUND_ROWS()');
+ return $fetched;
+ }
+
/** Check that the user match the given rule.
*/
public function checkUser(PlUser &$user)
/** Filter a list of user to extract the users matching the rule.
*/
- public function filter(array $users)
+ public function filter(array $users, $count = null, $offset = null)
{
$this->buildQuery();
$table = array();
$uids[] = $user->id();
$table[$user->id()] = $user;
}
- $fetched = XDB::fetchColumn('SELECT a.uid
- ' . $this->query . ' AND a.uid IN (' . implode(', ', $uids) . ')
- GROUP BY a.uid');
+ $fetched = $this->getUIDList($uids, $count, $offset);
$output = array();
foreach ($fetched as $uid) {
$output[] = $table[$uid];
return $output;
}
- public function getUIDs()
+ public function getUIDs($count = null, $offset = null)
{
- $this->buildQuery();
- return XDB::fetchColumn('SELECT a.uid
- ' . $this->query . '
- GROUP BY a.uid');
+ return $this->getUIDList(null, $count, $offset);
+ }
+
+ public function getUsers($count = null, $offset = null)
+ {
+ return User::getBulkUsersWithUIDs($this->getUIDs($count, $offset));
}
- public function getUsers()
+ public function getTotalCount()
{
- return User::getBuildUsersWithUIDs($this->getUIDs());
+ return $this->lastcount;
}
public function setCondition(UserFilterCondition &$cond)
public function addSort(UserFilterOrder &$sort)
{
- $this->sort[] =& $sort;
- $this->sortby = null;
+ $this->sort[] = $sort;
+ $this->orderby = null;
}
static public function getLegacy($promo_min, $promo_max)
}
+ /** DISPLAY
+ */
+ private $pd = false;
+ public function addDisplayFilter()
+ {
+ $this->pd = true;
+ return '';
+ }
+
+ private function displayJoins()
+ {
+ if ($this->pd) {
+ return array('pd' => array('left', 'profile_display', '$ME.pid = $PID'));
+ } else {
+ return array();
+ }
+ }
+
/** NAMES
*/
+ /* name tokens */
const LASTNAME = 'lastname';
const FIRSTNAME = 'firstname';
const NICKNAME = 'nickname';
const PSEUDONYM = 'pseudonym';
const NAME = 'name';
+ /* name variants */
const VN_MARITAL = 'marital';
const VN_ORDINARY = 'ordinary';
const VN_OTHER = 'other';
const VN_INI = 'ini';
+ /* display names */
+ const DN_FULL = 'directory_name';
+ const DN_DISPLAY = 'yourself';
+ const DN_YOURSELF = 'yourself';
+ const DN_DIRECTORY = 'directory_name';
+ const DN_PRIVATE = 'private_name';
+ const DN_PUBLIC = 'public_name';
+ const DN_SHORT = 'short_name';
+ const DN_SORT = 'sort_name';
static public $name_variants = array(
self::LASTNAME => array(self::VN_MARITAL, self::VN_ORDINARY),
- self::FIRSTNAME => array(self::VN_ORDINARY, self::VN_INI, self::VN_OTHER),
- self::NICKNAME => array(), self::PSEUDONYM => array(),
- self::NAME => array());
+ self::FIRSTNAME => array(self::VN_ORDINARY, self::VN_INI, self::VN_OTHER)
+ );
static public function assertName($name)
{
}
}
+ static public function isDisplayName($name)
+ {
+ return $name == self::DN_FULL || $name == self::DN_DISPLAY
+ || $name == self::DN_YOURSELF || $name == self::DN_DIRECTORY
+ || $name == self::DN_PRIVATE || $name == self::DN_PUBLIC
+ || $name == self::DN_SHORT || $name == self::DN_SORT;
+ }
+
private $pn = array();
private $pno = 0;
public function addNameFilter($type, $variant = null)
}
}
+ static public function promoYear($grade)
+ {
+ // XXX: Definition of promotion for phds and masters might change in near future.
+ return ($grade == UserFilter::GRADE_ING) ? 'entry_year' : 'grad_year';
+ }
+
private $pepe = array();
private $with_pee = false;
private $pe_g = 0;
$ofs = 0;
}
+ $sdesc = $sort{0} == '-';
+ $sf = $sdesc ? substr($sort, 1) : $sort;
+ if ($sf == 'promo') {
+ $se = new UFO_Promo(null, $sdesc);
+ } else {
+ $se = new UFO_Name($sf, null, null, $sdesc);
+ }
+
if (Env::b('admin')) {
- $users = $globals->asso()->getAdmins($sort, NB_PER_PAGE, $ofs * NB_PER_PAGE);
- $count = $globals->asso()->getAdminCount();
+ $uf = $globals->asso()->getAdmins(null, $se);
} else {
- $users = $globals->asso()->getMembers($sort, NB_PER_PAGE, $ofs * NB_PER_PAGE);
- $count = $globals->asso()->getMemberCount();
+ $uf = $globals->asso()->getMembers(null, $se);
}
+ $users = $uf->getUsers(NB_PER_PAGE, $ofs * NB_PER_PAGE);
+ $count = $uf->getTotalCount();
+
$page->assign('pages', floor(($count + NB_PER_PAGE - 1) / NB_PER_PAGE));
$page->assign('current', $ofs);
$page->assign('order', $sort);
{
global $globals;
$vcard = new VCard($photos == 'photos', 'Membre du groupe ' . $globals->asso('nom'));
- $vcard->addUsers($globals->asso()->getMemberUIDs());
+ $vcard->addUsers($globals->asso()->getMembers()->getUIDs());
$vcard->show();
}
if (is_null($filename)) {
$filename = $globals->asso('diminutif') . '.csv';
}
- $users = $globals->asso()->getMembers('directory_name');
+ $users = $globals->asso()->getMembers(null, new UFO_Name('directory_name'))->getUsers();
header('Content-Type: text/x-csv; charset=utf-8;');
header('Pragma: ');
header('Cache-Control: ');
if ($globals->asso('notif_unsub')) {
$mailer = new PlMailer('xnetgrp/unsubscription-notif.mail.tpl');
- $uids = XDB::fetchColumn('SELECT uid
- FROM groupex.membres
- WHERE perms = \'admin\' AND asso_id = {?}',
- $globals->asso('id'));
- $users = User::getBuildUsersWithUIDs($uids);
- foreach ($users as $user) {
+ foreach ($globals->asso()->getMembers()->getUsers() as $user) {
$mailer->addTo($user);
}
$mailer->assign('group', $globals->asso('nom'));