function handler_issues_promo($page, $action = '') { $page->changeTpl('fusionax/promo_issues.tpl'); if ($action == 'edit') { S::assert_xsrf_token(); $issues = XDB::rawIterRow('SELECT p.pid, pd.directory_name, pd.promo, pm.entry_year_ax, pe.entry_year, pe.grad_year FROM profile_merge_issues AS pm INNER JOIN profiles AS p ON (pm.pid = p.pid) 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)) WHERE FIND_IN_SET(\'promo\', pm.issues) ORDER BY pd.directory_name'); while (list($pid, $name, $promo, $deathAX, $deathXorgEntry, $deathXorgGrad) = $issues->next()) { $choiceXorg = Post::has('XORG_' . $pid); if (!(Post::has('display_' . $pid) && Post::has('entry_' . $pid) && Post::has('grad_' . $pid))) { continue; } $display = Post::i('display_' . $pid); $entry = Post::i('entry_' . $pid); $grad = Post::i('grad_' . $pid); if (!($grad <= $entry + 5 && $grad >= $entry + 3 && ($display >= $entry && $display <= $grad - 3))) { $page->trigError("La promotion de {$name} n'a pas été corrigée."); continue; } XDB::execute('UPDATE profile_display SET promo = {?} WHERE pid = {?}', 'X' . $display, $pid); XDB::execute('UPDATE profile_education SET entry_year = {?}, grad_year = {?} WHERE pid = {?} AND FIND_IN_SET(\'primary\', flags)', $entry, $grad, $pid); $page->trigSuccess("La promotion de {$name} a bien été corrigée."); } } $issues = XDB::rawFetchAllAssoc('SELECT p.pid, p.hrpid, pd.directory_name, pd.promo, pm.entry_year_ax, pe.entry_year, pe.grad_year FROM profile_merge_issues AS pm INNER JOIN profiles AS p ON (pm.pid = p.pid) 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)) WHERE FIND_IN_SET(\'promo\', pm.issues) ORDER BY pd.directory_name'); $page->assign('issues', $issues); $page->assign('total', count($issues)); }
public function handler_admin_nl_sync($page) { global $globals; $nl = $this->getNl(); if (!$nl) { return PL_FORBIDDEN; } if (Env::has('add_users')) { S::assert_xsrf_token(); $nl->bulkSubscribe(array_keys(Env::v('add_users'))); $page->trigSuccess('Ajouts réalisés avec succès.'); } // TODO(x2006barrois): remove raw SQL query. $uids = XDB::fetchColumn('SELECT DISTINCT(g.uid) FROM group_members AS g WHERE g.asso_id = {?} AND NOT EXISTS (SELECT ni.* FROM newsletter_ins AS ni INNER JOIN newsletters AS n ON (ni.nlid = n.id) WHERE g.uid = ni.uid AND n.group_id = g.asso_id)', $globals->asso('id')); $users = User::getBulkUsersWithUIDs($uids); usort($users, 'User::compareDirectoryName'); $page->setTitle('Synchronisation de la newsletter'); $page->changeTpl('newsletter/sync.tpl'); $page->assign('users', $users); }
function handler_ajax_modify($page) { S::assert_xsrf_token(); if (!S::user()->hasRights(Group::from('qdj'), Rights::admin())) { return PL_FORBIDDEN; } $qdj = new QDJ(Json::i('id')); $page->jsonAssign('success', false); if (Json::has('date')) { $date = Json::t('date'); if (!$date) { $qdj->date(false); $page->jsonAssign('success', true); } else { try { $qdj->date(new FrankizDateTime($date)); $page->jsonAssign('success', true); } catch (Exception $e) { } } } else { if (Json::has('delete')) { if (Json::b('delete')) { $qdj->delete(); $page->jsonAssign('success', true); } } } return PL_JSON; }
function handler_ajax_todo_clear($page) { S::assert_xsrf_token(); XDB::execute('DELETE FROM todo WHERE uid = {?} AND checked = 1', S::user()->id()); if (XDB::affectedRows() != 1) { $page->jsonAssign('error', "Impossible de nettoyer la liste des tâches"); } return PL_JSON; }
function handler_remove($page, $id = null) { S::assert_xsrf_token(); $val = ValidateFilter::fromId($id, false); if ($val === false) { $page->trigError("This item doesn't exist"); return; } $val->select(ValidateSelect::validate()); if ($val->writer()->id() != S::user()->id()) { throw new Exception("Invalid crendentials"); } S::logger()->log('proposal/remove', array('type' => $val->type(), 'writer' => $val->writer()->id(), 'group' => $val->group()->id(), 'created' => $val->created()->toDb(), 'item' => $val->itemToDb())); $val->item()->sendmailcancel(S::user()); $val->clean(); pl_redirect(Env::v('url')); }
public function HandleAction($action) { switch ($action) { case 'suscribe': S::assert_xsrf_token(); $subs = array_keys(Post::v('sub_ml')); $res = XDB::iterRow("SELECT sub, domain\n FROM register_subs\n WHERE uid = {?} AND type = 'list'\n ORDER BY domain", S::i('uid')); while (list($sub, $domain) = $res->next()) { if (array_shift($subs) == "{$sub}@{$domain}") { MailingList::subscribeTo($sub, $domain); } } $this->UpdateOnYes(); pl_redirect('lists'); break; case 'dismiss': $this->UpdateOnDismiss(); break; case 'no': $this->UpdateOnNo(); break; } }
function handler_aaliases($page, $alias = null) { global $globals; require_once 'emails.inc.php'; $page->setTitle('Administration - Aliases'); if (Post::has('new_alias')) { pl_redirect('admin/aliases/' . Post::t('new_alias') . '@' . $globals->mail->domain); } // If no alias, list them all. if (is_null($alias)) { $page->changeTpl('lists/admin_aliases.tpl'); $page->assign('aliases', array_merge(iterate_list_alias($globals->mail->domain), iterate_list_alias($globals->mail->domain2))); return; } list($local_part, $domain) = explode('@', $alias); if (!($globals->mail->domain == $domain || $globals->mail->domain2 == $domain) || !preg_match("/^[a-zA-Z0-9\\-\\.]*\$/", $local_part)) { $page->trigErrorRedirect('Le nom de l\'alias est erroné.', $globals->asso('diminutif') . 'admin/aliases'); } // Now we can perform the action. if (Post::has('del_alias')) { S::assert_xsrf_token(); delete_list_alias($local_part, $domain); $page->trigSuccessRedirect($alias . ' supprimé.', 'admin/aliases'); } if (Post::has('add_member')) { S::assert_xsrf_token(); if (add_to_list_alias(Post::t('add_member'), $local_part, $domain)) { $page->trigSuccess('Ajout réussit.'); } else { $page->trigError('Ajout infructueux.'); } } if (Get::has('del_member')) { S::assert_xsrf_token(); if (delete_from_list_alias(Get::t('del_member'), $local_part, $domain)) { $page->trigSuccess('Suppression réussie.'); } else { $page->trigError('Suppression infructueuse.'); } } $page->changeTpl('lists/admin_edit_alias.tpl'); $page->assign('members', list_alias_members($local_part, $domain)); $page->assign('alias', $alias); }
function handler_password($page) { global $globals; if (Post::has('pwhash') && Post::t('pwhash')) { S::assert_xsrf_token(); S::set('password', $password = Post::t('pwhash')); XDB::execute('UPDATE accounts SET password = {?} WHERE uid={?}', $password, S::i('uid')); // If GoogleApps is enabled, and the user did choose to use synchronized passwords, // updates the Google Apps password as well. if ($globals->mailstorage->googleapps_domain) { require_once 'googleapps.inc.php'; $account = new GoogleAppsAccount(S::user()); if ($account->active() && $account->sync_password) { $account->set_password($password); } } S::logger()->log('passwd'); Platal::session()->setAccessCookie(true); $page->changeTpl('platal/password.success.tpl'); $page->run(); } $page->changeTpl('platal/password.tpl'); $page->setTitle('Mon mot de passe'); $page->assign('do_auth', 0); }
function handler_public($page, $hruid = null) { $page->changeTpl('marketing/public.tpl'); // Retrieves the user info, and checks the user is not yet registered. $user = User::getSilent($hruid); if (!$user || !$user->hasProfile()) { return PL_NOT_FOUND; } if ($user->state != 'pending') { $page->kill('Cet utilisateur est déjà inscrit'); } // Displays the page, and handles the eventual user actions. $page->assign('full_name', $user->fullName()); $page->assign('promo', $user->promo()); if (Post::has('valide')) { S::assert_xsrf_token(); $email = trim(Post::v('mail')); require_once 'emails.inc.php'; if (!isvalid_email_redirection($email, $user)) { $page->trigError('Email invalide !'); } else { // On cherche les marketings précédents sur cette adresse // email, en se restreignant au dernier mois if (Marketing::get($user->id(), $email, true)) { $page->assign('already', true); } else { $page->assign('ok', true); check_email($email, "Une adresse surveillée est proposée au marketing par " . S::user()->login()); $market = new Marketing($user->id(), $email, 'default', null, Post::v('origine'), S::v('uid'), Post::v('origine') == 'user' ? Post::v('personal_notes') : null); $market->add(); } } } else { global $globals; require_once 'marketing.inc.php'; $sender = User::getSilent(S::v('uid')); $perso_signature = 'Cordialement,<br />-- <br />' . $sender->fullName(); $market = new AnnuaireMarketing(null, true); $text = $market->getText(array('sexe' => $user->isFemale(), 'forlife_email' => $user->hruid . "@" . $user->mainEmailDomain(), 'forlife_email2' => $user->hruid . "@" . $user->alternateEmailDomain())); $text = str_replace('%%hash%%', '', $text); $text = str_replace('%%personal_notes%%', '<em id="personal_notes_display"></em>', $text); $text = str_replace('%%sender%%', '<span id="sender">' . $perso_signature . '</span>', $text); $page->assign('text', nl2br($text)); $page->assign('perso_signature', $perso_signature); $page->assign('mail_part', 'escaped_html'); } }
function handler_edit($page) { global $globals; $user = S::user(); if (empty($user)) { return PL_NOT_FOUND; } if ($user->type != 'xnet') { pl_redirect('index'); } $page->changeTpl('xnet/edit.tpl'); if (Post::has('change')) { S::assert_xsrf_token(); // Convert user status to X if (!Post::blank('login_X')) { $forlife = $this->changeLogin($page, $user, Post::t('login_X')); if ($forlife) { pl_redirect('index'); } } require_once 'emails.inc.php'; require_once 'name.func.inc.php'; // Update user info $lastname = capitalize_name(Post::t('lastname')); $firstname = capitalize_name(Post::t('firstname')); $full_name = build_full_name($firstname, $lastname); $directory_name = build_directory_name($firstname, $lastname); $sort_name = build_sort_name($firstname, $lastname); XDB::query('UPDATE accounts SET full_name = {?}, directory_name = {?}, sort_name = {?}, display_name = {?}, firstname = {?}, lastname = {?}, sex = {?} WHERE uid = {?}', $full_name, $directory_name, $sort_name, Post::t('display_name'), Post::t('firstname'), Post::t('lastname'), Post::t('sex') == 'male' ? 'male' : 'female', $user->id()); // Updates email. $new_email = strtolower(Post::t('email')); if (require_email_update($user, $new_email)) { XDB::query('UPDATE accounts SET email = {?} WHERE uid = {?}', $new_email, $user->id()); $listClient = new MMList(S::user()); $listClient->change_user_email($user->forlifeEmail(), $new_email); update_alias_user($user->forlifeEmail(), $new_email); } $user = User::getWithUID($user->id()); S::set('user', $user); $page->trigSuccess('Données mises à jour.'); } $page->addJsLink('password.js'); $page->assign('user', $user); }
function handler_acreate($page) { if (!$this->get_lists_domain()) { return PL_NOT_FOUND; } $page->changeTpl('xnetlists/alias-create.tpl'); if (!Post::has('submit')) { return; } else { S::assert_xsrf_token(); } if (!Post::has('liste')) { $page->trigError('Le champs « adresse souhaitée » est vide.'); return; } $list = Post::v('liste'); if (!preg_match("/^[a-zA-Z0-9\\-\\.]*\$/", $list)) { $page->trigError('Le nom de l\'alias ne doit contenir que des lettres,' . ' chiffres, tirets et points.'); return; } require_once 'emails.inc.php'; $lists_domain = $this->get_lists_domain(); if (list_exist($list, $lists_domain)) { $page->trigError('Cet alias est déjà pris.'); return; } add_to_list_alias(S::i('uid'), $list, $lists_domain); pl_redirect('alias/admin/' . $list . '@' . $lists_domain); }
function handler_admin_user($page, $user = null) { require_once 'emails.inc.php'; require_once 'googleapps.inc.php'; $page->changeTpl('googleapps/admin.user.tpl'); $page->setTitle('Administration Google Apps'); $page->assign('googleapps_admin', GoogleAppsAccount::is_administrator(S::v('uid'))); if (!$user && Post::has('login')) { $user = Post::v('login'); } $user = User::get($user); if ($user) { $account = new GoogleAppsAccount($user); // Apply requested actions. if (Post::has('suspend') && $account->active() && !$account->pending_update_suspension) { S::assert_xsrf_token(); $account->suspend(); $page->trigSuccess('Le compte est en cours de suspension.'); } else { if (Post::has('unsuspend') && $account->suspended() && !$account->pending_update_suspension) { S::assert_xsrf_token(); $account->do_unsuspend(); $page->trigSuccess('Le compte est en cours de réactivation.'); } else { if (Post::has('forcesync') && $account->active() && $account->sync_password) { $account->set_password($user->password()); $page->trigSuccess('Le mot de passe est en cours de synchronisation.'); } else { if (Post::has('sync') && $account->active()) { $account->set_password($user->password()); $account->set_password_sync(true); } else { if (Post::has('nosync') && $account->active()) { $account->set_password_sync(false); } } } } } // Displays basic account information. $page->assign('account', $account); $page->assign('admin_account', GoogleAppsAccount::is_administrator($user->id())); $page->assign('googleapps_storage', Email::is_active_storage($user, 'googleapps')); $page->assign('user', $user->id()); // Retrieves user's pending requests. $res = XDB::iterator("SELECT q_id, q_recipient_id, p_status, j_type, UNIX_TIMESTAMP(p_entry_date) AS p_entry_date\n FROM gapps_queue\n WHERE q_recipient_id = {?}\n ORDER BY p_entry_date DESC", $user->id()); $page->assign('requests', $res); } }
function handler_trust($page) { $this->load('openid.inc.php'); $server = new OpenId(); $user = S::user(); // Initializes the OpenId environment from the request. if (!$server->Initialize() || !$server->IsAuthorizationRequest()) { $page->kill("Ta requête OpenID a échoué, merci de réessayer."); } // Prepares the SREG data, if any is required. $sreg_response = $server->GetSRegDataForRequest($user); // Asks the user about her trust level of the current request, if not // done yet. if (!Post::has('trust_accept') && !Post::has('trust_cancel')) { $page->changeTpl('openid/trust.tpl'); $page->assign('openid_query', $server->GetQueryStringForRequest()); $page->assign('relying_party', $server->GetEndpoint()); $page->assign('sreg_data', $sreg_response->contents()); return; } // Interprets the form results, and updates the user whitelist. S::assert_xsrf_token(); $trusted = $server->UpdateEndpointTrust($user, Post::b('trust_accept') && !Post::b('trust_cancel'), Post::b('trust_always')); // Finally answers the request. if ($server->IsUserAuthorized($user) && $trusted) { $server->AnswerRequest(true, Post::b('trust_sreg') ? $sreg_response : null); } else { $server->AnswerRequest(false); } }
function handler_admin($page, $eid = null, $item_id = null) { global $globals; $this->load('xnetevents.inc.php'); $evt = get_event_detail($eid, $item_id); if (!$evt) { return PL_NOT_FOUND; } $page->changeTpl('xnetevents/admin.tpl'); if (!$evt['show_participants'] && !may_update()) { return PL_FORBIDDEN; } if (may_update() && Post::v('adm')) { S::assert_xsrf_token(); $member = User::getSilent(Post::v('mail')); if (!$member) { $page->trigError("Membre introuvable"); } // change the price paid by a participant if (Env::v('adm') == 'prix' && $member) { $amount = strtr(Env::v('montant'), ',', '.'); XDB::execute("UPDATE group_event_participants\n SET paid = paid + {?}\n WHERE uid = {?} AND eid = {?} AND nb > 0\n ORDER BY item_id ASC\n LIMIT 1", $amount, $member->uid, $evt['eid']); subscribe_lists_event($member->uid, $evt['short_name'], 1, $amount); } // change the number of personns coming with a participant if (Env::v('adm') == 'nbs' && $member) { $res = XDB::query("SELECT SUM(paid)\n FROM group_event_participants\n WHERE uid = {?} AND eid = {?}", $member->uid, $evt['eid']); $paid = $res->fetchOneCell(); // Ensure we have an integer if ($paid == null) { $paid = 0; } $nbs = Post::v('nb', array()); $paid_inserted = false; foreach ($nbs as $id => $nb) { $nb = max(intval($nb), 0); if (!$paid_inserted && $nb > 0) { $item_paid = $paid; $paid_inserted = true; } else { $item_paid = 0; } XDB::execute('INSERT INTO group_event_participants (eid, uid, item_id, nb, flags, paid) VALUES ({?}, {?}, {?}, {?}, {?}, {?}) ON DUPLICATE KEY UPDATE nb = VALUES(nb), flags = VALUES(flags), paid = VALUES(paid)', $evt['eid'], $member->uid, $id, $nb, '', $item_paid); } $res = XDB::query('SELECT COUNT(uid) AS cnt, SUM(nb) AS nb FROM group_event_participants WHERE uid = {?} AND eid = {?} GROUP BY uid', $member->uid, $evt['eid']); $u = $res->fetchOneAssoc(); if ($paid == 0 && Post::v('cancel')) { XDB::execute("DELETE FROM group_event_participants\n WHERE uid = {?} AND eid = {?}", $member->uid, $evt['eid']); $u = 0; subscribe_lists_event($member->uid, $evt['short_name'], -1, $paid); } else { $u = $u['cnt'] ? $u['nb'] : null; subscribe_lists_event($member->uid, $evt['short_name'], $u > 0 ? 1 : 0, $paid); } } $evt = get_event_detail($eid, $item_id); } $page->assign_by_ref('evt', $evt); $page->assign('tout', is_null($item_id)); if (count($evt['moments'])) { $page->assign('moments', $evt['moments']); } if ($evt['paiement_id']) { $infos = User::getBulkUsersWithUIDs(XDB::fetchAllAssoc('SELECT t.uid, t.amount FROM payment_transactions AS t LEFT JOIN group_event_participants AS ep ON(ep.uid = t.uid AND ep.eid = {?}) WHERE t.status = "confirmed" AND t.ref = {?} AND ep.uid IS NULL', $evt['eid'], $evt['paiement_id']), 'uid', 'user'); $page->assign('oublis', count($infos)); $page->assign('oubliinscription', $infos); } $absents = User::getBulkUsersFromDB('SELECT p.uid FROM group_event_participants AS p LEFT JOIN group_event_participants AS p2 ON (p2.uid = p.uid AND p2.eid = p.eid AND p2.nb != 0) WHERE p.eid = {?} AND p2.eid IS NULL GROUP BY p.uid', $evt['eid']); $ofs = Env::i('offset'); $part = get_event_participants($evt, $item_id, UserFilter::sortByName(), NB_PER_PAGE, $ofs * NB_PER_PAGE); $nbp = ceil($evt['user_count'] / NB_PER_PAGE); if ($nbp > 1) { $links = array(); if ($ofs) { $links['précédent'] = $ofs - 1; } for ($i = 1; $i <= $nbp; $i++) { $links[(string) $i] = $i - 1; } if ($ofs < $nbp - 1) { $links['suivant'] = $ofs + 1; } $page->assign('links', $links); } $page->assign('absents', $absents); $page->assign('participants', $part); }
function handler_phd($page, $promo = null, $validate = false) { $page->changeTpl('admin/phd.tpl'); $eduDegrees = DirEnum::getOptions(DirEnum::EDUDEGREES); $eduDegrees = array_flip($eduDegrees); // get the list of the years when phd students are supposed to finish but have not yet been flagged as completed $promo_list = XDB::fetchColumn('SELECT DISTINCT(grad_year) FROM profile_education WHERE FIND_IN_SET(\'primary\', flags) AND NOT FIND_IN_SET(\'completed\', flags) AND degreeid = {?} ORDER BY grad_year', $eduDegrees[Profile::DEGREE_D]); // case when no promo was selected that is the admin/phd page if (is_null($promo)) { $page->assign('promo_list', $promo_list); $page->assign('nothing', count($promo_list) == 0); return; } // case when we want to add a list and we have data, that is admin/phd/bulk/validate if ($promo == "bulk" && Post::has('people')) { S::assert_xsrf_token(); $lines = explode("\n", Post::t('people')); $separator = Env::t('separator'); foreach ($lines as $line) { $infos = explode($separator, $line); if (sizeof($infos) !== 2) { $page->trigError("La ligne {$line} n'a pas été ajoutée : mauvais nombre de champs."); continue; } $infos = array_map('trim', $infos); // $info[0] is prenom.nom or hrid. We first try the hrid case, then we try over the possible promos. // We trigger an error if the search was unsuccessful. $user = User::getSilent($infos[0]); if (is_null($user)) { foreach ($promo_list as $promo_possible) { $user = User::getSilent($infos[0] . '.d' . $promo_possible); if (!is_null($user)) { break; } } if (is_null($user)) { $page->trigError("La ligne {$line} n'a pas été ajoutée : aucun compte trouvé."); continue; } } if ($user->type !== 'phd') { $page->trigError("La ligne {$line} n'a pas été ajoutée : le compte n'est pas celui d'un doctorant."); continue; } $grad_year = $infos[1]; if (!$grad_year) { $page->trigError("La ligne {$line} n'a pas été ajoutée : année de soutenance vide."); continue; } $profile = $user->profile(); // We have the pid, we now need the id that completes the PK in profile_education. $res = XDB::fetchOneCell('SELECT pe.id FROM profile_education AS pe WHERE FIND_IN_SET(\'primary\', pe.flags) AND NOT FIND_IN_SET(\'completed\', pe.flags) AND pe.pid = {?}', $profile->id()); if (!$res) { $page->trigError("Le profil " . $profile->hrid() . " a déjà une année de soutenance indiquée."); continue; } // When we are here, we have the pid, id for profile_education table, and $grad_year. Time to UPDATE ! XDB::execute('UPDATE profile_education SET flags = CONCAT(flags, \',completed\'), grad_year = {?} WHERE pid = {?} AND id = {?}', $grad_year, $profile->id(), $res); XDB::execute('UPDATE profile_display SET promo = {?} WHERE pid = {?}', 'D' . $grad_year, $profile->id()); $page->trigSuccess("Promotion de " . $profile->fullName() . " validée."); } $errors = $page->nb_errs(); if ($errors == 0) { $page->trigSuccess("L'opération a été effectuée avec succès."); } else { $page->trigSuccess('L\'opération a été effectuée avec succès, sauf pour ' . ($errors == 1 ? 'l\'erreur signalée' : "les {$errors} erreurs signalées") . ' ci-dessus.'); } } elseif ($validate) { S::assert_xsrf_token(); $list = XDB::iterator('SELECT pe.pid, pd.directory_name FROM profile_education AS pe INNER JOIN profile_display AS pd ON (pe.pid = pd.pid) WHERE FIND_IN_SET(\'primary\', pe.flags) AND NOT FIND_IN_SET(\'completed\', pe.flags) AND pe.degreeid = {?} AND pe.grad_year = {?}', $eduDegrees[Profile::DEGREE_D], $promo); while ($res = $list->next()) { $pid = $res['pid']; $name = $res['directory_name']; if (Post::b('completed_' . $pid)) { $grad_year = Post::t('grad_year_' . $pid); XDB::execute('UPDATE profile_education SET flags = CONCAT(flags, \',completed\'), grad_year = {?} WHERE FIND_IN_SET(\'primary\', flags) AND pid = {?}', $grad_year, $pid); XDB::execute('UPDATE profile_display SET promo = {?} WHERE pid = {?}', 'D' . $grad_year, $pid); $page->trigSuccess("Promotion de {$name} validée."); } } } // case we are on a graduation year page, e.g. admin/phd/2007 or admin/phd/2007/validate $list = XDB::iterator('SELECT pe.pid, pd.directory_name FROM profile_education AS pe INNER JOIN profile_display AS pd ON (pe.pid = pd.pid) WHERE FIND_IN_SET(\'primary\', pe.flags) AND NOT FIND_IN_SET(\'completed\', pe.flags) AND pe.degreeid = {?} AND pe.grad_year = {?} ORDER BY pd.directory_name', $eduDegrees[Profile::DEGREE_D], $promo); $page->assign('list', $list); $page->assign('promo', $promo); }
protected function action_updateProfile() { global $globals; $page =& Platal::page(); $colors = glob(dirname(__FILE__) . '/../../htdocs/images/banana/m2*.gif'); foreach ($colors as $key => $path) { $path = basename($path, '.gif'); $colors[$key] = substr($path, 2); } $page->assign('colors', $colors); if (Post::has('action') && Post::v('action') == 'Enregistrer') { S::assert_xsrf_token(); $flags = new PlFlagSet(); if (Post::b('bananadisplay')) { $flags->addFlag('threads'); } if (Post::b('bananaupdate')) { $flags->addFlag('automaj'); } if (Post::b('bananaxface')) { $flags->addFlag('xface'); } $unread = Post::s('unread'); $read = Post::s('read'); if (!in_array($unread, $colors) || !in_array($read, $colors)) { $page->trigError('Le choix de type pour l\'arborescence est invalide'); } else { $last_seen = XDB::query('SELECT last_seen FROM forum_profiles WHERE uid = {?}', $this->user->id()); if ($last_seen->numRows() > 0) { $last_seen = $last_seen->fetchOneCell(); } else { $last_seen = '0000-00-00'; } XDB::execute('INSERT INTO forum_profiles (uid, sig, mail, name, flags, tree_unread, tree_read, last_seen) VALUES ({?}, {?}, {?}, {?}, {?}, {?}, {?}, {?}) ON DUPLICATE KEY UPDATE sig = VALUES(sig), mail = VALUES(mail), name = VALUES(name), flags = VALUES(flags), tree_unread = VALUES(tree_unread), tree_read = VALUES(tree_read), last_seen = VALUES(last_seen)', $this->user->id(), Post::v('bananasig'), Post::v('bananamail'), Post::v('banananame'), $flags, $unread, $read, $last_seen); $page->trigSuccess('Ton profil a été mis à jour'); } } $infos = $this->fetchProfile(); $page->assign('nom', $infos['name']); $page->assign('mail', $infos['mail']); $page->assign('sig', $infos['sig']); $page->assign('disp', $infos['threads']); $page->assign('maj', $infos['maj']); $page->assign('xface', $infos['xface']); $page->assign('unread', $infos['tree_unread']); $page->assign('read', $infos['tree_read']); return null; }
function handler_nl_search($page) { S::assert_xsrf_token(); $nl = $this->getNl(); if (!$nl) { return PL_NOT_FOUND; } if (!Post::has('nl_search')) { pl_redirect($nl->prefix(true, false)); } $nl_search = Post::t('nl_search'); $nl_search_type = Post::t('nl_search_type'); if (!$nl_search || !($nl_search_type > 0 && $nl_search_type < 10)) { $page->trigErrorRedirect('La recherche est vide ou erronée.', $nl->prefix()); } $page->changeTpl('newsletter/search.tpl'); $user = S::user(); $fields = array(1 => 'all', 2 => 'all', 3 => 'title', 4 => 'body', 5 => 'append', 6 => 'all', 7 => 'title', 8 => 'head', 9 => 'signature'); $res_articles = $res_issues = array(); if ($nl_search_type < 6) { $res_articles = $nl->articleSearch($nl_search, $fields[$nl_search_type], $user); } if ($nl_search_type > 5 || $nl_search_type == 1) { $res_issues = $nl->issueSearch($nl_search, $fields[$nl_search_type], $user); } $articles_count = count($res_articles); $issues_count = count($res_issues); $results_count = $articles_count + $issues_count; if ($results_count > 200) { $page->trigError('Recherche trop générale.'); } elseif ($results_count == 0) { $page->trigWarning('Aucun résultat pour cette recherche.'); } else { $page->assign('res_articles', $res_articles); $page->assign('res_issues', $res_issues); $page->assign('articles_count', $articles_count); $page->assign('issues_count', $issues_count); } $page->assign_by_ref('nl', $nl); $page->assign('nl_search', $nl_search); $page->assign('nl_search_type', $nl_search_type); $page->assign('results_count', $results_count); }
function handler_admin($page, $nid = false) { $news = News::fromId($nid); if ($news !== false) { $news->select(NewsSelect::news()); if (S::user()->hasRights($news->target()->group(), Rights::admin()) || S::user()->isWeb()) { if (Env::has('modify') || Env::has('delete')) { S::assert_xsrf_token(); } if (Env::has('modify')) { $news->title(Env::t('title')); $news->content(Env::t('news_content')); $news->begin(new FrankizDateTime(Env::t('begin'))); $news->end(new FrankizDateTime(Env::t('end'))); if (Env::has('reappear')) { $news->removeReadFlags(); } if (Env::has('image')) { $image = new ImageFilter(new PFC_And(new IFC_Id(Env::i('image')), new IFC_Temp())); $image = $image->get(true); if (!$image) { throw new Exception("This image doesn't exist anymore"); } $image->select(FrankizImageSelect::caste()); $image->label($news->title()); $image->caste($news->target()); $news->image($image); } $page->assign('msg', "L'annonce a été modifiée."); } if (Env::has('delete')) { $news->delete(); $page->assign('delete', true); } } } $page->assign('news', $news); $page->assign('isEdition', true); $page->assign('title', "Modifier l'annonce"); $page->addCssLink('validate.css'); $page->changeTpl('news/admin.tpl'); }
function handler_admin_events($page, $action = 'list', $eid = null) { $page->changeTpl('events/admin.tpl'); $page->setTitle('Administration - Evenements'); $page->register_modifier('hde', 'html_entity_decode'); $arch = $action == 'archives'; $page->assign('action', $action); $upload = new PlUpload(S::user()->login(), 'event'); if ((Env::has('preview') || Post::v('action') == "Proposer") && $eid) { $action = 'edit'; $this->upload_image($page, $upload); } if (Post::v('action') == 'Pas d\'image' && $eid) { S::assert_xsrf_token(); $upload->rm(); XDB::execute("DELETE FROM announce_photos WHERE eid = {?}", $eid); $action = 'edit'; } elseif (Post::v('action') == 'Supprimer l\'image' && $eid) { S::assert_xsrf_token(); $upload->rm(); $action = 'edit'; } elseif (Post::v('action') == "Proposer" && $eid) { S::assert_xsrf_token(); $promo_min = Post::i('promo_min'); $promo_max = Post::i('promo_max'); if ($promo_min != 0 && ($promo_min <= 1900 || $promo_min >= 2020) || $promo_max != 0 && ($promo_max <= 1900 || $promo_max >= 2020 || $promo_max < $promo_min)) { $page->trigError("L'intervalle de promotions {$promo_min} -> {$promo_max} n'est pas valide"); $action = 'edit'; } else { $res = XDB::query('SELECT flags FROM announces WHERE id = {?}', $eid); $flags = new PlFlagSet($res->fetchOneCell()); $flags->addFlag('wiki'); if (Post::v('important')) { $flags->addFlag('important'); } else { $flags->rmFlag('important'); } XDB::execute('UPDATE announces SET creation_date = creation_date, titre={?}, texte={?}, expiration={?}, promo_min={?}, promo_max={?}, flags = {?} WHERE id = {?}', Post::v('titre'), Post::v('texte'), Post::v('expiration'), Post::v('promo_min'), Post::v('promo_max'), $flags, $eid); if ($upload->exists() && (list($x, $y, $type) = $upload->imageInfo())) { XDB::execute('INSERT INTO announce_photos (eid, attachmime, attach, x, y) VALUES ({?}, {?}, {?}, {?}, {?}) ON DUPLICATE KEY UPDATE attachmime = VALUES(attachmime), attach = VALUES(attach), x = VALUES(x), y = VALUES(y)', $eid, $type, $upload->getContents(), $x, $y); $upload->rm(); } } } if ($action == 'edit') { $res = XDB::query('SELECT titre, texte, expiration, promo_min, promo_max, FIND_IN_SET(\'important\', flags), attach IS NOT NULL FROM announces AS e LEFT JOIN announce_photos AS p ON(e.id = p.eid) WHERE id={?}', $eid); list($titre, $texte, $expiration, $promo_min, $promo_max, $important, $img) = $res->fetchOneRow(); $page->assign('titre', $titre); $page->assign('texte', $texte); $page->assign('promo_min', $promo_min); $page->assign('promo_max', $promo_max); $page->assign('expiration', $expiration); $page->assign('important', $important); $page->assign('eid', $eid); $page->assign('img', $img); $page->assign_by_ref('upload', $upload); $select = ""; for ($i = 1; $i < 30; $i++) { $p_stamp = date("Ymd", time() + 3600 * 24 * $i); $year = substr($p_stamp, 0, 4); $month = substr($p_stamp, 4, 2); $day = substr($p_stamp, 6, 2); $select .= "<option value=\"{$p_stamp}\"" . ($p_stamp == strtr($expiration, array("-" => "")) ? " selected" : "") . "> {$day} / {$month} / {$year}</option>\n"; } $page->assign('select', $select); } else { switch ($action) { case 'delete': S::assert_xsrf_token(); XDB::execute('DELETE from announces WHERE id = {?}', $eid); break; case "archive": S::assert_xsrf_token(); XDB::execute('UPDATE announces SET creation_date = creation_date, flags = CONCAT(flags,",archive") WHERE id = {?}', $eid); break; case "unarchive": S::assert_xsrf_token(); XDB::execute('UPDATE announces SET creation_date = creation_date, flags = REPLACE(flags,"archive","") WHERE id = {?}', $eid); $action = 'archives'; $arch = true; break; case "valid": S::assert_xsrf_token(); XDB::execute('UPDATE announces SET creation_date = creation_date, flags = CONCAT(flags,",valide") WHERE id = {?}', $eid); break; case "unvalid": S::assert_xsrf_token(); XDB::execute('UPDATE announces SET creation_date = creation_date, flags = REPLACE(flags,"valide", "") WHERE id = {?}', $eid); break; } $pid = $eid && $action == 'preview' ? $eid : -1; $sql = "SELECT e.id, e.titre, e.texte,e.id = {$pid} AS preview, e.uid,\n DATE_FORMAT(e.creation_date,'%d/%m/%Y %T') AS creation_date,\n DATE_FORMAT(e.expiration,'%d/%m/%Y') AS expiration,\n e.promo_min, e.promo_max,\n FIND_IN_SET('valide', e.flags) AS fvalide,\n FIND_IN_SET('archive', e.flags) AS farch,\n FIND_IN_SET('wiki', e.flags) AS wiki\n FROM announces AS e\n WHERE " . ($arch ? "" : "!") . "FIND_IN_SET('archive',e.flags)\n ORDER BY FIND_IN_SET('valide',e.flags), e.expiration DESC"; $page->assign('evs', XDB::iterator($sql)); } $page->assign('arch', $arch); $page->assign('admin_evts', true); }
function handler_ajax_comment($page) { S::assert_xsrf_token(); $g = Group::fromId(Json::i('gid')); if ($g) { $user = Json::has('uid') ? new User(Json::i('uid')) : S::user(); if ($user->isMe(S::user()) || S::user()->hasRights($g, Rights::admin()) || S::user()->isWeb()) { $comments = Json::t('comments'); $user->comments($g, $comments); $page->jsonAssign('uid', $user->id()); } } else { $page->jsonAssign('error', "Ce groupe n'existe pas"); } return PL_JSON; }
function handler_admin_announce($page) { global $globals; $page->changeTpl('xnetgrp/announce-admin.tpl'); if (Env::has('del')) { S::assert_xsrf_token(); XDB::execute('DELETE FROM group_announces WHERE id = {?} AND asso_id = {?}', Env::i('del'), $globals->asso('id')); } $res = XDB::iterator('SELECT id, titre, expiration, expiration < CURRENT_DATE() AS perime FROM group_announces WHERE asso_id = {?} ORDER BY expiration DESC', $globals->asso('id')); $page->assign('articles', $res); }
function handler_adm_transfers($page, $action = null, $id = null) { // list/log all bank transfers and link them to individual transactions if (Post::has('generate')) { $recon_ids = array_keys(Post::v('recon_id')); // generate a new reconcilation group ID $res = XDB::query("SELECT MAX(recongroup_id)+1 FROM payment_reconcilations"); $recongp_id = $res->fetchOneCell(); if ($recongp_id == null) { $recongp_id = 1; } // add reconcilations to group // FIXME: should check if reconcilations are in good status XDB::execute("UPDATE payment_reconcilations\n SET recongroup_id = {?}, status = 'closed'\n WHERE id IN {?}", $recongp_id, $recon_ids); // create transfers XDB::execute('INSERT INTO payment_transfers SELECT NULL, {?}, t.ref, SUM(t.amount+t.commission), NULL, p.text, NULL FROM payment_transactions AS t LEFT JOIN payments AS p ON (t.ref = p.id) LEFT JOIN groups AS g ON (p.asso_id = g.id) WHERE t.recon_id IN {?} AND t.status = "confirmed" GROUP BY t.ref', $recongp_id, $recon_ids); //$res = XDB::query("SELECT * FROM payment_reconcilations WHERE id IN {?}", $recon_ids); //$recons = $res->fetchAllAssoc(); $page->trigSuccess('Les virements ont été générés pour ' . count($recon_ids) . ' réconciliations.'); $this->handler_adm_reconcile($page); } elseif ($action == 'delgroup') { S::assert_xsrf_token(); XDB::execute("UPDATE payment_reconcilations\n SET status = 'transfering', recongroup_id = NULL\n WHERE recongroup_id = {?}", $id); XDB::execute("DELETE FROM payment_transfers\n WHERE recongroup_id = {?} AND date IS NULL", $id); $page->trigSuccess("Les virements non réalisés ont été supprimé du groupe " . $id . "."); $this->handler_adm_reconcile($page); } elseif ($action == "confirm") { S::assert_xsrf_token(); $account_id = XDB::fetchOneCell('SELECT rib_id FROM payments AS p LEFT JOIN payment_transfers AS t ON (t.payment_id = p.id) WHERE t.id = {?}', $id); XDB::execute('UPDATE payment_transfers SET date = NOW(), account_id = {?} WHERE id = {?}', $account_id, $id); $page->trigSuccess('Virement ' . $id . ' confirmé.'); $this->handler_adm_reconcile($page); } else { pl_redirect('admin/reconcile'); } }
function handler_batch($page) { $page->changeTpl('carnet/batch.tpl'); $errors = false; $incomplete = array(); if (Post::has('add')) { S::assert_xsrf_token(); require_once 'userset.inc.php'; require_once 'emails.inc.php'; require_once 'marketing.inc.php'; $list = explode("\n", Post::v('list')); $origin = Post::v('origin'); foreach ($list as $item) { if ($item = trim($item)) { $elements = preg_split("/\\s/", $item); $email = array_pop($elements); if (!isvalid_email($email)) { $page->trigError('Email invalide : ' . $email); $incomplete[] = $item; $errors = true; continue; } $user = User::getSilent($email); if (is_null($user)) { $details = implode(' ', $elements); $promo = trim(array_pop($elements)); $cond = new PFC_And(); if (preg_match('/^[MDX]\\d{4}$/', $promo)) { $cond->addChild(new UFC_Promo('=', UserFilter::DISPLAY, $promo)); } else { $cond->addChild(new UFC_NameTokens($promo)); } foreach ($elements as $element) { $cond->addChild(new UFC_NameTokens($element)); } $uf = new UserFilter($cond); $count = $uf->getTotalCount(); if ($count == 0) { $page->trigError('Les informations : « ' . $item . ' » ne correspondent à aucun camarade.'); $incomplete[] = $item; $errors = true; continue; } elseif ($count > 1) { $page->trigError('Les informations : « ' . $item . ' » sont ambigues et correspondent à plusieurs camarades.'); $incomplete[] = $item; $errors = true; continue; } else { $user = $uf->getUser(); } } if ($user->state == 'active') { $this->addRegistered($page, $user->profile()); } else { if (!User::isForeignEmailAddress($email)) { $page->trigError('Email pas encore attribué : ' . $email); $incomplete[] = $item; $errors = true; } else { $this->addNonRegistered($page, $user); if (!Marketing::get($user->id(), $email, true)) { check_email($email, "Une adresse surveillée est proposée au marketing par " . S::user()->login()); $market = new Marketing($user->id(), $email, 'default', null, $origin, S::v('uid'), null); $market->add(); } } } } } } $page->assign('errors', $errors); $page->assign('incomplete', $incomplete); }
function handler_broken_addr($page) { require_once 'emails.inc.php'; $page->changeTpl('emails/broken_addr.tpl'); if (Env::has('sort_broken')) { S::assert_xsrf_token(); $list = trim(Env::v('list')); if ($list == '') { $page->trigError('La liste est vide.'); } else { $valid_emails = array(); $invalid_emails = array(); $broken_list = explode("\n", $list); sort($broken_list); foreach ($broken_list as $orig_email) { $orig_email = trim($orig_email); if ($orig_email != '') { $email = valide_email($orig_email); if (empty($email) || $email == '@') { $invalid_emails[] = trim($orig_email) . ': invalid email'; } elseif (!in_array($email, $valid_emails)) { $nb = XDB::fetchOneCell('SELECT COUNT(*) FROM email_redirect_account WHERE redirect = {?}', $email); if ($nb > 0) { $valid_emails[] = $email; } else { $invalid_emails[] = $orig_email . ': no such redirection'; } } } } $page->assign('valid_emails', $valid_emails); $page->assign('invalid_emails', $invalid_emails); } } if (Env::has('process_broken')) { S::assert_xsrf_token(); $list = trim(Env::v('list')); if ($list == '') { $page->trigError('La liste est vide.'); } else { require_once 'notifs.inc.php'; $broken_user_list = array(); $broken_user_email_count = array(); $broken_user_profiles = array(); $broken_list = explode("\n", $list); sort($broken_list); foreach ($broken_list as $email) { $email = trim($email); $userobj = null; if ($user = mark_broken_email($email, true)) { $userobj = User::getSilentWithUID($user['uid']); } if (is_null($userobj)) { continue; } $profile = $userobj->profile(); if (is_null($profile)) { continue; } if ($user['nb_mails'] > 0 && $user['notify']) { $mail = new PlMailer('emails/broken.mail.tpl'); $mail->setTo($userobj); $mail->assign('user', $user); $mail->assign('email', $email); $mail->send(); } else { WatchProfileUpdate::register($profile, 'broken'); } $pid = $profile->id(); if (!isset($broken_user_list[$pid])) { $broken_user_list[$pid] = array($email); } else { $broken_user_list[$pid][] = $email; } $broken_user_email_count[$pid] = $user['nb_mails']; $broken_user_profiles[$pid] = $profile; } XDB::execute('UPDATE email_redirect_account SET broken_level = broken_level - 1 WHERE flags = \'active\' AND broken_level > 1 AND DATE_ADD(last, INTERVAL 1 MONTH) < CURDATE()'); XDB::execute('UPDATE email_redirect_account SET broken_level = 0 WHERE flags = \'active\' AND broken_level = 1 AND DATE_ADD(last, INTERVAL 1 YEAR) < CURDATE()'); // Sort $broken_user_list with (promo, sortname, pid) $sortable_array = array(); foreach ($broken_user_list as $pid => $mails) { $profile = $broken_user_profiles[$pid]; $sortable_array[$pid] = array($profile->promo(), $profile->sortName(), $pid); } asort($sortable_array); // Output the list of users with recently broken addresses, // along with the count of valid redirections. pl_cached_content_headers('text/x-csv', null, 1, 'broken.csv'); $csv = fopen('php://output', 'w'); fputcsv($csv, array('nom', 'promo', 'bounces', 'nbmails', 'url', 'corps', 'job', 'networking'), ';'); $corpsList = DirEnum::getOptions(DirEnum::CURRENTCORPS); foreach (array_keys($sortable_array) as $pid) { $mails = $broken_user_list[$pid]; $profile = $broken_user_profiles[$pid]; $current_corps = $profile->getCorpsName(); $jobs = $profile->getJobs(); $companies = array(); foreach ($jobs as $job) { $companies[] = $job->company->name; } $networkings = $profile->getNetworking(Profile::NETWORKING_ALL); $networking_list = array(); foreach ($networkings as $networking) { $networking_list[] = $networking['address']; } fputcsv($csv, array($profile->fullName(), $profile->promo(), join(',', $mails), $broken_user_email_count[$pid], 'https://www.polytechnique.org/marketing/broken/' . $profile->hrid(), $current_corps, implode(',', $companies), implode(',', $networking_list)), ';'); } fclose($csv); exit; } } }
function handler_ajax_modify($page, $type) { $json = json_decode(Env::v('json')); if ($type == 'instance') { $id = $json->admin_id; $ai = new ActivityInstance($id); $ai->select(ActivityInstanceSelect::base()); if (!S::user()->hasRights($ai->target()->group(), Rights::admin())) { throw new Exception("Invalid credentials"); } S::assert_xsrf_token(); try { $begin = new FrankizDateTime($json->begin); $end = new FrankizDateTime($json->end); if ($ai->regular()) { $ai->comment($json->activity_comment); $ai->begin($begin); $ai->end($end); } else { $ai->begin($begin); $ai->end($end); $a = $ai->activity(); $a->title($json->title); $a->description($json->activity_description); } $page->jsonAssign('success', true); } catch (Exception $e) { $page->jsonAssign('success', false); } } else { if ($type == 'regular') { $id = $json->aid; $a = new Activity($id); $a->select(ActivitySelect::base()); if (!S::user()->hasRights($a->target()->group(), Rights::admin())) { throw new Exception("Invalid credentials"); } S::assert_xsrf_token(); if (preg_match('`^\\d{2}:\\d{2}:\\d{2}$`', $json->begin) && strtotime($json->begin) !== false && preg_match('`^\\d{2}:\\d{2}:\\d{2}$`', $json->end) && strtotime($json->end) !== false) { $a->title($json->title); $a->description($json->activity_description); $key = 'days[]'; $days = unflatten($json->{$key}); $a->days(implode(',', $days)); $a->default_begin($json->begin); $a->default_end($json->end); $page->jsonAssign('success', true); } else { $page->jsonAssign('success', false); } } } return PL_JSON; }
function handler_admin_trombino($page, $login = null, $action = null) { $page->changeTpl('profile/admin_trombino.tpl'); $page->setTitle('Administration - Trombino'); if (!$login || !($user = User::get($login))) { return PL_NOT_FOUND; } else { $page->assign_by_ref('user', $user); } switch ($action) { case "original": PlImage::fromFile("/home/web/trombino/photos" . $user->promo() . "/" . $user->login() . ".jpg", "image/jpeg")->send(); exit; case "new": S::assert_xsrf_token(); $data = file_get_contents($_FILES['userfile']['tmp_name']); list($x, $y) = getimagesize($_FILES['userfile']['tmp_name']); $mimetype = substr($_FILES['userfile']['type'], 6); unlink($_FILES['userfile']['tmp_name']); XDB::execute('INSERT INTO profile_photos (pid, attachmime, attach, x, y) VALUES ({?}, {?}, {?}, {?}, {?}) ON DUPLICATE KEY UPDATE attachmime = VALUES(attachmime), attach = VALUES(attach), x = VALUES(x), y = VALUES(y)', $user->profile()->id(), $mimetype, $data, $x, $y); break; case "delete": S::assert_xsrf_token(); XDB::execute('DELETE FROM profile_photos WHERE pid = {?}', $user->profile()->id()); break; } }