code:
<?php
/**
 * StatusNet, the distributed open-source microblogging tool
 *
 * Settings for SMS
 *
 * 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>
 * @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);
}

/**
 * Settings for SMS
 *
 * @category Settings
 * @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/
 *
 * @see      SettingsAction
 */

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

    /**
     * Instructions for use
     *
     * @return instructions for use
     */
    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%%.');
    }

    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
     */
    function showContent()
    {
        if (!common_config('sms', 'enabled')) {
            $this->element('div', array('class' => 'error'),
                           // TRANS: Message given in the SMS settings if SMS is not enabled on the site.
                           _('SMS is not available.'));
            return;
        }

        $user = common_current_user();

        $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->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 {
            $confirm = $this->getConfirmation();
            if ($confirm) {
                $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'));
            } else {
                $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')) ? $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->sms) {
        $this->elementStart('fieldset', array('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->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?
     */
    function getConfirmation()
    {
        $user = common_current_user();

        $confirm = new Confirm_address();

        $confirm->user_id      = $user->id;
        $confirm->address_type = 'sms';

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

    /**
     * Handle posts to this form
     *
     * Based on the button that was pressed, muxes out to other functions
     * to do the actual task requested.
     *
     * All sub-functions reload the form with a message -- success or failure.
     *
     * @return void
     */
    function handlePost()
    {
        // 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->showForm(_('There was a problem with your session token. '.
                              'Try again, please.'));
            return;
        }

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

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

        $user = common_current_user();

        assert(!is_null($user)); // should already be checked

        $user->query('BEGIN');

        $original = clone($user);

        $user->smsnotify = $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.
            $this->serverError(_('Could not update user.'));
        }

        $user->query('COMMIT');

        // TRANS: Confirmation message for successful SMS preferences save.
        $this->showForm(_('SMS preferences saved.'), true);
    }

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

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

        // Some validation

        if (!$sms) {
            // TRANS: Message given saving SMS phone number without having provided one.
            $this->showForm(_('No phone number.'));
            return;
        }

        if (!$carrier_id) {
            // TRANS: Message given saving SMS phone number without having selected a carrier.
            $this->showForm(_('No carrier selected.'));
            return;
        }

        $sms = common_canonical_sms($sms);

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

        $confirm = new Confirm_address();

        $confirm->address       = $sms;
        $confirm->address_extra = $carrier_id;
        $confirm->address_type  = 'sms';
        $confirm->user_id       = $user->id;
        $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.
        $msg = _('A confirmation code was sent to the phone number you added. '.
                 'Check your phone for the code and instructions '.
                 'on how to use it.');

        $this->showForm($msg, true);
    }

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

        $confirm = $this->getConfirmation();

        if (!$confirm) {
            // TRANS: Message given canceling SMS phone number confirmation that is not pending.
            $this->showForm(_('No pending confirmation to cancel.'));
            return;
        }
        if ($confirm->address != $sms) {
            // TRANS: Message given canceling SMS phone number confirmation for the wrong phone number.
            $this->showForm(_('That is the wrong confirmation number.'));
            return;
        }

        $result = $confirm->delete();

        if (!$result) {
            common_log_db_error($confirm, 'DELETE', __FILE__);
            // TRANS: Server error thrown on database error canceling SMS phone number confirmation.
            $this->serverError(_('Could not delete SMS confirmation.'));
        }

        // TRANS: Message given after successfully canceling SMS phone number confirmation.
        $this->showForm(_('SMS confirmation cancelled.'), true);
    }

    /**
     * Remove a phone number from the user's account
     *
     * @return void
     */
    function removeAddress()
    {
        $user = common_current_user();

        $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.
            $this->showForm(_('That is not your phone number.'));
            return;
        }

        $original = clone($user);

        $user->sms      = null;
        $user->carrier  = null;
        $user->smsemail = 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.
        $this->showForm(_('The SMS phone number was removed.'), true);
    }

    /**
     * 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
     */
    function smsExists($sms)
    {
        $user = common_current_user();

        $other = User::getKV('sms', $sms);

        if (!$other) {
            return false;
        } else {
            return $other->id != $user->id;
        }
    }

    /**
     * Show a drop-down box with all the SMS carriers in the DB
     *
     * @return void
     */
    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', array('value' => 0),
                       // TRANS: Default option for mobile carrier dropdown menu in SMS settings.
                       _('Select a carrier'));
        while ($carrier->fetch()) {
            $this->element('option', array('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
     */
    function confirmCode()
    {
        $code = $this->trimmed('code');

        if (!$code) {
            // TRANS: Message given saving SMS phone number confirmation code without having provided one.
            $this->showForm(_('No code entered.'));
            return;
        }

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

    /**
     * Handle a request to remove an incoming email address
     *
     * @return void
     */
    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.
            $this->showForm(_('No incoming email address.'));
            return;
        }

        $orig = clone($user);

        $user->incomingemail = null;

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

        // TRANS: Confirmation text after updating SMS settings.
        $this->showForm(_('Incoming email address removed.'), true);
    }

    /**
     * Generate a new incoming email address
     *
     * @return void
     *
     * @see Emailsettings::newIncoming
     */
    function newIncoming()
    {
        $user = common_current_user();

        $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.
        $this->showForm(_('New incoming email address added.'), true);
    }
}


code:
<?php
/**
 * Startpage action. Decides what to show on the first page.
 */

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

class StartpageAction extends ManagedAction
{
    function isReadOnly($args)
    {
        return true;
    }

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

repo_name: piratas/tortuga

license: mit


code:
<?php
/*
 * StatusNet - the distributed open-source microblogging tool
 * Copyright (C) 2008, 2009, StatusNet, Inc.
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

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

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

    function prepare($args)
    {
        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($args)
    {
        parent::handle($args);
        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('STATUSNET') && !defined('LACONICA')) {
    exit(1);
}

require_once(INSTALLDIR.'/lib/profilelist.php');

/**
 * 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->scoped->id != $this->target->id) {
            // TRANS: Client error displayed when trying to approve group applicants without being a group administrator.
            $this->clientError(_('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;

        $members = $this->target->getRequests($offset, $limit);

        if ($members) {
            // @fixme change!
            $member_list = new SubQueueList($members, $this);
            $cnt = $member_list->show();
        }

        $members->free();

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

class SubQueueList extends ProfileList
{
    function newListItem($profile)
    {
        return new SubQueueListItem($profile, $this->action);
    }
}

class SubQueueListItem extends ProfileListItem
{
    function showActions()
    {
        $this->startActions();
        if (Event::handle('StartProfileListItemActionElements', array($this))) {
            $this->showApproveButtons();
            Event::handle('EndProfileListItemActionElements', array($this));
        }
        $this->endActions();
    }

    function showApproveButtons()
    {
        $this->out->elementStart('li', 'entity_approval');
        $form = new ApproveSubForm($this->out, $this->profile);
        $form->show();
        $this->out->elementEnd('li');
    }
}


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($args)
    {
        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($args)
    {
        // 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($args)
    {
        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($args)
    {
        parent::handle($args);

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

class SubscribersList extends SubscriptionList
{
    function newListItem($profile)
    {
        return new SubscribersListItem($profile, $this->owner, $this->action);
    }
}

class SubscribersListItem extends SubscriptionListItem
{
    function showActions()
    {
        $this->startActions();
        if (Event::handle('StartProfileListItemActionElements', array($this))) {
            $this->showSubscribeButton();
            // Relevant code!
            $this->showBlockForm();
            Event::handle('EndProfileListItemActionElements', array($this));
        }
        $this->endActions();
    }

    function showBlockForm()
    {
        $user = common_current_user();

        if (!empty($user) && $this->owner->id == $user->id) {
            $returnto = array('action' => 'subscribers',
                              'nickname' => $this->owner->getNickname());
            $page = $this->out->arg('page');
            if ($page) {
                $returnto['param-page'] = $page;
            }
            $bf = new BlockForm($this->out, $this->profile, $returnto);
            $bf->show();
        }
    }

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

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

        return $aAttrs;
    }

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

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

        return $aAttrs;
    }
}


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('STATUSNET') && !defined('LACONICA')) {
    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->id === $this->target->id) {
            $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, $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())));
    }
}

// XXX SubscriptionsList and SubscriptionList are dangerously close

class SubscriptionsList extends SubscriptionList
{
    function newListItem($profile)
    {
        return new SubscriptionsListItem($profile, $this->owner, $this->action);
    }
}

class SubscriptionsListItem extends SubscriptionListItem
{
    function showOwnerControls()
    {
        $sub = Subscription::pkeyGet(array('subscriber' => $this->owner->id,
                                           'subscribed' => $this->profile->id));
        if (!$sub) {
            return;
        }

        $transports = array();
        Event::handle('GetImTransports', array(&$transports));
        if (!$transports && !common_config('sms', 'enabled')) {
            return;
        }

        $this->out->elementStart('form', array('id' => 'subedit-' . $this->profile->id,
                                          'method' => 'post',
                                          'class' => 'form_subscription_edit',
                                          'action' => common_local_url('subedit')));
        $this->out->hidden('token', common_session_token());
        $this->out->hidden('profile', $this->profile->id);
        if ($transports) {
            $attrs = array('name' => 'jabber',
                           'type' => 'checkbox',
                           'class' => 'checkbox',
                           'id' => 'jabber-'.$this->profile->id);
            if ($sub->jabber) {
                $attrs['checked'] = 'checked';
            }

            $this->out->element('input', $attrs);
            // TRANS: Checkbox label for enabling IM messages for a profile in a subscriptions list.
            $this->out->element('label', array('for' => 'jabber-'.$this->profile->id), _m('LABEL','IM'));
        } else {
            $this->out->hidden('jabber', $sub->jabber);
        }
        if (common_config('sms', 'enabled')) {
            $attrs = array('name' => 'sms',
                           'type' => 'checkbox',
                           'class' => 'checkbox',
                           'id' => 'sms-'.$this->profile->id);
            if ($sub->sms) {
                $attrs['checked'] = 'checked';
            }

            $this->out->element('input', $attrs);
            // TRANS: Checkbox label for enabling SMS messages for a profile in a subscriptions list.
            $this->out->element('label', array('for' => 'sms-'.$this->profile->id), _('SMS'));
        } else {
            $this->out->hidden('sms', $sub->sms);
        }
        // TRANS: Save button for settings for a profile in a subscriptions list.
        $this->out->submit('save', _m('BUTTON','Save'));
        $this->out->elementEnd('form');
    }
}


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 SupAction extends Action
{
    function handle($args)
    {
        parent::handle($args);

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

    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',
                                                   array('seconds' => $period));
        }

        return $available;
    }

    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 ' .
                        ((common_config('db','type') == 'pgsql') ?
                       'WHERE extract(epoch from created) > (extract(epoch from now()) - ' . $seconds . ') ' :
                       'WHERE created > "'.$divider.'" ' ) .
                       ') AS latest ' .
                       'GROUP BY profile_id');

        $updates = array();

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

        return $updates;
    }

    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)) {
            common_redirect(common_local_url('publictagcloud'), 301);
        }

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

require_once(INSTALLDIR.'/lib/rssaction.php');

// Formatting of RSS handled by Rss10Action
class TagrssAction extends Rss10Action
{
    var $tag;

    function prepare($args) {
        parent::prepare($args);
        $tag = common_canonical_tag($this->trimmed('tag'));
        $this->tag = Notice_tag::getKV('tag', $tag);
        if (!$this->tag) {
            // TRANS: Client error when requesting a tag feed for a non-existing tag.
            $this->clientError(_('No such tag.'));
        } else {
            $this->notices = $this->getNotices($this->limit);
            return true;
        }
    }

    function getNotices($limit=0)
    {
        $tag = $this->tag;

        if (is_null($tag)) {
            return null;
        }

        $notice = Notice_tag::getStream($tag->tag, 0, ($limit == 0) ? NOTICES_PER_PAGE : $limit);
        while ($notice->fetch()) {
            $notices[] = clone($notice);
        }

        return $notices;
    }

    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  Top
 * @package   StatusNet
 * @author    Evan Prodromou <evan@status.net>
 * @copyright 2010 StatusNet, Inc.
 * @license   http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0
 * @link      http://status.net/
 */

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

/**
 * An action to redirect to the top of the site
 *
 * @category  Action
 * @package   StatusNet
 * @author    Evan Prodromou <evan@status.net>
 * @copyright 2010 StatusNet, Inc.
 * @license   http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0
 * @link      http://status.net/
 */

class TopAction extends Action
{
    /**
     * For initializing members of the class.
     *
     * @param array $argarray misc. arguments
     *
     * @return boolean true
     */

    function prepare($argarray)
    {
        parent::prepare($argarray);
        return true;
    }

    /**
     * Handler method
     *
     * @param array $argarray is ignored since it's now passed in in prepare()
     *
     * @return void
     */

    function handle($argarray=null)
    {
        if (common_config('singleuser', 'enabled')) {
            $url = common_local_url('showstream', array('nickname' => User::singleUserNickname()));
        } else {
            $url = common_local_url('public');
        }

        // XXX: Permanent? I think so.

        common_redirect($url, 301);

        return;
    }
}


code:
<?php
/**
 * Unblock a user action class.
 *
 * PHP version 5
 *
 * @category Action
 * @package  StatusNet
 * @author   Evan Prodromou <evan@status.net>
 * @author   Robin Millette <millette@status.net>
 * @license  http://www.fsf.org/licensing/licenses/agpl.html AGPLv3
 * @link     http://status.net/
 *
 * 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);
}

/**
 * Unblock a user action class.
 *
 * @category Action
 * @package  StatusNet
 * @author   Evan Prodromou <evan@status.net>
 * @author   Robin Millette <millette@status.net>
 * @license  http://www.fsf.org/licensing/licenses/agpl.html AGPLv3
 * @link     http://status.net/
 */
class UnblockAction extends ProfileFormAction
{
    function prepare($args)
    {
        if (!parent::prepare($args)) {
            return false;
        }

        $cur = common_current_user();

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

        if (!$cur->hasBlocked($this->profile)) {
            // TRANS: Client error displayed when trying to unblock a non-blocked user.
            $this->clientError(_("You haven't blocked that user."));
        }

        return true;
    }

    /**
     * Unblock a user.
     *
     * @return void
     */
    function handlePost()
    {
        $cur = common_current_user();

        $result = false;

        if (Event::handle('StartUnblockProfile', array($cur, $this->profile))) {
            $result = $cur->unblock($this->profile);
            if ($result) {
                Event::handle('EndUnblockProfile', array($cur, $this->profile));
            }
        }

        if (!$result) {
            // TRANS: Server error displayed when removing a user block.
            $this->serverError(_('Error removing the block.'));
        }
    }
}


code:
<?php
/**
 * StatusNet, the distributed open-source microblogging tool
 *
 * Action class to unsandbox a user
 *
 * PHP version 5
 *
 * LICENCE: This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 * @category  Action
 * @package   StatusNet
 * @author    Evan Prodromou <evan@status.net>
 * @copyright 2009 StatusNet, Inc.
 * @license   http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
 * @link      http://status.net/
 */

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

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

        $cur = common_current_user();

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

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

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

        if (!$this->profile->isSandboxed()) {
            // TRANS: Client error on page to unsilence a user when the to be unsandboxed user has not been sandboxed.
            $this->clientError(_('User is not sandboxed.'));
        }

        return true;
    }

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


code:
<?php
/**
 * StatusNet, the distributed open-source microblogging tool
 *
 * Action class to unsilence a user
 *
 * PHP version 5
 *
 * LICENCE: This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 * @category  Action
 * @package   StatusNet
 * @author    Evan Prodromou <evan@status.net>
 * @copyright 2009 StatusNet, Inc.
 * @license   http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
 * @link      http://status.net/
 */

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

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

        $cur = common_current_user();

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

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

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

        if (!$this->profile->isSilenced()) {
            // TRANS: Client error on page to unsilence a user when the to be unsilenced user has not been silenced.
            $this->clientError(_('User is not silenced.'));
        }

        return true;
    }

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


code:
<?php
/**
 * Unsubscribe handler
 *
 * PHP version 5
 *
 * @category Action
 * @package  StatusNet
 * @author   Evan Prodromou <evan@status.net>
 * @author   Robin Millette <millette@status.net>
 * @license  http://www.fsf.org/licensing/licenses/agpl.html AGPLv3
 * @link     http://status.net/
 *
 * 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);
}

/**
 * Unsubscribe handler
 *
 * @category Action
 * @package  StatusNet
 * @author   Evan Prodromou <evan@status.net>
 * @author   Robin Millette <millette@status.net>
 * @license  http://www.fsf.org/licensing/licenses/agpl.html AGPLv3
 * @link     http://status.net/
 */
class UnsubscribeAction extends Action
{
    function handle($args)
    {
        parent::handle($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.'));
        }

        if ($_SERVER['REQUEST_METHOD'] != 'POST') {
            common_redirect(common_local_url('subscriptions',
                                             array('nickname' => $this->scoped->nickname)));
        }

        /* Use a session token for 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.'));
        }

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

        if (!$other_id) {
            // TRANS: Client error displayed when trying to unsubscribe without providing a profile ID.
            $this->clientError(_('No profile ID in request.'));
        }

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

        if (!($other instanceof Profile)) {
            // TRANS: Client error displayed when trying to unsubscribe while providing a non-existing profile ID.
            $this->clientError(_('No profile with that ID.'));
        }

        try {
            Subscription::cancel($this->scoped, $other);
        } catch (Exception $e) {
            $this->clientError($e->getMessage());
        }

        if ($this->boolean('ajax')) {
            $this->startHTML('text/xml;charset=utf-8');
            $this->elementStart('head');
            // TRANS: Page title for page to unsubscribe.
            $this->element('title', null, _('Unsubscribed'));
            $this->elementEnd('head');
            $this->elementStart('body');
            $subscribe = new SubscribeForm($this, $other);
            $subscribe->show();
            $this->elementEnd('body');
            $this->endHTML();
        } else {
            common_redirect(common_local_url('subscriptions', array('nickname' => $this->scoped->nickname)), 303);
        }
    }
}


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

/**
 * Unsubscribe 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 UnsubscribepeopletagAction extends Action
{
    var $peopletag = null;
    var $tagger = null;

    /**
     * Prepare to run
     */

    function prepare($args)
    {
        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($args)
    {
        parent::handle($args);

        $cur = common_current_user();

        Profile_tag_subscription::remove($this->peopletag, $cur);

        if ($this->boolean('ajax')) {
            $this->startHTML('text/xml;charset=utf-8');
            $this->elementStart('head');
            // TRANS: Page title for form that allows unsubscribing from a list.
            // TRANS: %1$s is a nickname, %2$s is a list, %3$s is a tagger nickname.
            $this->element('title', null, sprintf(_('%1$s unsubscribed from list %2$s by %3$s'),
                                                  $cur->nickname,
                                                  $this->peopletag->tag,
                                                  $this->tagger->nickname));
            $this->elementEnd('head');
            $this->elementStart('body');
            $lf = new SubscribePeopletagForm($this, $this->peopletag);
            $lf->show();
            $this->elementEnd('body');
            $this->endHTML();
        } else {
            if (common_get_returnto()) {
                common_redirect(common_get_returnto(), 303);
            }
            common_redirect(common_local_url('peopletagsbyuser', array('nickname' => $this->tagger->nickname)), 303);
        }
    }
}


code:
<?php
/**
 * StatusNet, the distributed open-source microblogging tool
 *
 * Miscellaneous settings
 *
 * 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    Robin Millette <millette@status.net>
 * @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('STATUSNET') && !defined('LACONICA')) {
    exit(1);
}

/**
 * Miscellaneous settings actions
 *
 * Currently this just manages URL shortening.
 *
 * @category Settings
 * @package  StatusNet
 * @author   Robin Millette <millette@status.net>
 * @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 UrlsettingsAction extends SettingsAction
{
    /**
     * Title of the page
     *
     * @return string Title of the page
     */
    function title()
    {
        // TRANS: Title of URL settings tab in profile settings.
        return _('URL settings');
    }

    /**
     * Instructions for use
     *
     * @return instructions for use
     */
    function getInstructions()
    {
        // TRANS: Instructions for tab "Other" in user profile settings.
        return _('Manage various other options.');
    }

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

    /**
     * Content area of the page
     *
     * Shows a form for uploading an avatar.
     *
     * @return void
     */
    function showContent()
    {
        $user = common_current_user();

        $this->elementStart('form', array('method' => 'post',
                                          'id' => 'form_settings_other',
                                          'class' => 'form_settings',
                                          'action' =>
                                          common_local_url('urlsettings')));
        $this->elementStart('fieldset');
        $this->hidden('token', common_session_token());
        $this->elementStart('ul', 'form_data');

        $shorteners = array();

        Event::handle('GetUrlShorteners', array(&$shorteners));

        $services = array();

        foreach ($shorteners as $name => $value)
        {
            $services[$name] = $name;
            if ($value['freeService']) {
                // TRANS: Used as a suffix for free URL shorteners in a dropdown list in the tab "Other" of a
                // TRANS: user's profile settings. This message has one space at the beginning. Use your
                // TRANS: language's word separator here if it has one (most likely a single space).
                $services[$name] .= _(' (free service)');
            }
        }

        // Include default values

        // TRANS: Default value for URL shortening settings.
        $services['none']     = _('[none]');
        // TRANS: Default value for URL shortening settings.
        $services['internal'] = _('[internal]');

        if ($services) {
            asort($services);

            $this->elementStart('li');
            // TRANS: Label for dropdown with URL shortener services.
            $this->dropdown('urlshorteningservice', _('Shorten URLs with'),
                            // TRANS: Tooltip for for dropdown with URL shortener services.
                            $services, _('Automatic shortening service to use.'),
                            false, $user->urlshorteningservice);
            $this->elementEnd('li');
        }
        $this->elementStart('li');
        $this->input('maxurllength',
                     // TRANS: Field label in URL settings in profile.
                     _('URL longer than'),
                     (!is_null($this->arg('maxurllength'))) ?
                     $this->arg('maxurllength') : User_urlshortener_prefs::maxUrlLength($user),
                     // TRANS: Field title in URL settings in profile.
                     _('URLs longer than this will be shortened, -1 means never shorten because a URL is long.'));
        $this->elementEnd('li');
        $this->elementStart('li');
        $this->input('maxnoticelength',
                     // TRANS: Field label in URL settings in profile.
                     _('Text longer than'),
                     (!is_null($this->arg('maxnoticelength'))) ?
                     $this->arg('maxnoticelength') : User_urlshortener_prefs::maxNoticeLength($user),
                     // TRANS: Field title in URL settings in profile.
                     _('URLs in notices longer than this will always be shortened, -1 means only shorten if the full post exceeds maximum length.'));
        $this->elementEnd('li');
        $this->elementEnd('ul');
        // TRANS: Button text for saving "Other settings" in profile.
        $this->submit('save', _m('BUTTON','Save'));
        $this->elementEnd('fieldset');
        $this->elementEnd('form');
    }

    /**
     * Handle a post
     *
     * Saves the changes to url-shortening prefs and shows a success or failure
     * message.
     *
     * @return void
     */
    function handlePost()
    {
        // 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->showForm(_('There was a problem with your session token. '.
                              'Try again, please.'));
            return;
        }

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

        if (!is_null($urlshorteningservice) && strlen($urlshorteningservice) > 50) {
            // TRANS: Form validation error for form "Other settings" in user profile.
            $this->showForm(_('URL shortening service is too long (maximum 50 characters).'));
            return;
        }

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

        if (!Validate::number($maxurllength, array('min' => -1))) {
            // TRANS: Client exception thrown when the maximum URL settings value is invalid in profile URL settings.
            throw new ClientException(_('Invalid number for maximum URL length.'));
        }

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

        if (!Validate::number($maxnoticelength, array('min' => -1))) {
            // TRANS: Client exception thrown when the maximum notice length settings value is invalid in profile URL settings.
            throw new ClientException(_('Invalid number for maximum notice length.'));
        }

        $user = common_current_user();

        assert(!is_null($user)); // should already be checked

        $user->query('BEGIN');

        $original = clone($user);

        $user->urlshorteningservice = $urlshorteningservice;

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

        if ($result === false) {
            common_log_db_error($user, 'UPDATE', __FILE__);
            // TRANS: Server error displayed when "Other" settings in user profile could not be updated on the server.
            $this->serverError(_('Could not update user.'));
        }

        $prefs = User_urlshortener_prefs::getPrefs($user);
        $orig  = null;

        if (empty($prefs)) {
            $prefs = new User_urlshortener_prefs();

            $prefs->user_id = $user->id;
            $prefs->created = common_sql_now();
        } else {
            $orig = clone($prefs);
        }

        $prefs->urlshorteningservice = $urlshorteningservice;
        $prefs->maxurllength         = $maxurllength;
        $prefs->maxnoticelength      = $maxnoticelength;

        if (!empty($orig)) {
            $result = $prefs->update($orig);
        } else {
            $result = $prefs->insert();
        }

        if (!$result) {
            // TRANS: Server exception thrown in profile URL settings when preferences could not be saved.
            throw new ServerException(_('Error saving user URL shortening preferences.'));
        }

        $user->query('COMMIT');

        // TRANS: Confirmation message after saving preferences.
        $this->showForm(_('Preferences saved.'), true);
    }
}