code:
<?php
/**
 * StatusNet, the distributed open-source microblogging tool
 *
 * widget for displaying a list of notices
 *
 * 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  UI
 * @package   StatusNet
 * @author    Evan Prodromou <evan@status.net>
 * @author    Sarven Capadisli <csarven@status.net>
 * @copyright 2008 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') && !defined('STATUSNET')) { exit(1); }

/**
 * widget for displaying a list of notices
 *
 * There are a number of actions that display a list of notices, in
 * reverse chronological order. This widget abstracts out most of the
 * code for UI for notice lists. It's overridden to hide some
 * data for e.g. the profile page.
 *
 * @category UI
 * @package  StatusNet
 * @author   Evan Prodromou <evan@status.net>
 * @license  http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
 * @link     http://status.net/
 * @see      Notice
 * @see      NoticeListItem
 * @see      ProfileNoticeList
 */
class NoticeList extends Widget
{
    /** the current stream of notices being displayed. */

    var $notice = null;

    protected $addressees = true;
    protected $attachments = true;
    protected $id_prefix = null;
    protected $maxchars = 0;
    protected $options = true;
    protected $show_n = NOTICES_PER_PAGE;

    /**
     * constructor
     *
     * @param Notice $notice stream of notices from DB_DataObject
     */
    function __construct(Notice $notice, $out=null, array $prefs=array())
    {
        parent::__construct($out);
        $this->notice = $notice;

        // integer preferences
        foreach(array('show_n', 'maxchars') as $key) {
            if (array_key_exists($key, $prefs)) {
                $this->$key = (int)$prefs[$key];
            }
        }
        // boolean preferences
        foreach(array('addressees', 'attachments', 'options') as $key) {
            if (array_key_exists($key, $prefs)) {
                $this->$key = (bool)$prefs[$key];
            }
        }
        // string preferences
        foreach(array('id_prefix') as $key) {
            if (array_key_exists($key, $prefs)) {
                $this->$key = $prefs[$key];
            }
        }
    }

    /**
     * show the list of notices
     *
     * "Uses up" the stream by looping through it. So, probably can't
     * be called twice on the same list.
     *
     * @param integer $n    The amount of notices to show.
     *
     * @return int  Total amount of notices actually available.
     */
    public function show()
    {
        $this->out->elementStart('ol', array('class' => 'notices xoxo'));

		$notices = $this->notice->fetchAll();
		$total   = count($notices);
		$notices = array_slice($notices, 0, $this->show_n);

    	self::prefill($notices);

    	foreach ($notices as $notice) {

            try {
                $item = $this->newListItem($notice);
                $item->show();
            } catch (Exception $e) {
                // we log exceptions and continue
                common_log(LOG_ERR, $e->getMessage());
                continue;
            }
        }

        $this->out->elementEnd('ol');
        return $total;
    }

    /**
     * returns a new list item for the current notice
     *
     * Recipe (factory?) method; overridden by sub-classes to give
     * a different list item class.
     *
     * @param Notice $notice the current notice
     *
     * @return NoticeListItem a list item for displaying the notice
     */
    function newListItem(Notice $notice)
    {
        $prefs = array('addressees' => $this->addressees,
                       'attachments' => $this->attachments,
                       'id_prefix' => $this->id_prefix,
                       'maxchars' => $this->maxchars,
                       'options' => $this->options);
        return new NoticeListItem($notice, $this->out, $prefs);
    }

    static function prefill(array &$notices)
    {
        $scoped = Profile::current();
        $notice_ids = Notice::_idsOf($notices);

        if (Event::handle('StartNoticeListPrefill', array(&$notices, $notice_ids, $scoped))) {

            // Prefill attachments
            Notice::fillAttachments($notices);
            // Prefill the profiles
            $profiles = Notice::fillProfiles($notices);

            Event::handle('EndNoticeListPrefill', array(&$notices, &$profiles, $notice_ids, $scoped));
        }
    }
}


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

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

/**
 * Placeholder for showing faves...
 */
abstract class NoticeListActorsItem extends NoticeListItem
{
    /**
     * @return array of profile IDs
     */
    abstract function getProfiles();

    abstract function getListMessage($count, $you);

    function show()
    {
        $links = array();
        $you = false;
        $cur = common_current_user();
        foreach ($this->getProfiles() as $id) {
            if ($cur && $cur->id == $id) {
                $you = true;
                // TRANS: Reference to the logged in user in favourite list.
                array_unshift($links, _m('FAVELIST', 'You'));
            } else {
                $profile = Profile::getKV('id', $id);
                if ($profile instanceof Profile) {
                    $links[] = sprintf('%s',
                                       htmlspecialchars($profile->getUrl()),
                                       htmlspecialchars($profile->getBestName()));
                }
            }
        }

        if ($links) {
            $count = count($links);
            $msg = $this->getListMessage($count, $you);
            $out = sprintf($msg, $this->magicList($links));

            $this->showStart();
            $this->out->raw($out);
            $this->showEnd();
            return $count;
        } else {
            return 0;
        }
    }

    function magicList($items)
    {
        if (count($items) == 0) {
            return '';
        } else if (count($items) == 1) {
            return $items[0];
        } else {
            $first = array_slice($items, 0, -1);
            $last = array_slice($items, -1, 1);
            // TRANS: Separator in list of user names like "Jim, Bob, Mary".
            $separator = _(', ');
            // TRANS: For building a list such as "Jim, Bob, Mary and 5 others like this".
            // TRANS: %1$s is a list of users, separated by a separator (default: ", "), %2$s is the last user in the list.
            return sprintf(_m('FAVELIST', '%1$s and %2$s'), implode($separator, $first), implode($separator, $last));
        }
    }
}

repo_name: piratas/tortuga

license: mit


code:
<?php
/**
 * StatusNet - the distributed open-source microblogging tool
 * Copyright (C) 2010, StatusNet, Inc.
 *
 * An item in a notice list
 *
 * 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 2010 StatusNet, Inc.
 * @license   http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0
 * @link      http://status.net/
 */

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

/**
 * widget for displaying a single notice
 *
 * This widget has the core smarts for showing a single notice: what to display,
 * where, and under which circumstances. Its key method is show(); this is a recipe
 * that calls all the other show*() methods to build up a single notice. The
 * ProfileNoticeListItem subclass, for example, overrides showAuthor() to skip
 * author info (since that's implicit by the data in the page).
 *
 * @category UI
 * @package  StatusNet
 * @author   Evan Prodromou <evan@status.net>
 * @license  http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
 * @link     http://status.net/
 * @see      NoticeList
 * @see      ProfileNoticeListItem
 */
class NoticeListItem extends Widget
{
    /** The notice this item will show. */
    var $notice = null;

    /** The notice that was repeated. */
    var $repeat = null;

    /** The profile of the author of the notice, extracted once for convenience. */
    var $profile = null;

    protected $addressees = true;
    protected $attachments = true;
    protected $id_prefix = null;
    protected $options = true;
    protected $maxchars = 0;   // if <= 0 it means use full posts
    protected $item_tag = 'li';

    /**
     * constructor
     *
     * Also initializes the profile attribute.
     *
     * @param Notice $notice The notice we'll display
     */
    function __construct(Notice $notice, Action $out=null, array $prefs=array())
    {
        parent::__construct($out);
        if (!empty($notice->repeat_of)) {
            $original = Notice::getKV('id', $notice->repeat_of);
            if (!$original instanceof Notice) { // could have been deleted
                $this->notice = $notice;
            } else {
                $this->notice = $original;
                $this->repeat = $notice;
            }
        } else {
            $this->notice  = $notice;
        }

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

        // integer preferences
        foreach(array('maxchars') as $key) {
            if (array_key_exists($key, $prefs)) {
                $this->$key = (int)$prefs[$key];
            }
        }
        // boolean preferences
        foreach(array('addressees', 'attachments', 'options') as $key) {
            if (array_key_exists($key, $prefs)) {
                $this->$key = (bool)$prefs[$key];
            }
        }
        // string preferences
        foreach(array('id_prefix', 'item_tag') as $key) {
            if (array_key_exists($key, $prefs)) {
                $this->$key = $prefs[$key];
            }
        }
    }

    /**
     * recipe function for displaying a single notice.
     *
     * 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 show()
    {
        if (empty($this->notice)) {
            common_log(LOG_WARNING, "Trying to show missing notice; skipping.");
            return;
        } else if (empty($this->profile)) {
            common_log(LOG_WARNING, "Trying to show missing profile (" . $this->notice->profile_id . "); skipping.");
            return;
        }

        $this->showStart();
        if (Event::handle('StartShowNoticeItem', array($this))) {
            $this->showNotice();
            Event::handle('EndShowNoticeItem', array($this));
        }
        $this->showEnd();
    }

    function showNotice()
    {
        if (Event::handle('StartShowNoticeItemNotice', array($this))) {
            $this->showNoticeHeaders();
            $this->showContent();
            $this->showNoticeFooter();
            Event::handle('EndShowNoticeItemNotice', array($this));
        }
    }

    function showNoticeHeaders()
    {
        $this->elementStart('section', array('class'=>'notice-headers'));
        $this->showNoticeTitle();
        $this->showAuthor();
        if ($this->addressees) { $this->showAddressees(); }
        $this->elementEnd('section');
    }

    function showNoticeFooter()
    {
        $this->elementStart('footer');
        $this->showNoticeInfo();
        if ($this->options) { $this->showNoticeOptions(); }
        if ($this->attachments) { $this->showNoticeAttachments(); }
        $this->elementEnd('footer');
    }

    function showNoticeTitle()
    {
        if (Event::handle('StartShowNoticeTitle', array($this))) {
            $this->element('a', array('href' => $this->notice->getUrl(),
                                      'class' => 'notice-title'),
                           $this->notice->getTitle());
            Event::handle('EndShowNoticeTitle', array($this));
        }
    }

    function showNoticeInfo()
    {
        if (Event::handle('StartShowNoticeInfo', array($this))) {
            $this->showNoticeLink();
            $this->showNoticeSource();
            $this->showNoticeLocation();
            $this->showPermalink();
            Event::handle('EndShowNoticeInfo', array($this));
        }
    }

    function showNoticeOptions()
    {
        if (Event::handle('StartShowNoticeOptions', array($this))) {
            $user = common_current_user();
            if ($user) {
                $this->out->elementStart('div', 'notice-options');
                if (Event::handle('StartShowNoticeOptionItems', array($this))) {
                    $this->showReplyLink();
                    $this->showDeleteLink();
                    Event::handle('EndShowNoticeOptionItems', array($this));
                }
                $this->out->elementEnd('div');
            }
            Event::handle('EndShowNoticeOptions', array($this));
        }
    }

    /**
     * start a single notice.
     *
     * @return void
     */
    function showStart()
    {
        if (Event::handle('StartOpenNoticeListItemElement', array($this))) {
            $id = (empty($this->repeat)) ? $this->notice->id : $this->repeat->id;
            $class = 'h-entry notice';
            if ($this->notice->scope != 0 && $this->notice->scope != 1) {
                $class .= ' limited-scope';
            }
            if (!empty($this->notice->source)) {
                $class .= ' notice-source-'.$this->notice->source;
            }
            $id_prefix = (strlen($this->id_prefix) ? $this->id_prefix . '-' : '');
            $this->out->elementStart($this->item_tag, array('class' => $class,
                                                 'id' => "${id_prefix}notice-${id}"));
            Event::handle('EndOpenNoticeListItemElement', array($this));
        }
    }

    /**
     * show the author of a notice
     *
     * By default, this shows the avatar and (linked) nickname of the author.
     *
     * @return void
     */

    function showAuthor()
    {
        $attrs = array('href' => $this->profile->profileurl,
                       'class' => 'h-card p-author',
                       'title' => $this->profile->getNickname());

        if (Event::handle('StartShowNoticeItemAuthor', array($this->profile, $this->out, &$attrs))) {
            $this->out->elementStart('a', $attrs);
            $this->showAvatar($this->profile);
            $this->out->text($this->profile->getStreamName());
            $this->out->elementEnd('a');
            Event::handle('EndShowNoticeItemAuthor', array($this->profile, $this->out));
        }
    }

    function showAddressees()
    {
        $pa = $this->getProfileAddressees();

        if (!empty($pa)) {
            $this->out->elementStart('ul', 'addressees');
            $first = true;
            foreach ($pa as $addr) {
                $this->out->elementStart('li', 'h-card');
                $text = $addr['text'];
                unset($addr['text']);
                $this->out->element('a', $addr, $text);
                $this->out->elementEnd('li');
            }
            $this->out->elementEnd('ul', 'addressees');
        }
    }

    function getProfileAddressees()
    {
        $pa = array();

        $attentions = $this->getReplyProfiles();

        foreach ($attentions as $attn) {
            $class = $attn->isGroup() ? 'group' : 'account';
            $pa[] = array('href' => $attn->profileurl,
                          'title' => $attn->getNickname(),
                          'class' => "addressee {$class}",
                          'text' => $attn->getStreamName());
        }

        return $pa;
    }

    function getReplyProfiles()
    {
        return $this->notice->getReplyProfiles();
    }

    /**
     * show the nickname of the author
     *
     * Links to the author's profile page
     *
     * @return void
     */
    function showNickname()
    {
        $this->out->raw('' .
                        htmlspecialchars($this->profile->getNickname()) .
                        '');
    }

    /**
     * show the content of the notice
     *
     * Shows the content of the notice. This is pre-rendered for efficiency
     * at save time. Some very old notices might not be pre-rendered, so
     * they're rendered on the spot.
     *
     * @return void
     */
    function showContent()
    {
        // FIXME: URL, image, video, audio
        $this->out->elementStart('article', array('class' => 'e-content'));
        if (Event::handle('StartShowNoticeContent', array($this->notice, $this->out, $this->out->getScoped()))) {
            if ($this->maxchars > 0 && mb_strlen($this->notice->content) > $this->maxchars) {
                $this->out->text(mb_substr($this->notice->content, 0, $this->maxchars) . '[…]');
            } elseif ($this->notice->rendered) {
                $this->out->raw($this->notice->rendered);
            } else {
                // XXX: may be some uncooked notices in the DB,
                // we cook them right now. This should probably disappear in future
                // versions (>> 0.4.x)
                $this->out->raw(common_render_content($this->notice->content, $this->notice));
            }
            Event::handle('EndShowNoticeContent', array($this->notice, $this->out, $this->out->getScoped()));
        }
        $this->out->elementEnd('article');
    }

    function showNoticeAttachments() {
        if (common_config('attachments', 'show_thumbs')) {
            $al = new InlineAttachmentList($this->notice, $this->out);
            $al->show();
        }
    }

    /**
     * show the link to the main page for the notice
     *
     * Displays a local link to the rendered notice, with "relative" time.
     *
     * @return void
     */
    function showNoticeLink()
    {
        $this->out->elementStart('a', array('rel' => 'bookmark',
                                            'class' => 'timestamp',
                                            'href' => Conversation::getUrlFromNotice($this->notice)));
        $this->out->element('time', array('class' => 'dt-published',
                                          'datetime' => common_date_iso8601($this->notice->created),
                                          // TRANS: Timestamp title (tooltip text) for NoticeListItem
                                          'title' => common_exact_date($this->notice->created)),
                            common_date_string($this->notice->created));
        $this->out->elementEnd('a');
    }

    /**
     * show the notice location
     *
     * shows the notice location in the correct language.
     *
     * If an URL is available, makes a link. Otherwise, just a span.
     *
     * @return void
     */
    function showNoticeLocation()
    {
        $id = $this->notice->id;

        $location = $this->notice->getLocation();

        if (empty($location)) {
            return;
        }

        $name = $location->getName();

        $lat = $this->notice->lat;
        $lon = $this->notice->lon;
        $latlon = (!empty($lat) && !empty($lon)) ? $lat.';'.$lon : '';

        if (empty($name)) {
            $latdms = $this->decimalDegreesToDMS(abs($lat));
            $londms = $this->decimalDegreesToDMS(abs($lon));
            // TRANS: Used in coordinates as abbreviation of north.
            $north = _('N');
            // TRANS: Used in coordinates as abbreviation of south.
            $south = _('S');
            // TRANS: Used in coordinates as abbreviation of east.
            $east = _('E');
            // TRANS: Used in coordinates as abbreviation of west.
            $west = _('W');
            $name = sprintf(
                // TRANS: Coordinates message.
                // TRANS: %1$s is lattitude degrees, %2$s is lattitude minutes,
                // TRANS: %3$s is lattitude seconds, %4$s is N (north) or S (south) depending on lattitude,
                // TRANS: %5$s is longitude degrees, %6$s is longitude minutes,
                // TRANS: %7$s is longitude seconds, %8$s is E (east) or W (west) depending on longitude,
                _('%1$u°%2$u\'%3$u"%4$s %5$u°%6$u\'%7$u"%8$s'),
                $latdms['deg'],$latdms['min'], $latdms['sec'],($lat>0? $north:$south),
                $londms['deg'],$londms['min'], $londms['sec'],($lon>0? $east:$west));
        }

        $url  = $location->getUrl();

        $this->out->text(' ');
        $this->out->elementStart('span', array('class' => 'location'));
        // TRANS: Followed by geo location.
        $this->out->text(_('at'));
        $this->out->text(' ');
        if (empty($url)) {
            $this->out->element('abbr', array('class' => 'geo',
                                              'title' => $latlon),
                                $name);
        } else {
            $xstr = new XMLStringer(false);
            $xstr->elementStart('a', array('href' => $url,
                                           'rel' => 'external'));
            $xstr->element('abbr', array('class' => 'geo',
                                         'title' => $latlon),
                           $name);
            $xstr->elementEnd('a');
            $this->out->raw($xstr->getString());
        }
        $this->out->elementEnd('span');
    }

    /**
     * @param number $dec decimal degrees
     * @return array split into 'deg', 'min', and 'sec'
     */
    function decimalDegreesToDMS($dec)
    {
        $deg = intval($dec);
        $tempma = abs($dec) - abs($deg);

        $tempma = $tempma * 3600;
        $min = floor($tempma / 60);
        $sec = $tempma - ($min*60);

        return array("deg"=>$deg,"min"=>$min,"sec"=>$sec);
    }

    /**
     * Show the source of the notice
     *
     * Either the name (and link) of the API client that posted the notice,
     * or one of other other channels.
     *
     * @return void
     */
    function showNoticeSource()
    {
        $ns = $this->notice->getSource();

        if (!$ns instanceof Notice_source) {
            return false;
        }

        // TRANS: A possible notice source (web interface).
        $source_name = (empty($ns->name)) ? ($ns->code ? _($ns->code) : _m('SOURCE','web')) : _($ns->name);
        $this->out->text(' ');
        $this->out->elementStart('span', 'source');
        // @todo FIXME: probably i18n issue. If "from" is followed by text, that should be a parameter to "from" (from %s).
        // TRANS: Followed by notice source.
        $this->out->text(_('from'));
        $this->out->text(' ');

        $name  = $source_name;
        $url   = $ns->url;
        $title = null;

        if (Event::handle('StartNoticeSourceLink', array($this->notice, &$name, &$url, &$title))) {
            $name = $source_name;
            $url  = $ns->url;
        }
        Event::handle('EndNoticeSourceLink', array($this->notice, &$name, &$url, &$title));

        // if $ns->name and $ns->url are populated we have
        // configured a source attr somewhere
        if (!empty($name) && !empty($url)) {
            $this->out->elementStart('span', 'device');

            $attrs = array(
                'href' => $url,
                'rel' => 'external'
            );

            if (!empty($title)) {
                $attrs['title'] = $title;
            }

            $this->out->element('a', $attrs, $name);
            $this->out->elementEnd('span');
        } else {
            $this->out->element('span', 'device', $name);
        }

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

    /**
     * show link to single-notice view for this notice item
     *
     * A permalink that goes to this specific object and nothing else
     *
     * @return void
     */
    function showPermalink()
    {
        $class = 'permalink u-url';
        if (!$this->notice->isLocal()) {
            $class .= ' external';
        }
        try {
            $this->out->element('a',
                        array('href' => $this->notice->getUrl(),
                              'class' => $class),
                        // TRANS: Addition in notice list item for single-notice view.
                        _('permalink'));
        } catch (InvalidUrlException $e) {
            // no permalink available
        }
    }

    /**
     * show a link to reply to the current notice
     *
     * Should either do the reply in the current notice form (if available), or
     * link out to the notice-posting form. A little flakey, doesn't always work.
     *
     * @return void
     */
    function showReplyLink()
    {
        if (common_logged_in()) {
            $this->out->text(' ');
            $reply_url = common_local_url('newnotice',
                                          array('replyto' => $this->profile->getNickname(), 'inreplyto' => $this->notice->id));
            $this->out->elementStart('a', array('href' => $reply_url,
                                                'class' => 'notice_reply',
                                                // TRANS: Link title in notice list item to reply to a notice.
                                                'title' => _('Reply to this notice.')));
            // TRANS: Link text in notice list item to reply to a notice.
            $this->out->text(_('Reply'));
            $this->out->text(' ');
            $this->out->element('span', 'notice_id', $this->notice->id);
            $this->out->elementEnd('a');
        }
    }

    /**
     * if the user is the author, let them delete the notice
     *
     * @return void
     */
    function showDeleteLink()
    {
        $user = common_current_user();

        $todel = (empty($this->repeat)) ? $this->notice : $this->repeat;

        if (!empty($user) &&
            ($todel->profile_id == $user->id || $user->hasRight(Right::DELETEOTHERSNOTICE))) {
            $this->out->text(' ');
            $deleteurl = common_local_url('deletenotice',
                                          array('notice' => $todel->id));
            $this->out->element('a', array('href' => $deleteurl,
                                           'class' => 'notice_delete popup',
                                           // TRANS: Link title in notice list item to delete a notice.
                                           'title' => _('Delete this notice from the timeline.')),
                                           // TRANS: Link text in notice list item to delete a notice.
                                           _('Delete'));
        }
    }

    /**
     * finish the notice
     *
     * Close the last elements in the notice list item
     *
     * @return void
     */
    function showEnd()
    {
        if (Event::handle('StartCloseNoticeListItemElement', array($this))) {
            $this->out->elementEnd('li');
            Event::handle('EndCloseNoticeListItemElement', array($this));
        }
    }

    /**
     * Get the notice in question
     *
     * For hooks, etc., this may be useful
     *
     * @return Notice The notice we're showing
     */

    function getNotice()
    {
        return $this->notice;
    }
}


code:
<?php
/**
 * StatusNet - the distributed open-source microblogging tool
 * Copyright (C) 2011, StatusNet, Inc.
 *
 * For use by microapps to customize notice list item output
 *
 * 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  Microapp
 * @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);
}

/**
 * For use by microapps to customize NoticeListItem output
 *
 * @category  Microapp
 * @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/
 */
class NoticeListItemAdapter
{
    protected $nli;

    /**
     * Wrap a notice list item.
     *
     * @param NoticeListItem $nli item to wrap
     */
    function __construct($nli)
    {
        $this->nli = $nli;
    }

    /**
     * Delegate unimplemented methods to the notice list item attribute.
     *
     * @param string $name      Name of the method
     * @param array  $arguments Arguments called
     *
     * @return mixed Return value of the method.
     */
    function __call($name, $arguments)
    {
        return call_user_func_array(array($this->nli, $name), $arguments);
    }

    function __get($name)
    {
        return $this->nli->$name;
    }
}


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

define('NOTICES_PER_SECTION', 6);

/**
 * Base class for sections showing lists of notices
 *
 * These are the widgets that show interesting data about a person
 * group, or site.
 *
 * @todo migrate this to use a variant of NoticeList
 *
 * @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 NoticeSection extends Section
{
    protected $addressees = false;
    protected $attachments = false;
    protected $maxchars = 140;
    protected $options = false;
    protected $show_n = NOTICES_PER_SECTION;

    function showContent()
    {
        $prefs = array();
        foreach (array('addressees', 'attachments', 'maxchars', 'options', 'show_n') as $key) {
            $prefs[$key] = $this->$key;
        }
        $prefs['id_prefix'] = $this->divId();

        // args: notice object, html outputter, preference array for notice lists and their items
        $list = new NoticeList($this->getNotices(), $this->out, $prefs);
        $total = $list->show(); // returns total amount of notices available
        return ($total > $this->show_n);  // do we have more to show?
    }

    function getNotices()
    {
        return null;
    }
}


code:
<?php
/**
 * StatusNet - the distributed open-source microblogging tool
 * Copyright (C) 2011, StatusNet, Inc.
 *
 * A stream of notices
 *
 * 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  Stream
 * @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 for notice streams
 *
 * @category  Stream
 * @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 NoticeStream
{
    // Will only get notices with the 'post' activityverb by default.
    protected $selectVerbs = array();

    public function __construct()
    {
        $this->selectVerbs = array(ActivityVerb::POST, ActivityUtils::resolveUri(ActivityVerb::POST, true));
    }

    abstract function getNoticeIds($offset, $limit, $since_id, $max_id);

    function getNotices($offset, $limit, $sinceId = null, $maxId = null)
    {
        $ids = $this->getNoticeIds($offset, $limit, $sinceId, $maxId);

        $notices = self::getStreamByIds($ids);

        return $notices;
    }

    static function getStreamByIds($ids)
    {
    	return Notice::multiGet('id', $ids);
    }
}


code:
<?php

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

/**
 * Parent class for an exception when a POST upload does not contain a file.
 *
 * @category Exception
 * @package  GNUsocial
 * @author   Mikael Nordfeldth <mmn@hethane.se>
 * @license  http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPLv3
 * @link     http://gnu.io/
 */

class NoUploadedMediaException extends ClientException
{
    public $fieldname = null;

    public function __construct($fieldname, $msg=null)
    {
        $this->fieldname = $fieldname;

        if ($msg === null) {
            // TRANS: Exception text shown when no uploaded media was provided in POST
            // TRANS: %s is the HTML input field name.
            $msg = sprintf(_('There is no uploaded media for input field "%s".'), $this->fieldname);
        }

        parent::__construct($msg, 400);
    }
}


code:
<?php
/**
 * GNU social - a federating social network
 *
 * class for when an object that's supposed to have a URI is missing it
 *
 * 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  Exception
 * @package   GNUsocial
 * @author    Mikael Nordfeldth <mmn@hethane.se>
 * @copyright 2014 Free Software Foundation, Inc.
 * @license   http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPLv3
 * @link      https://www.gnu.org/software/social/
 */

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

class NoUriException extends ServerException
{
    var $object = null;

    public function __construct(Managed_DataObject $object)
    {
        $this->object = $object;
        $msg = get_class($object) . ' does not have a URI.';
        parent::__construct($msg);
    }
}


code:
<?php
/**
 * StatusNet, the distributed open-source microblogging tool
 *
 * Form for nudging 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/form.php';

/**
 * Form for nudging 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      DisfavorForm
 */
class NudgeForm extends Form
{
    /**
     * Profile of user to nudge
     */
    var $profile = null;

    /**
     * Constructor
     *
     * @param HTMLOutputter $out     output channel
     * @param Profile       $profile profile of user to nudge
     */
    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 'form_user_nudge';
    }

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

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

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

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


code:
<?php
/**
 * StatusNet, the distributed open-source microblogging tool
 *
 * Base class for doing OAuth calls as a consumer
 *
 * 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    Zach Copley <zach@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 'OAuth.php';

/**
 * Exception wrapper for cURL errors
 *
 * @category Integration
 * @package  StatusNet
 * @author   Zach Copley <zach@status.net>
 * @license  http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
 * @link     http://status.net/
 *
 */
class OAuthClientException extends Exception
{
}

/**
 * Base class for doing OAuth calls as a consumer
 *
 * @category Integration
 * @package  StatusNet
 * @author   Zach Copley <zach@status.net>
 * @license  http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
 * @link     http://status.net/
 *
 */
class OAuthClient
{
    var $consumer;
    var $token;

    /**
     * Constructor
     *
     * Can be initialized with just consumer key and secret for requesting new
     * tokens or with additional request token or access token
     *
     * @param string $consumer_key       consumer key
     * @param string $consumer_secret    consumer secret
     * @param string $oauth_token        user's token
     * @param string $oauth_token_secret user's secret
     *
     * @return nothing
     */
    function __construct($consumer_key, $consumer_secret,
                         $oauth_token = null, $oauth_token_secret = null)
    {
        $this->sha1_method = new OAuthSignatureMethod_HMAC_SHA1();
        $this->consumer    = new OAuthConsumer($consumer_key, $consumer_secret);
        $this->token       = null;

        if (isset($oauth_token) && isset($oauth_token_secret)) {
            $this->token = new OAuthToken($oauth_token, $oauth_token_secret);
        }
    }

    /**
     * Gets a request token from the given url
     *
     * @param string $url      OAuth endpoint for grabbing request tokens
     * @param string $callback authorized request token callback
     *
     * @return OAuthToken $token the request token
     */
    function getRequestToken($url, $callback = null)
    {
        $params = null;

        if (!is_null($callback)) {
            $params['oauth_callback'] = $callback;
        }

        $response = $this->oAuthGet($url, $params);

        $arr = array();
        parse_str($response, $arr);

        $token   = $arr['oauth_token'];
        $secret  = $arr['oauth_token_secret'];
        $confirm = $arr['oauth_callback_confirmed'];

        if (isset($token) && isset($secret)) {

            $token = new OAuthToken($token, $secret);

            if (isset($confirm)) {
                if ($confirm == 'true') {
                    return $token;
                } else {
                    throw new OAuthClientException(
                        'Callback was not confirmed by remote OAuth side.'
                    );
                }
            }
            return $token;
        } else {
            throw new OAuthClientException(
                'Could not get a request token from remote OAuth side.'
            );
        }
    }

    /**
     * Builds a link that can be redirected to in order to
     * authorize a request token.
     *
     * @param string     $url            endpoint for authorizing request tokens
     * @param OAuthToken $request_token  the request token to be authorized
     *
     * @return string $authorize_url the url to redirect to
     */
    function getAuthorizeLink($url, $request_token)
    {
        $authorize_url = $url . '?oauth_token=' .
            $request_token->key;

        return $authorize_url;
    }

    /**
     * Fetches an access token
     *
     * @param string $url      OAuth endpoint for exchanging authorized request tokens
     *                         for access tokens
     * @param string $verifier 1.0a verifier
     *
     * @return OAuthToken $token the access token
     */
    function getAccessToken($url, $verifier = null)
    {
        $params = array();

        if (!is_null($verifier)) {
            $params['oauth_verifier'] = $verifier;
        }

        $response = $this->oAuthPost($url, $params);

        $arr = array();
        parse_str($response, $arr);

        $token  = $arr['oauth_token'];
        $secret = $arr['oauth_token_secret'];

        if (isset($token) && isset($secret)) {
            $token = new OAuthToken($token, $secret);
            return $token;
        } else {
            throw new OAuthClientException(
                'Could not get a access token from remote OAuth side.'
            );
        }
    }

    /**
     * Use HTTP GET to make a signed OAuth requesta
     *
     * @param string $url    OAuth request token endpoint
     * @param array  $params additional parameters
     *
     * @return mixed the request
     */
    function oAuthGet($url, $params = null)
    {
        $request = OAuthRequest::from_consumer_and_token($this->consumer,
            $this->token, 'GET', $url, $params);
        $request->sign_request($this->sha1_method,
            $this->consumer, $this->token);

        return $this->httpRequest($request->to_url());
    }

    /**
     * Use HTTP POST to make a signed OAuth request
     *
     * @param string $url    OAuth endpoint
     * @param array  $params additional post parameters
     *
     * @return mixed the request
     */
    function oAuthPost($url, $params = null)
    {
        $request = OAuthRequest::from_consumer_and_token($this->consumer,
            $this->token, 'POST', $url, $params);
        $request->sign_request($this->sha1_method,
            $this->consumer, $this->token);

        return $this->httpRequest($request->get_normalized_http_url(),
            $request->to_postdata());
    }

    /**
     * Make a HTTP request.
     *
     * @param string $url    Where to make the
     * @param array  $params post parameters
     *
     * @return mixed the request
     */
    function httpRequest($url, $params = null)
    {
        $request = new HTTPClient($url);
        $request->setConfig(array(
            'connect_timeout' => 120,
            'timeout' => 120,
            'follow_redirects' => true,
            'ssl_verify_peer' => false,
            'ssl_verify_host' => false
        ));

        // Twitter was strict about accepting invalid "Expect" headers
        // between 2008ish and October 2012. Caused "417 Expectation failed"
        //$request->setHeader('Expect', '');

        if (isset($params)) {
            $request->setMethod(HTTP_Request2::METHOD_POST);
            $request->setBody($params);
        }

        try {
            $response = $request->send();
            $code = $response->getStatus();
            if ($code < 200 || $code >= 400) {
                throw new OAuthClientException($response->getBody(), $code);
            }
            return $response->getBody();
        } catch (Exception $e) {
            throw new OAuthClientException($e->getMessage(), $e->getCode());
        }
    }

}


code:
<?php
/**
 * StatusNet, the distributed open-source microblogging tool
 *
 * Base class for making daemons that can do several tasks in parallel.
 *
 * 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  Daemon
 * @package   StatusNet
 * @author    Zach Copley <zach@status.net>
 * @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);
}

declare(ticks = 1);

/**
 * Daemon able to spawn multiple child processes to do work in parallel
 *
 * @category Daemon
 * @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 ParallelizingDaemon extends Daemon
{
    private $_children     = array();
    private $_interval     = 0; // seconds
    private $_max_children = 0; // maximum number of children
    private $_debug        = false;

    /**
     *  Constructor
     *
     * @param string  $id           the name/id of this daemon
     * @param int     $interval     sleep this long before doing everything again
     * @param int     $max_children maximum number of child processes at a time
     * @param boolean $debug        debug output flag
     *
     * @return void
     *
     **/

    function __construct($id = null, $interval = 60, $max_children = 2,
                         $debug = null)
    {
        parent::__construct(true); // daemonize

        $this->_interval     = $interval;
        $this->_max_children = $max_children;
        $this->_debug        = $debug;

        if (isset($id)) {
            $this->set_id($id);
        }
    }

    /**
     * Run the daemon
     *
     * @return void
     */

    function run()
    {
        if (isset($this->_debug)) {
            echo $this->name() . " - Debugging output enabled.\n";
        }

        do {

            $objects = $this->getObjects();

            foreach ($objects as $o) {

                // Fork a child for each object

                $pid = pcntl_fork();

                if ($pid == -1) {
                    die ($this->name() . ' - Couldn\'t fork!');
                }

                if ($pid) {

                    // Parent

                    if (isset($this->_debug)) {
                        echo $this->name() .
                          " - Forked new child - pid $pid.\n";

                    }

                    $this->_children[] = $pid;

                } else {

                    // Child

                    // Do something with each object

                    $this->childTask($o);

                    exit();
                }

                // Remove child from ps list as it finishes

                while (($c = pcntl_wait($status, WNOHANG OR WUNTRACED)) > 0) {

                    if (isset($this->_debug)) {
                        echo $this->name() . " - Child $c finished.\n";
                    }

                    $this->removePs($this->_children, $c);
                }

                // Wait! We have too many damn kids.

                if (sizeof($this->_children) >= $this->_max_children) {

                    if (isset($this->_debug)) {
                        echo $this->name() . " - Too many children. Waiting...\n";
                    }

                    if (($c = pcntl_wait($status, WUNTRACED)) > 0) {

                        if (isset($this->_debug)) {
                            echo $this->name() .
                              " - Finished waiting for child $c.\n";
                        }

                        $this->removePs($this->_children, $c);
                    }
                }
            }

            // Remove all children from the process list before restarting
            while (($c = pcntl_wait($status, WUNTRACED)) > 0) {

                if (isset($this->_debug)) {
                    echo $this->name() . " - Child $c finished.\n";
                }

                $this->removePs($this->_children, $c);
            }

            // Rest for a bit

            if (isset($this->_debug)) {
                echo $this->name() . ' - Waiting ' . $this->_interval .
                  " secs before running again.\n";
            }

            if ($this->_interval > 0) {
                sleep($this->_interval);
            }

        } while (true);
    }

    /**
     * Remove a child process from the list of children
     *
     * @param array &$plist array of processes
     * @param int   $ps     process id
     *
     * @return void
     */

    function removePs(&$plist, $ps)
    {
        for ($i = 0; $i < sizeof($plist); $i++) {
            if ($plist[$i] == $ps) {
                unset($plist[$i]);
                $plist = array_values($plist);
                break;
            }
        }
    }

    /**
     * Get a list of objects to work on in parallel
     *
     * @return array An array of objects to work on
     */

    function getObjects()
    {
        die('Implement ParallelizingDaemon::getObjects().');
    }

    /**
     * Do something with each object in parallel
     *
     * @param mixed $object data to work on
     *
     * @return void
     */

    function childTask($object)
    {
        die("Implement ParallelizingDaemon::childTask($object).");
    }

}


code:
<?php
/**
 * StatusNet, the distributed open-source microblogging tool
 *
 * Class for an exception when password hashing was unsuccessful
 *
 * 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  Exception
 * @package   GNUsocial
 * @author    Mikael Nordfeldth <mmn@hethane.se>
 * @copyright 2013 Free Software Foundation, Inc.
 * @license   http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPLv3
 * @link      http://www.gnu.org/software/social/
 */

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

class PasswordHashException extends ServerException
{
    public $obj;    // The object with query that gave no results

    public function __construct($msg=null, $code=500)
    {
        if ($msg === null) {
            $msg = _('Password hashing failed.');
        }

        parent::__construct($msg, $code);
    }
}


code:
<?php
/**
 * StatusNet, the distributed open-source microblogging tool
 *
 * Form for editing 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    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/form.php';
require_once INSTALLDIR.'/lib/togglepeopletag.php';

/**
 * Form for editing 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      GroupEditForm
 */
class PeopletagEditForm extends Form
{
    /**
     * peopletag to edit
     */

    var $peopletag = null;
    var $tagger    = null;

    /**
     * Constructor
     *
     * @param Action     $out   output channel
     * @param User_group $group group to join
     */
    function __construct($out=null, Profile_list $peopletag=null)
    {
        parent::__construct($out);

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

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

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

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

    /**
     * Name of the form
     *
     * @return void
     */
    function formLegend()
    {
        // TRANS: Form legend for list edit form.
        // TRANS: %s is a list.
        $this->out->element('legend', null, sprintf(_('Edit list %s'), $this->peopletag->tag));
    }

    /**
     * Data elements of the form
     *
     * @return void
     */
    function formData()
    {
        $id = $this->peopletag->id;
        $tag = $this->peopletag->tag;
        $description = $this->peopletag->description;
        $private = $this->peopletag->private;

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

        $this->out->elementStart('li');
        $this->out->hidden('id', $id);

        // TRANS: Field label for list.
        $this->out->input('tag', _m('LABEL','List'),
                          ($this->out->arg('tag')) ? $this->out->arg('tag') : $tag,
                          // TRANS: Field title for list.
                          _('Change the list (letters, numbers, -, ., and _ are allowed).'));
        $this->out->elementEnd('li');

        $this->out->elementStart('li');
        $desclimit = Profile_list::maxDescription();
        if ($desclimit == 0) {
            // TRANS: Field title for description of list.
            $descinstr = _('Describe the list or topic.');
        } else {
            // TRANS: Field title for description of list.
            // TRANS: %d is the maximum number of characters for the description.
            $descinstr = sprintf(_m('Describe the list or topic in %d character.',
                                    'Describe the list or topic in %d characters.',
                                    $desclimit),
                                 $desclimit);
        }
        // TRANS: Field label for description of list.
        $this->out->textarea('description', _('Description'),
                             ($this->out->arg('description')) ? $this->out->arg('description') : $description,
                             $descinstr);
        // TRANS: Checkbox label to mark a list private.
        $this->out->checkbox('private', _('Private'), $private);
        $this->out->elementEnd('li');
        $this->out->elementEnd('ul');
    }

    /**
     * Action elements
     *
     * @return void
     */
    function formActions()
    {
        // TRANS: Button text to save a list.
        $this->out->submit('submit', _('Save'));
        $this->out->submit('form_action-yes',
                      // TRANS: Button text to delete a list.
                      _m('BUTTON','Delete'),
                      'submit',
                      'delete',
                      // TRANS: Button title to delete a list.
                      _('Delete this list.'));
    }

    function showProfileList()
    {
        $tagged = $this->peopletag->getTagged();
        // TRANS: Header in list edit form.
        $this->out->element('h2', null, _('Add or remove people'));

        $this->out->elementStart('div', 'profile_search_wrap');
        // TRANS: Header in list edit form.
        $this->out->element('h3', null, _m('HEADER','Search'));
        $search = new SearchProfileForm($this->out, $this->peopletag);
        $search->show();
        $this->out->element('ul', array('id' => 'profile_search_results', 'class' => 'empty'));
        $this->out->elementEnd('div');

        $this->out->elementStart('ul', 'profile-lister');
        while ($tagged->fetch()) {
            $this->out->elementStart('li', 'entity_removable_profile');
            $this->showProfileItem($tagged);
            $this->out->elementStart('span', 'entity_actions');
            $untag = new UntagButton($this->out, $tagged, $this->peopletag);
            $untag->show();
            $this->out->elementEnd('span');
            $this->out->elementEnd('li');
        }
        $this->out->elementEnd('ul');
    }

    function showProfileItem($profile)
    {
        $item = new TaggedProfileItem($this->out, $profile);
        $item->show();
    }
}


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

/**
 * Base class for all actions
 *
 * This is the base class for all actions in the package. An action is
 * more or less a "view" in an MVC framework.
 *
 * Actions are responsible for extracting and validating parameters; using
 * model classes to read and write to the database; and doing ouput.
 *
 * @category Output
 * @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      HTMLOutputter
 */
class PeopletagGroupNav extends Widget
{
    var $action = null;

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

    /**
     * Show the menu
     *
     * @return void
     */
    function show()
    {
        $user = null;

	// FIXME: we should probably pass this in

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

        if (common_config('singleuser', 'enabled')) {
            $nickname = User::singleUserNickname();
        } else {
            $nickname = $this->action->arg('tagger');
        }

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

        if ($nickname) {
            $user = User::getKV('nickname', $nickname);
            $user_profile = $user->getProfile();

            if ($tag) {
                $tag = Profile_list::pkeyGet(array('tagger' => $user->id,
                                                   'tag'    => $tag));
            } else {
                $tag = false;
            }

        } else {
            $user_profile = false;
        }

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

        if (Event::handle('StartPeopletagGroupNav', array($this))) {
            // People tag timeline
            $this->out->menuItem(common_local_url('showprofiletag', array('tagger' => $user_profile->nickname,
                                                                          'tag'    => $tag->tag)),
                             // TRANS: Menu item in list navigation panel.
                             _m('MENU','List'),
                             // TRANS: Menu item title in list navigation panel.
                             // TRANS: %1$s is a list, %2$s is a nickname.
                             sprintf(_('%1$s list by %2$s.'), $tag->tag,
                                (($user_profile && $user_profile->fullname) ? $user_profile->fullname : $nickname)),
                             $action == 'showprofiletag', 'nav_timeline_peopletag');

            // Tagged
            $this->out->menuItem(common_local_url('peopletagged', array('tagger' => $user->nickname,
                                                                        'tag'    => $tag->tag)),
                             // TRANS: Menu item in list navigation panel.
                             _m('MENU','Listed'),
                             // TRANS: Menu item title in list navigation panel.
                             // TRANS: %1$s is a list, %2$s is a nickname.
                             sprintf(_('%1$s list by %2$s.'), $tag->tag,
                                (($user_profile && $user_profile->fullname) ? $user_profile->fullname : $nickname)),
                             $action == 'peopletagged', 'nav_peopletag_tagged');

            // Subscribers
            $this->out->menuItem(common_local_url('peopletagsubscribers', array('tagger' => $user->nickname,
                                                                                'tag'    => $tag->tag)),
                             // TRANS: Menu item in list navigation panel.
                             _m('MENU','Subscribers'),
                             // TRANS: Menu item title in list navigation panel.
                             // TRANS: %1$s is a list, %2$s is a nickname.
                             sprintf(_('Subscribers to %1$s list by %2$s.'), $tag->tag,
                                (($user_profile && $user_profile->fullname) ? $user_profile->fullname : $nickname)),
                             $action == 'peopletagsubscribers', 'nav_peopletag_subscribers');

            $cur = common_current_user();
            if (!empty($cur) && $user_profile->id == $cur->id) {
                // Edit
                $this->out->menuItem(common_local_url('editpeopletag', array('tagger' => $user->nickname,
                                                                             'tag'    => $tag->tag)),
                                 // TRANS: Menu item in list navigation panel.
                                 _m('MENU','Edit'),
                                 // TRANS: Menu item title in list navigation panel.
                                 // TRANS: %s is a list.
                                 sprintf(_('Edit %s list by you.'), $tag->tag,
                                    (($user_profile && $user_profile->fullname) ? $user_profile->fullname : $nickname)),
                                 $action == 'editpeopletag', 'nav_peopletag_edit');
            }

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


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

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

define('PEOPLETAGS_PER_PAGE', 20);

/**
 * Widget to show a list of peopletags
 *
 * @category Public
 * @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/
 */
class PeopletagList extends Widget
{
    /** Current peopletag, peopletag query. */
    var $peopletag = null;
    /** current user **/
    var $user = null;

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

        $this->peopletag = $peopletag;

        if (!empty($owner)) {
            $this->user = $owner;
        } else {
            $this->user = common_current_user();
        }
    }

    function show()
    {
        $this->out->elementStart('ul', 'peopletags xoxo hfeed');

        $cnt = 0;

        while ($this->peopletag->fetch()) {
            $cnt++;
            if($cnt > PEOPLETAGS_PER_PAGE) {
                break;
            }
            $this->showPeopletag();
        }

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

        return $cnt;
    }

    function showPeopletag()
    {
        $ptag = new PeopletagListItem($this->peopletag, $this->user, $this->out);
        $ptag->show();
    }
}

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/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('EndGroupGroupNav', array($this));
        }
        $this->out->elementEnd('ul');
    }
}


code:
<?php
/**
 * StatusNet - the distributed open-source microblogging tool
 * Copyright (C) 2011, StatusNet, Inc.
 *
 * Stream of notices for a list
 *
 * 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  Stream
 * @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);
}

/**
 * Stream of notices for a list
 *
 * @category  Stream
 * @package   StatusNet
 * @author    Evan Prodromou <evan@status.net>
 * @author    Shashi Gowda <connect2shashi@gmail.com>
 * @copyright 2011 StatusNet, Inc.
 * @license   http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0
 * @link      http://status.net/
 */
class PeopletagNoticeStream extends ScopingNoticeStream
{
    function __construct($plist, $profile = -1)
    {
        if (is_int($profile) && $profile == -1) {
            $profile = Profile::current();
        }
        parent::__construct(new CachingNoticeStream(new RawPeopletagNoticeStream($plist),
                                                    'profile_list:notice_ids:' . $plist->id),
                            $profile);
    }
}

/**
 * Stream of notices for a list
 *
 * @category  Stream
 * @package   StatusNet
 * @author    Evan Prodromou <evan@status.net>
 * @author    Shashi Gowda <connect2shashi@gmail.com>
 * @copyright 2011 StatusNet, Inc.
 * @license   http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0
 * @link      http://status.net/
 */
class RawPeopletagNoticeStream extends NoticeStream
{
    protected $profile_list;

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

    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"', $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
/**
 * StatusNet, the distributed open-source microblogging tool
 *
 * Peopletags with the most subscribers section
 *
 * 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);
}

/**
 * Peopletags with the most subscribers section
 *
 * @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/
 */
class PeopletagsBySubsSection extends PeopletagSection
{
    function getPeopletags()
    {
        $qry = 'SELECT profile_list.*, subscriber_count as value ' .
               'FROM profile_list WHERE profile_list.private = false ' .
               'ORDER BY value DESC ';

        $limit = PEOPLETAGS_PER_SECTION;
        $offset = 0;

        if (common_config('db','type') == 'pgsql') {
            $qry .= ' LIMIT ' . $limit . ' OFFSET ' . $offset;
        } else {
            $qry .= ' LIMIT ' . $offset . ', ' . $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/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;

        $auth_user = common_current_user();
        $ptags = $this->profile->getOtherTags($auth_user, $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';
    }
}