public function commit() { if ($this->user->hasProfile()) { XDB::execute('UPDATE profiles SET alias_pub = {?} WHERE pid = {?}', $this->public, $this->user->profile()->id()); } if ($this->old) { $success = XDB::execute('UPDATE email_source_account SET email = {?} WHERE uid = {?} AND type = \'alias_aux\'', $this->alias, $this->user->id()); } else { $success = XDB::execute('INSERT INTO email_source_account (email, uid, domain, type, flags) SELECT {?}, {?}, id, \'alias_aux\', \'\' FROM email_virtual_domains WHERE name = {?}', $this->alias, $this->user->id(), Platal::globals()->mail->alias_dom); } if ($success) { // Update the local User object, to pick up the new bestalias. require_once 'emails.inc.php'; fix_bestalias($this->user); $this->user = User::getSilentWithUID($this->user->id()); } return $success; }
public function getGeocodedAddress(Address $address, $defaultLanguage = null, $forceLanguage = false) { $this->prepareAddress($address); $textAddress = $this->getTextToGeocode($address->text); if (is_null($defaultLanguage)) { $defaultLanguage = Platal::globals()->geocoder->gmaps_language; } // Try to geocode the full address. $address->geocoding_calls = 1; if ($geocodedData = $this->getPlacemarkForAddress($textAddress, $defaultLanguage)) { $this->getUpdatedAddress($address, $geocodedData, null, $forceLanguage); return; } // If the full geocoding failed, try to geocode only the final part of the address. // We start by geocoding everything but the first line, and continue until we get // a result. To respect the limit of GMaps calls, we ignore the first few lines // if there are too many address lines. $addressLines = explode("\n", $textAddress); $linesCount = count($addressLines); for ($i = max(1, $linesCount - self::MAX_GMAPS_RPC_CALLS + 1); $i < $linesCount; ++$i) { $extraLines = implode("\n", array_slice($addressLines, 0, $i)); $toGeocode = implode("\n", array_slice($addressLines, $i)); ++$address->geocoding_calls; if ($geocodedData = $this->getPlacemarkForAddress($toGeocode, $defaultLanguage)) { $this->getUpdatedAddress($address, $geocodedData, $extraLines, $forceLanguage); return; } } }
public function __construct(PlWizard $wiz) { parent::__construct($wiz); $this->settings['addresses'] = new ProfileSettingAddresses(); $this->watched['addresses'] = true; Platal::page()->assign('geocoding_removal', true); }
public function commit() { if (!$this->warning) { Platal::load('admin', 'homonyms.inc.php'); fix_homonym($this->user, $this->email); } return true; }
protected function report_error($error) { parent::report_error($error); $raven = $this->setup_raven(); if ($raven != null) { $raven->captureException($error); } }
public static function get($level) { Platal::assert(array_key_exists($level, self::$view_levels), "Invalid visibility access level {$level}."); if (!array_key_exists($level, self::$vis_list)) { self::$vis_list[$level] = new Visibility($level); } return self::$vis_list[$level]; }
function handler_exit($page, $level = null) { global $globals; if (S::has('suid')) { Platal::session()->stopSUID(); pl_redirect('/'); } Platal::session()->destroy(); http_redirect($globals->baseurl_http); $page->changeTpl('exit.tpl'); }
function handler_index($page) { if (Platal::globals()->merge->state == 'pending') { $page->changeTpl('fusionax/index.tpl'); } elseif (Platal::globals()->merge->state == 'done') { $issueList = array('name' => 'noms', 'job' => 'emplois', 'address' => 'adresses', 'promo' => 'promotions', 'deathdate' => 'dates de décès', 'phone' => 'téléphones', 'education' => 'formations'); $issues = XDB::rawFetchOneAssoc("SELECT COUNT(*) AS total,\n SUM(FIND_IN_SET('name', issues)) DIV 1 AS name,\n SUM(FIND_IN_SET('job', issues)) DIV 2 AS job,\n SUM(FIND_IN_SET('address', issues)) DIV 3 AS address,\n SUM(FIND_IN_SET('promo', issues)) DIV 4 AS promo,\n SUM(FIND_IN_SET('deathdate', issues)) DIV 5 AS deathdate,\n SUM(FIND_IN_SET('phone', issues)) DIV 6 AS phone,\n SUM(FIND_IN_SET('education', issues)) DIV 7 AS education\n FROM profile_merge_issues\n WHERE issues IS NOT NULL OR issues != ''"); $page->changeTpl('fusionax/issues.tpl'); $page->assign('issues', $issues); $page->assign('issueList', $issueList); } }
private static function ListMergeIssues(Profile $profile) { if (Platal::globals()->merge->state != 'done') { return null; } $flags = XDB::fetchOneCell('SELECT issues FROM profile_merge_issues WHERE pid = {?}', $profile->id()); if (!$flags) { return null; } return new PlFlagSet($flags); }
function send_robot_homonym(PlUser $user, $email) { $cc = "validation+homonyme@" . Platal::globals()->mail->domain; $from = "\"Support Polytechnique.org\" <{$cc}>"; $body = Post::has('mailbody') ? Post::t('mailbody') : get_robot_mail_text($user, $email); $user = User::getSilentWithUID($user->id()); $mymail = new PlMailer(); $mymail->setFrom($from); $mymail->setSubject("Mise en place du robot {$email}@" . $user->mainEmailDomain()); $mymail->addCc($cc); $mymail->setTxtBody($body); $mymail->sendTo($user); }
private static function init($type) { if (Platal::globals()->cacheEnabled() && S::has('__DE_' . $type)) { self::$enumerations[$type] = S::v('__DE_' . $type); } else { $cls = "DE_" . ucfirst($type); $obj = new $cls(); self::$enumerations[$type] = $obj; if (Platal::globals()->cacheEnabled() && $obj->capabilities & DirEnumeration::SAVE_IN_SESSION) { S::set('__DE_' . $type, $obj); } } }
function smarty_function_poison($params, $smarty) { if (S::logged()) { return ''; } $count = isset($params['count']) ? $params['count'] : 20; $seed = isset($params['seed']) ? $params['seed'] : date('r'); Platal::load('poison', 'poison.inc.php'); $emails = get_poison_emails($seed, $count); $str = "<textarea>"; foreach ($emails as $email) { $str .= "<a href=\"mailto:{$email}\">{$email}</a> "; } return $str . '</textarea>'; }
public function __construct(PlUser $owner) { $notifs = Watch::getEvents($owner); $infos = array(); foreach ($notifs as $n) { foreach ($n['users'] as $user) { $op = $n['operation']; $date = $op->getDate($user); @($datetext = new Date($date)); @($datetext = $datetext->format('%e %B %Y')); $profile = $user->profile(); $infos[] = array('operation' => $op, 'title' => '[' . $op->getTitle(1) . '] - ' . $user->fullName() . ' le ' . $datetext, 'author' => $user->fullName(), 'publication' => $op->publicationDate($user), 'date' => strtotime($date), 'id' => $op->flag . '-' . $user->id() . '-' . strtotime($date), 'data' => $op->getData($user), 'hruid' => $user->login(), 'dead' => $user->deathdate, 'profile' => $user->profile()->hrid(), 'link' => Platal::globals()->baseurl . '/profile/' . $profile->hrid(), 'user' => $user, 'contact' => $owner->isContact($profile)); } } $this->it = PlIteratorUtils::fromArray($infos); }
function handler_ig_events($page) { require_once 'gadgets/gadgets.inc.php'; init_igoogle_html('gadgets/ig-events.tpl', AUTH_COOKIE); $events = XDB::iterator("SELECT SQL_CALC_FOUND_ROWS\n e.id, e.titre, UNIX_TIMESTAMP(e.creation_date) AS creation_date,\n ev.uid IS NULL AS nonlu, e.uid\n FROM announces AS e\n LEFT JOIN announce_read AS ev ON (e.id = ev.evt_id AND ev.uid = {?})\n WHERE FIND_IN_SET('valide', e.flags) AND expiration >= NOW()\n ORDER BY e.creation_date DESC", S::i('uid')); $page->assign('event_count', XDB::query("SELECT FOUND_ROWS()")->fetchOneCell()); Platal::load('events', 'feed.inc.php'); $user = S::user(); $data = array(); while ($e = PlFeed::nextEvent($events, $user)) { $data[] = $e; if (count($data) == 5) { break; } } $page->assign('events', $data); }
function handler_rss($page, $group, $alias, $hash, $file = null) { if (is_null($file)) { if (is_null($hash)) { return PL_FORBIDDEN; } $this->handler_rss($page, null, $group, $alias, $hash); } $user = Platal::session()->tokenAuth($alias, $hash); if (is_null($user)) { return PL_FORBIDDEN; } require_once 'banana/forum.inc.php'; $banana = new ForumsBanana($user, array('group' => $group, 'action' => 'rss2')); $banana->run(); exit; }
function paypal_erreur($text, $send = true) { global $erreur, $globals; if ($erreur) { return; } $erreur = $text; if (!$send) { return; } $mymail = new PlMailer(); $mymail->addTo($globals->money->email); $mymail->setFrom("webmaster@" . $globals->mail->domain); $mymail->setSubject("erreur lors d'un télépaiement (PayPal)"); $mymail->setTxtBody("raison de l'erreur : " . $text . "\n" . "paiement : {$conf_title} \n\n" . "dump de REQUEST :\n" . var_export($_REQUEST, true)); $mymail->send(); Platal::page()->trigError($text); }
function handler_sso($page) { $this->load('sso.inc.php'); // First, perform security checks. if (!wats4u_sso_check()) { return PL_BAD_REQUEST; } global $globals; if (!S::logged()) { // Request auth. $page->assign('external_auth', true); $page->assign('ext_url', $globals->wats4u->public_url); $page->setTitle('Authentification'); $page->setDefaultSkin('group_login'); $page->assign('group', null); return PL_DO_AUTH; } if (!S::user()->checkPerms(PERMS_USER)) { // External (X.net) account return PL_FORBIDDEN; } // Update the last login information (unless the user is in SUID). $uid = S::i('uid'); if (!S::suid()) { global $platal; S::logger($uid)->log('connexion_wats4u', $platal->path . ' ' . urldecode($_GET['url'])); } // If we logged in specifically for this 'external_auth' request // and didn't want to "keep access to services", we kill the session // just before returning. // See classes/xorgsession.php:startSessionAs if (S::b('external_auth_exit')) { S::logger()->log('deconnexion', @$_SERVER['HTTP_REFERER']); Platal::session()->killAccessCookie(); Platal::session()->destroy(); } // Compute return URL $full_return = wats4u_sso_build_return_url(S::user()); if ($full_return === "") { // Something went wrong $page->kill("Erreur dans le traitement de la requête Wats4U."); } http_redirect($full_return); }
/** Tries to return the correct profile from a given hrpid. */ private function findProfile($hrpid = null) { if (is_null($hrpid)) { $user = S::user(); if (!$user->hasProfile()) { return PL_NOT_FOUND; } else { $profile = $user->profile(false, 0, Visibility::get(Visibility::VIEW_ADMIN)); } } else { $profile = Profile::get($hrpid, 0, Visibility::get(Visibility::VIEW_ADMIN)); } if (!$profile) { return PL_NOT_FOUND; } else { if (!S::user()->canEdit($profile) && Platal::notAllowed()) { return PL_FORBIDDEN; } } return $profile; }
function handler_su($page, $uid = null) { if (S::has('suid')) { $page->kill("Déjà en SUID !!!"); } if ($uid === null) { throw new Exception("You forgot to pass the uid you want to impersonate"); } $user = new UserFilter(new UFC_Uid($uid)); $user = $user->get(true); if ($user !== false) { $user->select(UserSelect::login()); if (!Platal::session()->startSUID($user)) { $page->trigError('Impossible d\'effectuer un SUID sur ' . $uid); } else { S::logger()->log('admin/su', array('uid' => $user->id())); pl_redirect('home'); } } else { throw new Exception("Impossible de faire un SUID sur " . $uid); } }
function init_igoogle_html($template, $auth = AUTH_PUBLIC) { $page =& Platal::page(); $page->changeTpl('gadgets/ig-skin.tpl', NO_SKIN); $page->register_modifier('escape_html', 'escape_html'); $page->default_modifiers = array('@escape_html'); header('Accept-Charset: utf-8'); // Adds external JavaScript libraries provided by iGoogle to the page. if (Env::has('libs')) { $libs = preg_split('/,/', Env::s('libs'), -1, PREG_SPLIT_NO_EMPTY); foreach ($libs as $lib) { if (preg_match('@^[a-z0-9/._-]+$@i', $lib) && !preg_match('@([.][.])|([.]/)|(//)@', $lib)) { $page->append('gadget_js', 'https://www.google.com/ig/f/' . $lib); } } } // Redirects the user to the login pagin if required. if ($auth > S::v('auth', AUTH_PUBLIC)) { $page->assign('gadget_tpl', 'gadgets/ig-login.tpl'); return false; } $page->assign('gadget_tpl', $template); return true; }
* 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 * ***************************************************************************/ Platal::load('newsletter'); class FXLetterModule extends NewsletterModule { function handlers() { return array('fxletter' => $this->make_hook('nl', AUTH_COOKIE, 'user'), 'fxletter/out' => $this->make_hook('out', AUTH_COOKIE, 'user'), 'fxletter/show' => $this->make_hook('nl_show', AUTH_COOKIE, 'user'), 'fxletter/search' => $this->make_hook('nl_search', AUTH_COOKIE, 'user'), 'fxletter/admin' => $this->make_hook('admin_nl', AUTH_PASSWD, 'user'), 'fxletter/admin/edit' => $this->make_hook('admin_nl_edit', AUTH_PASSWD, 'user'), 'fxletter/admin/edit/valid' => $this->make_hook('admin_nl_valid', AUTH_PASSWD, 'user'), 'fxletter/admin/edit/cancel' => $this->make_hook('admin_nl_cancel', AUTH_PASSWD, 'user'), 'fxletter/admin/edit/delete' => $this->make_hook('admin_nl_delete', AUTH_PASSWD, 'user'), 'fxletter/admin/categories' => $this->make_hook('admin_nl_cat', AUTH_PASSWD, 'user'), 'fxletter/stat' => $this->make_hook('stat_nl', AUTH_PASSWD, 'user')); } protected function getNl() { require_once 'newsletter.inc.php'; return NewsLetter::forGroup(NewsLetter::GROUP_FX); } function handler_out($page, $hash = null, $issue_id = null) { $hash = $hash == 'nohash' ? null : $hash; if (!$hash) {
protected function trigSuccess($msg) { Platal::page()->trigSuccess($msg); }
/** * to validate a form */ public function handle_form() { if (is_null($this->item)) { return false; } // edit informations if (Env::has('edit')) { if ($this->item->handle_editor()) { $this->update(); Platal::page()->assign('msg', 'Requête mise à jour'); return true; } return false; } // add a comment if (Env::has('add_comm')) { if (!strlen(Env::t('comm'))) { return false; } $this->item->add_comment(S::user()->displayName(), Env::v('comm')); $this->item->sendmailcomment($this->writer); $this->update(); Platal::page()->assign('msg', 'Commentaire ajouté'); return true; } if (Env::has('accept')) { if ($this->commit()) { Platal::page()->assign('msg', 'Email de validation envoyé'); return true; } else { Platal::page()->assign('msg', 'Erreur lors de la validation'); return false; } } if (Env::has('delete')) { if (!Env::v('ans')) { Platal::page()->assign('msg', 'Pas de motivation pour le refus !!!'); return false; } else { if ($this->item->delete()) { $this->item->sendmailfinal(false); $this->clean(); Platal::page()->assign('msg', 'Email de refus envoyé'); return true; } else { Platal::page()->assign('msg', 'Erreur lors de la suppression des données'); return false; } } } return false; }
protected function prepare() { $tpl = parent::prepare(); global $wiz; $wiz = new PlWizard('Banana', PlPage::getCoreTpl('plwizard.tpl'), true, false); foreach ($this->pages as $name => &$mpage) { $wiz->addPage($this->handler, $mpage['text'], $name); } $wiz->apply(Platal::page(), $this->base, $this->page); return $tpl; }
protected function find_hook() { $ans = parent::find_hook(); $this->https = false; return $ans; }
/** * The authentication schema is based on three query parameters: * ?user=<hruid>×tamp=<timestamp>&sig=<sig> * where: * - hruid is the hruid of the querying user * - timestamp is the current UNIX timestamp, which has to be within a * given distance of the server-side UNIX timestamp * - sig is the HMAC of "<method>#<resource>#<payload>#<timestamp>" using * a known secret of the user as the key. * * At the moment, the shared secret of the user is the sha1 hash of its * password. This is temporary, though, until better support for tokens is * implemented in plat/al. * TODO(vzanotti): Switch to dedicated secrets for authentication. */ public function apiAuth($method, $resource, $payload) { // Verify that the timestamp is within acceptable bounds. $timestamp = Env::i('timestamp', 0); if (abs($timestamp - time()) > Platal::globals()->api->timestamp_tolerance) { return null; } // Retrieve the user corresponding to the forlife. Note that at the // moment, other aliases are also accepted. $user = User::getSilent(Env::s('user', '')); if (is_null($user) || !$user->isActive()) { return null; } // Determine the list of tokens associated with the user. At the moment, // this is just the sha1 of the password. $tokens = array($user->password()); // For each token, try to validate the signature. $message = implode('#', array($method, $resource, $payload, $timestamp)); $signature = Env::s('sig'); foreach ($tokens as $token) { $expected_signature = hash_hmac(Platal::globals()->api->hmac_algo, $message, $token); if ($signature == $expected_signature) { return $user; } } return null; }
function handler_pdf($page, $arg0 = null, $arg1 = null) { $this->load('contacts.pdf.inc.php'); $user = S::user(); Platal::session()->close(); $order = array(new UFO_Name()); if ($arg0 == 'promo') { $order = array_unshift($order, new UFO_Promo()); } else { $order[] = new UFO_Promo(); } $filter = new UserFilter(new UFC_Contact($user), $order); $pdf = new ContactsPDF(); $it = $filter->iterProfiles(); while ($p = $it->next()) { $pdf = ContactsPDF::addContact($pdf, $p, $arg0 == 'photos' || $arg1 == 'photos'); } $pdf->Output(); exit; }
function createAliases($subState) { global $globals; $res = XDB::query("SELECT hruid, state, type\n FROM accounts\n WHERE uid = {?} AND hruid != ''", $subState->i('uid')); if ($res->numRows() == 0) { return "Tu n'as pas d'adresse à vie pré-attribuée.<br />" . "Envoie un mail à <a href=\"mailto:support@{$globals->mail->domain}\">" . "support@{$globals->mail->domain}</a> en expliquant ta situation."; } else { list($forlife, $state, $type) = $res->fetchOneRow(); } if ($state == 'active') { return "Tu es déjà inscrit, si tu ne te souviens plus de ton mot de passe d'accès au site, " . "tu peux suivre <a href=\"recovery\">la procédure de récupération de mot de passe</a>."; } else { if ($state == 'disabled') { return "Ton compte a été désactivé par les administrateurs du site suite à des abus. " . "Pour plus d'information ou pour demander la réactivation du compte, tu peux t'adresser à " . "<a href=\"mailto:support@{$globals->mail->domain}\">support@{$globals->mail->domain}</a>."; } } $emailXorg = PlUser::makeUserName($subState->t('firstname'), $subState->t('lastname')); $suffix = (User::$sub_mail_domains[$type] ? substr(User::$sub_mail_domains[$type], 0, 1) : '') . substr($subState->v('yearpromo'), -2); $emailXorg2 = $emailXorg . '.' . $suffix; // Search for homonyms: // * first case: only one homonym already registered. $res = XDB::query('SELECT uid, expire FROM email_source_account WHERE email = {?} AND type != \'alias_aux\'', $emailXorg); // * second case: at least two homonyms registerd. $result = XDB::query("SELECT hrmid\n FROM email_source_other\n WHERE type = 'homonym' AND email = {?}", $emailXorg); if ($res->numRows() || $result->numRows()) { if ($res->numRows()) { list($h_id, $expire) = $res->fetchOneRow(); if (empty($expire)) { XDB::execute('UPDATE email_source_account SET expire = ADDDATE(NOW(), INTERVAL 1 MONTH) WHERE email = {?} AND type != \'alias_aux\'', $emailXorg); $hrmid = User::makeHomonymHrmid($emailXorg); XDB::execute('INSERT IGNORE INTO homonyms_list (hrmid, uid) VALUES ({?}, {?}), ({?}, {?})', $hrmid, $h_id, $hrmid, $subState->i('uid')); $als = XDB::fetchColumn('SELECT email FROM email_source_account WHERE uid = {?} AND type != \'alias_aux\' AND expire IS NULL', $h_id); $homonym = User::getSilentWithUID($h_id); $mailer = new PlMailer('register/lostalias.mail.tpl'); $mailer->addTo($homonym); $mailer->setSubject("Perte de ton alias {$emailXorg} dans un mois !"); $mailer->assign('emailXorg', $emailXorg); $mailer->assign('als', join(', ', $als)); $mailer->SetTxtBody(wordwrap($msg, 72)); $mailer->send(); } } else { $hrmid = $result->fetchOneCell(); XDB::execute('INSERT IGNORE INTO homonyms_list (hrmid, uid) VALUES ({?}, {?})', $hrmid, $subState->i('uid')); // TODO: insert into source_other if new domain } $subState->set('forlife', $forlife); $subState->set('bestalias', $emailXorg2); $subState->set('emailXorg2', null); } else { $subState->set('forlife', $forlife); $subState->set('bestalias', $emailXorg); $subState->set('emailXorg2', $emailXorg2); } $subState->set('main_mail_domain', User::$sub_mail_domains[$type] . Platal::globals()->mail->domain); return true; }
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_rss($page, $liste = null, $alias = null, $hash = null) { if (!$liste) { return PL_NOT_FOUND; } $user = Platal::session()->tokenAuth($alias, $hash); if (is_null($user)) { return PL_FORBIDDEN; } $mlist = $this->prepare_list($liste); if (list($det) = $mlist->getMembers()) { if (substr($liste, 0, 5) != 'promo' && ($det['ins'] || $det['priv']) && !$det['own'] && $det['sub'] < 2) { exit; } require_once 'banana/ml.inc.php'; $banana = new MLBanana($user, array('listname' => $mlist->mbox, 'domain' => $mlist->domain, 'action' => 'rss2')); $banana->run(); } exit; }