/** * Discards from the logger database session details for users. * * @param userPerms Permission level to use for that round of discards. * @param retentionPeriod Minimal number of months to keep entries for. * @param minimalBacklog Minimal number of entries to keep for any given user, * no matter what. */ function discardExpiredSessions($userPerms, $retentionPeriod, $minimalBacklog) { $begin = time(); switch ($userPerms) { case 'user': $state = 'active'; $isAdmin = 0; break; case 'admin': $state = 'active'; $isAdmin = 1; break; case 'disabled': $state = 'disabled'; $isAdmin = 0; break; default: return; } list($low, $high) = XDB::fetchOneRow("SELECT MIN(uid), MAX(uid)\n FROM #x5dat#.accounts\n WHERE state = {?} AND is_admin = {?}", $state, $isAdmin); $batchSize = 100; $nbBatches = 0; $affectedRows = 0; // Run in batches. for ($lowUID = $low; $lowUID <= $high; $lowUID += $batchSize) { // Slight optimization for last loop: adjust to exactly what's necessary. $highUID = min($high + 1, $lowUID + $batchSize); XDB::execute("DELETE s\n FROM log_sessions AS s\n JOIN (SELECT a.uid,\n (SELECT us.start\n FROM log_sessions AS us\n WHERE us.uid = a.uid AND (us.suid IS NULL OR us.suid = 0)\n ORDER BY us.start DESC\n LIMIT {?}, 1) AS no_discard_limit\n FROM #x5dat#.accounts AS a\n WHERE a.state = {?} AND a.is_admin = {?}\n AND a.uid >= {?} AND a.uid < {?}\n ORDER BY a.uid ASC) AS ut ON (ut.uid = s.uid)\n WHERE s.start < DATE_SUB(NOW(), INTERVAL {?} MONTH)\n AND s.start < ut.no_discard_limit", $minimalBacklog - 1, $state, $isAdmin, $lowUID, $highUID, $retentionPeriod); $nbBatches += 1; $affectedRows += XDB::affectedRows(); } $duration = time() - $begin; echo "Users with permission '{$userPerms}': removed {$affectedRows} sessions in {$duration} seconds ({$nbBatches} batches).\n"; }
public function handler_notifs($page, $action = null, $arg = null) { $page->changeTpl('carnet/notifs.tpl'); if ($action) { S::assert_xsrf_token(); switch ($action) { case 'add_promo': $this->addPromo($page, $arg); break; case 'del_promo': $this->delPromo($page, $arg); break; case 'add_group': $this->addGroup($page, $arg); break; case 'del_group': $this->delGroup($page, $arg); break; case 'del_nonins': $user = User::get($arg); if ($user) { $this->delNonRegistered($page, $user); } break; case 'add_nonins': $user = User::get($arg); if ($user) { $this->addNonRegistered($page, $user); } break; } } if (Env::has('subs')) { S::assert_xsrf_token(); $flags = new PlFlagSet(); foreach (Env::v('sub') as $key => $value) { $flags->addFlag($key, $value); } XDB::execute('UPDATE watch SET actions = {?} WHERE uid = {?}', $flags, S::i('uid')); S::user()->invalidWatchCache(); Platal::session()->updateNbNotifs(); } if (Env::has('flags_contacts')) { S::assert_xsrf_token(); XDB::execute('UPDATE watch SET ' . XDB::changeFlag('flags', 'contacts', Env::b('contacts')) . ' WHERE uid = {?}', S::i('uid')); S::user()->invalidWatchCache(); Platal::session()->updateNbNotifs(); } if (Env::has('flags_mail')) { S::assert_xsrf_token(); XDB::execute('UPDATE watch SET ' . XDB::changeFlag('flags', 'mail', Env::b('mail')) . ' WHERE uid = {?}', S::i('uid')); S::user()->invalidWatchCache(); Platal::session()->updateNbNotifs(); } $user = S::user(); $nonins = new UserFilter(new UFC_WatchRegistration($user)); $promo = XDB::fetchColumn('SELECT promo FROM watch_promo WHERE uid = {?} ORDER BY promo', S::i('uid')); $page->assign('promo_count', count($promo)); $ranges = array(); $range_start = null; $range_end = null; foreach ($promo as $p) { if (is_null($range_start)) { $range_start = $range_end = $p; } else { if ($p != $range_end + 1) { $ranges[] = array($range_start, $range_end); $range_start = $range_end = $p; } else { $range_end = $p; } } } $ranges[] = array($range_start, $range_end); $page->assign('promo_ranges', $ranges); $page->assign('nonins', $nonins->getUsers()); $groups = XDB::fetchColumn('SELECT g.nom FROM watch_group AS w INNER JOIN groups AS g ON (g.id = w.groupid) WHERE w.uid = {?} ORDER BY g.nom', S::i('uid')); $page->assign('groups', $groups); $page->assign('groups_count', count($groups)); list($flags, $actions) = XDB::fetchOneRow('SELECT flags, actions FROM watch WHERE uid = {?}', S::i('uid')); $flags = new PlFlagSet($flags); $actions = new PlFlagSet($actions); $page->assign('flags', $flags); $page->assign('actions', $actions); }
/** Save an article * @p $a A reference to a NLArticle object (will be modified once saved) */ public function saveArticle($a) { $this->fetchArticles(); // Prevent cid to be 0 (use NULL instead) $a->cid = $a->cid == 0 ? null : $a->cid; if ($a->aid >= 0) { // Article already exists in DB XDB::execute('UPDATE newsletter_art SET cid = {?}, pos = {?}, title = {?}, body = {?}, append = {?} WHERE id = {?} AND aid = {?}', $a->cid, $a->pos, $a->title, $a->body, $a->append, $this->id, $a->aid); } else { // New article XDB::startTransaction(); list($aid, $pos) = XDB::fetchOneRow('SELECT MAX(aid) AS aid, MAX(pos) AS pos FROM newsletter_art AS a WHERE a.id = {?}', $this->id); $a->aid = ++$aid; $a->pos = $a->pos ? $a->pos : ++$pos; XDB::execute('INSERT INTO newsletter_art (id, aid, cid, pos, title, body, append) VALUES ({?}, {?}, {?}, {?}, {?}, {?}, {?})', $this->id, $a->aid, $a->cid, $a->pos, $a->title, $a->body, $a->append); XDB::commit(); } // Update local ID of article $this->arts[$a->aid] = $a; }
public function formatPostalAddress() { // Performs rough formatting. $text = mb_strtoupper(replace_accent($this->text)); $text = str_replace(array(',', ';', '.', ':', '!', '?', '"', '«', '»'), '', $text); $text = preg_replace('/( |\\t)+/', ' ', $text); $arrayText = explode("\n", $text); $arrayText = array_map('trim', $arrayText); // Formats according to country rules. Thus we first identify the // country, then apply corresponding formatting or translate country // into default language. $count = count($arrayText); list($countryId, $country) = XDB::fetchOneRow('SELECT gc.iso_3166_1_a2, gc.country FROM geoloc_countries AS gc INNER JOIN geoloc_languages AS gl ON (gc.iso_3166_1_a2 = gl.iso_3166_1_a2) WHERE gl.countryPlain = {?} OR gc.countryPlain = {?}', $arrayText[$count - 1], $arrayText[$count - 1]); if (is_null($countryId)) { $text = $this->formatPostalAddressFR($arrayText); } elseif (in_array(strtoupper($countryId), Address::$formattings)) { $text = call_user_func(array($this, 'formatPostalAddress' . strtoupper($countryId)), $arrayText); } else { $arrayText[$count - 1] = mb_strtoupper(replace_accent($country)); $text = implode("\n", $arrayText); } $this->postalText = $text; }
function handler_alias($page, $action = null, $value = null) { global $globals; $page->changeTpl('emails/alias.tpl'); $page->setTitle('Alias melix.net'); $user = S::user(); $page->assign('request', AliasReq::get_request($user->id())); // Remove the email alias. if ($action == 'delete') { S::assert_xsrf_token(); XDB::execute('DELETE FROM email_source_account WHERE uid = {?} AND type = \'alias_aux\'', $user->id()); require_once 'emails.inc.php'; fix_bestalias($user); } // Fetch existing auxiliary aliases. list($alias, $old_alias) = XDB::fetchOneRow('SELECT CONCAT(s.email, \'@\', d.name), s.email FROM email_source_account AS s INNER JOIN email_virtual_domains AS d ON (s.domain = d.id) WHERE s.uid = {?} AND s.type = \'alias_aux\'', $user->id()); $visibility = $user->hasProfile() && $user->profile()->isVisible($user->profile()->alias_pub); $page->assign('current', $alias); $page->assign('user', $user); $page->assign('mail_public', $visibility); if ($action == 'ask' && Env::has('alias') && Env::has('reason')) { S::assert_xsrf_token(); // Retrieves user request. $new_alias = Env::v('alias'); $reason = Env::v('reason'); $public = Env::v('public', 'off') == 'on' ? 'private' : 'hidden'; $page->assign('r_alias', $new_alias); $page->assign('r_reason', $reason); if ($public == 'private') { $page->assign('r_public', true); } // Checks special charaters in alias. if (!preg_match("/^[a-zA-Z0-9\\-.]{2,19}[a-zA-Z0-9\\-]\$/", $new_alias)) { $page->trigError("L'adresse demandée n'est pas valide." . " Vérifie qu'elle comporte entre 3 et 20 caractères" . " et qu'elle ne contient que des lettres non accentuées," . " des chiffres ou les caractères '-' et '.'. De plus, elle ne" . " peut pas se terminer par un point."); return; } else { // Checks if the alias has already been given. $res = XDB::query('SELECT COUNT(email) FROM email_source_account WHERE email = {?} AND type = \'alias_aux\'', $new_alias); if ($res->fetchOneCell() > 0) { $page->trigError("L'alias {$new_alias} a déja été attribué. Tu ne peux donc pas l'obtenir."); return; } // Checks if the alias has already been asked for. $it = Validate::iterate('alias'); while ($req = $it->next()) { if ($req->alias == $new_alias) { $page->trigError("L'alias {$new_alias} a déja été demandé. Tu ne peux donc pas l'obtenir pour l'instant."); return; } } // Sends requests. This will erase any previous alias pending request. $myalias = new AliasReq($user, $new_alias, $reason, $public, $old_alias); $myalias->submit(); $page->assign('success', $new_alias); return; } } elseif ($action == 'set' && ($value == 'public' || $value == 'private')) { if (!S::has_xsrf_token()) { return PL_FORBIDDEN; } if ($user->hasProfile()) { XDB::execute('UPDATE profiles SET alias_pub = {?} WHERE pid = {?}', $value, $user->profile()->id()); } exit; } }
public static function extremePromotions($education) { return XDB::fetchOneRow("SELECT MIN(pe.promo_year) AS min, MAX(pe.promo_year) AS max\n FROM profile_education AS pe\n INNER JOIN profile_education_degree_enum AS pede ON (pe.degreeid = pede.id)\n WHERE pede.degree = {?} AND FIND_IN_SET('primary', pe.flags)", $education); }
/** * Tries to returns an email adresse of the user even if * the emil field is empty. * * /!\ To set the 'email' field, use the email() setter * */ public function bestEmail() { if ($this->email == '') { if (empty($this->bestEmail)) { $res = XDB::fetchOneRow("SELECT s.forlife, f.domain\n FROM studies AS s\n INNER JOIN formations AS f\n ON s.formation_id = f.formation_id\n WHERE s.uid = {?} ", $this->id); $this->bestEmail = $res[0] . '@' . $res[1]; } return $this->bestEmail; } return $this->email; }
/** * Get where the IP is from * @param string $ip IP * @return integer Binary combination of IPAddress:: constants * * TODO: add global cache */ public static function getOrigin($ip) { // Localhost if ($ip == '127.0.0.1') { return self::INTERNAL; } // Not Polytechnique if (substr($ip, 0, 8) == '129.104.') { // Polytechnique $origin = self::POLYTECHIQUE; // Read 3rd number $digit4 = strpos($ip, '.', 9); $ip3 = (int) substr($ip, 8, $digit4 - 8); if (!$digit4 || !$ip3) { return $origin; } // Polytechnique's DMZ is external if ($ip3 == 30 || $ip3 == 247) { return $origin; } $origin |= self::INTERNAL; // 129.104.192.0/18 has access to student zone if ($ip3 >= 192) { $origin |= self::HAS_STUDENT; } // Query database to know wether this IP is a premise (=room for a group) // or a student room list($is_student, $is_premise) = XDB::fetchOneRow('SELECT EXISTS(SELECT rid FROM rooms_users AS ru WHERE ru.rid = ips.rid ) AS stu, EXISTS(SELECT rid FROM rooms_groups AS rg WHERE rg.rid = ips.rid ) AS pre FROM ips WHERE ips.ip = {?} LIMIT 1', $ip); if ($is_student) { $origin |= self::STUDENT; } if ($is_premise) { $origin |= self::PREMISE; } return $origin; } // External IP return 0; }
#!/usr/bin/php5 <?php require_once 'connect.db.inc.php'; require_once '../../include/name.func.inc.php'; $pids = XDB::fetchOneRow("SELECT pid\n FROM profile_public_names\n WHERE firstname_ordinary = '0' OR lastname_marital = '0' OR lastname_ordinary = '0'"); XDB::execute("UPDATE profile_public_names\n SET firstname_ordinary = ''\n WHERE firstname_ordinary = '0'"); XDB::execute("UPDATE profile_public_names\n SET lastname_ordinary = ''\n WHERE lastname_ordinary = '0'"); XDB::execute("UPDATE profile_public_names\n SET lastname_ordinary = ''\n WHERE lastname_ordinary = '0'"); foreach ($pids as $pid) { $profile = Profile::get($pid); $item = XDB::fetchOneAssoc('SELECT * FROM profile_public_names WHERE pid = {?}', $pid); update_display_names($profile, $item); } // vim:set et sw=4 sts=4 sws=4 foldmethod=marker fenc=utf-8:
/** * Get an object by its ID or with a secondary key * @param mixed $id * @param boolean $tryKey try the other key if $id is not an index * @return false if nothing is found, a meta object otherwise * * Note: This method is to be called when there is only one expected object. * For several objects, you should use FrankizFilter and Collection instead. */ public static function fromId($id, $tryKey = true) { if (empty($id)) { return false; } // If $id is not an ID, return from result if (!static::isId($id)) { if (!$tryKey) { return false; } try { return static::from($id); } catch (ItemNotFoundException $e) { return false; } } // Get schema $schema = Schema::get(get_called_class()); $className = $schema->className(); $id_col = $schema->id(); $key_col = $schema->fromKey(); $mysql_key = $key_col && $key_col != $id_col ? XDB::format(' OR ' . $key_col . ' = {?}', $id) : ''; $res = XDB::fetchOneRow('SELECT ' . $id_col . ' AS id FROM ' . $schema->table() . ' WHERE ' . $id_col . ' = {?}' . $mysql_key . ' LIMIT 1', $id); return isset($res[0]) ? new $className($res[0]) : false; }
function handler_ajax_medal($page, $i, $id) { pl_content_headers("text/html"); $page->changeTpl('profile/deco.medal.tpl', NO_SKIN); list($valid, $has_levels) = XDB::fetchOneRow("SELECT NOT FIND_IN_SET('validation', flags), FIND_IN_SET('has_levels', flags)\n FROM profile_medal_enum\n WHERE id = {?}", $id); $page->assign('id', $i); $page->assign('medal', array('id' => $id, 'grade' => 0, 'valid' => $valid, 'has_levels' => $has_levels)); }