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

/**
 * User profile page
 *
 * @category  Personal
 * @package   GNUsocial
 * @author    Evan Prodromou <evan@status.net>
 * @author    Sarven Capadisli <csarven@status.net>
 * @copyright 2009 Free Software Foundation, Inc http://www.fsf.org
 * @license   https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
 */

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

/**
 * 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 NoticestreamAction
{
    public function getStream()
    {
        if (empty($this->tag)) {
            $stream = new ProfileNoticeStream($this->target, $this->scoped);
        } else {
            $stream = new TaggedProfileNoticeStream($this->target, $this->tag, $this->scoped);
        }

        return $stream;
    }

    public function title()
    {
        $base = $this->target->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 sprintf(_('Notices by %s'), $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
                );
            }
        }
    }

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

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

    public function showPageNoticeBlock()
    {
        return;
    }

    public function getFeeds()
    {
        if (!empty($this->tag)) {
            return [new Feed(
                Feed::RSS1,
                common_local_url(
                    'userrss',
                    [
                        'nickname' => $this->target->getNickname(),
                        '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->getNickname(),
                    $this->tag
                )
            )];
        }

        if (!$this->target->isLocal()) {
            // remote profiles at least have Atom, but we can't guarantee anything else
            return [new Feed(
                Feed::ATOM,
                $this->target->getAtomFeed(),
                // TRANS: Title for link to notice feed.
                // TRANS: %s is a user nickname.
                sprintf(
                    _('Notice feed for %s (Atom)'),
                    $this->target->getNickname()
                )
            )];
        }

        return [
            new Feed(
                Feed::JSON,
                common_local_url(
                    'ApiTimelineUser',
                    [
                        'id'     => $this->target->getID(),
                        '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->getNickname()
                )
            ),
            new Feed(
                Feed::RSS1,
                common_local_url(
                    'userrss',
                    ['nickname' => $this->target->getNickname()]
                ),
                // TRANS: Title for link to notice feed.
                // TRANS: %s is a user nickname.
                sprintf(
                    _('Notice feed for %s (RSS 1.0)'),
                    $this->target->getNickname()
                )
            ),
            new Feed(
                Feed::RSS2,
                common_local_url(
                    'ApiTimelineUser',
                    [
                        'id'     => $this->target->getID(),
                        '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->getNickname()
                )
            ),
            new Feed(
                Feed::ATOM,
                $this->target->getAtomFeed(),
                // TRANS: Title for link to notice feed.
                // TRANS: %s is a user nickname.
                sprintf(
                    _('Notice feed for %s (Atom)'),
                    $this->target->getNickname()
                )
            ),
            new Feed(
                Feed::FOAF,
                common_local_url(
                    'foaf',
                    ['nickname' => $this->target->getNickname()]
                ),
                // 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->getNickname())
            )
        ];
    }

    public function extraHeaders()
    {
        parent::extraHeaders();
        // Publish all the rel="me" in the HTTP headers on our main profile page
        if (get_class($this) == 'ShowstreamAction') {
            foreach ($this->target->getRelMes() as $relMe) {
                header('Link: <' . htmlspecialchars($relMe['href']) . '>; rel="me"', false);
            }
        }
    }

    public function extraHead()
    {
        if (!$this->target->isLocal()) {
            $this->element(
                'meta',
                [
                    'name'    => 'robots',
                    'content' => 'noindex',
                ]
            );
        }

        if ($this->target->bio) {
            $this->element(
                'meta',
                [
                    'name'    => 'description',
                    'content' => $this->target->getDescription(),
                ]
            );
        }

        $rsd = common_local_url(
            'rsd',
            ['nickname' => $this->target->getNickname()]
        );

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

        if ($this->page != 1) {
            $this->element(
                'link',
                [
                    'rel' => 'canonical',
                    'href' => $this->target->getUrl(),
                ]
            );
        }
    }

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

        if ($this->scoped instanceof Profile) {
            if ($this->target->getID() === $this->scoped->getID()) {
                // 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->getNickname(), '@' . $this->target->getNickname());
            }
        } 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->getNickname());
        }

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

    public function showNotices()
    {
        $pnl = new PrimaryNoticeList($this->notice, $this);
        $cnt = $pnl->show();
        if (0 == $cnt) {
            $this->showEmptyListMessage();
        }

        // either nickname or id will be used, depending on which action (showstream, userbyid...)
        $args = array('nickname' => $this->target->getNickname(), 'id' => $this->target->getID());
        if (!empty($this->tag)) {
            $args['tag'] = $this->tag;
        }
        $this->pagination(
            $this->page > 1,
            $cnt > NOTICES_PER_PAGE,
            $this->page,
            $this->getActionName(),
            $args
        );
    }

    public 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->getNickname(),
                $this->target->getNickname()
            );
        } 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->getNickname(),
                $this->target->getNickname()
            );
        }
        $this->elementStart('div', array('id' => 'anon_notice'));
        $this->raw(common_markup_to_html($m));
        $this->elementEnd('div');
    }

    public function noticeFormOptions()
    {
        $options = parent::noticeFormOptions();

        if (!$this->scoped instanceof Profile || !$this->scoped->sameAs($this->target)) {
            $options['to_profile'] = $this->target;
        }

        return $options;
    }
}


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('GNUSOCIAL')) { 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
{
    function handlePost()
    {
        assert($this->scoped instanceof Profile);
        assert($this->profile instanceof Profile);

        $this->profile->silenceAs($this->scoped);
    }
}

repo_name: suraj/sloth

license: mit


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 _m('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 = [];

        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(_m('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(_m('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(_m('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(_m('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(_m('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(_m('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(_m('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(_m('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(_m('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.
                     _m('The name of your site, like "Yourcompany Microblog".'));
        $this->unli();

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

        $this->li();
        // TRANS: Field label on site settings panel.
        $this->input('broughtbyurl', _m('Brought by URL'),
                     // TRANS: Field title on site settings panel.
                     _m('URL used for credits link in footer of each page.'));
        $this->unli();
        $this->li();
        // TRANS: Field label on site settings panel.
        $this->input('email', _m('Email'),
                     // TRANS: Field title on site settings panel.
                     _m('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 = [];

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

        asort($timezones);

        $this->li();
        // TRANS: Dropdown label on site settings panel.
        $this->out->dropdown('timezone', _m('Default timezone'),
                             // TRANS: Dropdown title on site settings panel.
                             $timezones, _m('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.
                             _m('Default language'),
                             get_nice_language_list(),
                             // TRANS: Dropdown title on site settings panel.
                             _m('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.
                     _m('Text limit'),
                     // TRANS: Field title on site settings panel.
                     _m('Maximum number of characters for notices.'));
        $this->unli();

        $this->li();
        $this->input('dupelimit',
                     // TRANS: Field label on site settings panel.
                     _m('Dupe limit'),
                     // TRANS: Field title on site settings panel.
                     _m('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', ['id' => 'settings_site_logo']);
        // TRANS: Fieldset legend for form to change logo.
        $this->out->element('legend', null, _m('Logo'));

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

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

        $this->li();
        $this->input('ssllogo',
                     // TRANS: Field label for SSL GNU social site logo.
                     _m('SSL logo'),
                     // TRANS: Title for field label for SSL GNU social 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.
                           _m('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('GNUSOCIAL')) { exit(1); }

/**
 * 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
        $siteNotice = common_purify($siteNotice);
    }
}

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.')
        );
    }
}


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

/**
 * Settings for SMS.
 *
 * @category  Setting
 * @package   GNUsocial
 * @author    Evan Prodromou <evan@status.net>
 * @copyright 2008-2009 StatusNet, Inc.
 * @license   https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
 */

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

/**
 * Settings for SMS
 *
 * @copyright 2008-2009 StatusNet, Inc.
 * @license   https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
 *
 * @see      SettingsAction
 */
class SmssettingsAction extends SettingsAction
{
    protected function doPreparation()
    {
        if (!common_config('sms', 'enabled')) {
            // TRANS: Message given in the SMS settings if SMS is not enabled on the site.
            throw new ServerException(_('SMS is not available.'));
        }
    }

    /**
     * Title of the page
     *
     * @return string Title of the page
     */
    public function title()
    {
        // TRANS: Title for SMS settings.
        return _('SMS settings');
    }

    /**
     * Instructions for use
     *
     * @return instructions for use
     */
    public function getInstructions()
    {
        // XXX: For consistency of parameters in messages, this should be a
        //      regular parameters, replaced with sprintf().
        // TRANS: SMS settings page instructions.
        // TRANS: %%site.name%% is the name of the site.
        return _('You can receive SMS messages through email from %%site.name%%.');
    }

    public function showScripts()
    {
        parent::showScripts();
        $this->autofocus('sms');
    }

    /**
     * Content area of the page
     *
     * Shows a form for adding and removing SMS phone numbers and setting
     * SMS preferences.
     *
     * @return void
     */
    public function showContent()
    {
        $user = $this->scoped->getUser();

        $this->elementStart('form', array('method' => 'post',
                                          'id' => 'form_settings_sms',
                                          'class' => 'form_settings',
                                          'action' =>
                                          common_local_url('smssettings')));

        $this->elementStart('fieldset', array('id' => 'settings_sms_address'));
        // TRANS: Form legend for SMS settings form.
        $this->element('legend', null, _('SMS address'));
        $this->hidden('token', common_session_token());

        if (!$user->isNull('sms')) {
            $carrier = $user->getCarrier();
            $this->element(
                'p',
                'form_confirmed',
                $user->sms . ' (' . $carrier->name . ')'
            );
            $this->element(
                'p',
                'form_guide',
                // TRANS: Form guide in SMS settings form.
                _('Current confirmed SMS-enabled phone number.')
            );
            $this->hidden('sms', $user->sms);
            $this->hidden('carrier', $user->carrier);
            // TRANS: Button label to remove a confirmed SMS address.
            $this->submit('remove', _m('BUTTON', 'Remove'));
        } else {
            try {
                $confirm = $this->getConfirmation();
                $carrier = Sms_carrier::getKV($confirm->address_extra);
                $this->element(
                    'p',
                    'form_unconfirmed',
                    $confirm->address . ' (' . $carrier->name . ')'
                );
                $this->element(
                    'p',
                    'form_guide',
                    // TRANS: Form guide in IM settings form.
                    _('Awaiting confirmation on this phone number.')
                );
                $this->hidden('sms', $confirm->address);
                $this->hidden('carrier', $confirm->address_extra);
                // TRANS: Button label to cancel a SMS address confirmation procedure.
                $this->submit('cancel', _m('BUTTON', 'Cancel'));

                $this->elementStart('ul', 'form_data');
                $this->elementStart('li');
                // TRANS: Field label for SMS address input in SMS settings form.
                $this->input(
                    'code',
                    _('Confirmation code'),
                    null,
                    // TRANS: Form field instructions in SMS settings form.
                    _('Enter the code you received on your phone.')
                );
                $this->elementEnd('li');
                $this->elementEnd('ul');
                // TRANS: Button label to confirm SMS confirmation code in SMS settings.
                $this->submit('confirm', _m('BUTTON', 'Confirm'));
            } catch (NoResultException $e) {
                $this->elementStart('ul', 'form_data');
                $this->elementStart('li');
                // TRANS: Field label for SMS phone number input in SMS settings form.
                $this->input(
                    'sms',
                    _('SMS phone number'),
                    ($this->arg('sms') ?: null),
                    // TRANS: SMS phone number input field instructions in SMS settings form.
                    _('Phone number, no punctuation or spaces, ' .
                    'with area code.')
                );
                $this->elementEnd('li');
                $this->elementEnd('ul');
                $this->carrierSelect();
                // TRANS: Button label for adding a SMS phone number in SMS settings form.
                $this->submit('add', _m('BUTTON', 'Add'));
            }
        }
        $this->elementEnd('fieldset');

        if (!$user->isNull('sms')) {
            $this->elementStart('fieldset', ['id' => 'settings_sms_incoming_email']);
            // XXX: Confused! This is about SMS. Should this message be updated?
            // TRANS: Form legend for incoming SMS settings form.
            $this->element('legend', null, _('Incoming email'));

            if (!$user->isNull('incomingemail')) {
                $this->element('p', 'form_unconfirmed', $user->incomingemail);
                $this->element(
                    'p',
                    'form_note',
                    // XXX: Confused! This is about SMS. Should this message be updated?
                    // TRANS: Form instructions for incoming SMS e-mail address form in SMS settings.
                    _('Send email to this address to post new notices.')
                );
                // TRANS: Button label for removing a set sender SMS e-mail address to post notices from.
                $this->submit('removeincoming', _m('BUTTON', 'Remove'));
            }

            $this->element(
                'p',
                'form_guide',
                // XXX: Confused! This is about SMS. Should this message be updated?
                // TRANS: Instructions for incoming SMS e-mail address input form.
                _('Make a new email address for posting to; ' .
                  'cancels the old one.')
            );
            // TRANS: Button label for adding an SMS e-mail address to send notices from.
            $this->submit('newincoming', _m('BUTTON', 'New'));
            $this->elementEnd('fieldset');
        }

        $this->elementStart('fieldset', array('id' => 'settings_sms_preferences'));
        // TRANS: Form legend for SMS preferences form.
        $this->element('legend', null, _('SMS preferences'));

        $this->elementStart('ul', 'form_data');
        $this->elementStart('li');
        $this->checkbox(
            'smsnotify',
            // TRANS: Checkbox label in SMS preferences form.
            _('Send me notices through SMS; ' .
              'I understand I may incur ' .
              'exorbitant charges from my carrier.'),
            $user->smsnotify
        );
        $this->elementEnd('li');
        $this->elementEnd('ul');

        // TRANS: Button label to save SMS preferences.
        $this->submit('save', _m('BUTTON', 'Save'));

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

    /**
     * Get a pending confirmation, if any, for this user
     *
     * @return void
     *
     * @todo very similar to EmailsettingsAction::getConfirmation(); refactor?
     */
    public function getConfirmation()
    {
        $confirm = new Confirm_address();

        $confirm->user_id      = $this->scoped->getID();
        $confirm->address_type = 'sms';

        if ($confirm->find(true)) {
            return $confirm;
        }

        throw new NoResultException($confirm);
    }

    protected function doPost()
    {
        if ($this->arg('save')) {
            return $this->savePreferences();
        } elseif ($this->arg('add')) {
            return $this->addAddress();
        } elseif ($this->arg('cancel')) {
            return $this->cancelConfirmation();
        } elseif ($this->arg('remove')) {
            return $this->removeAddress();
        } elseif ($this->arg('removeincoming')) {
            return $this->removeIncoming();
        } elseif ($this->arg('newincoming')) {
            return $this->newIncoming();
        } elseif ($this->arg('confirm')) {
            return $this->confirmCode();
        }
        // TRANS: Message given submitting a form with an unknown action in SMS settings.
        throw new ClientException(_('Unexpected form submission.'));
    }

    /**
     * Handle a request to save preferences
     *
     * Sets the user's SMS preferences in the DB.
     *
     * @return void
     */
    public function savePreferences()
    {
        $user = $this->scoped->getUser();

        $user->query('BEGIN');

        $original = clone($user);

        $user->smsnotify = $this->boolean('smsnotify');

        $result = $user->update($original);

        if ($result === false) {
            common_log_db_error($user, 'UPDATE', __FILE__);
            // TRANS: Server error thrown on database error updating SMS preferences.
            throw new ServerException(_('Could not update user.'));
        }

        $user->query('COMMIT');

        // TRANS: Confirmation message for successful SMS preferences save.
        return _('SMS preferences saved.');
    }

    /**
     * Add a new SMS number for confirmation
     *
     * When the user requests a new SMS number, sends a confirmation
     * message.
     *
     * @return void
     */
    public function addAddress()
    {
        $user = common_current_user();

        $sms        = $this->trimmed('sms');
        $carrier_id = $this->trimmed('carrier');

        // Some validation

        if (empty($sms)) {
            // TRANS: Message given saving SMS phone number without having provided one.
            throw new ClientException(_('No phone number.'));
        }

        if (empty($carrier_id)) {
            // TRANS: Message given saving SMS phone number without having selected a carrier.
            throw new ClientException(_('No carrier selected.'));
        }

        $sms = common_canonical_sms($sms);

        if ($user->sms === $sms) {
            // TRANS: Message given saving SMS phone number that is already set.
            throw new AlreadyFulfilledException(_('That is already your phone number.'));
        } elseif ($this->smsExists($sms)) {
            // TRANS: Message given saving SMS phone number that is already set for another user.
            throw new ClientException(_('That phone number already belongs to another user.'));
        }

        $confirm = new Confirm_address();

        $confirm->address       = $sms;
        $confirm->address_extra = $carrier_id;
        $confirm->address_type  = 'sms';
        $confirm->user_id       = $this->scoped->getID();
        $confirm->code          = common_confirmation_code(40);

        $result = $confirm->insert();

        if ($result === false) {
            common_log_db_error($confirm, 'INSERT', __FILE__);
            // TRANS: Server error thrown on database error adding SMS confirmation code.
            $this->serverError(_('Could not insert confirmation code.'));
        }

        $carrier = Sms_carrier::getKV($carrier_id);

        mail_confirm_sms(
            $confirm->code,
            $user->nickname,
            $carrier->toEmailAddress($sms)
        );

        // TRANS: Message given saving valid SMS phone number that is to be confirmed.
        return _('A confirmation code was sent to the phone number you added. '.
                 'Check your phone for the code and instructions '.
                 'on how to use it.');
    }

    /**
     * Cancel a pending confirmation
     *
     * Cancels the confirmation.
     *
     * @return void
     */
    public function cancelConfirmation()
    {
        $sms     = $this->trimmed('sms');
        $carrier = $this->trimmed('carrier');

        try {
            $confirm = $this->getConfirmation();
            if ($confirm->address != $sms) {
                // TRANS: Message given canceling SMS phone number confirmation for the wrong phone number.
                throw new ClientException(_('That is the wrong confirmation number.'));
            }
        } catch (NoResultException $e) {
            // TRANS: Message given canceling SMS phone number confirmation that is not pending.
            throw new AlreadyFulfilledException(_('No pending confirmation to cancel.'));
        }

        $confirm->delete();

        // TRANS: Message given after successfully canceling SMS phone number confirmation.
        return _('SMS confirmation cancelled.');
    }

    /**
     * Remove a phone number from the user's account
     *
     * @return void
     */
    public function removeAddress()
    {
        $user = $this->scoped->getUser();

        $sms     = $this->arg('sms');
        $carrier = $this->arg('carrier');

        // Maybe an old tab open...?

        if ($user->sms != $sms) {
            // TRANS: Message given trying to remove an SMS phone number that is not
            // TRANS: registered for the active user.
            throw new ClientException(_('That is not your phone number.'));
        }

        $original = clone($user);

        $user->sms      = $user->sqlValue('NULL');
        $user->carrier  = $user->sqlValue('NULL');
        $user->smsemail = $user->sqlValue('NULL');

        // Throws exception on failure. Also performs it within a transaction.
        $user->updateWithKeys($original);

        // TRANS: Message given after successfully removing a registered SMS phone number.
        return _('The SMS phone number was removed.');
    }

    /**
     * Does this sms number exist in our database?
     *
     * Also checks if it belongs to someone else
     *
     * @param string $sms phone number to check
     *
     * @return boolean does the number exist
     */
    public function smsExists($sms)
    {
        $other = User::getKV('sms', $sms);

        if (!$other instanceof User) {
            return false;
        }

        return !$this->scoped->sameAs($other->getProfile());
    }

    /**
     * Show a drop-down box with all the SMS carriers in the DB
     *
     * @return void
     */
    public function carrierSelect()
    {
        $carrier = new Sms_carrier();

        $cnt = $carrier->find();

        $this->elementStart('ul', 'form_data');
        $this->elementStart('li');
        // TRANS: Label for mobile carrier dropdown menu in SMS settings.
        $this->element('label', array('for' => 'carrier'), _('Mobile carrier'));
        $this->elementStart('select', array('name' => 'carrier',
                                            'id' => 'carrier'));
        $this->element(
            'option',
            ['value' => 0],
            // TRANS: Default option for mobile carrier dropdown menu in SMS settings.
            _('Select a carrier')
        );
        while ($carrier->fetch()) {
            $this->element(
                'option',
                ['value' => $carrier->id],
                $carrier->name
            );
        }
        $this->elementEnd('select');
        $this->element(
            'p',
            'form_guide',
            // TRANS: Form instructions for mobile carrier dropdown menu in SMS settings.
            // TRANS: %s is an administrative contact's e-mail address.
            sprintf(
                _('Mobile carrier for your phone. ' .
                  'If you know a carrier that accepts ' .
                  'SMS over email but isn\'t listed here, ' .
                  'send email to let us know at %s.'),
                common_config('site', 'email')
            )
        );
        $this->elementEnd('li');
        $this->elementEnd('ul');
    }

    /**
     * Confirm an SMS confirmation code
     *
     * Redirects to the confirmaddress page for this code
     *
     * @return void
     */
    public function confirmCode()
    {
        $code = $this->trimmed('code');

        if (empty($code)) {
            // TRANS: Message given saving SMS phone number confirmation code without having provided one.
            throw new ClientException(_('No code entered.'));
        }

        common_redirect(common_local_url('confirmaddress', array('code' => $code)), 303);
    }

    /**
     * Handle a request to remove an incoming email address
     *
     * @return void
     */
    public function removeIncoming()
    {
        $user = common_current_user();

        if (!$user->incomingemail) {
            // TRANS: Form validation error displayed when trying to remove an incoming e-mail address while no address has been set.
            throw new ClientException(_('No incoming email address.'));
        }

        $orig = clone($user);

        $user->incomingemail = $user->sqlValue('NULL');

        // Throws exception on failure. Also performs it within a transaction.
        $user->updateWithKeys($orig);

        // TRANS: Confirmation text after updating SMS settings.
        return _('Incoming email address removed.');
    }

    /**
     * Generate a new incoming email address
     *
     * @return void
     *
     * @see Emailsettings::newIncoming
     */
    public function newIncoming()
    {
        $user = $this->scoped->getUser();

        $orig = clone($user);

        $user->incomingemail = mail_new_incoming_address();

        // Throws exception on failure. Also performs it within a transaction.
        $user->updateWithKeys($orig);

        // TRANS: Confirmation text after updating SMS settings.
        return _('New incoming email address added.');
    }
}


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('STATUSNET') && !defined('LACONICA')) { exit(1); }

// @todo FIXME: Documentation needed.
class SubeditAction extends Action
{
    var $profile = null;

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

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

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

        $id = $this->trimmed('profile');

        if (!$id) {
            // TRANS: Client error displayed trying a change a subscription without providing a profile.
            $this->clientError(_('No profile specified.'));
        }

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

        if (!$this->profile) {
            // TRANS: Client error displayed trying a change a subscription for a non-existant profile ID.
            $this->clientError(_('No profile with that ID.'));
        }

        return true;
    }

    function handle()
    {
        parent::handle();
        if ($_SERVER['REQUEST_METHOD'] == 'POST') {
            $cur = common_current_user();

            $sub = Subscription::pkeyGet(array('subscriber' => $cur->id,
                                               'subscribed' => $this->profile->id));

            if (!$sub) {
                // TRANS: Client error displayed trying a change a subscription for a non-subscribed profile.
                $this->clientError(_('You are not subscribed to that profile.'));
            }

            $orig = clone($sub);

            $sub->jabber = $this->boolean('jabber');
            $sub->sms = $this->boolean('sms');

            $result = $sub->update($orig);

            if (!$result) {
                common_log_db_error($sub, 'UPDATE', __FILE__);
                // TRANS: Server error displayed when updating a subscription fails with a database error.
                $this->serverError(_('Could not save subscription.'));
            }

            common_redirect(common_local_url('subscriptions', array('nickname' => $cur->nickname)), 303);
        }
    }
}


code:
<?php
/**
 * StatusNet, the distributed open-source microblogging tool
 *
 * List of group members
 *
 * 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>
 * @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('GNUSOCIAL')) { exit(1); }

/**
 * List of group members
 *
 * @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 SubqueueAction extends GalleryAction
{
    protected $needLogin = true;

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

        if (!$this->target->sameAs($this->scoped)) {
            // TRANS: Client error displayed when trying to approve group applicants without being a group administrator.
            throw new ClientException(_('You may only approve your own pending subscriptions.'));
        }
        return true;
    }

    function title()
    {
        if ($this->page == 1) {
            // TRANS: Title of the first page showing pending subscribers still awaiting approval.
            // TRANS: %s is the name of the user.
            return sprintf(_('%s subscribers awaiting approval'),
                           $this->target->getNickname());
        } else {
            // TRANS: Title of all but the first page showing pending subscribersmembers still awaiting approval.
            // TRANS: %1$s is the name of the user, %2$d is the page number of the members list.
            return sprintf(_('%1$s subscribers awaiting approval, page %2$d'),
                           $this->target->getNickname(),
                           $this->page);
        }
    }

    function showPageNotice()
    {
        $this->element('p', 'instructions',
                       // TRANS: Page notice for group members page.
                       _('A list of users awaiting approval to subscribe to you.'));
    }

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

        $cnt = 0;

        try {
            $subqueue = $this->target->getRequests($offset, $limit);
        } catch (NoResultException $e) {
            // TRANS: If no pending subscription requests are found
            $this->element('div', null, _m('You have no pending subscription requests.'));
            return;
        }

        $list = new SubQueueList($subqueue, $this);
        $cnt = $list->show();

        $subqueue->free();

        $this->pagination($this->page > 1, $cnt > PROFILES_PER_PAGE,
                          $this->page, 'subqueue',
                          array('nickname' => $this->target->getNickname())); // urgh
    }
}


code:
<?php
/**
 * StatusNet - the distributed open-source microblogging tool
 * Copyright (C) 2008-2011, 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    Evan Prodromou <evan@status.net>
 * @copyright 2008-2010 StatusNet, Inc.
 * @license   http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPLv3
 * @link      http://status.net/
 */

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

/**
 * Subscription action
 *
 * Subscribing to a profile. Likely to work for OStatus profiles.
 *
 * 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    Evan Prodromou <evan@status.net>
 * @copyright 2008-2010 StatusNet, Inc.
 * @license   http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPLv3
 * @link      http://status.net/
 */
class SubscribeAction extends Action
{
    var $user;
    var $other;

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

        // Only allow POST requests

        if ($_SERVER['REQUEST_METHOD'] != 'POST') {
            // TRANS: Client error displayed trying to perform any request method other than POST.
            // TRANS: Do not translate POST.
            $this->clientError(_('This action only accepts POST requests.'));
        }

        // CSRF protection

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

        if (!$token || $token != common_session_token()) {
            // TRANS: Client error displayed when the session token is not okay.
            $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

        $other_id = $this->arg('subscribeto');

        $this->other = Profile::getKV('id', $other_id);

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

        return true;
    }

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

        $sub = Subscription::ensureStart($this->user->getProfile(),
                                   $this->other);

        if ($this->boolean('ajax')) {
            $this->startHTML('text/xml;charset=utf-8');
            $this->elementStart('head');
            // TRANS: Page title when subscription succeeded.
            $this->element('title', null, _('Subscribed'));
            $this->elementEnd('head');
            $this->elementStart('body');
            if ($sub instanceof Subscription) {
                $form = new UnsubscribeForm($this, $this->other);
            } else {
                $form = new CancelSubscriptionForm($this, $this->other);
            }
            $form->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
 *
 * Subscribe to a peopletag
 *
 * 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  Peopletag
 * @package   StatusNet
 * @author    Shashi Gowda <connect2shashi@gmail.com>
 * @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);
}

/**
 * Subscribe to a peopletag
 *
 * This is the action for subscribing to a peopletag. It works more or less like the join action
 * for groups.
 *
 * @category Peopletag
 * @package  StatusNet
 * @author   Shashi Gowda <connect2shashi@gmail.com>
 * @license  http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
 * @link     http://status.net/
 */
class SubscribepeopletagAction extends Action
{
    var $peopletag = null;
    var $tagger = null;

    /**
     * Prepare to run
     */
    function prepare(array $args = array())
    {
        parent::prepare($args);

        if (!common_logged_in()) {
            // TRANS: Client error displayed when trying to perform an action while not logged in.
            $this->clientError(_('You must be logged in to unsubscribe from a list.'));
        }
        // Only allow POST requests

        if ($_SERVER['REQUEST_METHOD'] != 'POST') {
            // TRANS: Client error displayed when trying to use another method than POST.
            $this->clientError(_('This action only accepts POST requests.'));
        }

        // 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.'));
        }

        $tagger_arg = $this->trimmed('tagger');
        $tag_arg = $this->trimmed('tag');

        $id = intval($this->arg('id'));
        if ($id) {
            $this->peopletag = Profile_list::getKV('id', $id);
        } else {
            // TRANS: Client error displayed when trying to perform an action without providing an ID.
            $this->clientError(_('No ID given.'), 404);
        }

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

        $this->tagger = Profile::getKV('id', $this->peopletag->tagger);

        return true;
    }

    /**
     * Handle the request
     *
     * On POST, add the current user to the group
     *
     * @param array $args unused
     *
     * @return void
     */

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

        $cur = common_current_user();

        try {
            Profile_tag_subscription::add($this->peopletag, $cur);
        } catch (Exception $e) {
            // TRANS: Server error displayed subscribing to a list fails.
            // TRANS: %1$s is a user nickname, %2$s is a list, %3$s is the error message (no period).
            $this->serverError(sprintf(_('Could not subscribe user %1$s to list %2$s: %3$s'),
                                       $cur->nickname, $this->peopletag->tag), $e->getMessage());
        }

        if ($this->boolean('ajax')) {
            $this->startHTML('text/xml;charset=utf-8');
            $this->elementStart('head');
            // TRANS: Title of form to subscribe to a list.
            // TRANS: %1%s is a user nickname, %2$s is a list, %3$s is a tagger nickname.
            $this->element('title', null, sprintf(_('%1$s subscribed to list %2$s by %3$s'),
                                                  $cur->nickname,
                                                  $this->peopletag->tag,
                                                  $this->tagger->nickname));
            $this->elementEnd('head');
            $this->elementStart('body');
            $lf = new UnsubscribePeopletagForm($this, $this->peopletag);
            $lf->show();
            $this->elementEnd('body');
            $this->endHTML();
        } else {
            common_redirect(common_local_url('peopletagsubscribers',
                                array('tagger' => $this->tagger->nickname,
                                      'tag' =>$this->peopletag->tag)),
                            303);
        }
    }
}


code:
<?php
/**
 * StatusNet, the distributed open-source microblogging tool
 *
 * List a user's subscribers
 *
 * 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  Social
 * @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);
}

/**
 * List a user's subscribers
 *
 * @category Social
 * @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 SubscribersAction extends GalleryAction
{
    function title()
    {
        if ($this->page == 1) {
            // TRANS: Header for list of subscribers for a user (first page).
            // TRANS: %s is the user's nickname.
            return sprintf(_('%s subscribers'), $this->target->getNickname());
        } else {
            // TRANS: Header for list of subscribers for a user (not first page).
            // TRANS: %1$s is the user's nickname, $2$d is the page number.
            return sprintf(_('%1$s subscribers, page %2$d'),
                           $this->target->getNickname(),
                           $this->page);
        }
    }

    function showPageNotice()
    {
        if ($this->scoped instanceof Profile && $this->scoped->id === $this->target->id) {
            $this->element('p', null,
                           // TRANS: Page notice for page with an overview of all subscribers
                           // TRANS: of the logged in user's own profile.
                           _('These are the people who listen to '.
                             'your notices.'));
        } else {
            $this->element('p', null,
                           // TRANS: Page notice for page with an overview of all subscribers of a user other
                           // TRANS: than the logged in user. %s is the user nickname.
                           sprintf(_('These are the people who '.
                                     'listen to %s\'s notices.'),
                                   $this->target->getNickname()));
        }
    }

    function showContent()
    {
        parent::showContent();

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

        $cnt = 0;

        if ($this->tag) {
            $subscribers = $this->target->getTaggedSubscribers($this->tag, $offset, $limit);
        } else {
            $subscribers = $this->target->getSubscribers($offset, $limit);
        }

        if ($subscribers) {
            $subscribers_list = new SubscribersList($subscribers, $this->target->getUser(), $this);
            $cnt = $subscribers_list->show();
            if (0 == $cnt) {
                $this->showEmptyListMessage();
            }
        }

        $this->pagination($this->page > 1, $cnt > PROFILES_PER_PAGE,
                          $this->page, 'subscribers',
                          array('nickname' => $this->target->getNickname()));
    }

    function showEmptyListMessage()
    {
        if ($this->scoped instanceof Profile && $this->target->id === $this->scoped->id) {
            // TRANS: Subscriber list text when the logged in user has no subscribers.
            $message = _('You have no subscribers. Try subscribing to people you know and they might return the favor.');
        } elseif ($this->scoped instanceof Profile) {
            // TRANS: Subscriber list text when looking at the subscribers for a of a user other
            // TRANS: than the logged in user that has no subscribers. %s is the user nickname.
            $message = sprintf(_('%s has no subscribers. Want to be the first?'), $this->target->getNickname());
        } else {
            // TRANS: Subscriber list text when looking at the subscribers for a of a user that has none
            // TRANS: as an anonymous user. %s is the user nickname.
            // TRANS: This message contains a Markdown URL. The link description is between
            // TRANS: square brackets, and the link between parentheses. Do not separate "]("
            // TRANS: and do not change the URL part.
            $message = sprintf(_('%s has no subscribers. Why not [register an account](%%%%action.register%%%%) and be the first?'), $this->target->getNickname());
        }

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

    function showSections()
    {
        parent::showSections();
    }
}


code:
<?php
/**
 * StatusNet, the distributed open-source microblogging tool
 *
 * List of a user's subscriptions
 *
 * 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  Social
 * @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('GNUSOCIAL')) { exit(1); }

/**
 * A list of the user's subscriptions
 *
 * @category Social
 * @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 SubscriptionsAction extends GalleryAction
{
    function title()
    {
        if ($this->page == 1) {
            // TRANS: Header for subscriptions overview for a user (first page).
            // TRANS: %s is a user nickname.
            return sprintf(_('%s subscriptions'), $this->target->getNickname());
        } else {
            // TRANS: Header for subscriptions overview for a user (not first page).
            // TRANS: %1$s is a user nickname, %2$d is the page number.
            return sprintf(_('%1$s subscriptions, page %2$d'),
                           $this->target->getNickname(),
                           $this->page);
        }
    }

    function showPageNotice()
    {
        if ($this->scoped instanceof Profile && $this->scoped->sameAs($this->getTarget())) {
            $this->element('p', null,
                           // TRANS: Page notice for page with an overview of all subscriptions
                           // TRANS: of the logged in user's own profile.
                           _('These are the people whose notices '.
                             'you listen to.'));
        } else {
            $this->element('p', null,
                           // TRANS: Page notice for page with an overview of all subscriptions of a user other
                           // TRANS: than the logged in user. %s is the user nickname.
                           sprintf(_('These are the people whose '.
                                     'notices %s listens to.'),
                                   $this->target->getNickname()));
        }
    }

    function getAllTags()
    {
        return $this->getTags('subscribed', 'subscriber');
    }

    function showContent()
    {
        if (Event::handle('StartShowSubscriptionsContent', array($this))) {
            parent::showContent();

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

            $cnt = 0;

            if ($this->tag) {
                $subscriptions = $this->target->getTaggedSubscriptions($this->tag, $offset, $limit);
            } else {
                $subscriptions = $this->target->getSubscribed($offset, $limit);
            }

            if ($subscriptions) {
                $subscriptions_list = new SubscriptionsList($subscriptions, $this->target->getUser(), $this);
                $cnt = $subscriptions_list->show();
                if (0 == $cnt) {
                    $this->showEmptyListMessage();
                }
            }

            $this->pagination($this->page > 1, $cnt > PROFILES_PER_PAGE,
                              $this->page, 'subscriptions',
                              array('nickname' => $this->target->getNickname()));

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

    function showScripts()
    {
        parent::showScripts();
        $this->autofocus('tag');
    }

    function showEmptyListMessage()
    {
        if ($this->scoped instanceof Profile && $this->target->id === $this->scoped->id) {
                // TRANS: Subscription list text when the logged in user has no subscriptions.
                // TRANS: This message contains Markdown URLs. The link description is between
                // TRANS: square brackets, and the link between parentheses. Do not separate "]("
                // TRANS: and do not change the URL part.
                $message = _('You\'re not listening to anyone\'s notices right now, try subscribing to people you know. '.
                             'Try [people search](%%action.peoplesearch%%), look for members in groups you\'re interested '.
                             'in and in our [featured users](%%action.featured%%).');
        } else {
            // TRANS: Subscription list text when looking at the subscriptions for a of a user that has none
            // TRANS: as an anonymous user. %s is the user nickname.
            $message = sprintf(_('%s is not listening to anyone.'), $this->target->getNickname());
        }

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

    /**
     * Link to feeds of subscriptions
     *
     * @return array of Feed objects
     */
    function getFeeds()
    {
        return array(new Feed(Feed::ATOM,
                              common_local_url('AtomPubSubscriptionFeed',
                                               array('subscriber' => $this->target->id)),
                              // TRANS: Atom feed title. %s is a profile nickname.
                              sprintf(_('Subscription feed for %s (Atom)'),
                                      $this->target->getNickname())));
    }
}


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

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

// @todo FIXME: documentation needed.
class SupAction extends Action
{
    public function handle()
    {
        parent::handle();

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

        if (!$seconds) {
            $seconds = 15;
        }

        $updates = $this->getUpdates($seconds);

        header('Content-Type: application/json; charset=utf-8');

        print json_encode(array('updated_time' => date('c'),
                                'since_time' => date('c', time() - $seconds),
                                'available_periods' => $this->availablePeriods(),
                                'period' => $seconds,
                                'updates' => $updates));
    }

    public function availablePeriods()
    {
        static $periods = array(86400, 43200, 21600, 7200,
                                3600, 1800, 600, 300, 120,
                                60, 30, 15);
        $available = array();
        foreach ($periods as $period) {
            $available[$period] = common_local_url(
                'sup',
                ['seconds' => $period]
            );
        }

        return $available;
    }

    public function getUpdates($seconds)
    {
        $notice = new Notice();

        // XXX: cache this. Depends on how big this protocol becomes;
        // Re-doing this query every 15 seconds isn't the end of the world.

        $divider = common_sql_date(time() - $seconds);

        $notice->query('SELECT profile_id, max(id) AS max_id ' .
                       'FROM ( ' .
                       'SELECT profile_id, id FROM notice ' .
                       "WHERE created > TIMESTAMP '" . $divider . "' " .
                       ') AS latest ' .
                       'GROUP BY profile_id');

        $updates = array();

        while ($notice->fetch()) {
            $updates[] = array($notice->profile_id, $notice->max_id);
        }

        return $updates;
    }

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


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

// @todo FIXME: documentation missing.
class TagAction extends ManagedAction
{
    var $notice;
    var $tag;
    var $page;

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

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

        if (empty($this->tag)) {
            throw new ClientException(_('No valid tag data.'));
        }

        // after common_canonical_tag we have a lowercase, no-specials tag string
        if ($this->tag !== $taginput) {
            common_redirect(common_local_url('tag', array('tag' => $this->tag)), 301);
        }

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

        common_set_returnto($this->selfUrl());

        $this->notice = Notice_tag::getStream($this->tag)->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 title()
    {
        if ($this->page == 1) {
            // TRANS: Title for first page of notices with tags.
            // TRANS: %s is the tag.
            return sprintf(_('Notices tagged with %s'), $this->tag);
        } else {
            // TRANS: Title for all but the first page of notices with tags.
            // TRANS: %1$s is the tag, %2$d is the page number.
            return sprintf(_('Notices tagged with %1$s, page %2$d'),
                           $this->tag,
                           $this->page);
        }
    }

    function getFeeds()
    {
        return array(new Feed(Feed::JSON,
                              common_local_url('ApiTimelineTag',
                                               array('format' => 'as',
                                                     'tag' => $this->tag)),
                              // TRANS: Link label for feed on "notices with tag" page.
                              // TRANS: %s is the tag the feed is for.
                              sprintf(_('Notice feed for tag %s (Activity Streams JSON)'),
                                      $this->tag)),
                     new Feed(Feed::RSS1,
                              common_local_url('tagrss',
                                               array('tag' => $this->tag)),
                              // TRANS: Link label for feed on "notices with tag" page.
                              // TRANS: %s is the tag the feed is for.
                              sprintf(_('Notice feed for tag %s (RSS 1.0)'),
                                      $this->tag)),
                     new Feed(Feed::RSS2,
                              common_local_url('ApiTimelineTag',
                                               array('format' => 'rss',
                                                     'tag' => $this->tag)),
                              // TRANS: Link label for feed on "notices with tag" page.
                              // TRANS: %s is the tag the feed is for.
                              sprintf(_('Notice feed for tag %s (RSS 2.0)'),
                                      $this->tag)),
                     new Feed(Feed::ATOM,
                              common_local_url('ApiTimelineTag',
                                               array('format' => 'atom',
                                                     'tag' => $this->tag)),
                              // TRANS: Link label for feed on "notices with tag" page.
                              // TRANS: %s is the tag the feed is for.
                              sprintf(_('Notice feed for tag %s (Atom)'),
                                      $this->tag)));
    }

    protected function showContent()
    {
        if(Event::handle('StartTagShowContent', array($this))) {

            $nl = new PrimaryNoticeList($this->notice, $this, array('show_n'=>NOTICES_PER_PAGE));

            $cnt = $nl->show();

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

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

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


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

class TagprofileAction extends FormAction
{
    var $error = null;

    protected $target = null;
    protected $form = 'TagProfile';

    protected function doPreparation()
    {
        $id = $this->trimmed('id');
        $uri = $this->trimmed('uri');
        if (!empty($id))  {
            $this->target = Profile::getKV('id', $id);

            if (!$this->target instanceof Profile) {
                // TRANS: Client error displayed when referring to non-existing profile ID.
                $this->clientError(_('No profile with that ID.'));
            }
        } elseif (!empty($uri)) {
            $this->target = Profile::fromUri($uri);
        } else {
            // TRANS: Client error displayed when trying to tag a user but no ID or profile is provided.
            $this->clientError(_('No profile identifier provided.'));
        }

        if (!$this->scoped->canTag($this->target)) {
            // TRANS: Client error displayed when trying to tag a user that cannot be tagged.
            $this->clientError(_('You cannot tag this user.'));
        }

        $this->formOpts = $this->target;

        return true;
    }

    function title()
    {
        if (!$this->target instanceof Profile) {
            // TRANS: Title for list form when not on a profile page.
            return _('List a profile');
        }
        // TRANS: Title for list form when on a profile page.
        // TRANS: %s is a profile nickname.
        return sprintf(_m('ADDTOLIST','List %s'), $this->target->getNickname());
    }

    function showPage()
    {
        // Only serve page content if we aren't POSTing via ajax
        // otherwise, we serve XML content from doPost()
        if (!$this->isPost() || !$this->boolean('ajax')) {
            parent::showPage();
        }
    }

    function showContent()
    {
        $this->elementStart('div', 'entity_profile h-card');
        // TRANS: Header in list form.
        $this->element('h2', null, _('User profile'));

        $avatarUrl = $this->target->avatarUrl(AVATAR_PROFILE_SIZE);
        $this->element('img', array('src' => $avatarUrl,
                                    'class' => 'u-photo avatar entity_depiction',
                                    'width' => AVATAR_PROFILE_SIZE,
                                    'height' => AVATAR_PROFILE_SIZE,
                                    'alt' => $this->target->getBestName()));

        $this->element('a', array('href' => $this->target->getUrl(),
                                  'class' => 'entity_nickname p-nickname'),
                       $this->target->getNickname());
        if ($this->target->fullname) {
            $this->element('div', 'p-name entity_fn', $this->target->fullname);
        }

        if ($this->target->location) {
            $this->element('div', 'p-locality label entity_location', $this->target->location);
        }

        if ($this->target->homepage) {
            $this->element('a', array('href' => $this->target->homepage,
                                      'rel' => 'me',
                                      'class' => 'u-url entity_url'),
                           $this->target->homepage);
        }

        if ($this->target->bio) {
            $this->element('div', 'p-note entity_note', $this->target->bio);
        }

        $this->elementEnd('div');

        if (Event::handle('StartShowTagProfileForm', array($this, $this->target))) {
            parent::showContent();
            Event::handle('EndShowTagProfileForm', array($this, $this->target));
        }
    }

    protected function doPost()
    {
        $tagstring = $this->trimmed('tags');
        $token = $this->trimmed('token');

        if (Event::handle('StartSavePeopletags', array($this, $tagstring))) {
            $tags = array();
            $tag_priv = array();

            if (is_string($tagstring) && strlen($tagstring) > 0) {

                $tags = preg_split('/[\s,]+/', $tagstring);

                foreach ($tags as &$tag) {
                    $private = @$tag[0] === '.';

                    $tag = common_canonical_tag($tag);
                    if (!common_valid_profile_tag($tag)) {
                        // TRANS: Form validation error displayed if a given tag is invalid.
                        // TRANS: %s is the invalid tag.
                        throw new ClientException(sprintf(_('Invalid tag: "%s".'), $tag));
                    }

                    $tag_priv[$tag] = $private;
                }
            }

            $result = Profile_tag::setTags($this->scoped->getID(), $this->target->getID(), $tags, $tag_priv);
            if (!$result) {
                throw new ServerException('The tags could not be saved.');
            }

            if ($this->boolean('ajax')) {
                $this->startHTML('text/xml;charset=utf-8');
                $this->elementStart('head');
                $this->element('title', null, _m('TITLE','Tags'));
                $this->elementEnd('head');
                $this->elementStart('body');

                if ($this->scoped->id == $this->target->id) {
                    $widget = new SelftagsWidget($this, $this->scoped, $this->target);
                    $widget->show();
                } else {
                    $widget = new PeopletagsWidget($this, $this->scoped, $this->target);
                    $widget->show();
                }

                $this->elementEnd('body');
                $this->endHTML();
            } else {
                // TRANS: Success message if lists are saved.
                $this->msg = _('Lists saved.');
                $this->showForm();
            }

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


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 TagrssAction extends Rss10Action
{
    protected $tag;

    protected function doStreamPreparation()
    {
        $tag = common_canonical_tag($this->trimmed('tag'));
        $this->tag = Notice_tag::getKV('tag', $tag);
        if (!$this->tag instanceof Notice_tag) {
            // TRANS: Client error when requesting a tag feed for a non-existing tag.
            $this->clientError(_('No such tag.'));
        }
    }

    protected function getNotices()
    {
        $stream = Notice_tag::getStream($this->tag->tag)->getNotices(0, $this->limit);
        return $stream->fetchAll();
    }

    function getChannel()
    {
        $tagname = $this->tag->tag;
        $c = array('url' => common_local_url('tagrss', array('tag' => $tagname)),
               'title' => $tagname,
               'link' => common_local_url('tagrss', array('tag' => $tagname)),
               // TRANS: Tag feed description.
               // TRANS: %1$s is the tag name, %2$s is the StatusNet sitename.
               'description' => sprintf(_('Updates tagged with %1$s on %2$s!'),
                                        $tagname, common_config('site', 'name')));
        return $c;
    }

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


code:
<?php
/**
 * StatusNet - the distributed open-source microblogging tool
 * Copyright (C) 2011, StatusNet, Inc.
 *
 * Redirect to the appropriate top-of-site
 *
 * 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  Action
 * @package   GNUsocial
 * @author    Evan Prodromou <evan@status.net>
 * @author    Mikael Nordfeldth <mmn@hethane.se>
 * @copyright 2010 StatusNet, Inc.
 * @copyright 2015 Free Software Foundation, Inc.
 * @license   https://www.gnu.org/licenses/agpl-3.0.html AGPL 3.0
 * @link      https://gnu.io/social
 */

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

class TopAction extends ManagedAction
{
    public function showPage()
    {
        if (common_config('singleuser', 'enabled')) {
            $user = User::singleUser();
            common_redirect(common_local_url('showstream', array('nickname' => $user->getNickname())), 303);
        } elseif (common_config('public', 'localonly')) {
            common_redirect(common_local_url('public'), 303);
        } else {
            common_redirect(common_local_url('networkpublic'), 303);
        }
    }
}