code:
<?php
/**
 * StatusNet, the distributed open-source microblogging tool
 *
 * Widget to show a list of peopletags
 *
 * 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  Public
 * @package   StatusNet
 * @author    Shashi Gowda <connect2shashi@gmail.com>
 * @copyright 2008-2009 StatusNet, Inc.
 * @license   http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
 * @link      http://status.net/
 */

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

class PeopletagListItem extends Widget
{
    var $peopletag = null;
    var $current = null;
    var $profile = null;

    /**
     * constructor
     *
     * Also initializes the owner attribute.
     *
     * @param Notice $notice The notice we'll display
     */
    function __construct($peopletag, $current, $out=null)
    {
        parent::__construct($out);
        $this->peopletag  = $peopletag;
        $this->current = $current;
        $this->profile = Profile::getKV('id', $this->peopletag->tagger);
    }

    /**
     * recipe function for displaying a single peopletag.
     *
     * This uses all the other methods to correctly display a notice. Override
     * it or one of the others to fine-tune the output.
     *
     * @return void
     */
    function url()
    {
        return $this->peopletag->homeUrl();
    }

    function show()
    {
        if (empty($this->peopletag)) {
            common_log(LOG_WARNING, "Trying to show missing peopletag; skipping.");
            return;
        }

        if (Event::handle('StartShowPeopletagItem', array($this))) {
            $this->showStart();
            $this->showPeopletag();
            $this->showStats();
            $this->showEnd();
            Event::handle('EndShowPeopletagItem', array($this));
        }
    }

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

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

    function showPeopletag()
    {
        $this->showCreator();
        $this->showTag();
        $this->showPrivacy();
        $this->showUpdated();
        $this->showActions();
        $this->showDescription();
    }

    function showStats()
    {
        $this->out->elementStart('div', 'entry-summary entity_statistics');
        $this->out->elementStart('span', 'tagged-count');
        $this->out->element('a',
            array('href' => common_local_url('peopletagged',
                                              array('tagger' => $this->profile->nickname,
                                                    'tag' => $this->peopletag->tag))),
            // TRANS: Link description for link to list of users tagged with a tag (so part of a list).
            _('Listed'));
        $this->out->raw($this->peopletag->taggedCount());
        $this->out->elementEnd('span');

        $this->out->elementStart('span', 'subscriber-count');
        $this->out->element('a',
            array('href' => common_local_url('peopletagsubscribers',
                                              array('tagger' => $this->profile->nickname,
                                                    'tag' => $this->peopletag->tag))),
            // TRANS: Link description for link to list of users subscribed to a tag.
            _('Subscribers'));
        $this->out->raw($this->peopletag->subscriberCount());
        $this->out->elementEnd('span');
        $this->out->elementEnd('div');
    }

    function showOwnerOptions()
    {
        $this->out->elementStart('li', 'entity_edit');
        $this->out->element('a', array('href' =>
                    common_local_url('editpeopletag', array('tagger' => $this->profile->nickname,
                                                    'tag' => $this->peopletag->tag)),
                                  // TRANS: Title for link to edit list settings.
                                  'title' => _('Edit list settings.')),
                       // TRANS: Text for link to edit list settings.
                       _('Edit'));
        $this->out->elementEnd('li');
    }

    function showSubscribeForm()
    {
        $this->out->elementStart('li');

        if (Event::handle('StartSubscribePeopletagForm', array($this->out, $this->peopletag))) {
            if ($this->current) {
                if ($this->peopletag->hasSubscriber($this->current->id)) {
                    $form = new UnsubscribePeopletagForm($this->out, $this->peopletag);
                    $form->show();
                } else {
                    $form = new SubscribePeopletagForm($this->out, $this->peopletag);
                    $form->show();
                }
            }
            Event::handle('EndSubscribePeopletagForm', array($this->out, $this->peopletag));
        }

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

    function showCreator()
    {
        $attrs = array();
        $attrs['href'] = $this->profile->profileurl;
        $attrs['class'] = 'h-card p-author nickname p-name';
        $attrs['rel'] = 'contact';
        $attrs['title'] = $this->profile->getFancyName();

        $this->out->elementStart('a', $attrs);
        $this->showAvatar($this->profile);
        $this->out->text($this->profile->getNickname());
        $this->out->elementEnd('a');
    }

    function showUpdated()
    {
        if (!empty($this->peopletag->modified)) {
            $this->out->element('abbr',
                array('title' => common_date_w3dtf($this->peopletag->modified),
                      'class' => 'updated'),
                common_date_string($this->peopletag->modified));
        }
    }

    function showPrivacy()
    {
        if ($this->peopletag->private) {
            $this->out->elementStart('a',
                array('href' => common_local_url('peopletagsbyuser',
                    array('nickname' => $this->profile->nickname, 'private' => 1))));
            // TRANS: Privacy mode text in list list item for private list.
            $this->out->element('span', 'privacy_mode', _m('MODE','Private'));
            $this->out->elementEnd('a');
        }
    }

    function showTag()
    {
        $this->out->elementStart('span', 'entry-title tag');
        $this->out->element('a',
            array('rel'   => 'bookmark',
                  'href'  => $this->url()),
            htmlspecialchars($this->peopletag->tag));
        $this->out->elementEnd('span');
    }

    function showActions()
    {
        $this->out->elementStart('div', 'entity_actions');
        $this->out->elementStart('ul');

        if (!$this->peopletag->private) {
            $this->showSubscribeForm();
        }

        if (!empty($this->current) && $this->profile->id == $this->current->id) {
            $this->showOwnerOptions();
        }
        $this->out->elementEnd('ul');
        $this->out->elementEnd('div');
    }

    function showDescription()
    {
        $this->out->element('div', 'e-content description', $this->peopletag->description);
    }
}


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

require_once INSTALLDIR . '/lib/ui/widget.php';

/**
 * Tabset for a group
 *
 * Shows a group of tabs for a particular user group
 *
 * @category Output
 * @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/
 *
 * @see      HTMLOutputter
 */
class PeopletagNav extends Menu
{
    var $group = null;

    /**
     * Construction
     *
     * @param Action $action current action, used for output
     */
    function __construct($action=null, $profile=null)
    {
        parent::__construct($action);
        $this->profile = $profile;
    }

    /**
     * Show the menu
     *
     * @return void
     */
    function show()
    {
        $action_name = $this->action->trimmed('action');
        $nickname = $this->profile->nickname;

        $this->out->elementStart('ul', array('class' => 'nav'));
        if (Event::handle('StartPeopletagGroupNav', array($this))) {
            $this->out->menuItem(common_local_url('peopletagsubscriptions', array('nickname' =>
                                                                     $nickname)),
                                 // TRANS: Menu item in the group navigation page.
                                 _m('MENU','List Subscriptions'),
                                 // TRANS: Tooltip for menu item in the group navigation page.
                                 // TRANS: %s is a user nickname.
                                 sprintf(_m('TOOLTIP','Lists subscribed to by %s.'), $nickname),
                                 $action_name == 'peopletagsubscriptions',
                                 'nav_list_group');
            $this->out->menuItem(common_local_url('peopletagsforuser', array('nickname' =>
                                                                        $nickname)),
                                 // TRANS: Menu item in the group navigation page.
                                 // TRANS: %s is a user nickname.
                                 sprintf(_m('MENU','Lists with %s'), $nickname),
                                 // TRANS: Tooltip for menu item in the group navigation page.
                                 // TRANS: %s is a user nickname.
                                 sprintf(_m('TOOLTIP','Lists with %s.'), $nickname),
                                 $action_name == 'peopletagsforuser',
                                 'nav_lists_with');
            $this->out->menuItem(common_local_url('peopletagsbyuser', array('nickname' =>
                                                                        $nickname)),
                                 // TRANS: Menu item in the group navigation page.
                                 // TRANS: %s is a user nickname.
                                 sprintf(_m('MENU','Lists by %s'), $nickname),
                                 // TRANS: Tooltip for menu item in the group navigation page.
                                 // TRANS: %s is a user nickname.
                                 sprintf(_m('TOOLTIP','Lists by %s.'), $nickname),
                                 $action_name == 'peopletagsbyuser',
                                 'nav_lists_by');
            Event::handle('EndPeopletagGroupNav', array($this));
        }
        $this->out->elementEnd('ul');
    }
}

repo_name: suraj/sloth

license: mit


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

/**
 * Stream of notices for a list
 *
 * @category  Stream
 * @package   GNUsocial
 * @author    Evan Prodromou <evan@status.net>
 * @author    Shashi Gowda <connect2shashi@gmail.com>
 * @copyright 2011 StatusNet, Inc.
 * @license   https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
 */

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

/**
 * Stream of notices for a list
 *
 * @copyright 2011 StatusNet, Inc.
 * @license   https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
 */
class PeopletagNoticeStream extends ScopingNoticeStream
{
    public function __construct($plist, Profile $scoped = null)
    {
        parent::__construct(
            new CachingNoticeStream(
                new RawPeopletagNoticeStream($plist),
                'profile_list:notice_ids:' . $plist->id
            ),
            $scoped
        );
    }
}

/**
 * Stream of notices for a list
 *
 * @copyright 2011 StatusNet, Inc.
 * @license   https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
 */
class RawPeopletagNoticeStream extends NoticeStream
{
    protected $profile_list;

    public function __construct($profile_list)
    {
        $this->profile_list = $profile_list;
    }

    /**
     * Query notices by users associated with this tag from the database.
     *
     * @param integer $offset   offset
     * @param integer $limit    maximum no of results
     * @param integer $since_id=null    since this id
     * @param integer $max_id=null  maximum id in result
     *
     * @return array array of notice ids.
     */

    public function getNoticeIds($offset, $limit, $since_id, $max_id)
    {
        $notice = new Notice();

        $notice->selectAdd();
        $notice->selectAdd('notice.id');

        $ptag = new Profile_tag();
        $ptag->tag    = $this->profile_list->tag;
        $ptag->tagger = $this->profile_list->tagger;
        $notice->joinAdd(array('profile_id', 'profile_tag:tagged'));
        $notice->whereAdd('profile_tag.tagger = ' . $this->profile_list->tagger);
        $notice->whereAdd(sprintf(
            "profile_tag.tag = '%s'",
            $notice->escape($this->profile_list->tag)
        ));

        if ($since_id != 0) {
            $notice->whereAdd('notice.id > ' . $since_id);
        }

        if ($max_id != 0) {
            $notice->whereAdd('notice.id <= ' . $max_id);
        }

        $notice->orderBy('notice.id DESC');

        if (!is_null($offset)) {
            $notice->limit($offset, $limit);
        }

        $ids = array();
        if ($notice->find()) {
            while ($notice->fetch()) {
                $ids[] = $notice->id;
            }
        }

        return $ids;
    }
}


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

/**
 * Peopletags with the most subscribers section
 *
 * @category  Widget
 * @package   GNUsocial
 * @author    Evan Prodromou <evan@status.net>
 * @copyright 2009 StatusNet, Inc.
 * @license   https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
 */

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

/**
 * Peopletags with the most subscribers section
 *
 * @copyright 2009 StatusNet, Inc.
 * @license   https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
 */
class PeopletagsBySubsSection extends PeopletagSection
{
    function getPeopletags()
    {
        $limit = PEOPLETAGS_PER_SECTION;

        $qry = 'SELECT profile_list.*, subscriber_count AS value ' .
            'FROM profile_list WHERE profile_list.private = FALSE ' .
            'ORDER BY value DESC ' .
            'LIMIT ' . $limit;

        $peopletag = Memcached_DataObject::cachedQuery('Profile_list', $qry, 3600);
        return $peopletag;
    }

    function title()
    {
        // TRANS: Title for section contaning lists with the most subscribers.
        return _('Popular lists');
    }

    function divId()
    {
        return 'top_peopletags_by_subs';
    }
}


code:
<?php
/**
 * StatusNet, the distributed open-source microblogging tool
 *
 * Base class for sections showing lists of peopletags
 *
 * 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  Widget
 * @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);
}

require_once INSTALLDIR . '/lib/profile/peopletaglist.php';

define('PEOPLETAGS_PER_SECTION', 6);

/**
 * Base class for sections
 *
 * These are the widgets that show interesting data about a person
 * peopletag, or site.
 *
 * @category Widget
 * @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 PeopletagSection extends Section
{
    protected $avatarSize = AVATAR_MINI_SIZE;

    function showContent()
    {
        $tags = $this->getPeopletags();

        if (!$tags) {
            return false;
        }

        $cnt = 0;

        $this->out->elementStart('table', 'peopletag_section');

        while ($tags->fetch() && ++$cnt <= PEOPLETAGS_PER_SECTION) {
            $this->showPeopletag($tags);
        }

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

        return ($cnt > PEOPLETAGS_PER_SECTION);
    }

    function getPeopletags()
    {
        return null;
    }

    function showPeopletag($peopletag)
    {
        $tag = new PeopletagSectionItem($peopletag, null, $this->out);
        $tag->show();
    }
}

class PeopletagSectionItem extends PeopletagListItem
{
    function showStart()
    {
    }

    function showEnd()
    {
    }

    function showPeopletag()
    {
        $this->showCreator();
        $this->showTag();
        $this->showPrivacy();
    }

    function show()
    {
        if (empty($this->peopletag)) {
            common_log(LOG_WARNING, "Trying to show missing peopletag; skipping.");
            return;
        }
        $mode = ($this->peopletag->private) ? 'private' : 'public';

        $this->out->elementStart('tr');

        $this->out->elementStart('td', 'peopletag mode-' . $mode);
        $this->showPeopletag();
        $this->out->elementEnd('td');

        if (isset($this->peopletag->value)) {
            $this->out->element('td', 'value', $this->peopletag->value);
        }
        $this->out->elementEnd('tr');
    }

    function showTag()
    {
        // TRANS: List summary. %1$d is the number of users in the list,
        // TRANS: %2$d is the number of subscribers to the list.
        $title = sprintf(_('Listed: %1$d Subscribers: %2$d'),
                         $this->peopletag->taggedCount(),
                         $this->peopletag->subscriberCount());

        $this->out->elementStart('span', 'entry-title tag');

        $this->out->element('a',
            array('rel'   => 'bookmark',
                  'href'  => $this->url(),
                  'title' => $title),
            htmlspecialchars($this->peopletag->tag));
        $this->out->elementEnd('span');
    }
}


code:
<?php
/**
 * StatusNet, the distributed open-source microblogging tool
 *
 * Lists a user is in
 *
 * 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  Widget
 * @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);
}

/**
 * List a user has is in
 *
 * @category Widget
 * @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 PeopletagsForUserSection extends PeopletagSection
{
    var $profile=null;

    function __construct($out, Profile $profile)
    {
        parent::__construct($out);
        $this->profile = $profile;
    }

    function getPeopletags()
    {
        $limit = PEOPLETAGS_PER_SECTION+1;
        $offset = 0;

        $ptags = $this->profile->getOtherTags(Profile::current(), $offset, $limit);

        return $ptags;
    }

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

        if (!empty($user) && $this->profile->id == $user->id) {
            // TRANS: Title for page that displays which lists current user is part of.
            return sprintf(_('Lists with you'));
        }
        // TRANS: Title for page that displays which lists a user is part of.
        // TRANS: %s is a profile name.
        return sprintf(_('Lists with %s'), $this->profile->getBestName());
    }

    function link()
    {
        return common_local_url('peopletagsforuser',
                array('nickname' => $this->profile->nickname));
    }

    function moreUrl()
    {
        return $this->link();
    }

    function divId()
    {
        return 'peopletag_subscriptions';
    }
}


code:
<?php
/**
 * StatusNet, the distributed open-source microblogging tool
 *
 * Peopletags a user has subscribed to
 *
 * 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  Widget
 * @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);
}

/**
 * Peopletags a user has subscribed to
 *
 * @category Widget
 * @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 PeopletagSubscriptionsSection extends PeopletagSection
{
    var $profile=null;
    var $ptags=null;

    function __construct($out, Profile $profile)
    {
        parent::__construct($out);
        $this->profile = $profile;

        $limit = PEOPLETAGS_PER_SECTION+1;
        $offset = 0;

        $this->ptags = $this->profile->getTagSubscriptions($offset, $limit);
    }

    function getPeopletags()
    {
        return $this->ptags;
    }

    function title()
    {
        // TRANS: Title for page that displays lists a user has subscribed to.
        return _('List subscriptions');
    }

    function link()
    {
        return common_local_url('peopletagsubscriptions',
                array('nickname' => $this->profile->nickname));
    }

    function moreUrl()
    {
        return $this->link();
    }

    function divId()
    {
        return 'peopletag_subscriptions';
    }
}


code:
<?php
/**
 * StatusNet, the distributed open-source microblogging tool
 *
 * Tags for a profile
 *
 * 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
 * @license   http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
 * @link      http://status.net/
 */

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

/*
 * Show a bunch of peopletags
 * provide ajax editing if the current user owns the tags
 *
 * @category Action
 * @pacage   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
 */
class PeopletagsWidget extends Widget
{
    /*
     * the query, current peopletag.
     * or an array of strings (tags)
     */

    var $tag=null;

    var $user=null;
    var $tagger=null;
    var $tagged=null;

    function __construct($out, $tagger, $tagged)
    {
        parent::__construct($out);

        $this->user   = common_current_user();
        $this->tag = Profile_tag::getTags($tagger->id, $tagged->id, $this->user);
        $this->tagger = $tagger;
        $this->tagged = $tagged;
    }

    function show()
    {
        if (Event::handle('StartShowPeopletags', array($this, $this->tagger, $this->tagged))) {
            if ($this->tag->N > 0) {
                $this->showTags();
            }
            else {
                $this->showEmptyList();
            }
            Event::handle('EndShowPeopletags', array($this, $this->tagger, $this->tagged));
        }
    }

    function url()
    {
        return $this->tag->homeUrl();
    }

    function label()
    {
        // TRANS: Label in lists widget.
        return _m('LABEL','Your lists');
    }

    function showTags()
    {
        $this->out->elementStart('dl', 'entity_tags user_profile_tags');
        $this->out->element('dt', null, $this->label());
        $this->out->elementStart('dd');

        $class = 'tags xoxo';
        if ($this->isEditable()) {
            $class .= ' editable';
        }

        $tags = array();
        $this->out->elementStart('ul', $class);
        while ($this->tag->fetch()) {
            $mode = $this->tag->private ? 'private' : 'public';
            $tags[] = $this->tag->tag;

            $this->out->elementStart('li', 'hashptag mode-' . $mode);
            // Avoid space by using raw output.
            $pt = '#url()) .
              '">' . htmlspecialchars($this->tag->tag) . '';
            $this->out->raw($pt);
            $this->out->elementEnd('li');
        }
        $this->out->elementEnd('ul');

        if ($this->isEditable()) {
            $this->showEditTagForm($tags);
        }

        $this->out->elementEnd('dd');
        $this->out->elementEnd('dl');
    }

    function showEditTagForm($tags=null)
    {
        $this->out->elementStart('div', 'form_tag_user_wrap');
        $this->out->elementStart('form', array('method' => 'post',
                                           'class' => 'form_tag_user',
                                           'name' => 'tagprofile',
                                           'action' => common_local_url('tagprofile', array('id' => $this->tagged->id))));

        $this->out->elementStart('fieldset');
        // TRANS: Fieldset legend in lists widget.
        $this->out->element('legend', null, _m('LEGEND','Edit lists'));
        $this->out->hidden('token', common_session_token());
        $this->out->hidden('id', $this->tagged->id);

        if (!$tags) {
            $tags = array();
        }

        $this->out->input('tags', $this->label(),
                     ($this->out->arg('tags')) ? $this->out->arg('tags') : implode(' ', $tags));
        // TRANS: Button text to save tags for a profile.
        $this->out->submit('save', _m('BUTTON','Save'));

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

    function showEmptyList()
    {
        $this->out->elementStart('dl', 'entity_tags user_profile_tags');
        $this->out->element('dt', null, $this->label());
        $this->out->elementStart('dd');

        $class = 'tags';
        if ($this->isEditable()) {
            $class .= ' editable';
        }

        $this->out->elementStart('ul', $class);
        // TRANS: Empty list message for tags.
        $this->out->element('li', null, _('(None)'));
        $this->out->elementEnd('ul');

        if ($this->isEditable()) {
            $this->showEditTagForm();
        }
        $this->out->elementEnd('dd');
        $this->out->elementEnd('dl');
    }

    function isEditable()
    {
        return !empty($this->user) && $this->tagger->id == $this->user->id;
    }
}


code:
<?php
/**
 * StatusNet, the distributed open-source microblogging tool
 *
 * Menu for personal group of actions
 *
 * 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  Menu
 * @package   StatusNet
 * @author    Evan Prodromou <evan@status.net>
 * @author    Sarven Capadisli <csarven@status.net>
 * @copyright 2008-2011 StatusNet, Inc.
 * @license   http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
 * @link      http://status.net/
 */

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

/**
 * Menu for personal group of actions
 *
 * @category Menu
 * @package  StatusNet
 * @author   Evan Prodromou <evan@status.net>
 * @author   Sarven Capadisli <csarven@status.net>
 * @copyright 2008-2011 StatusNet, Inc.
 * @license  http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
 * @link     http://status.net/
 */
class PersonalGroupNav extends Menu
{
    /**
     * Show the menu
     *
     * @return void
     */
    public function show()
    {
        // FIXME: Legacy StatusNet behaviour was to do this, but really it should be the GroupNav
        // of the targeted user! ($this->action->arg('nickname')
        $target = Profile::current();

        if (!$target instanceof Profile) {
            throw new ServerException('Cannot show personal group navigation without a current user.');
        }

        $nickname  = $target->getNickname();
        $name      = $target->getBestName();

        $scoped = Profile::current();

        $action = $this->actionName;
        $mine = ($this->action->arg('nickname') == $nickname); // @fixme kinda vague

        $this->out->elementStart('ul', array('class' => 'nav'));

        if (Event::handle('StartPersonalGroupNav', array($this, $target, $scoped))) {
            $this->out->menuItem(common_local_url('all', array('nickname' =>
                                                               $nickname)),
                                 // TRANS: Menu item in personal group navigation menu.
                                 _m('MENU','Home'),
                                 // TRANS: Menu item title in personal group navigation menu.
                                 // TRANS: %s is a username.
                                 sprintf(_('%s and friends'), $name),
                                 $mine && $action =='all', 'nav_timeline_personal');
            $this->out->menuItem(common_local_url('showstream', array('nickname' =>
                                                                      $nickname)),
                                 // TRANS: Menu item in personal group navigation menu.
                                 _m('MENU','Profile'),
                                 // TRANS: Menu item title in personal group navigation menu.
                                 _('Your profile'),
                                 $mine && $action =='showstream',
                                 'nav_profile');
            $this->out->menuItem(common_local_url('replies', array('nickname' =>
                                                                   $nickname)),
                                 // TRANS: Menu item in personal group navigation menu.
                                 _m('MENU','Replies'),
                                 // TRANS: Menu item title in personal group navigation menu.
                                 // TRANS: %s is a username.
                                 sprintf(_('Replies to %s'), $name),
                                 $mine && $action =='replies', 'nav_timeline_replies');

            Event::handle('EndPersonalGroupNav', array($this, $target, $scoped));
        }
        $this->out->elementEnd('ul');
    }
}


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

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

/**
 * Profile action common superclass
 *
 * Abstracts out common code from profile and personal tabs
 *
 * @category Personal
 * @package  StatusNet
 * @author   Evan Prodromou <evan@status.net>
 * @license  http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
 * @link     http://status.net/
 */
abstract class ProfileAction extends ManagedAction
{
    var $page    = null;
    var $tag     = null;

    protected $target  = null;    // Profile that we're showing

    protected function doPreparation()
    {
        // showstream requires a nickname
        $nickname_arg = $this->trimmed('nickname');
        $nickname     = common_canonical_nickname($nickname_arg);

        // Permanent redirect on non-canonical nickname
        if ($nickname_arg !== $nickname) {
            $args = array('nickname' => $nickname);
            if ($this->arg('page') && $this->arg('page') != 1) {
                $args['page'] = $this->arg['page'];
            }
            common_redirect(common_local_url($this->getActionName(), $args), 301);
        }

        try {
            $user = User::getByNickname($nickname);
        } catch (NoSuchUserException $e) {
            $group = Local_group::getKV('nickname', $nickname);
            if ($group instanceof Local_group) {
                common_redirect($group->getProfile()->getUrl());
            }

            // No user nor group found, throw the NoSuchUserException again
            throw $e;
        }

        $this->target = $user->getProfile();
    }

    protected function prepare(array $args=array())
    {
        // this will call ->doPreparation() which child classes use to set $this->target
        parent::prepare($args);

        if ($this->target->isPerson() && $this->target->hasRole(Profile_role::SILENCED)
                && (!$this->scoped instanceof Profile || !$this->scoped->hasRight(Right::SILENCEUSER))) {
            throw new ClientException(_('This profile has been silenced by site moderators'), 403);
        }

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

        return true;
    }

    public function getTarget()
    {
        if (!$this->target instanceof Profile) {
            throw new ServerException('No target profile in ProfileAction class');
        }
        return $this->target;
    }

    function isReadOnly($args)
    {
        return true;
    }

    function showSections()
    {
        $this->showSubscriptions();
        $this->showSubscribers();
        $this->showGroups();
        $this->showLists();
        $this->showStatistics();
    }

    /**
     * Convenience function for common pattern of links to subscription/groups sections.
     *
     * @param string $actionClass
     * @param string $title
     * @param string $cssClass
     */
    private function statsSectionLink($actionClass, $title, $cssClass='')
    {
        $this->element('a', array('href' => common_local_url($actionClass,
                                                             array('nickname' => $this->target->getNickname())),
                                  'class' => $cssClass),
                       $title);
    }

    function showSubscriptions()
    {
        $this->elementStart('div', array('id' => 'entity_subscriptions',
                                         'class' => 'section'));
        if (Event::handle('StartShowSubscriptionsMiniList', array($this))) {
            $this->elementStart('h2');
            // TRANS: H2 text for user subscription statistics.
            $this->statsSectionLink('subscriptions', _('Following'));
            $this->text(' ');
            $this->text($this->target->subscriptionCount());
            $this->elementEnd('h2');

            try {
                $profile = $this->target->getSubscribed(0, PROFILES_PER_MINILIST + 1);
                $pml = new ProfileMiniList($profile, $this);
                $pml->show();
            } catch (NoResultException $e) {
                // TRANS: Text for user subscription statistics if the user has no subscription
                $this->element('p', null, _('(None)'));
            }

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

    function showSubscribers()
    {
        $this->elementStart('div', array('id' => 'entity_subscribers',
                                         'class' => 'section'));

        if (Event::handle('StartShowSubscribersMiniList', array($this))) {

            $this->elementStart('h2');
            // TRANS: H2 text for user subscriber statistics.
            $this->statsSectionLink('subscribers', _('Followers'));
            $this->text(' ');
            $this->text($this->target->subscriberCount());
            $this->elementEnd('h2');

            try {
                $profile = $this->target->getSubscribers(0, PROFILES_PER_MINILIST + 1);
                $sml = new SubscribersMiniList($profile, $this);
                $sml->show();
            } catch (NoResultException $e) {
                // TRANS: Text for user subscriber statistics if user has no subscribers.
                $this->element('p', null, _('(None)'));
            }

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

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

    function showStatistics()
    {
        $notice_count = $this->target->noticeCount();
        $age_days     = (time() - strtotime($this->target->created)) / 86400;
        if ($age_days < 1) {
            // Rather than extrapolating out to a bajillion...
            $age_days = 1;
        }
        $daily_count = round($notice_count / $age_days);

        $this->elementStart('div', array('id' => 'entity_statistics',
                                         'class' => 'section'));

        // TRANS: H2 text for user statistics.
        $this->element('h2', null, _('Statistics'));

        $profile = $this->target;
        $actionParams = array('nickname' => $profile->nickname);
        $stats = array(
            array(
                'id' => 'user-id',
                // TRANS: Label for user statistics.
                'label' => _('User ID'),
                'value' => $profile->id,
            ),
            array(
                'id' => 'member-since',
                // TRANS: Label for user statistics.
                'label' => _('Member since'),
                'value' => date('j M Y', strtotime($profile->created))
            ),
            array(
                'id' => 'notices',
                // TRANS: Label for user statistics.
                'label' => _('Notices'),
                'value' => $notice_count,
            ),
            array(
                'id' => 'daily_notices',
                // TRANS: Label for user statistics.
                // TRANS: Average count of posts made per day since account registration.
                'label' => _('Daily average'),
                'value' => $daily_count
            )
        );

        // Give plugins a chance to add stats entries
        Event::handle('ProfileStats', array($profile, &$stats));

        foreach ($stats as $row) {
            $this->showStatsRow($row);
        }
        $this->elementEnd('div');
    }

    private function showStatsRow($row)
    {
        $this->elementStart('dl', 'entity_' . $row['id']);
        $this->elementStart('dt');
        if (!empty($row['link'])) {
            $this->element('a', array('href' => $row['link']), $row['label']);
        } else {
            $this->text($row['label']);
        }
        $this->elementEnd('dt');
        $this->element('dd', null, $row['value']);
        $this->elementEnd('dl');
    }

    function showGroups()
    {
        $groups = $this->target->getGroups(0, GROUPS_PER_MINILIST + 1);

        $this->elementStart('div', array('id' => 'entity_groups',
                                         'class' => 'section'));
        if (Event::handle('StartShowGroupsMiniList', array($this))) {
            $this->elementStart('h2');
            // TRANS: H2 text for user group membership statistics.
            $this->statsSectionLink('usergroups', _('Groups'));
            $this->text(' ');
            $this->text($this->target->getGroupCount());
            $this->elementEnd('h2');

            if ($groups instanceof User_group) {
                $gml = new GroupMiniList($groups, $this->target, $this);
                $cnt = $gml->show();
            } else {
                // TRANS: Text for user user group membership statistics if user is not a member of any group.
                $this->element('p', null, _('(None)'));
            }

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

    function showLists()
    {
        $lists = $this->target->getLists($this->scoped);

        if ($lists->N > 0) {
            $this->elementStart('div', array('id' => 'entity_lists',
                                             'class' => 'section'));

            if (Event::handle('StartShowListsMiniList', array($this))) {

                $url = common_local_url('peopletagsbyuser',
                                        array('nickname' => $this->target->getNickname()));

                $this->elementStart('h2');
                $this->element('a',
                               array('href' => $url),
                               // TRANS: H2 text for user list membership statistics.
                               _('Lists'));
                $this->text(' ');
                $this->text($lists->N);
                $this->elementEnd('h2');

                $this->elementStart('ul');

                $first = true;

                while ($lists->fetch()) {
                    if (!empty($lists->mainpage)) {
                        $url = $lists->mainpage;
                    } else {
                        $url = common_local_url('showprofiletag',
                                                array('nickname' => $this->target->getNickname(),
                                                      'tag'    => $lists->tag));
                    }
                    if (!$first) {
                        $this->text(', ');
                    } else {
                        $first = false;
                    }

                    $this->element('a', array('href' => $url),
                                   $lists->tag);
                }

                $this->elementEnd('ul');

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


code:
<?php
/**
 * StatusNet, the distributed open-source microblogging tool
 *
 * Superclass for forms that operate on a profile
 *
 * 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  Form
 * @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);
}

/**
 * Superclass for forms that operate on a profile
 *
 * Certain forms (block, silence, userflag, sandbox, delete) work on
 * a single profile and work almost the same. So, this form extracts
 * a lot of the common code to simplify those forms.
 *
 * @category Form
 * @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 ProfileActionForm extends Form
{
    /**
     * Profile of user to act on
     */

    var $profile = null;

    /**
     * Return-to args
     */

    var $args = null;

    /**
     * Constructor
     *
     * @param HTMLOutputter $out     output channel
     * @param Profile       $profile profile of user to act on
     * @param array         $args    return-to args
     */

    function __construct($out=null, $profile=null, $args=null)
    {
        parent::__construct($out);

        $this->profile = $profile;
        $this->args    = $args;
    }

    /**
     * ID of the form
     *
     * @return int ID of the form
     */

    function id()
    {
        return $this->target() . '-' . $this->profile->id;
    }

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

    function formClass()
    {
        return 'form_user_'.$this->target();
    }

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

    function action()
    {
        return common_local_url($this->target());
    }

    /**
     * Legend of the Form
     *
     * @return void
     */

    function formLegend()
    {
        $this->out->element('legend', null, $this->description());
    }

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

    function formData()
    {
        $action = $this->target();

        $this->out->hidden($action.'to-' . $this->profile->id,
                           $this->profile->id,
                           'profileid');

        if ($this->args) {
            foreach ($this->args as $k => $v) {
                $this->out->hidden('returnto-' . $k, $v);
            }
        }
    }

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

    function formActions()
    {
        $this->out->submit('submit', $this->title(), 'submit',
                           null, $this->description());
    }

    /**
     * Action this form targets
     *
     * @return string Name of the action, lowercased.
     */

    function target()
    {
        return null;
    }

    /**
     * Title of the form
     *
     * @return string Title of the form, internationalized
     */

    function title()
    {
        return null;
    }

    /**
     * Description of the form
     *
     * @return string description of the form, internationalized
     */

    function description()
    {
        return null;
    }
}


code:
<?php
/**
 * StatusNet - the distributed open-source microblogging tool
 * Copyright (C) 2011, StatusNet, Inc.
 *
 * Superclass for profile blocks
 *
 * 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  Widget
 * @package   StatusNet
 * @author    Evan Prodromou <evan@status.net>
 * @copyright 2011 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);
}

/**
 * Class comment
 *
 * @category  General
 * @package   StatusNet
 * @author    Evan Prodromou <evan@status.net>
 * @copyright 2011 StatusNet, Inc.
 * @license   http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0
 * @link      http://status.net/
 */

abstract class ProfileBlock extends Widget
{
    protected $avatarSize = AVATAR_PROFILE_SIZE;

    abstract function name();
    abstract function url();
    abstract function location();
    abstract function homepage();
    abstract function description();

    function show()
    {
        $this->showActions();
        $this->showAvatar($this->profile);
        $this->showName();
        $this->showLocation();
        $this->showHomepage();
        $this->showOtherProfiles();
        $this->showDescription();
        $this->showTags();
    }

    function showName()
    {
        $name = $this->name();

        if (!empty($name)) {
            $this->out->elementStart('p', 'profile_block_name');
            $url = $this->url();
            if (!empty($url)) {
                $this->out->element('a', array('href' => $url),
                                    $name);
            } else {
                $this->out->text($name);
            }
            $this->out->elementEnd('p');
        }
    }

    function showDescription()
    {
        $description = $this->description();

        if (!empty($description)) {
            $this->out->element(
                'p',
                'profile_block_description',
                $description
            );
        }
    }

    function showLocation()
    {
        $location = $this->location();

        if (!empty($location)) {
            $this->out->element('p', 'profile_block_location', $location);
        }
    }

    function showHomepage()
    {
        $homepage = $this->homepage();

        if (!empty($homepage)) {
            $this->out->element('a',
                                array('href' => $homepage,
                                      'rel' => 'me',
                                      'class' => 'profile_block_homepage'),
                                $homepage);
        }
    }

    function showOtherProfiles()
    {
        $otherProfiles = $this->otherProfiles();

        if (!empty($otherProfiles)) {

            $this->out->elementStart('ul',
                                     array('class' => 'profile_block_otherprofile_list'));

            foreach ($otherProfiles as $otherProfile) {
                $this->out->elementStart('li');
                $this->out->elementStart('a',
                                         array('href' => $otherProfile['href'],
                                               'rel' => 'me',
                                               'class' => 'profile_block_otherprofile',
                                               'title' => $otherProfile['text']));
                $this->out->element('img',
                                    array('src' => $otherProfile['image'],
                                          'class' => 'profile_block_otherprofile_icon'));
                $this->out->elementEnd('a');
                $this->out->elementEnd('li');
            }

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

    function showTags()
    {
    }

    function showActions()
    {
    }
}


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

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

/**
 * Superclass for actions that operate on 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 ProfileFormAction extends RedirectingAction
{
    var $profile = null;

    /**
     * Take arguments for running
     *
     * @param array $args $_REQUEST args
     *
     * @return boolean success flag
     */
    function prepare(array $args = array())
    {
        parent::prepare($args);

        $this->checkSessionToken();

        if (!common_logged_in()) {
            if ($_SERVER['REQUEST_METHOD'] == 'POST') {
            // TRANS: Error message displayed when trying to perform an action that requires a logged in user.
                $this->clientError(_('Not logged in.'));
            } else {
                // Redirect to login.
                common_set_returnto($this->selfUrl());
                $user = common_current_user();
                if (Event::handle('RedirectToLogin', array($this, $user))) {
                    common_redirect(common_local_url('login'), 303);
                }
            }
            return false;
        }

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

        if (!$id) {
            // TRANS: Client error displayed when trying to change user options without specifying a user to work on.
            $this->clientError(_('No profile specified.'));
        }

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

        if (!$this->profile) {
            // TRANS: Client error displayed when trying to change user options without specifying an existing user to work on.
            $this->clientError(_('No profile with that ID.'));
        }

        return true;
    }

    /**
     * Handle request
     *
     * @param array $args $_REQUEST args; handled in prepare()
     *
     * @return void
     */
    function handle()
    {
        parent::handle();

        if ($_SERVER['REQUEST_METHOD'] == 'POST') {
            try {
                $this->handlePost();
            } catch (AlreadyFulfilledException $e) {
                // 'tis alright
            }
            $this->returnToPrevious();
        }
    }

    /**
     * handle a POST request
     *
     * sub-classes should overload this request
     *
     * @return void
     */
    function handlePost()
    {
        // TRANS: Server error displayed when using an unimplemented method.
        $this->serverError(_("Unimplemented method."));
    }
}


code:
<?php
/**
 * StatusNet, the distributed open-source microblogging tool
 *
 * Widget to show a list of profiles
 *
 * 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  Public
 * @package   StatusNet
 * @author    Evan Prodromou <evan@status.net>
 * @copyright 2008-2009 StatusNet, Inc.
 * @license   http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
 * @link      http://status.net/
 */

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

/**
 * Widget to show a list of profiles
 *
 * @category Public
 * @package  StatusNet
 * @author   Zach Copley <zach@status.net>
 * @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 ProfileList extends Widget
{
    /** Current profile, profile query. */
    var $profile = null;
    /** Action object using us. */
    var $action = null;

    function __construct($profile, HTMLOutputter $action = null)
    {
        parent::__construct($action);

        $this->profile = $profile;
        $this->action = $action;
    }

    function show()
    {
        $cnt = 0;

        if (Event::handle('StartProfileList', array($this))) {
            $this->startList();
            $cnt = $this->showProfiles();
            $this->endList();
            Event::handle('EndProfileList', array($this));
        }

        return $cnt;
    }

    function startList()
    {
        $this->out->elementStart('ul', 'profile_list xoxo');
    }

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

    function showProfiles()
    {
        $cnt = $this->profile->N;
        $profiles = $this->profile->fetchAll();

        $max = min($cnt, $this->maxProfiles());

        for ($i = 0; $i < $max; $i++) {
            $pli = $this->newListItem($profiles[$i]);
            $pli->show();
        }

        return $cnt;
    }

    function newListItem(Profile $target)
    {
        return new ProfileListItem($target, $this->action);
    }

    function maxProfiles()
    {
        return PROFILES_PER_PAGE;
    }
}


code:
<?php
/**
 * StatusNet, the distributed open-source microblogging tool
 *
 * Widget to show a list of profiles
 *
 * 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  Public
 * @package   StatusNet
 * @author    Evan Prodromou <evan@status.net>
 * @copyright 2008-2009 StatusNet, Inc.
 * @license   http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
 * @link      http://status.net/
 */

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

class ProfileListItem extends Widget
{
    /** Current profile. */
    protected $target = null;
    var $profile = null;
    /** Action object using us. */
    var $action = null;

    // FIXME: Directory plugin sends a User_group here, but should send a Profile and handle User_group specifics itself?
    function __construct($target, HTMLOutputter $action, Profile $owner = null)
    {
        parent::__construct($action);

        $this->target = $target;
        if ($owner !== null) {
            $this->profile = $owner;
        } else {
            $this->profile = $this->target;
        }
        $this->action = $action;
    }

    function getTarget()
    {
        return $this->target;
    }

    function show()
    {
        if (Event::handle('StartProfileListItem', array($this))) {
            $this->startItem();
            if (Event::handle('StartProfileListItemProfile', array($this))) {
                $this->showProfile();
                Event::handle('EndProfileListItemProfile', array($this));
            }
            if (Event::handle('StartProfileListItemActions', array($this))) {
                $this->showActions();
                Event::handle('EndProfileListItemActions', array($this));
            }
            $this->endItem();
            Event::handle('EndProfileListItem', array($this));
        }
    }

    function startItem()
    {
        $this->out->elementStart('li', array('class' => 'profile',
                                             'id' => 'profile-' . $this->getTarget()->getID()));
    }

    function showProfile()
    {
        $this->startProfile();
        if (Event::handle('StartProfileListItemProfileElements', array($this))) {
            if (Event::handle('StartProfileListItemAvatar', array($this))) {
                $aAttrs = $this->linkAttributes();
                $this->out->elementStart('a', $aAttrs);
                $this->showAvatar($this->profile);
                $this->out->elementEnd('a');
                Event::handle('EndProfileListItemAvatar', array($this));
            }
            if (Event::handle('StartProfileListItemNickname', array($this))) {
                $this->showNickname();
                Event::handle('EndProfileListItemNickname', array($this));
            }
            if (Event::handle('StartProfileListItemFullName', array($this))) {
                $this->showFullName();
                Event::handle('EndProfileListItemFullName', array($this));
            }
            if (Event::handle('StartProfileListItemLocation', array($this))) {
                $this->showLocation();
                Event::handle('EndProfileListItemLocation', array($this));
            }
            if (Event::handle('StartProfileListItemHomepage', array($this))) {
                $this->showHomepage();
                Event::handle('EndProfileListItemHomepage', array($this));
            }
            if (Event::handle('StartProfileListItemBio', array($this))) {
                $this->showBio();
                Event::handle('EndProfileListItemBio', array($this));
            }
            if (Event::handle('StartProfileListItemTags', array($this))) {
                $this->showTags();
                Event::handle('EndProfileListItemTags', array($this));
            }
            Event::handle('EndProfileListItemProfileElements', array($this));
        }
        $this->endProfile();
    }

    function startProfile()
    {
        $this->out->elementStart('div', 'entity_profile h-card');
    }

    function showNickname()
    {
        $this->out->element('a', array('href'=>$this->profile->getUrl(),
                                       'class'=>'p-nickname'),
                            $this->profile->getNickname());
    }

    function showFullName()
    {
        if (!empty($this->profile->fullname)) {
            $this->out->element('span', 'p-name', $this->profile->fullname);
        }
    }

    function showLocation()
    {
        if (!empty($this->profile->location)) {
            $this->out->element('span', 'label p-locality', $this->profile->location);
        }
    }

    function showHomepage()
    {
        if (!empty($this->profile->homepage)) {
            $this->out->text(' ');
            $aAttrs = $this->homepageAttributes();
            $this->out->elementStart('a', $aAttrs);
            $this->out->raw($this->highlight($this->profile->homepage));
            $this->out->elementEnd('a');
        }
    }

    function showBio()
    {
        if (!empty($this->profile->bio)) {
            $this->out->elementStart('p', 'note');
            $this->out->raw($this->highlight($this->profile->bio));
            $this->out->elementEnd('p');
        }
    }

    function showTags()
    {
        $user = common_current_user();
        if (!empty($user)) {
            if ($user->id == $this->profile->getID()) {
                $tags = new SelftagsWidget($this->out, $user, $this->profile);
                $tags->show();
            } else if ($user->getProfile()->canTag($this->profile)) {
                $tags = new PeopletagsWidget($this->out, $user, $this->profile);
                $tags->show();
            }
        }
    }

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

    function showActions()
    {
        $this->startActions();
        if (Event::handle('StartProfileListItemActionElements', array($this))) {
            $this->showSubscribeButton();
            Event::handle('EndProfileListItemActionElements', array($this));
        }
        $this->endActions();
    }

    function startActions()
    {
        $this->out->elementStart('div', 'entity_actions');
        $this->out->elementStart('ul');
    }

    function showSubscribeButton()
    {
        // Is this a logged-in user, looking at someone else's
        // profile?

        $user = common_current_user();

        if (!empty($user) && $this->profile->id != $user->id) {
            $this->out->elementStart('li', 'entity_subscribe');
            if ($user->isSubscribed($this->profile)) {
                $usf = new UnsubscribeForm($this->out, $this->profile);
                $usf->show();
            } else {
                if (Event::handle('StartShowProfileListSubscribeButton', array($this))) {
                    $sf = new SubscribeForm($this->out, $this->profile);
                    $sf->show();
                    Event::handle('EndShowProfileListSubscribeButton', array($this));
                }
            }
            $this->out->elementEnd('li');
        }
    }

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

    function endItem()
    {
        $this->out->elementEnd('li');
    }

    function highlight($text)
    {
        return htmlspecialchars($text);
    }

    function linkAttributes()
    {
        return array('href' => $this->profile->profileurl,
                     'class' => 'u-url',
                     'rel' => 'contact');
    }

    function homepageAttributes()
    {
        return array('href' => $this->profile->homepage,
                     'class' => 'u-url');
    }
}


code:
<?php
/**
 * StatusNet, the distributed open-source microblogging tool
 *
 * Widget to show a list of profiles
 *
 * 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  Public
 * @package   StatusNet
 * @author    Evan Prodromou <evan@status.net>
 * @copyright 2008-2009 StatusNet, Inc.
 * @license   http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
 * @link      http://status.net/
 */

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

/**
 * Widget to show a list of profiles, good for sidebar
 *
 * @category Public
 * @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 ProfileMiniList extends ProfileList
{
    const MAX_PROFILES = PROFILES_PER_MINILIST; // put it in the class

    function startList()
    {
        $this->out->elementStart('ul', 'entities users xoxo');
    }

    function newListItem(Profile $target)
    {
        return new ProfileMiniListItem($target, $this->action);
    }

    function maxProfiles()
    {
        return PROFILES_PER_MINILIST;
    }

    function avatarSize()
    {
        return AVATAR_MINI_SIZE;
    }
}


code:
<?php
/**
 * StatusNet, the distributed open-source microblogging tool
 *
 * Widget to show a list of profiles
 *
 * 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  Public
 * @package   StatusNet
 * @author    Evan Prodromou <evan@status.net>
 * @copyright 2008-2009 StatusNet, Inc.
 * @license   http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
 * @link      http://status.net/
 */

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

/**
 * Widget to show a list of profiles, good for sidebar
 *
 * @category Public
 * @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 ProfileMiniListItem extends ProfileListItem
{
    function show()
    {
        $this->out->elementStart('li', 'h-card');
        if (Event::handle('StartProfileListItemProfileElements', array($this))) {
            if (Event::handle('StartProfileListItemAvatar', array($this))) {
                $aAttrs = $this->linkAttributes();
                $this->out->elementStart('a', $aAttrs);
                $avatarUrl = $this->profile->avatarUrl(AVATAR_MINI_SIZE);
                $this->out->element('img', array('src' => $avatarUrl,
                                                 'width' => AVATAR_MINI_SIZE,
                                                 'height' => AVATAR_MINI_SIZE,
                                                 'class' => 'avatar u-photo',
                                                 'alt' =>  $this->profile->getBestName()));
                $this->out->elementEnd('a');
                Event::handle('EndProfileListItemAvatar', array($this));
            }
            $this->out->elementEnd('li');
        }
    }

    // default; overridden for nofollow lists

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

        $aAttrs['title'] = $this->profile->getBestName();
        $aAttrs['rel']   = 'contact member'; // @todo: member? always?
        $aAttrs['class'] = 'u-url p-name';

        return $aAttrs;
    }
}


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

/**
 * Stream of notices by a profile
 *
 * @category  Stream
 * @package   GNUsocial
 * @author    Evan Prodromou <evan@status.net>
 * @copyright 2011 StatusNet, Inc.
 * @license   https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
 */

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

/**
 * Stream of notices by a profile
 *
 * @category  General
 * @package   GNUsocial
 * @author    Evan Prodromou <evan@status.net>
 * @copyright 2011 StatusNet, Inc.
 * @license   https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
 */

class ProfileNoticeStream extends ScopingNoticeStream
{
    protected $target;

    public function __construct(Profile $target, Profile $scoped = null)
    {
        $this->target = $target;
        parent::__construct(
            new CachingNoticeStream(
                new RawProfileNoticeStream($target),
                'profile:notice_ids:' . $target->getID()
            ),
            $scoped
        );
    }

    public function getNoticeIds($offset, $limit, $since_id = null, $max_id = null)
    {
        if ($this->impossibleStream()) {
            return array();
        } else {
            return parent::getNoticeIds($offset, $limit, $since_id, $max_id);
        }
    }

    public function getNotices($offset, $limit, $since_id = null, $max_id = null)
    {
        if ($this->impossibleStream()) {
            throw new PrivateStreamException($this->target, $this->scoped);
        } else {
            return parent::getNotices($offset, $limit, $since_id, $max_id);
        }
    }

    public function impossibleStream()
    {
        if (!$this->target->readableBy($this->scoped)) {
            // cannot read because it's a private stream and either noone's logged in or they are not subscribers
            return true;
        }

        // If it's a spammy stream, and no user or not a moderator

        if (common_config('notice', 'hidespam')) {
            // if this is a silenced user
            if ($this->target->hasRole(Profile_role::SILENCED) &&
                // and we are either not logged in
                (!$this->scoped instanceof Profile ||
                // or if we are, we are not logged in as the target, and we don't have right to review spam
                (!$this->scoped->sameAs($this->target) && !$this->scoped->hasRight(Right::REVIEWSPAM)))) {
                return true;
            }
        }

        return false;
    }
}

/**
 * Raw stream of notices by a profile
 *
 * @category  General
 * @package   GNUsocial
 * @author    Evan Prodromou <evan@status.net>
 * @copyright 2011 StatusNet, Inc.
 * @license   https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
 */

class RawProfileNoticeStream extends NoticeStream
{
    protected $target;
    protected $selectVerbs = array();   // select all verbs

    public function __construct(Profile $target)
    {
        parent::__construct();
        $this->target = $target;
    }

    public function getNoticeIds($offset, $limit, $since_id, $max_id)
    {
        $notice = new Notice();

        $notice->profile_id = $this->target->getID();

        $notice->selectAdd();
        $notice->selectAdd('id');

        $notice->whereAdd('scope <> ' . Notice::MESSAGE_SCOPE);

        Notice::addWhereSinceId($notice, $since_id);
        Notice::addWhereMaxId($notice, $max_id);

        self::filterVerbs($notice, $this->selectVerbs);

        $notice->orderBy('created DESC, id DESC');

        if (!is_null($offset)) {
            $notice->limit($offset, $limit);
        }

        $notice->find();

        $ids = array();

        while ($notice->fetch()) {
            $ids[] = $notice->id;
        }

        return $ids;
    }
}


code:
<?php
/**
 * StatusNet, the distributed open-source microblogging tool
 *
 * Base class for sections showing lists of people
 *
 * 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  Widget
 * @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') && !defined('LACONICA')) {
    exit(1);
}

define('PROFILES_PER_SECTION', 6);

/**
 * Base class for sections
 *
 * These are the widgets that show interesting data about a person
 * group, or site.
 *
 * @category Widget
 * @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/
 */

abstract class ProfileSection extends Section
{
    function showContent()
    {
        $profiles = $this->getProfiles();

        if (!$profiles->N) {
            return false;
        }

        $cnt = 0;

        $this->out->elementStart('table');
        $this->out->elementStart('tbody');
        while ($profiles->fetch() && ++$cnt <= PROFILES_PER_SECTION) {
            $this->showProfile($profiles);
        }
        $this->out->elementEnd('tbody');
        $this->out->elementEnd('table');

        return ($cnt > PROFILES_PER_SECTION);
    }

    function getProfiles()
    {
        return null;
    }

    function showProfile($profile)
    {
        $this->out->elementStart('tr');
        $this->out->elementStart('td');
        $this->out->elementStart('a', array('title' => $profile->getBestName(),
                                       'href' => $profile->profileurl,
                                       'rel' => 'contact member',
                                       'class' => 'h-card u-url'));
        $avatarUrl = $profile->avatarUrl(AVATAR_MINI_SIZE);
        $this->out->element('img', array('src' => $avatarUrl,
                                    'width' => AVATAR_MINI_SIZE,
                                    'height' => AVATAR_MINI_SIZE,
                                    'class' => 'avatar u-photo',
                                    'alt' => $profile->getBestName()));
        $this->out->elementEnd('a');
        $this->out->elementEnd('td');
        if (isset($profile->value)) {
            $this->out->element('td', 'value', $profile->value);
        }

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


code:
<?php

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

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


code:
<?php

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

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

    public 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
 *
 * Form for subscribing to 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  Form
 * @package   StatusNet
 * @author    Evan Prodromou <evan@status.net>
 * @author    Sarven Capadisli <csarven@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') && !defined('LACONICA')) {
    exit(1);
}

require_once INSTALLDIR . '/lib/util/form.php';

/**
 * Form for subscribing to a user
 *
 * @category Form
 * @package  StatusNet
 * @author   Evan Prodromou <evan@status.net>
 * @author   Sarven Capadisli <csarven@status.net>
 * @license  http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
 * @link     http://status.net/
 *
 * @see      UnsubscribeForm
 */
class SubscribeForm extends Form
{
    /**
     * Profile of user to subscribe to
     */
    var $profile = null;

    /**
     * Constructor
     *
     * @param HTMLOutputter $out     output channel
     * @param Profile       $profile profile of user to subscribe to
     */
    function __construct($out=null, $profile=null)
    {
        parent::__construct($out);

        $this->profile = $profile;
    }

    /**
     * ID of the form
     *
     * @return int ID of the form
     */
    function id()
    {
        return 'subscribe-' . $this->profile->id;
    }

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

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

    /**
     * Legend of the Form
     *
     * @return void
     */
    function formLegend()
    {
        // TRANS: Form of form to subscribe to a user.
        $this->out->element('legend', null, _('Subscribe to this user'));
    }

    /**
     * Data elements of the form
     *
     * @return void
     */
    function formData()
    {
        $this->out->hidden('subscribeto-' . $this->profile->id,
                           $this->profile->id,
                           'subscribeto');
    }

    /**
     * Action elements
     *
     * @return void
     */
    function formActions()
    {
        // TRANS: Button text to subscribe to a user.
        $this->out->submit('submit', _m('BUTTON','Subscribe'), 'submit', null,
                           // TRANS: Button title to subscribe to a user.
                           _('Subscribe to this user.'));
    }
}


code:
<?php
/**
 * StatusNet, the distributed open-source microblogging tool
 *
 * Form for subscribing 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  Form
 * @package   StatusNet
 * @author    Evan Prodromou <evan@status.net>
 * @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);
}

require_once INSTALLDIR . '/lib/util/form.php';

/**
 * Form for subscribing to a peopletag
 *
 * @category Form
 * @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/
 *
 * @see      UnsubscribeForm
 */
class SubscribePeopletagForm extends Form
{
    /**
     * peopletag for the user to join
     */
    var $peopletag = null;

    /**
     * Constructor
     *
     * @param HTMLOutputter $out   output channel
     * @param peopletag     $peopletag peopletag to subscribe to
     */
    function __construct($out=null, $peopletag=null)
    {
        parent::__construct($out);

        $this->peopletag = $peopletag;
    }

    /**
     * ID of the form
     *
     * @return string ID of the form
     */
    function id()
    {
        return 'peopletag-subscribe-' . $this->peopletag->id;
    }

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

    /**
     * Action of the form
     *
     * @return string URL of the action
     */
    function action()
    {
        return common_local_url('subscribepeopletag',
                                array('id' => $this->peopletag->id));
    }

    /**
     * Action elements
     *
     * @return void
     */
    function formActions()
    {
        // TRANS: Button text for subscribing to a list.
        $this->out->submit('submit', _m('BUTTON', 'Subscribe'));

    }
}


code:
<?php

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

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


code:
<?php

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

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

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

class SubscribersMiniList extends ProfileMiniList
{
    public function newListItem(Profile $profile)
    {
        return new SubscribersMiniListItem($profile, $this->action);
    }
}


code:
<?php

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

class SubscribersMiniListItem extends ProfileMiniListItem
{
    function linkAttributes()
    {
        $aAttrs = parent::linkAttributes();
        if (common_config('nofollow', 'subscribers')) {
            $aAttrs['rel'] .= ' nofollow';
        }
        return $aAttrs;
    }
}


code:
<?php
/**
 * StatusNet, the distributed open-source microblogging tool
 *
 * Widget to show a list of profiles
 *
 * 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  Public
 * @package   StatusNet
 * @author    Evan Prodromou <evan@status.net>
 * @copyright 2008-2009 StatusNet, Inc.
 * @license   http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
 * @link      http://status.net/
 */

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

/**
 * Widget to show a list of subscriptions
 *
 * @category Public
 * @package  StatusNet
 * @author   Zach Copley <zach@status.net>
 * @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 SubscriptionList extends ProfileList
{
    /** Owner of this list */
    var $owner = null;

    public function __construct($profile, $owner = null, $action = null)
    {
        parent::__construct($profile, $action);

        $this->owner = $owner;
    }

    public function newListItem(Profile $profile)
    {
        return new SubscriptionListItem($profile, $this->owner, $this->action);
    }
}


code:
<?php

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

class SubscriptionListItem extends ProfileListItem
{
    /** Owner of this list */
    var $owner = null;

    // FIXME: TagSubs plugin sends a TagSub here, but should send a Profile and handle TagSub specifics itself?
    function __construct($target, $owner, HTMLOutputter $action)
    {
        if ($owner instanceof Profile) {
            parent::__construct($target, $action, $owner);
        } else {
            parent::__construct($target, $action);
        }

        $this->owner = $owner;
    }

    function showProfile()
    {
        $this->startProfile();
        $this->showAvatar($this->profile);
        $this->showNickname();
        $this->showFullName();
        $this->showLocation();
        $this->showHomepage();
        $this->showBio();
        // Relevant portion!
        $this->showTags();
        if ($this->isOwn()) {
            $this->showOwnerControls();
        }
        $this->endProfile();
    }

    function showOwnerControls()
    {
        // pass
    }

    function isOwn()
    {
        $user = common_current_user();
        return (!empty($user) && ($this->owner->id == $user->id));
    }
}


code:
<?php

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

// XXX SubscriptionsList and SubscriptionList are dangerously close

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


code:
<?php

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

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