code:
<?php
/**
 * StatusNet - the distributed open-source microblogging tool
 * Copyright (C) 2008-2010, StatusNet, Inc.
 *
 * Subscription action.
 *
 * 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/>.
 *
 * PHP version 5
 *
 * @category  Action
 * @package   StatusNet
 * @author    Shashi Gowda <connect2shashi@gmail.com>
 * @license   http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPLv3
 * @link      http://status.net/
 */

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

require_once INSTALLDIR . '/lib/account/togglepeopletag.php';

/**
 * Subscription action
 *
 * Subscribing to a profile. Does not work for OMB 0.1 remote subscriptions,
 * but may work for other remote subscription protocols, like OStatus.
 *
 * Takes parameters:
 *
 *    - subscribeto: a profile ID
 *    - token: session token to prevent CSRF attacks
 *    - ajax: boolean; whether to return Ajax or full-browser results
 *
 * Only works if the current user is logged in.
 *
 * @category  Action
 * @package   StatusNet
 * @author    Shashi Gowda <connect2shashi@gmail.com>
 * @license   http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPLv3
 * @link      http://status.net/
 */
class RemovepeopletagAction extends Action
{
    var $user;
    var $tagged;
    var $peopletag;

    /**
     * Check pre-requisites and instantiate attributes
     *
     * @param Array $args array of arguments (URL, GET, POST)
     *
     * @return boolean success flag
     */
    function prepare(array $args = array())
    {
        parent::prepare($args);

        // 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.'.
                                 ' Try again, please.'));
        }

        // Only for logged-in users

        $this->user = common_current_user();

        if (empty($this->user)) {
            // TRANS: Error message displayed when trying to perform an action that requires a logged in user.
            $this->clientError(_('Not logged in.'));
        }

        // Profile to subscribe to

        $tagged_id = $this->arg('tagged');

        $this->tagged = Profile::getKV('id', $tagged_id);

        if (empty($this->tagged)) {
            // TRANS: Client error displayed when referring to a non-existing profile.
            $this->clientError(_('No such profile.'));
        }

        $id = $this->arg('peopletag_id');
        $this->peopletag = Profile_list::getKV('id', $id);

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

        return true;
    }

    /**
     * Handle request
     *
     * Does the subscription and returns results.
     *
     * @param Array $args unused.
     *
     * @return void
     */
    function handle()
    {
        // Throws exception on error

        $ptag = Profile_tag::unTag($this->user->id, $this->tagged->id,
                                $this->peopletag->tag);

        if (!$ptag) {
            $user = User::getKV('id', $this->tagged->id);
            if ($user) {
                $this->clientError(
                        // TRANS: Client error displayed when an unknown error occurs while delisting a user.
                        // TRANS: %s is a username.
                        sprintf(_('There was an unexpected error while delisting %s.'),
                        $user->nickname));
            } else {
                // TRANS: Client error displayed when an unknown error occurs while listing a user.
                // TRANS: %s is a profile URL.
                $this->clientError(sprintf(_('There was a problem listing %s. ' .
                                      'The remote server is probably not responding correctly, ' .
                                      'please try retrying later.'), $this->profile->profileurl));
            }
        }
        if ($this->boolean('ajax')) {
            $this->startHTML('text/xml;charset=utf-8');
            $this->elementStart('head');
            // TRANS: Title after removing a user from a list.
            $this->element('title', null, _('Unlisted'));
            $this->elementEnd('head');
            $this->elementStart('body');
            $unsubscribe = new TagButton($this, $this->tagged, $this->peopletag);
            $unsubscribe->show();
            $this->elementEnd('body');
            $this->endHTML();
        } else {
            $url = common_local_url('subscriptions',
                                    array('nickname' => $this->user->nickname));
            common_redirect($url, 303);
        }
    }
}


code:
<?php
/**
 * StatusNet, the distributed open-source microblogging tool
 *
 * List of replies
 *
 * 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); }

/**
 * List of replies
 *
 * @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 RepliesAction extends ShowstreamAction
{
    public function getStream()
    {
        return new ReplyNoticeStream($this->target->getID(), $this->scoped);
    }

    /**
     * Title of the page
     *
     * Includes name of user and page number.
     *
     * @return string title of page
     */
    function title()
    {
        if ($this->page == 1) {
            // TRANS: Title for first page of replies for a user.
            // TRANS: %s is a user nickname.
            return sprintf(_("Replies to %s"), $this->target->getNickname());
        } else {
            // TRANS: Title for all but the first page of replies for a user.
            // TRANS: %1$s is a user nickname, %2$d is a page number.
            return sprintf(_('Replies to %1$s, page %2$d'),
                           $this->target->getNickname(),
                           $this->page);
        }
    }

    /**
     * Feeds for the <head> section
     *
     * @return void
     */
    function getFeeds()
    {
        return array(new Feed(Feed::JSON,
                              common_local_url('ApiTimelineMentions',
                                               array(
                                                    'id' => $this->target->getNickname(),
                                                    'format' => 'as')),
                              // TRANS: Link for feed with replies for a user.
                              // TRANS: %s is a user nickname.
                              sprintf(_('Replies feed for %s (Activity Streams JSON)'),
                                      $this->target->getNickname())),
                     new Feed(Feed::RSS1,
                              common_local_url('repliesrss',
                                               array('nickname' => $this->target->getNickname())),
                              // TRANS: Link for feed with replies for a user.
                              // TRANS: %s is a user nickname.
                              sprintf(_('Replies feed for %s (RSS 1.0)'),
                                      $this->target->getNickname())),
                     new Feed(Feed::RSS2,
                              common_local_url('ApiTimelineMentions',
                                               array(
                                                    'id' => $this->target->getNickname(),
                                                    'format' => 'rss')),
                              // TRANS: Link for feed with replies for a user.
                              // TRANS: %s is a user nickname.
                              sprintf(_('Replies feed for %s (RSS 2.0)'),
                                      $this->target->getNickname())),
                     new Feed(Feed::ATOM,
                              common_local_url('ApiTimelineMentions',
                                               array(
                                                    'id' => $this->target->getNickname(),
                                                    'format' => 'atom')),
                              // TRANS: Link for feed with replies for a user.
                              // TRANS: %s is a user nickname.
                              sprintf(_('Replies feed for %s (Atom)'),
                                    $this->target->getNickname())));
    }

    function showContent()
    {
        $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, 'replies',
                          array('nickname' => $this->target->getNickname()));
    }

    function showEmptyListMessage()
    {
        // TRANS: Empty list message for page with replies for a user.
        // TRANS: %1$s is the user nickname.
        $message = sprintf(_('This is the timeline showing replies to %1$s but no notices have arrived yet.'), $this->target->getNickname());
        $message .= ' ';    // Spacing between this sentence and the next.

        if (common_logged_in()) {
            if ($this->target->getID() === $this->scoped->getID()) {
                // TRANS: Empty list message for page with replies for a user for the logged in user.
                // TRANS: This message contains a Markdown link in the form [link text](link).
                $message .= _('You can engage other users in a conversation, subscribe to more people or [join groups](%%action.groups%%).');
            } else {
                // TRANS: Empty list message for page with replies for a user for all logged in users but the user themselves.
                // TRANS: %1$s is a user nickname and %2$s is the same but with a prepended '@' character. This message contains a Markdown link in the form [link text](link).
                $message .= sprintf(_('You can try to [nudge %1$s](../%1$s) or [post something to them](%%%%action.newnotice%%%%?content=%2$s).'), $this->target->getNickname(), '@' . $this->target->getNickname());
            }
        } else {
            // TRANS: Empty list message for page with replies for a user for not logged in users.
            // TRANS: %1$s is a user nickname. This message contains a Markdown link in the form [link text](link).
            $message .= sprintf(_('Why not [register an account](%%%%action.register%%%%) and then nudge %s or post a notice to them.'), $this->target->getNickname());
        }

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

    public function isReadOnly($args)
    {
        return true;
    }
}

repo_name: ksuudilla/gnu

license: mit


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/>.
 */

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

// Formatting of RSS handled by Rss10Action

class RepliesrssAction extends TargetedRss10Action
{
    protected function getNotices()
    {
        $stream = $this->target->getReplies(0, $this->limit);
        return $stream->fetchAll();
    }

    function getChannel()
    {
        $c = array('url' => common_local_url('repliesrss',
                                             array('nickname' =>
                                                   $this->target->getNickname())),
                   // TRANS: RSS reply feed title. %s is a user nickname.
                   'title' => sprintf(_("Replies to %s"), $this->target->getNickname()),
                   'link' => common_local_url('replies',
                                              array('nickname' => $this->target->getNickname())),
                   // TRANS: RSS reply feed description.
                   // TRANS: %1$s is a user nickname, %2$s is the StatusNet site name.
                   'description' => sprintf(_('Replies to %1$s on %2$s.'),
                                              $this->target->getNickname(), common_config('site', 'name')));
        return $c;
    }

    function isReadOnly($args)
    {
        return true;
    }
}


code:
<?php
/**
 * StatusNet - the distributed open-source microblogging tool
 * Copyright (C) 2010, StatusNet, Inc.
 *
 * Restore a backup of your own account from the browser
 *
 * PHP version 5
 *
 * 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  Account
 * @package   StatusNet
 * @author    Evan Prodromou <evan@status.net>
 * @copyright 2010 StatusNet, Inc.
 * @license   http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0
 * @link      http://status.net/
 */

if (!defined('STATUSNET')) {
    // This check helps protect against security problems;
    // your code file can't be executed directly from the web.
    exit(1);
}

/**
 * Restore a backup of your own account from the browser
 *
 * @category  Account
 * @package   StatusNet
 * @author    Evan Prodromou <evan@status.net>
 * @copyright 2010 StatusNet, Inc.
 * @license   http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0
 * @link      http://status.net/
 */
class RestoreaccountAction extends Action
{
    private $success = false;
    private $inprogress = false;

    /**
     * Returns the title of the page
     *
     * @return string page title
     */
    function title()
    {
        // TRANS: Page title for page where a user account can be restored from backup.
        return _('Restore account');
    }

    /**
     * For initializing members of the class.
     *
     * @param array $args misc. arguments
     *
     * @return boolean true
     * @throws ClientException
     */
    function prepare(array $args = [])
    {
        parent::prepare($args);

        $cur = common_current_user();

        if (empty($cur)) {
            // TRANS: Client exception displayed when trying to restore an account while not logged in.
            throw new ClientException(_('Only logged-in users can restore their account.'), 403);
        }

        if (!$cur->hasRight(Right::RESTOREACCOUNT)) {
            // TRANS: Client exception displayed when trying to restore an account without having restore rights.
            throw new ClientException(_('You may not restore your account.'), 403);
        }

        return true;
    }

    /**
     * Handler method
     *
     * @return void
     * @throws ClientException
     */
    function handle()
    {
        parent::handle();

        if ($this->isPost()) {
            $this->restoreAccount();
        } else {
            $this->showPage();
        }
        return null;
    }

    /**
     * Queue a file for restoration
     *
     * Uses the UserActivityStream class; may take a long time!
     *
     * @return void
     * @throws ClientException
     * @throws Exception
     */
    function restoreAccount()
    {
        $this->checkSessionToken();

        if (!isset($_FILES['restorefile']['error'])) {
            // TRANS: Client exception displayed trying to restore an account while something went wrong uploading a file.
            throw new ClientException(_('No uploaded file.'));
        }

        switch ($_FILES['restorefile']['error']) {
        case UPLOAD_ERR_OK: // success, jump out
            break;
        case UPLOAD_ERR_INI_SIZE:
            // TRANS: Client exception thrown when an uploaded file is larger than set in php.ini.
            throw new ClientException(_('The uploaded file exceeds the ' .
                'upload_max_filesize directive in php.ini.'));
        case UPLOAD_ERR_FORM_SIZE:
            throw new ClientException(
                // TRANS: Client exception.
                _('The uploaded file exceeds the MAX_FILE_SIZE directive' .
                ' that was specified in the HTML form.'));
        case UPLOAD_ERR_PARTIAL:
            @unlink($_FILES['restorefile']['tmp_name']);
            // TRANS: Client exception.
            throw new ClientException(_('The uploaded file was only' .
                ' partially uploaded.'));
        case UPLOAD_ERR_NO_FILE:
            // TRANS: Client exception. No file; probably just a non-AJAX submission.
            throw new ClientException(_('No uploaded file.'));
        case UPLOAD_ERR_NO_TMP_DIR:
            // TRANS: Client exception thrown when a temporary folder is not present to store a file upload.
            throw new ClientException(_('Missing a temporary folder.'));
        case UPLOAD_ERR_CANT_WRITE:
            // TRANS: Client exception thrown when writing to disk is not possible during a file upload operation.
            throw new ClientException(_('Failed to write file to disk.'));
        case UPLOAD_ERR_EXTENSION:
            // TRANS: Client exception thrown when a file upload operation has been stopped by an extension.
            throw new ClientException(_('File upload stopped by extension.'));
        default:
            common_log(LOG_ERR, __METHOD__ . ": Unknown upload error " .
                $_FILES['restorefile']['error']);
            // TRANS: Client exception thrown when a file upload operation has failed with an unknown reason.
            throw new ClientException(_('System error uploading file.'));
        }

        $filename = $_FILES['restorefile']['tmp_name'];

        try {
            if (!file_exists($filename)) {
                // TRANS: Server exception thrown when an expected file upload could not be found.
                throw new ServerException(_("No such file '$filename'."));
            }

            if (!is_file($filename)) {
                // TRANS: Server exception thrown when an expected file upload is not an actual file.
                throw new ServerException(_("Not a regular file: '$filename'."));
            }

            if (!is_readable($filename)) {
                // TRANS: Server exception thrown when an expected file upload could not be read.
                throw new ServerException(_("File '$filename' not readable."));
            }

            common_debug(sprintf("Getting backup from file '%s'.", $filename));

            $xml = file_get_contents($filename);

            // This check is costly but we should probably give
            // the user some info ahead of time.
            $doc = new DOMDocument();

            // Disable PHP warnings so we don't spew low-level XML errors to output...
            // would be nice if we can just get exceptions instead.
            $old_err = error_reporting();
            error_reporting($old_err & ~E_WARNING);
            $doc->loadXML($xml);
            error_reporting($old_err);

            $feed = $doc->documentElement;

            if (!$feed ||
                $feed->namespaceURI != Activity::ATOM ||
                $feed->localName != 'feed') {
                // TRANS: Client exception thrown when a feed is not an Atom feed.
                throw new ClientException(_("Not an Atom feed."));
            }

            // Enqueue for processing.

            $qm = QueueManager::get();
            $qm->enqueue([common_current_user(), $xml, false], 'feedimp');

            if ($qm instanceof UnQueueManager) {
                // No active queuing means we've actually just completed the job!
                $this->success = true;
            } else {
                // We've fed data into background queues, and it's probably still running.
                $this->inprogress = true;
            }
            $this->showPage();

        } catch (Exception $e) {
            // Delete the file and re-throw
            @unlink($_FILES['restorefile']['tmp_name']);
            throw $e;
        }
    }

    /**
     * Show a little form so that the person can upload a file to restore
     *
     * @return void
     */
    function showContent()
    {
        if ($this->success) {
            $this->element('p', null,
                           // TRANS: Success message when a feed has been restored.
                           _('Feed has been restored. Your old posts should now appear in search and your profile page.'));
        } else if ($this->inprogress) {
            $this->element('p', null,
                           // TRANS: Message when a feed restore is in progress.
                           _('Feed will be restored. Please wait a few minutes for results.'));
        } else {
            $form = new RestoreAccountForm($this);
            $form->show();
        }
    }

    /**
     * Return true if read only.
     *
     * MAY override
     *
     * @param array $args other arguments
     *
     * @return boolean is read only action?
     */
    function isReadOnly($args)
    {
        return false;
    }

    /**
     * Return last modified, if applicable.
     *
     * MAY override
     *
     * @return string last modified http header
     */
    function lastModified()
    {
        // For comparison with If-Last-Modified
        // If not applicable, return null
        return null;
    }

    /**
     * Return etag, if applicable.
     *
     * MAY override
     *
     * @return string etag http header
     */
    function etag()
    {
        return null;
    }
}

/**
 * A form for backing up the account.
 *
 * @category  Account
 * @package   StatusNet
 * @author    Evan Prodromou <evan@status.net>
 * @copyright 2010 StatusNet, Inc.
 * @license   http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0
 * @link      http://status.net/
 */
class RestoreAccountForm extends Form
{
    function __construct($out=null) {
        parent::__construct($out);
        $this->enctype = 'multipart/form-data';
    }

    /**
     * Class of the form.
     *
     * @return string the form's class
     */
    function formClass()
    {
        return 'form_profile_restore';
    }

    /**
     * URL the form posts to
     *
     * @return string the form's action URL
     */
    function action()
    {
        return common_local_url('restoreaccount');
    }

    /**
     * Output form data
     *
     * Really, just instructions for doing a backup.
     *
     * @return void
     */
    function formData()
    {
        $this->out->elementStart('p', 'instructions');

        // TRANS: Form instructions for feed restore.
        $this->out->raw(_('You can upload a backed-up timeline in '.
                          'Activity Streams format.'));

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

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

        $this->out->elementStart('li', array ('id' => 'settings_attach'));
        $this->out->element('input', array('name' => 'restorefile',
                                           'type' => 'file',
                                           'id' => 'restorefile'));
        $this->out->elementEnd('li');

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

    /**
     * Buttons for the form
     *
     * In this case, a single submit button
     *
     * @return void
     */
    function formActions()
    {
        $this->out->submit('submit',
                           // TRANS: Submit button to confirm upload of a user backup file for account restore.
                           _m('BUTTON', 'Upload'),
                           'submit',
                           null,
                           // TRANS: Title for submit button to confirm upload of a user backup file for account restore.
                           _('Upload the file'));
    }
}


code:
<?php
/**
 * StatusNet, the distributed open-source microblogging tool
 *
 * Action class to sandbox 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);
}

/**
 * Sandbox 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 RevokeRoleAction extends ProfileFormAction
{
    /**
     * Check parameters
     *
     * @param array $args action arguments (URL, GET, POST)
     *
     * @return boolean success flag
     */
    function prepare(array $args = array())
    {
        if (!parent::prepare($args)) {
            return false;
        }

        $this->role = $this->arg('role');
        if (!Profile_role::isValid($this->role)) {
            // TRANS: Client error displayed when trying to revoke an invalid role.
            $this->clientError(_('Invalid role.'));
        }
        if (!Profile_role::isSettable($this->role)) {
            // TRANS: Client error displayed when trying to revoke a reserved role.
            $this->clientError(_('This role is reserved and cannot be set.'));
        }

        $cur = common_current_user();

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

        if (!$cur->hasRight(Right::REVOKEROLE)) {
            // TRANS: Client error displayed when trying to revoke a role without having the right to do that.
            $this->clientError(_('You cannot revoke user roles on this site.'));
        }

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

        if (!$this->profile->hasRole($this->role)) {
            // TRANS: Client error displayed when trying to revoke a role that is not set.
            $this->clientError(_('User does not have this role.'));
        }

        return true;
    }

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


code:
<?php
/**
 * StatusNet - the distributed open-source microblogging tool
 * Copyright (C) 2010, StatusNet, Inc.
 *
 * robots.txt generator
 *
 * PHP version 5
 *
 * @category Action
 * @package  StatusNet
 * @author   Evan Prodromou <evan@status.net>
 * @license  http://www.fsf.org/licensing/licenses/agpl.html AGPLv3
 * @link     http://status.net/
 *
 * 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/>.
 */

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

/**
 * Prints out a static robots.txt
 *
 * @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 RobotstxtAction extends ManagedAction
{
    public function showPage()
    {
        if (Event::handle('StartRobotsTxt', array($this))) {

            header('Content-Type: text/plain');

            print "User-Agent: *\n";

            if (common_config('site', 'private')) {

                print "Disallow: /\n";
            } else {
                $disallow = common_config('robotstxt', 'disallow');

                foreach ($disallow as $dir) {
                    print "Disallow: /$dir/\n";
                }

                $crawldelay = common_config('robotstxt', 'crawldelay');

                if (!empty($crawldelay)) {
                    print "Crawl-delay: " . $crawldelay . "\n";
                }
            }

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

    /**
     * Return true; this page doesn't touch the DB.
     *
     * @param array $args other arguments
     *
     * @return boolean is read only action?
     */
    function isReadOnly($args)
    {
        return true;
    }
}


code:
<?php
/**
 * StatusNet - the distributed open-source microblogging tool
 * Copyright (C) 2008-2010, StatusNet, Inc.
 *
 * Really Simple Discovery (RSD) for API access
 *
 * PHP version 5
 *
 * 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 API
 * @package  StatusNet
 * @author   Evan Prodromou <evan@status.net>
 * @license  http://www.fsf.org/licensing/licenses/agpl.html AGPLv3
 * @link     http://status.net/
 *
 */

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

/**
 * RSD action class
 *
 * Really Simple Discovery (RSD) is a simple (to a fault, maybe)
 * discovery tool for blog APIs.
 *
 * http://tales.phrasewise.com/rfc/rsd
 *
 * Anil Dash suggested that RSD be used for services that implement
 * the Twitter API:
 *
 * http://dashes.com/anil/2009/12/the-twitter-api-is-finished.html
 *
 * It's in use now for WordPress.com blogs:
 *
 * http://matt.wordpress.com/xmlrpc.php?rsd
 *
 * I (evan@status.net) have tried to stay faithful to the premise of
 * RSD, while adding information useful to StatusNet client developers.
 * In particular:
 *
 * - There is a link from each user's profile page to their personal
 *   RSD feed. A personal rsd.xml includes a 'blogID' element that is
 *   their username.
 * - There is a link from the public root to '/rsd.xml', a public RSD
 *   feed. It's identical to the personal rsd except it doesn't include
 *   a blogId.
 * - I've added a setting to the API to indicate that OAuth support is
 *   available.
 *
 * @category API
 * @package  StatusNet
 * @author   Evan Prodromou <evan@status.net>
 * @license  http://www.fsf.org/licensing/licenses/agpl.html AGPLv3
 * @link     http://status.net/
 */
class RsdAction extends Action
{
    /**
     * Optional attribute for the personal rsd.xml file.
     */
    var $user = null;

    /**
     * Prepare the action for use.
     *
     * Check for a nickname; redirect if non-canonical; if
     * not provided, assume public rsd.xml.
     *
     * @param array $args GET, POST, and URI arguments.
     *
     * @return boolean success flag
     */
    function prepare(array $args = array())
    {
        parent::prepare($args);

        // optional argument

        $nickname_arg = $this->arg('nickname');

        if (empty($nickname_arg)) {
            $this->user = null;
        } else {
            $nickname = common_canonical_nickname($nickname_arg);

            // Permanent redirect on non-canonical nickname

            if ($nickname_arg != $nickname) {
                common_redirect(common_local_url('rsd', array('nickname' => $nickname)), 301);
            }

            $this->user = User::getKV('nickname', $nickname);

            if (empty($this->user)) {
                // TRANS: Client error.
                $this->clientError(_('No such user.'), 404);
            }
        }

        return true;
    }

    /**
     * Action handler.
     *
     * Outputs the XML format for an RSD file. May include
     * personal information if this is a personal file
     * (based on whether $user attribute is set).
     *
     * @param array $args array of arguments
     *
     * @return nothing
     */
    function handle()
    {
        header('Content-Type: application/rsd+xml');

        $this->startXML();

        $rsdNS = 'http://archipelago.phrasewise.com/rsd';
        $this->elementStart('rsd', array('version' => '1.0',
                                         'xmlns' => $rsdNS));
        $this->elementStart('service');
        // TRANS: Engine name for RSD.
        $this->element('engineName', null, _('StatusNet'));
        $this->element('engineLink', null, 'http://status.net/');
        $this->elementStart('apis');
        if (Event::handle('StartRsdListApis', array($this, $this->user))) {

            $blogID   = (empty($this->user)) ? '' : $this->user->nickname;
            $apiAttrs = array('name' => 'Twitter',
                              'preferred' => 'true',
                              'apiLink' => $this->_apiRoot(),
                              'blogID' => $blogID);

            $this->elementStart('api', $apiAttrs);
            $this->elementStart('settings');
            $this->element('docs', null,
                           common_local_url('doc', array('title' => 'api')));
            $this->element('setting', array('name' => 'OAuth'),
                           'true');
            $this->elementEnd('settings');
            $this->elementEnd('api');

            // Atom API

            if (empty($this->user)) {
                $service = common_local_url('ApiAtomService');
            } else {
                $service = common_local_url('ApiAtomService', array('id' => $this->user->nickname));
            }

            $this->element('api', array('name' => 'Atom',
                                        'preferred' => 'false',
                                        'apiLink' => $service,
                                        'blogID' => $blogID));

            Event::handle('EndRsdListApis', array($this, $this->user));
        }
        $this->elementEnd('apis');
        $this->elementEnd('service');
        $this->elementEnd('rsd');

        $this->endXML();

        return true;
    }

    /**
     * Returns last-modified date for use in caching
     *
     * Per-user rsd.xml is dated to last change of user
     * (in case of nickname change); public has no date.
     *
     * @return string date of last change of this page
     */
    function lastModified()
    {
        if (!empty($this->user)) {
            return $this->user->modified;
        } else {
            return null;
        }
    }

    /**
     * Flag to indicate if this action is read-only
     *
     * It is; it doesn't change the DB.
     *
     * @param array $args ignored
     *
     * @return boolean true
     */
    function isReadOnly($args)
    {
        return true;
    }

    /**
     * Return current site's API root
     *
     * Varies based on URL parameters, like if fancy URLs are
     * turned on.
     *
     * @return string API root URI for this site
     */
    private function _apiRoot()
    {
        if (common_config('site', 'fancy')) {
            return common_path('api/', true);
        } else {
            return common_path('index.php/api/', true);
        }
    }
}


code:
<?php
/**
 * StatusNet, the distributed open-source microblogging tool
 *
 * Action class to sandbox 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);
}

/**
 * Sandbox 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 SandboxAction extends ProfileFormAction
{
    /**
     * Check parameters
     *
     * @param array $args action arguments (URL, GET, POST)
     *
     * @return boolean success flag
     */
    function prepare(array $args = array())
    {
        if (!parent::prepare($args)) {
            return false;
        }

        $cur = common_current_user();

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

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

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

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

        return true;
    }

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


code:
<?php
// This file is part of GNU social - https://www.gnu.org/software/social
//
// GNU social 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.
//
// GNU social 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 GNU social.  If not, see <http://www.gnu.org/licenses/>.

/**
 * Action for showing profiles self-tagged with a given tag
 *
 * @category  Action
 * @package   GNUsocial
 * @author    Evan Prodromou <evan@status.net>
 * @author    Zach Copley <zach@status.net>
 * @copyright 2009 StatusNet, Inc.
 * @license   https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
 */

defined('GNUSOCIAL') || die();

/**
 * This class outputs a paginated list of profiles self-tagged with a given tag
 *
 * @category  Output
 * @copyright 2009 StatusNet, Inc.
 * @license   https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
 *
 * @see       Action
 */
class SelftagAction extends Action
{
    public $tag  = null;
    public $page = null;

    /**
     * For initializing members of the class.
     *
     * @param array $args misc. arguments
     *
     * @return boolean true
     * @throws ClientException
     */
    public function prepare(array $args = [])
    {
        parent::prepare($args);

        $this->tag = $this->trimmed('tag');

        if (!common_valid_profile_tag($this->tag)) {
            // TRANS: Client error displayed when trying to list a profile with an invalid list.
            // TRANS: %s is the invalid list name.
            $this->clientError(sprintf(
                _('Not a valid list: %s.'),
                $this->tag
            ));
            return null;
        }

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

        common_set_returnto($this->selfUrl());

        return true;
    }

    /**
     * Handler method
     *
     * @return void is read only action?
     */
    public function handle()
    {
        parent::handle();
        $this->showPage();
    }

    /**
     * Whips up a query to get a list of profiles based on the provided
     * people tag and page, initalizes a ProfileList widget, and displays
     * it to the user.
     */
    public function showContent()
    {
        $profile = new Profile();

        $profile->joinAdd(['id', 'profile_list:tagger']);
        $profile->joinAdd(['id', 'profile_role:profile_id'], 'LEFT');

        $profile->whereAdd(sprintf(
            "profile_list.tag = '%s'",
            $profile->escape($this->tag)
        ));
        $profile->whereAdd("COALESCE(profile_role.role, '') <> 'silenced'");

        $user = common_current_user();
        if (!empty($user)) {
            $profile->whereAdd(sprintf(
                'profile_list.tagger = %d OR profile_list.private IS NOT TRUE',
                $user->getID()
            ));
        } else {
            $profile->whereAdd('profile_list.private IS NOT TRUE');
        }

        $profile->orderBy('profile_list.modified DESC, profile_list.id DESC');

        $offset = ($this->page - 1) * PROFILES_PER_PAGE;
        $limit  = PROFILES_PER_PAGE + 1;

        $profile->limit($offset, $limit);

        $profile->find();

        $ptl = new SelfTagProfileList($profile, $this); // pass the ammunition
        $cnt = $ptl->show();

        $this->pagination(
            $this->page > 1,
            $cnt > PROFILES_PER_PAGE,
            $this->page,
            'selftag',
            ['tag' => $this->tag]
        );
    }

    /**
     * Returns the page title
     *
     * @return string page title
     */
    public function title()
    {
        // TRANS: Page title for page showing self tags.
        // TRANS: %1$s is a tag, %2$d is a page number.
        return sprintf(
            _('Users self-tagged with %1$s, page %2$d'),
            $this->tag,
            $this->page
        );
    }
}

class SelfTagProfileList extends ProfileList
{
    public function newListItem(Profile $target)
    {
        return new SelfTagProfileListItem($target, $this->action);
    }
}

class SelfTagProfileListItem extends ProfileListItem
{
    public function linkAttributes()
    {
        $aAttrs = parent::linkAttributes();

        if (common_config('nofollow', 'selftag')) {
            $aAttrs['rel'] .= ' nofollow';
        }

        return $aAttrs;
    }

    public function homepageAttributes()
    {
        $aAttrs = parent::linkAttributes();

        if (common_config('nofollow', 'selftag')) {
            $aAttrs['rel'] = 'nofollow';
        }

        return $aAttrs;
    }

    public function showTags()
    {
        $selftags = new SelfTagsWidget($this->out, $this->profile, $this->profile);
        $selftags->show();

        $user = common_current_user();

        if (!empty($user) && $user->id != $this->profile->getID() &&
                $user->getProfile()->canTag($this->profile)) {
            $yourtags = new PeopleTagsWidget($this->out, $user, $this->profile);
            $yourtags->show();
        }
    }
}


code:
<?php
// This file is part of GNU social - https://www.gnu.org/software/social
//
// GNU social 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.
//
// GNU social 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 GNU social.  If not, see <http://www.gnu.org/licenses/>.

/**
 * Sessions administration panel
 *
 * @category  Settings
 * @package   GNUsocial
 * @author    Zach Copley <zach@status.net>
 * @copyright 2010 StatusNet, Inc.
 * @license   https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
 */

defined('GNUSOCIAL') || die();

/**
 * Admin site sessions
 *
 * @category  Admin
 * @package   GNUsocial
 * @author    Zach Copley <zach@status.net>
 * @license   https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
 */
class SessionsadminpanelAction extends AdminPanelAction
{
    /**
     * Returns the page title
     *
     * @return string page title
     */
    public function title()
    {
        // TRANS: Title for the sessions administration panel.
        return _m('TITLE', 'Sessions');
    }

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

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

    /**
     * Save settings from the form
     *
     * @return void
     */
    public 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('START TRANSACTION');

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

        $config->query('COMMIT');

        return;
    }

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

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

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

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

    /**
     * Data elements of the form
     *
     * @return void
     */
    public 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
     */
    public 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
// This file is part of GNU social - https://www.gnu.org/software/social
//
// GNU social 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.
//
// GNU social 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 GNU social.  If not, see <http://www.gnu.org/licenses/>.

/**
 * Show an OAuth application
 *
 * @category  Application
 * @package   GNUsocial
 * @author    Zach Copley <zach@status.net>
 * @copyright 2008-2011 StatusNet, Inc.
 * @license   https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
 */

defined('GNUSOCIAL') || die();

/**
 * Show an OAuth application
 *
 * @category  Application
 * @package   GNUsocial
 * @author    Zach Copley <zach@status.net>
 * @license   https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
 */
class ShowApplicationAction extends Action
{
    /**
     * Application to show
     */
    public $application = null;

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

    public $msg = null;

    public $success = null;

    /**
     * Load attributes based on database arguments
     *
     * Loads all the DB stuff
     *
     * @param array $args $_REQUEST array
     *
     * @return success flag
     */
    public function prepare(array $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
     */
    public function handle()
    {
        parent::handle();

        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
     */
    public function title()
    {
        if (!empty($this->application->name)) {
            return 'Application: ' . $this->application->name;
        }
    }

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

    public 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',
                [
                    'src'   => $this->application->icon,
                    'class' => 'u-photo logo entity_depiction',
                ]
            );
        }

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

        $this->element(
            'a',
            [
                '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',
            [
                'href' => common_local_url(
                    'editapplication',
                    ['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',
            [
                'id'     => 'form_reset_key',
                'class'  => 'form_reset_key',
                'method' => 'POST',
                'action' => common_local_url(
                    'showapplication',
                    ['id' => $this->application->id]
                ),
            ]
        );
        $this->elementStart('fieldset');
        $this->hidden('token', common_session_token());

        $this->element(
            'input',
            [
                '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',
            [
                'id' => 'form_delete_application',
                'class' => 'form_delete_application',
                'method' => 'POST',
                'action' => common_local_url(
                    'deleteapplication',
                    ['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',
            [
                'href'  => common_local_url('oauthappssettings'),
                'class' => 'more',
            ],
            'View your applications'
        );
        $this->elementEnd('p');
    }

    /**
     * Add a confirm script for Consumer key/secret reset
     *
     * @return void
     */
    public 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?
     *
     */
    public function resetKey()
    {
        $this->application->query('START TRANSACTION');

        $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();
    }
}


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('GNUSOCIAL')) { exit(1); }

/**
 * 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 $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);
        }
    }

    public function getStream()
    {
        if ($this->scoped instanceof Profile && $this->scoped->isLocal() && $this->scoped->getUser()->streamModeOnly()) {
            $stream = new GroupNoticeStream($this->group, $this->scoped);
        } else {
            $stream = new ThreadingGroupNoticeStream($this->group, $this->scoped);
        }

        return $stream;
    }

    /**
     * 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/notices/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
{
    protected $redirectAfterLogin = true;

    /**
     * Notice object to show
     */
    public $notice = null;

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

    /**
     * Avatar of the profile of the notice object
     */
    public $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=[])
    {
        parent::prepare($args);
        if ($this->boolean('ajax')) {
            GNUsocial::setApi(true);
        }

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

        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 = null;
        try {
            $notice = Notice::getByID($id);
            // Alright, got it!
            return $notice;
        } catch (NoResultException $e) {
            // Hm, not found.
            $deleted = null;
            Event::handle('IsNoticeDeleted', [$id, &$deleted]);
            if ($deleted === true) {
                // TRANS: Client error displayed trying to show a deleted notice.
                throw new ClientException(_('Notice deleted.'), 410);
            }
        }
        // TRANS: Client error displayed trying to show a non-existing notice.
        throw new ClientException(_('No such notice.'), 404);
    }

    /**
     * Is this action read-only?
     *
     * @return boolean true
     */
    public 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
     */
    public 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
     */
    public function etag()
    {
        $avtime = ($this->avatar) ?
          strtotime($this->avatar->modified) : 0;

        return 'W/"' . implode(':', [$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
     */
    public function title()
    {
        return $this->notice->getTitle();
    }

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

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

    public function getFeeds()
    {
        return [
            new Feed(Feed::JSON,
                     common_local_url('ApiStatusesShow',
                                      ['id' => $this->target->getID(),
                                       'format' => 'json']),
                     // TRANS: Title for link to single notice representation.
                     // TRANS: %s is a user nickname.
                     sprintf(_('Single notice (JSON)'))
            ),
            new Feed(Feed::ATOM,
                    common_local_url('ApiStatusesShow',
                                     ['id' => $this->target->getID(),
                                      'format' => 'atom']),
                    // TRANS: Title for link to notice feed.
                    // TRANS: %s is a user nickname.
                    sprintf(_('Single notice (Atom)'))
            )
        ];
    }

    /**
     * Extra <head> content
     *
     * Facebook OpenGraph metadata.
     *
     * @return void
     */
    public function extraHead()
    {
        // Extras to aid in sharing notices to Facebook
        $avatarUrl = $this->profile->avatarUrl(AVATAR_PROFILE_SIZE);
        $this->element('meta', ['property' => 'og:image',
                                'content' => $avatarUrl]);
        $this->element('meta', ['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('GNUSOCIAL')) { exit(1); }

class ShowprofiletagAction extends ShowstreamAction
{
    var $notice, $peopletag;

    protected function doStreamPreparation()
    {
        $tag = common_canonical_tag($this->arg('tag'));
        try {
            $this->peopletag = Profile_list::getByPK(['tagger' => $this->target->getID(), 'tag' => $tag]);
        } catch (NoResultException $e) {
            // TRANS: Client error displayed trying to reference a non-existing list.
            throw new ClientException('No such list.');
        }

        if ($this->peopletag->private && !$this->peopletag->getTagger()->sameAs($this->scoped)) {
            // TRANS: Client error displayed trying to reference a non-existing list.
            throw new AuthorizationException('You do not have permission to see this list.');
        }
    }

    public function getStream()
    {
        return new PeopletagNoticeStream($this->peopletag, $this->scoped);
    }

    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->target->getNickname(),
                                $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->target->getNickname()
                          );
        }
    }

    function getFeeds()
    {
        #XXX: make these actually work
        return array(new Feed(Feed::JSON,
                common_local_url(
                    'ApiTimelineList', array(
                        'user' => $this->target->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->target->getNickname())),
                new Feed(Feed::RSS2,
                common_local_url(
                    'ApiTimelineList', array(
                        'user' => $this->target->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->target->getNickname())),
            new Feed(Feed::ATOM,
                common_local_url(
                    'ApiTimelineList', array(
                        'user' => $this->target->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->target->getNickname()
                       )
              )
        );
    }

    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->target->getNickname()) . ' ';

        if (common_logged_in()) {
            if ($this->target->sameAs($this->scoped)) {
                // 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');
    }

    protected function showContent()
    {
        $this->showPeopletag();
        parent::showContent();
    }

    function showPeopletag()
    {
        $tag = new Peopletag($this->peopletag, $this->scoped, $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,
                                    'nickname' => $this->target->getNickname())
            );

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

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

    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->target->getNickname(),
                                                                           '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');
    }
}