code:
<?php
/**
 * StatusNet, the distributed open-source microblogging tool
 *
 * Sessions administration panel
 *
 * PHP version 5
 *
 * LICENCE: This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as published by
 * the Free Software Foundation, either version 3 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 Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 * @category  Settings
 * @package   StatusNet
 * @author    Zach Copley <zach@status.net>
 * @copyright 2010 StatusNet, Inc.
 * @license   http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
 * @link      http://status.net/
 */

if (!defined('STATUSNET')) {
    exit(1);
}

/**
 * Admin site sessions
 *
 * @category Admin
 * @package  StatusNet
 * @author   Zach Copley <zach@status.net>
 * @license  http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
 * @link     http://status.net/
 */
class SessionsadminpanelAction extends AdminPanelAction
{
    /**
     * Returns the page title
     *
     * @return string page title
     */
    function title()
    {
        // TRANS: Title for the sessions administration panel.
        return _m('TITLE','Sessions');
    }

    /**
     * Instructions for using this form.
     *
     * @return string instructions
     */
    function getInstructions()
    {
        // TRANS: Instructions for the sessions administration panel.
        return _('Session settings for this StatusNet site');
    }

    /**
     * Show the site admin panel form
     *
     * @return void
     */
    function showForm()
    {
        $form = new SessionsAdminPanelForm($this);
        $form->show();
        return;
    }

    /**
     * Save settings from the form
     *
     * @return void
     */
    function saveSettings()
    {
        static $booleans = array('sessions' => array('handle', 'debug'));

        $values = array();

        foreach ($booleans as $section => $parts) {
            foreach ($parts as $setting) {
                $values[$section][$setting] = ($this->boolean($setting)) ? 1 : 0;
            }
        }

        // This throws an exception on validation errors

        $this->validate($values);

        // assert(all values are valid);

        $config = new Config();

        $config->query('BEGIN');

        foreach ($booleans as $section => $parts) {
            foreach ($parts as $setting) {
                Config::save($section, $setting, $values[$section][$setting]);
            }
        }

        $config->query('COMMIT');

        return;
    }

    function validate(&$values)
    {
        // stub
    }
}

// @todo FIXME: Class documentation missing.
class SessionsAdminPanelForm extends AdminForm
{
    /**
     * ID of the form
     *
     * @return int ID of the form
     */
    function id()
    {
        return 'sessionsadminpanel';
    }

    /**
     * class of the form
     *
     * @return string class of the form
     */
    function formClass()
    {
        return 'form_settings';
    }

    /**
     * Action of the form
     *
     * @return string URL of the action
     */
    function action()
    {
        return common_local_url('sessionsadminpanel');
    }

    /**
     * Data elements of the form
     *
     * @return void
     */
    function formData()
    {
        $this->out->elementStart('fieldset', array('id' => 'settings_user_sessions'));
        // TRANS: Fieldset legend on the sessions administration panel.
        $this->out->element('legend', null, _m('LEGEND','Sessions'));

        $this->out->elementStart('ul', 'form_data');

        $this->li();
        // TRANS: Checkbox title on the sessions administration panel.
        // TRANS: Indicates if StatusNet should handle session administration.
        $this->out->checkbox('handle', _('Handle sessions'),
                              (bool) $this->value('handle', 'sessions'),
                              // TRANS: Checkbox title on the sessions administration panel.
                              // TRANS: Indicates if StatusNet should handle session administration.
                              _('Handle sessions ourselves.'));
        $this->unli();

        $this->li();
        // TRANS: Checkbox label on the sessions administration panel.
        // TRANS: Indicates if StatusNet should write session debugging output.
        $this->out->checkbox('debug', _('Session debugging'),
                              (bool) $this->value('debug', 'sessions'),
                              // TRANS: Checkbox title on the sessions administration panel.
                              _('Enable debugging output for sessions.'));
        $this->unli();

        $this->out->elementEnd('ul');

        $this->out->elementEnd('fieldset');
    }

    /**
     * Action elements
     *
     * @return void
     */
    function formActions()
    {
        $this->out->submit('submit',
                           // TRANS: Submit button text on the sessions administration panel.
                           _m('BUTTON','Save'),
                           'submit',
                           null,
                           // TRANS: Title for submit button on the sessions administration panel.
                           _('Save session settings'));
    }
}


code:
<?php
/**
 * StatusNet, the distributed open-source microblogging tool
 *
 * Show an OAuth application
 *
 * PHP version 5
 *
 * LICENCE: This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as published by
 * the Free Software Foundation, either version 3 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 Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 * @category  Application
 * @package   StatusNet
 * @author    Zach Copley <zach@status.net>
 * @copyright 2008-2011 StatusNet, Inc.
 * @license   http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
 * @link      http://status.net/
 */

if (!defined('STATUSNET') && !defined('LACONICA')) {
    exit(1);
}

/**
 * Show an OAuth application
 *
 * @category Application
 * @package  StatusNet
 * @author   Zach Copley <zach@status.net>
 * @license  http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
 * @link     http://status.net/
 */
class ShowApplicationAction extends Action
{
    /**
     * Application to show
     */
    var $application = null;

    /**
     * User who owns the app
     */
    var $owner = null;

    var $msg = null;

    var $success = null;

    /**
     * Load attributes based on database arguments
     *
     * Loads all the DB stuff
     *
     * @param array $args $_REQUEST array
     *
     * @return success flag
     */
    function prepare($args)
    {
        parent::prepare($args);

        $id = (int)$this->arg('id');

        $this->application  = Oauth_application::getKV($id);
        $this->owner        = User::getKV($this->application->owner);

        if (!common_logged_in()) {
            // TRANS: Client error displayed trying to display an OAuth application while not logged in.
            $this->clientError(_('You must be logged in to view an application.'));
        }

        if (empty($this->application)) {
            // TRANS: Client error displayed trying to display a non-existing OAuth application.
            $this->clientError(_('No such application.'), 404);
        }

        $cur = common_current_user();

        if ($cur->id != $this->owner->id) {
            // TRANS: Client error displayed trying to display an OAuth application for which the logged in user is not the owner.
            $this->clientError(_('You are not the owner of this application.'), 401);
        }

        return true;
    }

    /**
     * Handle the request
     *
     * Shows info about the app
     *
     * @return void
     */
    function handle($args)
    {
        parent::handle($args);

        if ($_SERVER['REQUEST_METHOD'] == 'POST') {

            // CSRF protection
            $token = $this->trimmed('token');
            if (!$token || $token != common_session_token()) {
                // TRANS: Client error displayed when the session token does not match or is not given.
                $this->clientError(_('There was a problem with your session token.'));
            }

            if ($this->arg('reset')) {
                $this->resetKey();
            }
        } else {
            $this->showPage();
        }
    }

    /**
     * Title of the page
     *
     * @return string title of the page
     */
    function title()
    {
        if (!empty($this->application->name)) {
            return 'Application: ' . $this->application->name;
        }
    }

    function showPageNotice()
    {
        if (!empty($this->msg)) {
            $this->element('div', ($this->success) ? 'success' : 'error', $this->msg);
        }
    }

    function showContent()
    {
        $cur = common_current_user();

        $consumer = $this->application->getConsumer();

        $this->elementStart('div', 'entity_profile h-card');
        // TRANS: Header on the OAuth application page.
        $this->element('h2', null, _('Application profile'));
        if (!empty($this->application->icon)) {
            $this->element('img', array('src' => $this->application->icon,
                                        'class' => 'u-photo logo entity_depiction'));
        }

        $this->element('a', array('href' =>  $this->application->source_url,
                                  'class' => 'u-url p-name entity_fn'),
                            $this->application->name);

        $this->element('a', array('href' =>  $this->application->homepage,
                                  'class' => 'u-url entity_org'),
                            $this->application->organization);

        $this->element('div',
                       'note entity_note',
                       $this->application->description);

        $this->elementStart('div', 'entity_statistics');
        $defaultAccess = ($this->application->access_type & Oauth_application::$writeAccess)
            ? 'read-write' : 'read-only';
        $profile = Profile::getKV($this->application->owner);

        $appUsers = new Oauth_application_user();
        $appUsers->application_id = $this->application->id;
        $userCnt = $appUsers->count();

        $this->raw(sprintf(
            // TRANS: Information output on an OAuth application page.
            // TRANS: %1$s is the application creator, %2$s is "read-only" or "read-write",
            // TRANS: %3$d is the number of users using the OAuth application.
            _m('Created by %1$s - %2$s access by default - %3$d user',
               'Created by %1$s - %2$s access by default - %3$d users',
               $userCnt),
              $profile->getBestName(),
              $defaultAccess,
              $userCnt
            ));
        $this->elementEnd('div');

        $this->elementEnd('div');

        $this->elementStart('div', 'entity_actions');
        // TRANS: Header on the OAuth application page.
        $this->element('h2', null, _('Application actions'));
        $this->elementStart('ul');
        $this->elementStart('li', 'entity_edit');
        $this->element('a',
                       array('href' => common_local_url('editapplication',
                                                        array('id' => $this->application->id))),
                       // TRANS: Link text to edit application on the OAuth application page.
                       _m('EDITAPP','Edit'));
        $this->elementEnd('li');

        $this->elementStart('li', 'entity_reset_keysecret');
        $this->elementStart('form', array(
            'id' => 'form_reset_key',
            'class' => 'form_reset_key',
            'method' => 'POST',
            'action' => common_local_url('showapplication',
                                         array('id' => $this->application->id))));
        $this->elementStart('fieldset');
        $this->hidden('token', common_session_token());

        $this->element('input', array('type' => 'submit',
                                      'id' => 'reset',
                                      'name' => 'reset',
                                      'class' => 'submit',
                                      // TRANS: Button text on the OAuth application page.
                                      // TRANS: Resets the OAuth consumer key and secret.
                                      'value' => _('Reset key & secret'),
                                      'onClick' => 'return confirmReset()'));
        $this->elementEnd('fieldset');
        $this->elementEnd('form');
        $this->elementEnd('li');

        $this->elementStart('li', 'entity_delete');
        $this->elementStart('form', array(
                                          'id' => 'form_delete_application',
                                          'class' => 'form_delete_application',
                                          'method' => 'POST',
                                          'action' => common_local_url('deleteapplication',
                                                                       array('id' => $this->application->id))));

        $this->elementStart('fieldset');
        $this->hidden('token', common_session_token());
        // TRANS: Submit button text the OAuth application page to delete an application.
        $this->submit('delete', _m('BUTTON','Delete'));
        $this->elementEnd('fieldset');
        $this->elementEnd('form');
        $this->elementEnd('li');

        $this->elementEnd('ul');
        $this->elementEnd('div');

        $this->elementStart('div', 'entity_data');
        // TRANS: Header on the OAuth application page.
        $this->element('h2', null, _('Application info'));

        $this->elementStart('dl');
        // TRANS: Field label on application page.
        $this->element('dt', null, _('Consumer key'));
        $this->element('dd', null, $consumer->consumer_key);
        // TRANS: Field label on application page.
        $this->element('dt', null, _('Consumer secret'));
        $this->element('dd', null, $consumer->consumer_secret);
        // TRANS: Field label on application page.
        $this->element('dt', null, _('Request token URL'));
        $this->element('dd', null, common_local_url('ApiOAuthRequestToken'));
        // TRANS: Field label on application page.
        $this->element('dt', null, _('Access token URL'));
        $this->element('dd', null, common_local_url('ApiOAuthAccessToken'));
        // TRANS: Field label on application page.
        $this->element('dt', null, _('Authorize URL'));
        $this->element('dd', null, common_local_url('ApiOAuthAuthorize'));
        $this->elementEnd('dl');

        $this->element('p', 'note',
            // TRANS: Note on the OAuth application page about signature support.
            _('Note: HMAC-SHA1 signatures are supported. The plaintext signature method is not supported.'));
        $this->elementEnd('div');

        $this->elementStart('p', array('id' => 'application_action'));
        $this->element('a',
            array('href' => common_local_url('oauthappssettings'),
                  'class' => 'more'),
                  'View your applications');
        $this->elementEnd('p');
    }

    /**
     * Add a confirm script for Consumer key/secret reset
     *
     * @return void
     */
    function showScripts()
    {
        parent::showScripts();

        // TRANS: Text in confirmation dialog to reset consumer key and secret for an OAuth application.
        $msg = _('Are you sure you want to reset your consumer key and secret?');

        $js  = 'function confirmReset() { ';
        $js .= '    var agree = confirm("' . $msg . '"); ';
        $js .= '    return agree;';
        $js .= '}';

        $this->inlineScript($js);
    }

    /**
     * Reset an application's Consumer key and secret
     *
     * XXX: Should this be moved to its own page with a confirm?
     *
     */
    function resetKey()
    {
        $this->application->query('BEGIN');

        $oauser = new Oauth_application_user();
        $oauser->application_id = $this->application->id;
        $result = $oauser->delete();

        if ($result === false) {
            common_log_db_error($oauser, 'DELETE', __FILE__);
            $this->success = false;
            $this->msg = ('Unable to reset consumer key and secret.');
            $this->showPage();
            return;
        }

        $consumer = $this->application->getConsumer();
        $result = $consumer->delete();

        if ($result === false) {
            common_log_db_error($consumer, 'DELETE', __FILE__);
            $this->success = false;
            $this->msg = ('Unable to reset consumer key and secret.');
            $this->showPage();
            return;
        }

        $consumer = Consumer::generateNew();

        $result = $consumer->insert();

        if (empty($result)) {
            common_log_db_error($consumer, 'INSERT', __FILE__);
            $this->application->query('ROLLBACK');
            $this->success = false;
            $this->msg = ('Unable to reset consumer key and secret.');
            $this->showPage();
            return;
        }

        $orig = clone($this->application);
        $this->application->consumer_key = $consumer->consumer_key;
        $result = $this->application->update($orig);

        if ($result === false) {
            common_log_db_error($application, 'UPDATE', __FILE__);
            $this->application->query('ROLLBACK');
            $this->success = false;
            $this->msg = ('Unable to reset consumer key and secret.');
            $this->showPage();
            return;
        }

        $this->application->query('COMMIT');

        $this->success = true;
        $this->msg = ('Consumer key and secret reset.');
        $this->showPage();
    }
}

license: mit


code:
<?php
/**
 * StatusNet, the distributed open-source microblogging tool
 *
 * Group main page
 *
 * PHP version 5
 *
 * LICENCE: This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as published by
 * the Free Software Foundation, either version 3 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 Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 * @category  Group
 * @package   StatusNet
 * @author    Evan Prodromou <evan@status.net>
 * @author    Sarven Capadisli <csarven@status.net>
 * @copyright 2008-2011 StatusNet, Inc.
 * @license   http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
 * @link      http://status.net/
 */

if (!defined('STATUSNET') && !defined('LACONICA')) {
    exit(1);
}

require_once INSTALLDIR.'/lib/noticelist.php';
require_once INSTALLDIR.'/lib/feedlist.php';

/**
 * Group main page
 *
 * @category Group
 * @package  StatusNet
 * @author   Evan Prodromou <evan@status.net>
 * @license  http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
 * @link     http://status.net/
 */
class ShowgroupAction extends GroupAction
{
    /** page we're viewing. */
    var $page = null;
    var $userProfile = null;
    var $notice = null;

    /**
     * Is this page read-only?
     *
     * @return boolean true
     */
    function isReadOnly($args)
    {
        return true;
    }

    /**
     * Title of the page
     *
     * @return string page title, with page number
     */
    function title()
    {
        $base = $this->group->getFancyName();

        if ($this->page == 1) {
            // TRANS: Page title for first group page. %s is a group name.
            return sprintf(_('%s group'), $base);
        } else {
            // TRANS: Page title for any but first group page.
            // TRANS: %1$s is a group name, $2$s is a page number.
            return sprintf(_('%1$s group, page %2$d'),
                           $base,
                           $this->page);
        }
    }

    /**
     * Prepare the action
     *
     * Reads and validates arguments and instantiates the attributes.
     *
     * @param array $args $_REQUEST args
     *
     * @return boolean success flag
     */
    protected function prepare(array $args=array())
    {
        parent::prepare($args);

        $this->page = ($this->arg('page')) ? ($this->arg('page')+0) : 1;

        $this->userProfile = Profile::current();

        $user = common_current_user();

        if (!empty($user) && $user->streamModeOnly()) {
            $stream = new GroupNoticeStream($this->group, $this->userProfile);
        } else {
            $stream = new ThreadingGroupNoticeStream($this->group, $this->userProfile);
        }

        $this->notice = $stream->getNotices(($this->page-1)*NOTICES_PER_PAGE,
                                            NOTICES_PER_PAGE + 1);

        common_set_returnto($this->selfUrl());

        return true;
    }

    /**
     * Handle the request
     *
     * Shows a profile for the group, some controls, and a list of
     * group notices.
     *
     * @return void
     */
    protected function handle()
    {
        parent::handle();
        $this->showPage();
    }

    /**
     * Show the page content
     *
     * Shows a group profile and a list of group notices
     */
    function showContent()
    {
        $this->showGroupNotices();
    }

    /**
     * Show the group notices
     *
     * @return void
     */
    function showGroupNotices()
    {
        $user = common_current_user();

        if (!empty($user) && $user->streamModeOnly()) {
            $nl = new PrimaryNoticeList($this->notice, $this, array('show_n'=>NOTICES_PER_PAGE));
        } else {
            $nl = new ThreadedNoticeList($this->notice, $this, $this->userProfile);
        }

        $cnt = $nl->show();

        $this->pagination($this->page > 1,
                          $cnt > NOTICES_PER_PAGE,
                          $this->page,
                          'showgroup',
                          array('nickname' => $this->group->nickname));
    }

    /**
     * Get a list of the feeds for this page
     *
     * @return void
     */
    function getFeeds()
    {
        $url =
          common_local_url('grouprss',
                           array('nickname' => $this->group->nickname));

        return array(new Feed(Feed::JSON,
                              common_local_url('ApiTimelineGroup',
                                               array('format' => 'as',
                                                     'id' => $this->group->id)),
                              // TRANS: Tooltip for feed link. %s is a group nickname.
                              sprintf(_('Notice feed for %s group (Activity Streams JSON)'),
                                      $this->group->nickname)),
                    new Feed(Feed::RSS1,
                              common_local_url('grouprss',
                                               array('nickname' => $this->group->nickname)),
                              // TRANS: Tooltip for feed link. %s is a group nickname.
                              sprintf(_('Notice feed for %s group (RSS 1.0)'),
                                      $this->group->nickname)),
                     new Feed(Feed::RSS2,
                              common_local_url('ApiTimelineGroup',
                                               array('format' => 'rss',
                                                     'id' => $this->group->id)),
                              // TRANS: Tooltip for feed link. %s is a group nickname.
                              sprintf(_('Notice feed for %s group (RSS 2.0)'),
                                      $this->group->nickname)),
                     new Feed(Feed::ATOM,
                              common_local_url('ApiTimelineGroup',
                                               array('format' => 'atom',
                                                     'id' => $this->group->id)),
                              // TRANS: Tooltip for feed link. %s is a group nickname.
                              sprintf(_('Notice feed for %s group (Atom)'),
                                      $this->group->nickname)),
                     new Feed(Feed::FOAF,
                              common_local_url('foafgroup',
                                               array('nickname' => $this->group->nickname)),
                              // TRANS: Tooltip for feed link. %s is a group nickname.
                              sprintf(_('FOAF for %s group'),
                                       $this->group->nickname)));
    }

    function showAnonymousMessage()
    {
        if (!(common_config('site','closed') || common_config('site','inviteonly'))) {
            // TRANS: Notice on group pages for anonymous users for StatusNet sites that accept new registrations.
            // TRANS: %s is the group name, %%%%site.name%%%% is the site name,
            // TRANS: %%%%action.register%%%% is the URL for registration, %%%%doc.help%%%% is a URL to help.
            // TRANS: This message contains Markdown links. Ensure they are formatted correctly: [Description](link).
            $m = sprintf(_('**%s** is a user group on %%%%site.name%%%%, a [micro-blogging](http://en.wikipedia.org/wiki/Micro-blogging) service ' .
                'based on the Free Software [StatusNet](http://status.net/) tool. Its members share ' .
                'short messages about their life and interests. '.
                '[Join now](%%%%action.register%%%%) to become part of this group and many more! ([Read more](%%%%doc.help%%%%))'),
                     $this->group->getBestName());
        } else {
            // TRANS: Notice on group pages for anonymous users for StatusNet sites that accept no new registrations.
            // TRANS: %s is the group name, %%%%site.name%%%% is the site name,
            // TRANS: This message contains Markdown links. Ensure they are formatted correctly: [Description](link).
            $m = sprintf(_('**%s** is a user group on %%%%site.name%%%%, a [micro-blogging](http://en.wikipedia.org/wiki/Micro-blogging) service ' .
                'based on the Free Software [StatusNet](http://status.net/) tool. Its members share ' .
                'short messages about their life and interests.'),
                     $this->group->getBestName());
        }
        $this->elementStart('div', array('id' => 'anon_notice'));
        $this->raw(common_markup_to_html($m));
        $this->elementEnd('div');
    }

    function extraHead()
    {
        if ($this->page != 1) {
            $this->element('link', array('rel' => 'canonical',
                                         'href' => $this->group->homeUrl()));
        }
    }
}


code:
<?php
/**
 * StatusNet, the distributed open-source microblogging tool
 *
 * Show a single notice
 *
 * PHP version 5
 *
 * LICENCE: This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as published by
 * the Free Software Foundation, either version 3 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 Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 * @category  Personal
 * @package   StatusNet
 * @author    Evan Prodromou <evan@status.net>
 * @copyright 2008-2011 StatusNet, Inc.
 * @license   http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
 * @link      http://status.net/
 */

if (!defined('GNUSOCIAL')) { exit(1); }

require_once INSTALLDIR.'/lib/noticelist.php';

/**
 * Show a single notice
 *
 * @category Personal
 * @package  StatusNet
 * @author   Evan Prodromou <evan@status.net>
 * @license  http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
 * @link     http://status.net/
 */
class ShownoticeAction extends ManagedAction
{
    /**
     * Notice object to show
     */
    var $notice = null;

    /**
     * Profile of the notice object
     */
    var $profile = null;

    /**
     * Avatar of the profile of the notice object
     */
    var $avatar = null;

    /**
     * Load attributes based on database arguments
     *
     * Loads all the DB stuff
     *
     * @param array $args $_REQUEST array
     *
     * @return success flag
     */
    protected function prepare(array $args=array())
    {
        parent::prepare($args);
        if ($this->boolean('ajax')) {
            StatusNet::setApi(true);
        }

        $this->notice = $this->getNotice();

        if (!$this->notice->inScope($this->scoped)) {
            // TRANS: Client exception thrown when trying a view a notice the user has no access to.
            throw new ClientException(_('Access restricted.'), 403);
        }

        $this->profile = $this->notice->getProfile();

        if (!$this->profile instanceof Profile) {
            // TRANS: Server error displayed trying to show a notice without a connected profile.
            $this->serverError(_('Notice has no profile.'), 500);
        }

        try {
            $this->user = $this->profile->getUser();
        } catch (NoSuchUserException $e) {
            // FIXME: deprecate $this->user stuff in extended classes
            $this->user = null;
        }

        try {
            $this->avatar = $this->profile->getAvatar(AVATAR_PROFILE_SIZE);
        } catch (Exception $e) {
            $this->avatar = null;
        }

        return true;
    }

    /**
     * Fetch the notice to show. This may be overridden by child classes to
     * customize what we fetch without duplicating all of the prepare() method.
     *
     * @return Notice
     */
    protected function getNotice()
    {
        $id = $this->arg('notice');

        $notice = Notice::getKV('id', $id);
        if ($notice instanceof Notice) {
            // Alright, got it!
            return $notice;
        }

        // Did we use to have it, and it got deleted?
        $deleted = Deleted_notice::getKV('id', $id);
        if ($deleted instanceof Deleted_notice) {
            // TRANS: Client error displayed trying to show a deleted notice.
            $this->clientError(_('Notice deleted.'), 410);
        }
        // TRANS: Client error displayed trying to show a non-existing notice.
        $this->clientError(_('No such notice.'), 404);
    }

    /**
     * Is this action read-only?
     *
     * @return boolean true
     */
    function isReadOnly($args)
    {
        return true;
    }

    /**
     * Last-modified date for page
     *
     * When was the content of this page last modified? Based on notice,
     * profile, avatar.
     *
     * @return int last-modified date as unix timestamp
     */
    function lastModified()
    {
        return max(strtotime($this->notice->modified),
                   strtotime($this->profile->modified),
                   ($this->avatar) ? strtotime($this->avatar->modified) : 0);
    }

    /**
     * An entity tag for this page
     *
     * Shows the ETag for the page, based on the notice ID and timestamps
     * for the notice, profile, and avatar. It's weak, since we change
     * the date text "one hour ago", etc.
     *
     * @return string etag
     */
    function etag()
    {
        $avtime = ($this->avatar) ?
          strtotime($this->avatar->modified) : 0;

        return 'W/"' . implode(':', array($this->arg('action'),
                                          common_user_cache_hash(),
                                          common_language(),
                                          $this->notice->id,
                                          strtotime($this->notice->created),
                                          strtotime($this->profile->modified),
                                          $avtime)) . '"';
    }

    /**
     * Title of the page
     *
     * @return string title of the page
     */
    function title()
    {
        return $this->notice->getTitle();
    }

    /**
     * Fill the content area of the page
     *
     * Shows a single notice list item.
     *
     * @return void
     */
    function showContent()
    {
        $this->elementStart('ol', array('class' => 'notices xoxo'));
        $nli = new NoticeListItem($this->notice, $this);
        $nli->show();
        $this->elementEnd('ol');
    }

    /**
     * Don't show page notice
     *
     * @return void
     */
    function showPageNoticeBlock()
    {
    }

    /**
     * Don't show aside
     *
     * @return void
     */
    function showAside() {
    }

    /**
     * Extra <head> content
     *
     * We show the microid(s) for the author, if any.
     *
     * @return void
     */
    function extraHead()
    {
        $user = User::getKV($this->profile->id);

        if (!$user instanceof User) {
            return;
        }

        if ($user->emailmicroid && $user->email && $this->notice->uri) {
            $id = new Microid('mailto:'. $user->email,
                              $this->notice->uri);
            $this->element('meta', array('name' => 'microid',
                                         'content' => $id->toString()));
        }

        // Extras to aid in sharing notices to Facebook
        $avatarUrl = $this->profile->avatarUrl(AVATAR_PROFILE_SIZE);
        $this->element('meta', array('property' => 'og:image',
                                     'content' => $avatarUrl));
        $this->element('meta', array('property' => 'og:description',
                                     'content' => $this->notice->content));
    }
}


code:
<?php
/**
 * StatusNet - the distributed open-source microblogging tool
 * Copyright (C) 2008, 2009, StatusNet, Inc.
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as published by
 * the Free Software Foundation, either version 3 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 Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 * @category Actions
 * @package  Actions
 * @license  GNU Affero General Public License http://www.gnu.org/licenses/
 * @link     http://status.net
 */

if (!defined('STATUSNET') && !defined('LACONICA')) {
    exit(1);
}

require_once INSTALLDIR.'/lib/profileminilist.php';
require_once INSTALLDIR.'/lib/peopletaglist.php';
require_once INSTALLDIR.'/lib/noticelist.php';
require_once INSTALLDIR.'/lib/feedlist.php';

class ShowprofiletagAction extends Action
{
    var $notice, $tagger, $peopletag, $userProfile;

    function isReadOnly($args)
    {
        return true;
    }

    function prepare($args)
    {
        parent::prepare($args);

        if (common_config('singleuser', 'enabled')) {
            $tagger_arg = User::singleUserNickname();
        } else {
            $tagger_arg = $this->arg('tagger');
        }
        $tag_arg = $this->arg('tag');
        $tagger = common_canonical_nickname($tagger_arg);
        $tag = common_canonical_tag($tag_arg);

        // Permanent redirect on non-canonical nickname

        if ($tagger_arg != $tagger || $tag_arg != $tag) {
            $args = array('tagger' => $nickname, 'tag' => $tag);
            if ($this->page != 1) {
                $args['page'] = $this->page;
            }
            common_redirect(common_local_url('showprofiletag', $args), 301);
        }

        if (!$tagger) {
            // TRANS: Client error displayed when a tagger is expected but not provided.
            $this->clientError(_('No tagger.'), 404);
        }

        $user = User::getKV('nickname', $tagger);

        if (!$user) {
            // TRANS: Client error displayed trying to perform an action related to a non-existing user.
            $this->clientError(_('No such user.'), 404);
        }

        $this->tagger = $user->getProfile();
        $this->peopletag = Profile_list::pkeyGet(array('tagger' => $user->id, 'tag' => $tag));

        $current = common_current_user();
        $can_see = !empty($this->peopletag) && (!$this->peopletag->private ||
                   ($this->peopletag->private && $this->peopletag->tagger === $current->id));

        if (!$can_see) {
            // TRANS: Client error displayed trying to reference a non-existing list.
            $this->clientError(_('No such list.'), 404);
        }

        $this->page = ($this->arg('page')) ? ($this->arg('page')+0) : 1;
        $this->userProfile = Profile::current();

        $stream = new PeopletagNoticeStream($this->peopletag, $this->userProfile);

        $this->notice = $stream->getNotices(($this->page-1)*NOTICES_PER_PAGE,
                                            NOTICES_PER_PAGE + 1);

        if ($this->page > 1 && $this->notice->N == 0) {
            // TRANS: Client error when page not found (404).
            $this->clientError(_('No such page.'), 404);
        }

        return true;
    }

    function handle($args)
    {
        parent::handle($args);

        if (!$this->peopletag) {
            // TRANS: Client error displayed trying to perform an action related to a non-existing user.
            $this->clientError(_('No such user.'));
        }

        $this->showPage();
    }

    function title()
    {
        if ($this->page > 1) {
            if($this->peopletag->private) {
                // TRANS: Title for private list timeline.
                // TRANS: %1$s is a list, %2$s is a page number.
                return sprintf(_('Private timeline for %1$s list by you, page %2$d'),
                                $this->peopletag->tag, $this->page);
            }

            $current = common_current_user();
            if (!empty($current) && $current->id == $this->peopletag->tagger) {
                // TRANS: Title for public list timeline where the viewer is the tagger.
                // TRANS: %1$s is a list, %2$s is a page number.
                return sprintf(_('Timeline for %1$s list by you, page %2$d'),
                                $this->peopletag->tag, $this->page);
            }

            // TRANS: Title for private list timeline.
            // TRANS: %1$s is a list, %2$s is the tagger's nickname, %3$d is a page number.
            return sprintf(_('Timeline for %1$s list by %2$s, page %3$d'),
                                $this->peopletag->tag,
                                $this->tagger->nickname,
                                $this->page
                          );
        } else {
            if($this->peopletag->private) {
                // TRANS: Title for private list timeline.
                // TRANS: %s is a list.
                return sprintf(_('Private timeline of %s list by you'),
                                $this->peopletag->tag);
            }

            $current = common_current_user();
            if (!empty($current) && $current->id == $this->peopletag->tagger) {
                // TRANS: Title for public list timeline where the viewer is the tagger.
                // TRANS: %s is a list.
                return sprintf(_('Timeline for %s list by you'),
                                $this->peopletag->tag);
            }

            // TRANS: Title for private list timeline.
            // TRANS: %1$s is a list, %2$s is the tagger's nickname.
            return sprintf(_('Timeline for %1$s list by %2$s'),
                                $this->peopletag->tag,
                                $this->tagger->nickname
                          );
        }
    }

    function getFeeds()
    {
        #XXX: make these actually work
        return array(new Feed(Feed::JSON,
                common_local_url(
                    'ApiTimelineList', array(
                        'user' => $this->tagger->id,
                        'id' => $this->peopletag->id,
                        'format' => 'as'
                    )
                ),
                // TRANS: Feed title.
                // TRANS: %s is tagger's nickname.
                sprintf(_('Feed for friends of %s (Activity Streams JSON)'), $this->tagger->nickname)),
                new Feed(Feed::RSS2,
                common_local_url(
                    'ApiTimelineList', array(
                        'user' => $this->tagger->id,
                        'id' => $this->peopletag->id,
                        'format' => 'rss'
                    )
                ),
                // TRANS: Feed title.
                // TRANS: %s is tagger's nickname.
                sprintf(_('Feed for friends of %s (RSS 2.0)'), $this->tagger->nickname)),
            new Feed(Feed::ATOM,
                common_local_url(
                    'ApiTimelineList', array(
                        'user' => $this->tagger->id,
                        'id' => $this->peopletag->id,
                        'format' => 'atom'
                    )
                ),
                // TRANS: Feed title.
                // TRANS: %1$s is a list, %2$s is tagger's nickname.
                sprintf(_('Feed for %1$s list by %2$s (Atom)'),
                            $this->peopletag->tag, $this->tagger->nickname
                       )
              )
        );
    }

    function showObjectNav()
    {
        $nav = new PeopletagGroupNav($this);
        $nav->show();
    }

    function showEmptyListMessage()
    {
        // TRANS: Empty list message for list timeline.
        // TRANS: %1$s is a list, %2$s is a tagger's nickname.
        $message = sprintf(_('This is the timeline for %1$s list by %2$s but no one has posted anything yet.'),
                           $this->peopletag->tag,
                           $this->tagger->nickname) . ' ';

        if (common_logged_in()) {
            $current_user = common_current_user();
            if ($this->tagger->id == $current_user->id) {
                // TRANS: Additional empty list message for list timeline for currently logged in user tagged tags.
                $message .= _('Try tagging more people.');
            }
        } else {
            // TRANS: Additional empty list message for list timeline.
            // TRANS: This message contains Markdown links in the form [description](link).
            $message .= _('Why not [register an account](%%%%action.register%%%%) and start following this timeline!');
        }

        $this->elementStart('div', 'guide');
        $this->raw(common_markup_to_html($message));
        $this->elementEnd('div');
    }

    function showContent()
    {
        $this->showPeopletag();
        $this->showNotices();
    }

    function showPeopletag()
    {
        $cur = common_current_user();
        $tag = new Peopletag($this->peopletag, $cur, $this);
        $tag->show();
    }

    function showNotices()
    {
        if (Event::handle('StartShowProfileTagContent', array($this))) {
            $nl = new PrimaryNoticeList($this->notice, $this, array('show_n'=>NOTICES_PER_PAGE));

            $cnt = $nl->show();

            if (0 == $cnt) {
                $this->showEmptyListMessage();
            }

            $this->pagination($this->page > 1,
                              $cnt > NOTICES_PER_PAGE,
                              $this->page,
                              'showprofiletag',
                              array('tag' => $this->peopletag->tag,
                                    'tagger' => $this->tagger->nickname)
            );

            Event::handle('EndShowProfileTagContent', array($this));
        }
    }

    function showSections()
    {
        $this->showTagged();
        if (!$this->peopletag->private) {
            $this->showSubscribers();
        }
        # $this->showStatistics();
    }

    function showPageTitle()
    {
        $this->element('h1', null, $this->title());
    }

    function showTagged()
    {
        $profile = $this->peopletag->getTagged(0, PROFILES_PER_MINILIST + 1);

        $this->elementStart('div', array('id' => 'entity_tagged',
                                         'class' => 'section'));
        if (Event::handle('StartShowTaggedProfilesMiniList', array($this))) {
            $title = '';

            // TRANS: Header on show list page.
            $this->element('h2', null, _('Listed'));

            $cnt = 0;

            if (!empty($profile)) {
                $pml = new ProfileMiniList($profile, $this);
                $cnt = $pml->show();
                if ($cnt == 0) {
                    // TRANS: Content of "Listed" page if there are no listed users.
                    $this->element('p', null, _('(None)'));
                }
            }

            if ($cnt > PROFILES_PER_MINILIST) {
                $this->elementStart('p');
                $this->element('a', array('href' => common_local_url('taggedprofiles',
                                                                     array('nickname' => $this->tagger->nickname,
                                                                           'profiletag' => $this->peopletag->tag)),
                                          'class' => 'more'),
                               // TRANS: Link for more "People in list x by a user"
                               // TRANS: if there are more than the mini list's maximum.
                               _('Show all'));
                $this->elementEnd('p');
            }

            Event::handle('EndShowTaggedProfilesMiniList', array($this));
        }
        $this->elementEnd('div');
    }

    function showSubscribers()
    {
        $profile = $this->peopletag->getSubscribers(0, PROFILES_PER_MINILIST + 1);

        $this->elementStart('div', array('id' => 'entity_subscribers',
                                         'class' => 'section'));
        if (Event::handle('StartShowProfileTagSubscribersMiniList', array($this))) {
            // TRANS: Header for tag subscribers.
            $this->element('h2', null, _('Subscribers'));

            $cnt = 0;

            if (!empty($profile)) {
                $pml = new ProfileMiniList($profile, $this);
                $cnt = $pml->show();
                if ($cnt == 0) {
                    // TRANS: Content of "People following tag x" if there are no subscribed users.
                    $this->element('p', null, _('(None)'));
                }
            }

            // FIXME: link to full list

            Event::handle('EndShowProfileTagSubscribersMiniList', array($this));
        }
        $this->elementEnd('div');
    }
}

class Peopletag extends PeopletagListItem
{
    protected $avatarSize = AVATAR_PROFILE_SIZE;

    function showStart()
    {
        $mode = $this->peopletag->private ? 'private' : 'public';
        $this->out->elementStart('div', array('class' => 'h-entry peopletag peopletag-profile mode-'.$mode,
                                             'id' => 'peopletag-' . $this->peopletag->id));
    }

    function showEnd()
    {
        $this->out->elementEnd('div');
    }
}


code:
<?php
/**
 * StatusNet, the distributed open-source microblogging tool
 *
 * User profile page
 *
 * PHP version 5
 *
 * LICENCE: This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as published by
 * the Free Software Foundation, either version 3 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 Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 * @category  Personal
 * @package   StatusNet
 * @author    Evan Prodromou <evan@status.net>
 * @author    Sarven Capadisli <csarven@status.net>
 * @copyright 2008-2009 StatusNet, Inc.
 * @license   http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
 * @link      http://status.net/
 */

if (!defined('STATUSNET') && !defined('LACONICA')) {
    exit(1);
}

require_once INSTALLDIR.'/lib/personalgroupnav.php';
require_once INSTALLDIR.'/lib/noticelist.php';
require_once INSTALLDIR.'/lib/profileminilist.php';
require_once INSTALLDIR.'/lib/groupminilist.php';
require_once INSTALLDIR.'/lib/feedlist.php';

/**
 * User profile page
 *
 * When I created this page, "show stream" seemed like the best name for it.
 * Now, it seems like a really bad name.
 *
 * It shows a stream of the user's posts, plus lots of profile info, links
 * to subscriptions and stuff, etc.
 *
 * @category Personal
 * @package  StatusNet
 * @author   Evan Prodromou <evan@status.net>
 * @license  http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
 * @link     http://status.net/
 */
class ShowstreamAction extends ProfileAction
{
    var $notice;

    protected function prepare(array $args=array())
    {
        parent::prepare($args);

        if (empty($this->tag)) {
            $stream = new ProfileNoticeStream($this->profile, $this->scoped);
        } else {
            $stream = new TaggedProfileNoticeStream($this->profile, $this->tag, $this->scoped);
        }

        $this->notice = $stream->getNotices(($this->page-1)*NOTICES_PER_PAGE, NOTICES_PER_PAGE + 1);

        return true;
    }

    function title()
    {
        $base = $this->profile->getFancyName();
        if (!empty($this->tag)) {
            if ($this->page == 1) {
                // TRANS: Page title showing tagged notices in one user's timeline.
                // TRANS: %1$s is the username, %2$s is the hash tag.
                return sprintf(_('Notices by %1$s tagged %2$s'), $base, $this->tag);
            } else {
                // TRANS: Page title showing tagged notices in one user's timeline.
                // TRANS: %1$s is the username, %2$s is the hash tag, %3$d is the page number.
                return sprintf(_('Notices by %1$s tagged %2$s, page %3$d'), $base, $this->tag, $this->page);
            }
        } else {
            if ($this->page == 1) {
                return $base;
            } else {
                // TRANS: Extended page title showing tagged notices in one user's timeline.
                // TRANS: %1$s is the username, %2$d is the page number.
                return sprintf(_('Notices by %1$s, page %2$d'),
                               $base,
                               $this->page);
            }
        }
    }

    function showContent()
    {
        $this->showNotices();
    }

    function showProfileBlock()
    {
        $block = new AccountProfileBlock($this, $this->profile);
        $block->show();
    }

    function showPageNoticeBlock()
    {
        return;
    }

    function getFeeds()
    {
        if (!empty($this->tag)) {
            return array(new Feed(Feed::RSS1,
                                  common_local_url('userrss',
                                                   array('nickname' => $this->target->nickname,
                                                         'tag' => $this->tag)),
                                  // TRANS: Title for link to notice feed.
                                  // TRANS: %1$s is a user nickname, %2$s is a hashtag.
                                  sprintf(_('Notice feed for %1$s tagged %2$s (RSS 1.0)'),
                                          $this->target->nickname, $this->tag)));
        }

        return array(new Feed(Feed::JSON,
                              common_local_url('ApiTimelineUser',
                                               array(
                                                    'id' => $this->user->id,
                                                    'format' => 'as')),
                              // TRANS: Title for link to notice feed.
                              // TRANS: %s is a user nickname.
                              sprintf(_('Notice feed for %s (Activity Streams JSON)'),
                                      $this->target->nickname)),
                     new Feed(Feed::RSS1,
                              common_local_url('userrss',
                                               array('nickname' => $this->target->nickname)),
                              // TRANS: Title for link to notice feed.
                              // TRANS: %s is a user nickname.
                              sprintf(_('Notice feed for %s (RSS 1.0)'),
                                      $this->target->nickname)),
                     new Feed(Feed::RSS2,
                              common_local_url('ApiTimelineUser',
                                               array(
                                                    'id' => $this->user->id,
                                                    'format' => 'rss')),
                              // TRANS: Title for link to notice feed.
                              // TRANS: %s is a user nickname.
                              sprintf(_('Notice feed for %s (RSS 2.0)'),
                                      $this->target->nickname)),
                     new Feed(Feed::ATOM,
                              common_local_url('ApiTimelineUser',
                                               array(
                                                    'id' => $this->user->id,
                                                    'format' => 'atom')),
                              // TRANS: Title for link to notice feed.
                              // TRANS: %s is a user nickname.
                              sprintf(_('Notice feed for %s (Atom)'),
                                      $this->target->nickname)),
                     new Feed(Feed::FOAF,
                              common_local_url('foaf', array('nickname' =>
                                                             $this->target->nickname)),
                              // TRANS: Title for link to notice feed. FOAF stands for Friend of a Friend.
                              // TRANS: More information at http://www.foaf-project.org. %s is a user nickname.
                              sprintf(_('FOAF for %s'), $this->target->nickname)));
    }

    function extraHead()
    {
        if ($this->profile->bio) {
            $this->element('meta', array('name' => 'description',
                                         'content' => $this->profile->bio));
        }

        if ($this->user->emailmicroid && $this->user->email && $this->profile->profileurl) {
            $id = new Microid('mailto:'.$this->user->email,
                              $this->selfUrl());
            $this->element('meta', array('name' => 'microid',
                                         'content' => $id->toString()));
        }

        // See https://wiki.mozilla.org/Microsummaries

        $this->element('link', array('rel' => 'microsummary',
                                     'href' => common_local_url('microsummary',
                                                                array('nickname' => $this->profile->nickname))));

        $rsd = common_local_url('rsd',
                                array('nickname' => $this->profile->nickname));

        // RSD, http://tales.phrasewise.com/rfc/rsd
        $this->element('link', array('rel' => 'EditURI',
                                     'type' => 'application/rsd+xml',
                                     'href' => $rsd));

        if ($this->page != 1) {
            $this->element('link', array('rel' => 'canonical',
                                         'href' => $this->profile->profileurl));
        }
    }

    function showEmptyListMessage()
    {
        // TRANS: First sentence of empty list message for a timeline. $1%s is a user nickname.
        $message = sprintf(_('This is the timeline for %1$s, but %1$s hasn\'t posted anything yet.'), $this->target->nickname) . ' ';

        if (common_logged_in()) {
            $current_user = common_current_user();
            if ($this->user->id === $current_user->id) {
                // TRANS: Second sentence of empty list message for a stream for the user themselves.
                $message .= _('Seen anything interesting recently? You haven\'t posted any notices yet, now would be a good time to start :)');
            } else {
                // TRANS: Second sentence of empty  list message for a non-self timeline. %1$s is a user nickname, %2$s is a part of a URL.
                // TRANS: This message contains a Markdown link. Keep "](" together.
                $message .= sprintf(_('You can try to nudge %1$s or [post something to them](%%%%action.newnotice%%%%?status_textarea=%2$s).'), $this->target->nickname, '@' . $this->target->nickname);
            }
        }
        else {
            // TRANS: Second sentence of empty message for anonymous users. %s is a user nickname.
            // TRANS: This message contains a Markdown link. Keep "](" together.
            $message .= sprintf(_('Why not [register an account](%%%%action.register%%%%) and then nudge %s or post a notice to them.'), $this->target->nickname);
        }

        $this->elementStart('div', 'guide');
        $this->raw(common_markup_to_html($message));
        $this->elementEnd('div');
    }

    function showNotices()
    {
        $pnl = null;
        if (Event::handle('ShowStreamNoticeList', array($this->notice, $this, &$pnl))) {
            $pnl = new ProfileNoticeList($this->notice, $this);
        }
        $cnt = $pnl->show();
        if (0 == $cnt) {
            $this->showEmptyListMessage();
        }

        $args = array('nickname' => $this->target->nickname);
        if (!empty($this->tag))
        {
            $args['tag'] = $this->tag;
        }
        $this->pagination($this->page>1, $cnt>NOTICES_PER_PAGE, $this->page,
                          'showstream', $args);
    }

    function showAnonymousMessage()
    {
        if (!(common_config('site','closed') || common_config('site','inviteonly'))) {
            // TRANS: Announcement for anonymous users showing a timeline if site registrations are open.
            // TRANS: This message contains a Markdown link. Keep "](" together.
            $m = sprintf(_('**%s** has an account on %%%%site.name%%%%, a [micro-blogging](http://en.wikipedia.org/wiki/Micro-blogging) service ' .
                           'based on the Free Software [StatusNet](http://status.net/) tool. ' .
                           '[Join now](%%%%action.register%%%%) to follow **%s**\'s notices and many more! ([Read more](%%%%doc.help%%%%))'),
                         $this->target->nickname, $this->target->nickname);
        } else {
            // TRANS: Announcement for anonymous users showing a timeline if site registrations are closed or invite only.
            // TRANS: This message contains a Markdown link. Keep "](" together.
            $m = sprintf(_('**%s** has an account on %%%%site.name%%%%, a [micro-blogging](http://en.wikipedia.org/wiki/Micro-blogging) service ' .
                           'based on the Free Software [StatusNet](http://status.net/) tool.'),
                         $this->target->nickname, $this->target->nickname);
        }
        $this->elementStart('div', array('id' => 'anon_notice'));
        $this->raw(common_markup_to_html($m));
        $this->elementEnd('div');
    }

    function showSections()
    {
        parent::showSections();
        if (!common_config('performance', 'high')) {
            $cloud = new PersonalTagCloudSection($this, $this->user);
            $cloud->show();
        }
    }

    function noticeFormOptions()
    {
        $options = parent::noticeFormOptions();
        $cur = common_current_user();

        if (empty($cur) || $cur->id != $this->profile->id) {
            $options['to_profile'] =  $this->profile;
        }

        return $options;
    }
}

// We don't show the author for a profile, since we already know who it is!

/**
 * Slightly modified from standard list; the author & avatar are hidden
 * in CSS. We used to remove them here too, but as it turns out that
 * confuses the inline reply code... and we hide them in CSS anyway
 * since realtime updates come through in original form.
 *
 * Remaining customization right now is for the repeat marker, where
 * it'll list who the original poster was instead of who did the repeat
 * (since the repeater is you, and the repeatee isn't shown!)
 * This will remain inconsistent if realtime updates come through,
 * since those'll get rendered as a regular NoticeListItem.
 */
class ProfileNoticeList extends NoticeList
{
    function newListItem($notice)
    {
        return new ProfileNoticeListItem($notice, $this->out);
    }
}

class ProfileNoticeListItem extends DoFollowListItem
{
    /**
     * show a link to the author of repeat
     *
     * @return void
     */
    function showRepeat()
    {
        if (!empty($this->repeat)) {

            // FIXME: this code is almost identical to default; need to refactor

            $attrs = array('href' => $this->profile->profileurl,
                           'class' => 'url');

            if (!empty($this->profile->fullname)) {
                $attrs['title'] = $this->profile->getFancyName();
            }

            $this->out->elementStart('span', 'repeat');

            $text_link = XMLStringer::estring('a', $attrs, $this->profile->nickname);

            // TRANS: Link to the author of a repeated notice. %s is a linked nickname.
            $this->out->raw(sprintf(_('Repeat of %s'), $text_link));

            $this->out->elementEnd('span');
        }
    }
}


code:
<?php
/**
 * StatusNet, the distributed open-source microblogging tool
 *
 * Action class to silence an abusive user
 *
 * PHP version 5
 *
 * LICENCE: This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as published by
 * the Free Software Foundation, either version 3 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 Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 * @category  Action
 * @package   StatusNet
 * @author    Evan Prodromou <evan@status.net>
 * @copyright 2009 StatusNet, Inc.
 * @license   http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
 * @link      http://status.net/
 */

if (!defined('STATUSNET')) {
    exit(1);
}

/**
 * Silence a user.
 *
 * @category Action
 * @package  StatusNet
 * @author   Evan Prodromou <evan@status.net>
 * @license  http://www.fsf.org/licensing/licenses/agpl.html AGPLv3
 * @link     http://status.net/
 */
class SilenceAction extends ProfileFormAction
{
    /**
     * Check parameters
     *
     * @param array $args action arguments (URL, GET, POST)
     *
     * @return boolean success flag
     */
    function prepare($args)
    {
        if (!parent::prepare($args)) {
            return false;
        }

        $cur = common_current_user();

        assert(!empty($cur)); // checked by parent

        if (!$cur->hasRight(Right::SILENCEUSER)) {
            // TRANS: Client error displayed trying to silence a user on a site where the feature is not enabled.
            $this->clientError(_('You cannot silence users on this site.'));
        }

        assert(!empty($this->profile)); // checked by parent

        if ($this->profile->isSilenced()) {
            // TRANS: Client error displayed trying to silence an already silenced user.
            $this->clientError(_('User is already silenced.'));
        }

        return true;
    }

    /**
     * Silence a user.
     *
     * @return void
     */
    function handlePost()
    {
        $this->profile->silence();
    }
}


code:
<?php
/**
 * StatusNet, the distributed open-source microblogging tool
 *
 * Site administration panel
 *
 * PHP version 5
 *
 * LICENCE: This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as published by
 * the Free Software Foundation, either version 3 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 Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 * @category  Settings
 * @package   StatusNet
 * @author    Evan Prodromou <evan@status.net>
 * @author    Zach Copley <zach@status.net>
 * @author    Sarven Capadisli <csarven@status.net>
 * @copyright 2008-2011 StatusNet, Inc.
 * @license   http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
 * @link      http://status.net/
 */

if (!defined('STATUSNET')) {
    exit(1);
}

/**
 * Administer site settings
 *
 * @category Admin
 * @package  StatusNet
 * @author   Evan Prodromou <evan@status.net>
 * @author   Zach Copley <zach@status.net>
 * @author   Sarven Capadisli <csarven@status.net>
 * @license  http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
 * @link     http://status.net/
 */
class SiteadminpanelAction extends AdminPanelAction
{
    /**
     * Returns the page title
     *
     * @return string page title
     */
    function title()
    {
        // TRANS: Title for site administration panel.
        return _m('TITLE','Site');
    }

    /**
     * Instructions for using this form.
     *
     * @return string instructions
     */
    function getInstructions()
    {
        // TRANS: Instructions for site administration panel.
        return _('Basic settings for this StatusNet site');
    }

    /**
     * Show the site admin panel form
     *
     * @return void
     */
    function showForm()
    {
        $form = new SiteAdminPanelForm($this);
        $form->show();
        return;
    }

    /**
     * Save settings from the form
     *
     * @return void
     */
    function saveSettings()
    {
        static $settings = array(
            'site' => array(
                'name',
                'broughtby',
                'broughtbyurl',
                'email',
                'timezone',
                'language',
                'site',
                'textlimit',
                'dupelimit',
                'logo',
                'ssllogo'
            )
        );

        $values = array();

        foreach ($settings as $section => $parts) {
            foreach ($parts as $setting) {
                $values[$section][$setting] = $this->trimmed($setting);
            }
        }

        // This throws an exception on validation errors

        $this->validate($values);

        // assert(all values are valid);

        $config = new Config();

        $config->query('BEGIN');

        foreach ($settings as $section => $parts) {
            foreach ($parts as $setting) {
                Config::save($section, $setting, $values[$section][$setting]);
            }
        }

        $config->query('COMMIT');

        return;
    }

    function validate(&$values)
    {
        // Validate site name

        if (empty($values['site']['name'])) {
            // TRANS: Client error displayed trying to save an empty site name.
            $this->clientError(_('Site name must have non-zero length.'));
        }

        // Validate email

        $values['site']['email'] = common_canonical_email($values['site']['email']);

        if (empty($values['site']['email'])) {
            // TRANS: Client error displayed trying to save site settings without a contact address.
            $this->clientError(_('You must have a valid contact email address.'));
        }
        if (!Validate::email($values['site']['email'], common_config('email', 'check_domain'))) {
            // TRANS: Client error displayed trying to save site settings without a valid contact address.
            $this->clientError(_('Not a valid email address.'));
        }

        // Validate logos
        if (!empty($values['site']['logo']) &&
                !common_valid_http_url($values['site']['logo'])) {
            // TRANS: Client error displayed when a logo URL is not valid.
            $this->clientError(_('Invalid logo URL.'));
        }

        if (!empty($values['site']['ssllogo']) &&
                !common_valid_http_url($values['site']['ssllogo'], true)) {
            // TRANS: Client error displayed when a SSL logo URL is invalid.
            $this->clientError(_('Invalid SSL logo URL.'));
        }

        // Validate timezone

        if (is_null($values['site']['timezone']) ||
            !in_array($values['site']['timezone'], DateTimeZone::listIdentifiers())) {
            // TRANS: Client error displayed trying to save site settings without a timezone.
            $this->clientError(_('Timezone not selected.'));
        }

        // Validate language

        if (!is_null($values['site']['language']) &&
            !in_array($values['site']['language'], array_keys(get_nice_language_list()))) {
            // TRANS: Client error displayed trying to save site settings with an invalid language code.
            // TRANS: %s is the invalid language code.
            $this->clientError(sprintf(_('Unknown language "%s".'), $values['site']['language']));
        }

        // Validate text limit

        if (!Validate::number($values['site']['textlimit'], array('min' => 0))) {
            // TRANS: Client error displayed trying to save site settings with a text limit below 0.
            $this->clientError(_('Minimum text limit is 0 (unlimited).'));
        }

        // Validate dupe limit

        if (!Validate::number($values['site']['dupelimit'], array('min' => 1))) {
            // TRANS: Client error displayed trying to save site settings with a text limit below 1.
            $this->clientError(_('Dupe limit must be one or more seconds.'));
        }
    }
}

// @todo FIXME: Class documentation missing.
class SiteAdminPanelForm extends AdminForm
{
    /**
     * ID of the form
     *
     * @return int ID of the form
     */
    function id()
    {
        return 'form_site_admin_panel';
    }

    /**
     * class of the form
     *
     * @return string class of the form
     */
    function formClass()
    {
        return 'form_settings';
    }

    /**
     * Action of the form
     *
     * @return string URL of the action
     */
    function action()
    {
        return common_local_url('siteadminpanel');
    }

    /**
     * Data elements of the form
     *
     * @return void
     */
    function formData()
    {
        $this->out->elementStart('fieldset', array('id' => 'settings_admin_general'));
        // TRANS: Fieldset legend on site settings panel.
        $this->out->element('legend', null, _m('LEGEND','General'));
        $this->out->elementStart('ul', 'form_data');
        $this->li();
        // TRANS: Field label on site settings panel.
        $this->input('name', _m('LABEL','Site name'),
                     // TRANS: Field title on site settings panel.
                     _('The name of your site, like "Yourcompany Microblog".'));
        $this->unli();

        $this->li();
        // TRANS: Field label on site settings panel.
        $this->input('broughtby', _('Brought by'),
                     // TRANS: Field title on site settings panel.
                     _('Text used for credits link in footer of each page.'));
        $this->unli();

        $this->li();
        // TRANS: Field label on site settings panel.
        $this->input('broughtbyurl', _('Brought by URL'),
                     // TRANS: Field title on site settings panel.
                     _('URL used for credits link in footer of each page.'));
        $this->unli();
        $this->li();
        // TRANS: Field label on site settings panel.
        $this->input('email', _('Email'),
                     // TRANS: Field title on site settings panel.
                     _('Contact email address for your site.'));
        $this->unli();
        $this->out->elementEnd('ul');
        $this->out->elementEnd('fieldset');

        $this->showLogo();

        $this->out->elementStart('fieldset', array('id' => 'settings_admin_local'));
        // TRANS: Fieldset legend on site settings panel.
        $this->out->element('legend', null, _m('LEGEND','Local'));
        $this->out->elementStart('ul', 'form_data');
        $timezones = array();

        foreach (DateTimeZone::listIdentifiers() as $k => $v) {
            $timezones[$v] = $v;
        }

        asort($timezones);

        $this->li();
        // TRANS: Dropdown label on site settings panel.
        $this->out->dropdown('timezone', _('Default timezone'),
                             // TRANS: Dropdown title on site settings panel.
                             $timezones, _('Default timezone for the site; usually UTC.'),
                             true, $this->value('timezone'));
        $this->unli();

        $this->li();
        $this->out->dropdown('language',
                             // TRANS: Dropdown label on site settings panel.
                             _('Default language'),
                             get_nice_language_list(),
                             // TRANS: Dropdown title on site settings panel.
                             _('The site language when autodetection from browser settings is not available.'),
                             false, $this->value('language'));
        $this->unli();

        $this->out->elementEnd('ul');
        $this->out->elementEnd('fieldset');

        $this->out->elementStart('fieldset', array('id' => 'settings_admin_limits'));
        // TRANS: Fieldset legend on site settings panel.
        $this->out->element('legend', null, _m('LEGEND','Limits'));
        $this->out->elementStart('ul', 'form_data');
        $this->li();
        $this->input('textlimit',
                     // TRANS: Field label on site settings panel.
                     _('Text limit'),
                     // TRANS: Field title on site settings panel.
                     _('Maximum number of characters for notices.'));
        $this->unli();

        $this->li();
        $this->input('dupelimit',
                     // TRANS: Field label on site settings panel.
                     _('Dupe limit'),
                     // TRANS: Field title on site settings panel.
                     _('How long users must wait (in seconds) to post the same thing again.'));
        $this->unli();
        $this->out->elementEnd('ul');
        $this->out->elementEnd('fieldset');
    }

    function showLogo()
    {
        $this->out->elementStart('fieldset', array('id' => 'settings_site_logo'));
        // TRANS: Fieldset legend for form to change logo.
        $this->out->element('legend', null, _('Logo'));

        $this->out->elementStart('ul', 'form_data');

        $this->li();
        $this->input('logo',
                     // TRANS: Field label for StatusNet site logo.
                     _('Site logo'),
                     // TRANS: Title for field label for StatusNet site logo.
                     'Logo for the site (full URL).');
        $this->unli();

        $this->li();
        $this->input('ssllogo',
                     // TRANS: Field label for SSL StatusNet site logo.
                     _('SSL logo'),
                     // TRANS: Title for field label for SSL StatusNet site logo.
                     'Logo to show on SSL pages (full URL).');
        $this->unli();

        $this->out->elementEnd('ul');

        $this->out->elementEnd('fieldset');
    }

    /**
     * Action elements
     *
     * @return void
     */
    function formActions()
    {
        $this->out->submit('submit',
                           // TRANS: Button text for saving site settings.
                           _m('BUTTON','Save'),
                           'submit',
                           null,
                           // TRANS: Button title for saving site settings.
                           _('Save the site settings.'));
    }
}


code:
<?php
/**
 * StatusNet, the distributed open-source microblogging tool
 *
 * Site notice administration panel
 *
 * PHP version 5
 *
 * LICENCE: This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as published by
 * the Free Software Foundation, either version 3 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 Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 * @category  Settings
 * @package   StatusNet
 * @author    Zach Copley <zach@status.net>
 * @copyright 2010 StatusNet, Inc.
 * @license   http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
 * @link      http://status.net/
 */

if (!defined('STATUSNET')) {
    exit(1);
}

require_once INSTALLDIR.'/extlib/htmLawed/htmLawed.php';

/**
 * Update the site-wide notice text
 *
 * @category Admin
 * @package  StatusNet
 * @author   Zach Copley <zach@status.net>
 * @license  http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
 * @link     http://status.net/
 */
class SitenoticeadminpanelAction extends AdminPanelAction
{
    /**
     * Returns the page title
     *
     * @return string page title
     */
    function title()
    {
        // TRANS: Page title for site-wide notice tab in admin panel.
        return _('Site Notice');
    }

    /**
     * Instructions for using this form.
     *
     * @return string instructions
     */
    function getInstructions()
    {
        // TRANS: Instructions for site-wide notice tab in admin panel.
        return _('Edit site-wide message');
    }

    /**
     * Show the site notice admin panel form
     *
     * @return void
     */
    function showForm()
    {
        $form = new SiteNoticeAdminPanelForm($this);
        $form->show();
        return;
    }

    /**
     * Save settings from the form
     *
     * @return void
     */
    function saveSettings()
    {
        $siteNotice = $this->trimmed('site-notice');

        // assert(all values are valid);
        // This throws an exception on validation errors

        $this->validate($siteNotice);

        $config = new Config();

        $result = Config::save('site', 'notice', $siteNotice);

        if (!$result) {
            // TRANS: Server error displayed when saving a site-wide notice was impossible.
            $this->ServerError(_('Unable to save site notice.'));
        }
    }

    function validate(&$siteNotice)
    {
        // Validate notice text

        if (mb_strlen($siteNotice) > 255)  {
            $this->clientError(
                // TRANS: Client error displayed when a site-wide notice was longer than allowed.
                _('Maximum length for the site-wide notice is 255 characters.')
            );
        }

        // scrub HTML input

        $config = array(
            'safe' => 1,
            'deny_attribute' => 'id,style,on*'
        );

        $siteNotice = htmLawed($siteNotice, $config);
    }
}

class SiteNoticeAdminPanelForm extends AdminForm
{
    /**
     * ID of the form
     *
     * @return int ID of the form
     */

    function id()
    {
        return 'form_site_notice_admin_panel';
    }

    /**
     * class of the form
     *
     * @return string class of the form
     */

    function formClass()
    {
        return 'form_settings';
    }

    /**
     * Action of the form
     *
     * @return string URL of the action
     */

    function action()
    {
        return common_local_url('sitenoticeadminpanel');
    }

    /**
     * Data elements of the form
     *
     * @return void
     */

    function formData()
    {
        $this->out->elementStart('ul', 'form_data');

        $this->out->elementStart('li');
        $this->out->textarea(
            'site-notice',
            // TRANS: Label for site-wide notice text field in admin panel.
            _('Site notice text'),
            common_config('site', 'notice'),
            // TRANS: Tooltip for site-wide notice text field in admin panel.
            _('Site-wide notice text (255 characters maximum; HTML allowed)')
        );
        $this->out->elementEnd('li');

        $this->out->elementEnd('ul');
    }

    /**
     * Action elements
     *
     * @return void
     */

    function formActions()
    {
        $this->out->submit(
            'submit',
            // TRANS: Button text for saving site notice in admin panel.
            _m('BUTTON','Save'),
            'submit',
            null,
            // TRANS: Button title to save site notice in admin panel.
            _('Save site notice.')
        );
    }
}