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

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

/**
 * Base class for queue handlers.
 *
 * As extensions of the Daemon class, each queue handler has the ability
 * to launch itself in the background, at which point it'll pass control
 * to the configured QueueManager class to poll for updates.
 *
 * Subclasses must override at least the following methods:
 * - transport
 * - handle_notice
 */

class DistribQueueHandler
{
    /**
     * Return transport keyword which identifies items this queue handler
     * services; must be defined for all subclasses.
     *
     * Must be 8 characters or less to fit in the queue_item database.
     * ex "email", "jabber", "sms", "irc", ...
     *
     * @return string
     */

    public function transport()
    {
        return 'distrib';
    }

    /**
     * Handle distribution of a notice after we've saved it:
     * @li add to local recipient inboxes
     * @li send email notifications to local @-reply targets
     * @li run final EndNoticeSave plugin events
     * @li put any remaining post-processing into the queues
     *
     * If this function indicates failure, a warning will be logged
     * and the item is placed back in the queue to be re-run.
     *
     * @param Notice $notice
     * @return boolean true on success, false on failure
     */
    public function handle(Notice $notice)
    {
        // We have to manually add attentions to non-profile subs and non-mentions
        $ptAtts = $notice->getAttentionsFromProfileTags();
        foreach (array_keys($ptAtts) as $profile_id) {
            $profile = Profile::getKV('id', $profile_id);
            if ($profile instanceof Profile) {
                try {
                    common_debug('Adding Attention for '.$notice->getID().' profile '.$profile->getID());
                    Attention::saveNew($notice, $profile);
                } catch (Exception $e) {
                    $this->logit($notice, $e);
                }
            }
        }

        try {
            $notice->sendReplyNotifications();
        } catch (Exception $e) {
            $this->logit($notice, $e);
        }

        try {
            Event::handle('EndNoticeDistribute', array($notice));
        } catch (Exception $e) {
            $this->logit($notice, $e);
        }

        try {
            Event::handle('EndNoticeSave', array($notice));
        } catch (Exception $e) {
            $this->logit($notice, $e);
        }

        try {
            // Enqueue for other handlers
            common_enqueue_notice($notice);
        } catch (Exception $e) {
            $this->logit($notice, $e);
        }

        return true;
    }

    protected function logit($notice, $e)
    {
        common_log(LOG_ERR, "Distrib queue exception saving notice $notice->id: " .
            $e->getMessage() . ' ' .
            str_replace("\n", " ", $e->getTraceAsString()));

        // We'll still return true so we don't get stuck in a loop
        // trying to run a bad insert over and over...
    }
}


code:
<?php
/**
 * StatusNet - the distributed open-source microblogging tool
 * Copyright (C) 2011, StatusNet, Inc.
 *
 * Utility for finding and parsing documentation files
 *
 * 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  Documentation
 * @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);
}

/**
 * Utility for finding and parsing documentation files
 *
 * @category  Documentation
 * @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 DocFile
{
    protected $filename;
    protected $contents;

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

    static function forTitle($title, $paths)
    {
        if (!is_array($paths)) {
            $paths = array($paths);
        }

        $filename = null;

        if (Event::handle('StartDocFileForTitle', array($title, &$paths, &$filename))) {

            foreach ($paths as $path) {

                $def = $path.'/'.$title;

                if (!file_exists($def)) {
                    $def = null;
                }

                $lang = glob($path.'/'.$title.'.*');

                if ($lang === false) {
                    $lang = array();
                }

                if (!empty($lang) || !empty($def)) {
                    $filename = self::negotiateLanguage($lang, $def);
                    break;
                }
            }

            Event::handle('EndDocFileForTitle', array($title, $paths, &$filename));
        }

        if (empty($filename)) {
            return null;
        } else {
            return new DocFile($filename);
        }
    }

    function toHTML($args=null)
    {
        if (is_null($args)) {
            $args = array();
        }

        if (empty($this->contents)) {
            $this->contents = file_get_contents($this->filename);
        }

        return common_markup_to_html($this->contents, $args);
    }

    static function defaultPaths()
    {
        $paths = array(INSTALLDIR.'/local/doc-src/',
                       INSTALLDIR.'/doc-src/');

        $site = GNUsocial::currentSite();

        if (!empty($site)) {
            array_unshift($paths, INSTALLDIR.'/local/doc-src/'.$site.'/');
        }

        return $paths;
    }

    static function mailPaths()
    {
        $paths = array(INSTALLDIR.'/local/mail-src/',
                       INSTALLDIR.'/mail-src/');

        $site = GNUsocial::currentSite();

        if (!empty($site)) {
            array_unshift($paths, INSTALLDIR.'/local/mail-src/'.$site.'/');
        }

        return $paths;
    }

    static function negotiateLanguage($filenames, $defaultFilename=null)
    {
        // XXX: do this better

        $langcode = common_language();

        foreach ($filenames as $filename) {
            if (preg_match('/\.'.$langcode.'$/', $filename)) {
                return $filename;
            }
        }

        return $defaultFilename;
    }
}

repo_name: piratas/tortuga

license: mit


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>
 * @copyright 2010 StatusNet, Inc.
 * @license   http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPLv3
 * @link      http://status.net/
 */

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

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

/**
 * StatusNet, the distributed open-source microblogging tool
 *
 * Widget superclass for notice list items that remove rel=nofollow
 *
 * When nofollow|external = 'sometimes', notices get rendered and saved
 * with rel=nofollow for external links. We want to remove that relationship
 * on some pages (profile, single notice, faves). This superclass for
 * some noticelistitems will strip that bit of code out when showing
 * notice content
 *
 * @category  UI
 * @package   StatusNet
 * @author    Evan Prodromou <evan@status.net>
 * @copyright 2010 StatusNet, Inc.
 * @license   http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPLv3
 * @link      http://status.net/
 */

class DoFollowListItem extends NoticeListItem
{
    /**
     * show the content of the notice
     *
     * Trims out the rel=nofollow for external links
     * if nofollow|external = 'sometimes'
     *
     * @return void
     */

    function showContent()
    {
        // FIXME: URL, image, video, audio
        $this->out->elementStart('article', array('class' => 'e-content'));

        if (!empty($this->notice->rendered)) {
            $html = $this->notice->rendered;
        } else {
            $html = common_render_content($this->notice->content, $this->notice);
        }

        if (common_config('nofollow', 'external') == 'sometimes') {
            // remove the nofollow part
            // XXX: cache the results here

            $html = preg_replace('/rel="(.*)nofollow ?/', 'rel="\1', $html);
        }

        $this->out->raw($html);

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


code:
<?php

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

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

/**
 * Base class for displaying HTTP errors
 *
 * @category Action
 * @package  StatusNet
 * @author   Zach Copley <zach@status.net>
 * @license  http://www.fsf.org/licensing/licenses/agpl.html AGPLv3
 * @link     http://status.net/
 */
class ErrorAction extends InfoAction
{
    static $status = array();

    var $code    = null;
    var $message = null;
    var $default = null;

    function __construct($message, $code, $output='php://output', $indent=null)
    {
        parent::__construct(null, $message, $output, $indent);

        $this->code = $code;
        $this->message = $message;
        $this->minimal = GNUsocial::isApi();

        // XXX: hack alert: usually we aren't going to
        // call this page directly, but because it's
        // an action it needs an args array anyway
        $this->prepare($_REQUEST);
    }

    function showPage()
    {
        if (GNUsocial::isAjax()) {
            $this->extraHeaders();
            $this->ajaxErrorMsg();
            exit();
        } if ($this->minimal) {
            // Even more minimal -- we're in a machine API
            // and don't want to flood the output.
            $this->extraHeaders();
            $this->showContent();
        } else {
            parent::showPage();
        }

        // We don't want to have any more output after this
        exit();
    }

    /**
     * Display content.
     *
     * @return nothing
     */
    function showContent()
    {
        $this->element('div', array('class' => 'error'), $this->message);
    }

    function showNoticeForm()
    {
    }

    /**
     * Show an Ajax-y error message
     *
     * Goes back to the browser, where it's shown in a popup.
     *
     * @param string $msg Message to show
     *
     * @return void
     */

    function ajaxErrorMsg()
    {
        $this->startHTML('text/xml;charset=utf-8', true);
        $this->elementStart('head');
        // TRANS: Page title after an AJAX error occurs on the send notice page.
        $this->element('title', null, _('Ajax Error'));
        $this->elementEnd('head');
        $this->elementStart('body');
        $this->element('p', array('id' => 'error'), $this->message);
        $this->elementEnd('body');
        $this->endHTML();
    }
}


code:
<?php
/**
 * StatusNet, the distributed open-source microblogging tool
 *
 * utilities for defining and running event handlers
 *
 * 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  Event
 * @package   StatusNet
 * @author    Evan Prodromou <evan@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);
}

/**
 * Class for events
 *
 * This "class" two static functions for managing events in the StatusNet code.
 *
 * @category Event
 * @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/
 *
 * @todo     Define a system for using Event instances
 */

class Event {

    /* Global array of hooks, mapping eventname => array of callables */

    protected static $_handlers = array();

    /**
     * Add an event handler
     *
     * To run some code at a particular point in StatusNet processing.
     * Named events include receiving an XMPP message, adding a new notice,
     * or showing part of an HTML page.
     *
     * The arguments to the handler vary by the event. Handlers can return
     * two possible values: false means that the event has been replaced by
     * the handler completely, and no default processing should be done.
     * Non-false means successful handling, and that the default processing
     * should succeed. (Note that this only makes sense for some events.)
     *
     * Handlers can also abort processing by throwing an exception; these will
     * be caught by the closest code and displayed as errors.
     *
     * @param string   $name    Name of the event
     * @param callable $handler Code to run
     *
     * @return void
     */

    public static function addHandler($name, $handler) {
        if (array_key_exists($name, Event::$_handlers)) {
            Event::$_handlers[$name][] = $handler;
        } else {
            Event::$_handlers[$name] = array($handler);
        }
    }

    /**
     * Handle an event
     *
     * Events are any point in the code that we want to expose for admins
     * or third-party developers to use.
     *
     * We pass in an array of arguments (including references, for stuff
     * that can be changed), and each assigned handler gets run with those
     * arguments. Exceptions can be thrown to indicate an error.
     *
     * @param string $name Name of the event that's happening
     * @param array  $args Arguments for handlers
     *
     * @return boolean flag saying whether to continue processing, based
     *                 on results of handlers.
     */

    public static function handle($name, array $args=array()) {
        $result = null;
        if (array_key_exists($name, Event::$_handlers)) {
            foreach (Event::$_handlers[$name] as $handler) {
                $result = call_user_func_array($handler, $args);
                if ($result === false) {
                    break;
                }
            }
        }
        return ($result !== false);
    }

    /**
     * Check to see if an event handler exists
     *
     * Look to see if there's any handler for a given event, or narrow
     * by providing the name of a specific plugin class.
     *
     * @param string $name Name of the event to look for
     * @param string $plugin Optional name of the plugin class to look for
     *
     * @return boolean flag saying whether such a handler exists
     *
     */

    public static function hasHandler($name, $plugin=null) {
        if (array_key_exists($name, Event::$_handlers)) {
            if (isset($plugin)) {
                foreach (Event::$_handlers[$name] as $handler) {
                    if (get_class($handler[0]) == $plugin) {
                        return true;
                    }
                }
            } else {
                return true;
            }
        }
        return false;
    }

    public static function getHandlers($name)
    {
        return Event::$_handlers[$name];
    }

    /**
     * Disables any and all handlers that have been set up so far;
     * use only if you know it's safe to reinitialize all plugins.
     */
    public static function clearHandlers() {
        Event::$_handlers = array();
    }
}


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

/**
 * Section for featured users
 *
 * @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 FeaturedUsersSection extends ProfileSection
{
    function show()
    {
        $featured_nicks = common_config('nickname', 'featured');
        if (empty($featured_nicks)) {
            return;
        }
        parent::show();
    }

    function getProfiles()
    {
        $featured_nicks = common_config('nickname', 'featured');

        if (!$featured_nicks) {
            return null;
        }

        $quoted = array();

        foreach ($featured_nicks as $nick) {
            $quoted[] = "'$nick'";
        }

        $table = "user";
        if(common_config('db','quote_identifiers')) {
          $table = '"' . $table . '"';
        }

        $qry = 'SELECT profile.* ' .
            'FROM profile JOIN '. $table .' on profile.id = '. $table .'.id ' .
          'WHERE '. $table .'.nickname in (' . implode(',', $quoted) . ') ' .
          'ORDER BY profile.created DESC ';

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

        if (common_config('db','type') == 'pgsql') {
            $qry .= ' LIMIT ' . $limit . ' OFFSET ' . $offset;
        } else {
            $qry .= ' LIMIT ' . $offset . ', ' . $limit;
        }

        $profile = Memcached_DataObject::cachedQuery('Profile',
                                                     $qry,
                                                     6 * 3600);
        return $profile;
    }

    function title()
    {
        // TRANS: Title for featured users section.
        return _('Featured users');
    }

    function divId()
    {
        return 'featured_users';
    }

    function moreUrl()
    {
        return common_local_url('featured');
    }
}


code:
<?php
/**
 * StatusNet, the distributed open-source microblogging tool
 *
 * Data structure for info about syndication feeds (RSS 1.0, RSS 2.0, Atom)
 *
 * 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  Feed
 * @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);
}

/**
 * Data structure for feeds
 *
 * This structure is a helpful container for shipping around information about syndication feeds.
 *
 * @category Feed
 * @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/
 */
class Feed
{
    const RSS1 = 1;
    const RSS2 = 2;
    const ATOM = 3;
    const FOAF = 4;
    const JSON = 5; // Activity Streams

    var $type = null;
    var $url = null;
    var $title = null;

    function __construct($type, $url, $title)
    {
        $this->type  = $type;
        $this->url   = $url;
        $this->title = $title;
    }

    function mimeType()
    {
        switch ($this->type) {
         case Feed::RSS1:
            return 'application/rdf+xml';
         case Feed::RSS2:
            return 'application/rss+xml';
         case Feed::ATOM:
            return 'application/atom+xml';
         case Feed::FOAF:
            return 'application/rdf+xml';
         case Feed::JSON:
            return 'application/stream+json';
         default:
            return null;
        }
    }

    function typeName()
    {
        switch ($this->type) {
         case Feed::RSS1:
            // TRANS: Feed type name.
            return _('RSS 1.0');
         case Feed::RSS2:
            // TRANS: Feed type name.
            return _('RSS 2.0');
         case Feed::ATOM:
            // TRANS: Feed type name.
            return _('Atom');
         case Feed::FOAF:
            // TRANS: Feed type name. FOAF stands for Friend of a Friend.
            return _('FOAF');
         case Feed::JSON:
            // TRANS: Feed type name. See http://activitystrea.ms/
            return _('Activity Streams');
         default:
            return null;
        }
    }

    function rel()
    {
        switch ($this->type) {
         case Feed::RSS1:
         case Feed::RSS2:
         case Feed::ATOM:
         case Feed::JSON:
            return 'alternate';
         case Feed::FOAF:
            return 'meta';
         default:
            return null;
        }
    }
}


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

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

/**
 * Importer for feeds of activities
 *
 * Takes an XML file representing a feed of activities and imports each
 * activity to the user in question.
 *
 * @category  Account
 * @package   StatusNet
 * @author    Evan Prodromou <evan@status.net>
 * @copyright 2010 StatusNet, Inc.
 * @license   http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0
 * @link      http://status.net/
 */
class FeedImporter extends QueueHandler
{
    /**
     * Transport identifier
     *
     * @return string identifier for this queue handler
     */
    public function transport()
    {
        return 'feedimp';
    }

    function handle($data)
    {
        list($user, $xml, $trusted) = $data;

        try {
            $doc = DOMDocument::loadXML($xml);

            $feed = $doc->documentElement;

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

            $author = ActivityUtils::getFeedAuthor($feed);

            if (empty($author)) {
                // TRANS: Client exception thrown when an imported feed does not have an author.
                throw new ClientException(_("No author in the feed."));
            }

            if (empty($user)) {
                if ($trusted) {
                    $user = $this->userFromAuthor($author);
                } else {
                    // TRANS: Client exception thrown when an imported feed does not have an author that
                    // TRANS: can be associated with a user.
                    throw new ClientException(_("Cannot import without a user."));
                }
            }

            $activities = $this->getActivities($feed);

            $qm = QueueManager::get();

            foreach ($activities as $activity) {
                $qm->enqueue(array($user, $author, $activity, $trusted), 'actimp');
            }
        } catch (ClientException $ce) {
            common_log(LOG_WARNING, $ce->getMessage());
            return true;
        } catch (ServerException $se) {
            common_log(LOG_ERR, $ce->getMessage());
            return false;
        } catch (Exception $e) {
            common_log(LOG_ERR, $ce->getMessage());
            return false;
        }
    }

    function getActivities($feed)
    {
        $entries = $feed->getElementsByTagNameNS(Activity::ATOM, 'entry');

        $activities = array();

        for ($i = 0; $i < $entries->length; $i++) {
            $activities[] = new Activity($entries->item($i));
        }

        usort($activities, array("FeedImporter", "activitySort"));

        return $activities;
    }

    /**
     * Sort activities oldest-first
     */
    static function activitySort($a, $b)
    {
        if ($a->time == $b->time) {
            return 0;
        } else if ($a->time < $b->time) {
            return -1;
        } else {
            return 1;
        }
    }

    function userFromAuthor($author)
    {
        $user = User::getKV('uri', $author->id);

        if (empty($user)) {
            $attrs =
                array('nickname' => Ostatus_profile::getActivityObjectNickname($author),
                      'uri' => $author->id);

            $user = User::register($attrs);
        }

        $profile = $user->getProfile();
        Ostatus_profile::updateProfile($profile, $author);

        // @todo FIXME: Update avatar
        return $user;
    }
}


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

/**
 * Widget for showing a list of feeds
 *
 * Typically used for Action::showExportList()
 *
 * @category Widget
 * @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      Action::showExportList()
 */
class FeedList extends Widget
{
    var $action = null;

    function __construct($action=null)
    {
	parent::__construct($action);
	$this->action = $action;
    }

    function show($feeds)
    {
        if (Event::handle('StartShowFeedLinkList', array($this->action, &$feeds))) {
            if (!empty($feeds)) {
                $this->out->elementStart('div', array('id' => 'export_data',
                                                      'class' => 'section'));
                // TRANS: Header for feed links (h2).
                $this->out->element('h2', null, _('Feeds'));
                $this->out->elementStart('ul', array('class' => 'xoxo'));

                foreach ($feeds as $feed) {
                    $this->feedItem($feed);
                }

                $this->out->elementEnd('ul');
                $this->out->elementEnd('div');
            }
            Event::handle('EndShowFeedLinkList', array($this->action, &$feeds));
        }
    }

    function feedItem($feed)
    {
        if (Event::handle('StartShowFeedLink', array($this->action, &$feed))) {
            $classname = null;

            switch ($feed->type) {
            case Feed::RSS1:
            case Feed::RSS2:
                $classname = 'rss';
                break;
            case Feed::ATOM:
                $classname = 'atom';
                break;
            case Feed::FOAF:
                $classname = 'foaf';
                break;
            case Feed::JSON:
                $classname = 'json';
                break;
            }

            $this->out->elementStart('li');
            $this->out->element('a', array('href' => $feed->url,
                                           'class' => $classname,
                                           'type' => $feed->mimeType(),
                                           'title' => $feed->title),
                                $feed->typeName());
            $this->out->elementEnd('li');
            Event::handle('EndShowFeedLink', array($this->action, $feed));
        }
    }
}


code:
<?php
/**
 * StatusNet, the distributed open-source microblogging tool
 *
 * Class for an exception when a database lookup returns no results
 *
 * 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 FileNotFoundException extends ServerException
{
    public $path = null;

    public function __construct($path)
    {
        $this->path = $path;
        parent::__construct(_('File not found in filesystem.'), 404);
    }
}


code:
<?php
/**
 * StatusNet - the distributed open-source microblogging tool
 * Copyright (C) 2011, StatusNet, Inc.
 *
 * Stream of notices that reference an URL
 *
 * 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 FileNoticeStream extends ScopingNoticeStream
{
    function __construct($file, $profile = -1)
    {
        if (is_int($profile) && $profile == -1) {
            $profile = Profile::current();
        }
        parent::__construct(new CachingNoticeStream(new RawFileNoticeStream($file),
                                                    'file:notice-ids:'.$file->id),
                            $profile);
    }
}

/**
 * Raw stream for a file
 *
 * @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/
 */

class RawFileNoticeStream extends NoticeStream
{
    protected $file = null;

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

    /**
     * Stream of notices linking to this URL
     *
     * @param integer $offset   Offset to show; default is 0
     * @param integer $limit    Limit of notices to show
     * @param integer $since_id Since this notice
     * @param integer $max_id   Before this notice
     *
     * @return array ids of notices that link to this file
     */
    function getNoticeIds($offset, $limit, $since_id, $max_id)
    {
        $f2p = new File_to_post();

        $f2p->selectAdd();
        $f2p->selectAdd('post_id');

        $f2p->file_id = $this->file->id;

        Notice::addWhereSinceId($f2p, $since_id, 'post_id', 'modified');
        Notice::addWhereMaxId($f2p, $max_id, 'post_id', 'modified');

        $f2p->orderBy('modified DESC, post_id DESC');

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

        $ids = array();

        if ($f2p->find()) {
            while ($f2p->fetch()) {
                $ids[] = $f2p->post_id;
            }
        }

        return $ids;
    }
}


code:
<?php
/**
 * StatusNet - the distributed open-source microblogging tool
 * Copyright (C) 2011, StatusNet, Inc.
 *
 * A notice stream that filters its upstream content
 *
 * 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);
}

/**
 * A class for presenting a filtered notice stream based on an upstream stream
 *
 * @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 FilteringNoticeStream extends NoticeStream
{
    protected $upstream;

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

    abstract function filter($notice);

    function getNoticeIds($offset, $limit, $since_id, $max_id)
    {
        // "offset" is virtual; we have to get a lot
        $total = $offset + $limit;

        $filtered = array();

        $startAt = 0;
        $askFor  = $total;

        // Keep going till we have $total notices in $notices array,
        // or we get nothing from upstream.

        $results = null;
        $round = 0;

        do {
            $raw = $this->upstream->getNotices($startAt, $askFor, $since_id, $max_id);

            $results = $raw->N;
            if ($results == 0) {
                break;
            }

            $notices = $raw->fetchAll();
            $this->prefill($notices);
            foreach ($notices as $notice) {
                if ($this->filter($notice)) {
                    $filtered[] = $notice->id;
                    if (count($filtered) >= $total) {
                        break;
                    }
                }
            }

            // XXX: make these smarter; factor hit rate into $askFor
            $startAt += $askFor;
            $hits = count($filtered);
            $lastAsk = $askFor;

            if ($hits === 0) {
                $askFor = max(min(2 * $askFor, NOTICES_PER_PAGE * 50), NOTICES_PER_PAGE);
            } else {
                $askFor = max(min(intval(ceil(($total - $hits)*$startAt/$hits)), NOTICES_PER_PAGE * 50), NOTICES_PER_PAGE);
            }

            $round++;
        } while (count($filtered) < $total && $results >= $lastAsk);

        return array_slice(array_values($filtered), $offset, $limit);
    }

    function prefill($notices)
    {
        return;
    }
}


code:
<?php
/**
 * StatusNet, the distributed open-source microblogging tool
 *
 * Base class for forms
 *
 * 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>
 * @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/widget.php';

/**
 * Base class for forms
 *
 * We have a lot of common forms (subscribe, fave, delete) and this superclass
 * lets us abstract out the basic features of the form.
 *
 * @category Widget
 * @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 Form extends Widget
{
    var $enctype = null;

    /**
     * Show the form
     *
     * Uses a recipe to output the form.
     *
     * @return void
     * @see Widget::show()
     */

    function show()
    {
        $attributes = array('id' => $this->id(),
            'class' => $this->formClass(),
            'method' => $this->method(),
            'action' => $this->action());

        if (!empty($this->enctype)) {
            $attributes['enctype'] = $this->enctype;
        }
        $this->out->elementStart('form', $attributes);
        $this->out->elementStart('fieldset');
        $this->formLegend();
        $this->sessionToken();
        $this->formData();
        $this->formActions();
        $this->out->elementEnd('fieldset');
        $this->out->elementEnd('form');
    }

    /**
     * Include a session token for CSRF protection
     *
     * @return void
     */

    function sessionToken()
    {
        if (strtolower($this->method()) == 'post') {
            $this->out->hidden('token-' . $this->id() ?: common_random_hexstr(3), common_session_token(), 'token');
        }
    }

    /**
     * Name of the form
     *
     * Sub-classes should overload this with the name of their form.
     *
     * @return void
     */

    function formLegend()
    {
    }

    /**
     * Visible or invisible data elements
     *
     * Display the form fields that make up the data of the form.
     * Sub-classes should overload this to show their data.
     *
     * @return void
     */

    function formData()
    {
    }

    /**
     * HTTP method used to submit the form
     *
     * Defaults to post. Subclasses can override if they need to.
     *
     * @return string the method to use for submitting
     */
     function method()
     {
         return 'post';
     }

    /**
     * Buttons for form actions
     *
     * Submit and cancel buttons (or whatever)
     * Sub-classes should overload this to show their own buttons.
     *
     * @return void
     */

    function formActions()
    {
    }

    /**
     * ID of the form
     *
     * Should be unique on the page. Sub-classes should overload this
     * to show their own IDs.
     *
     * @return int ID of the form
     */

    function id()
    {
        return null;
    }

    /**
     * Action of the form.
     *
     * URL to post to. Should be overloaded by subclasses to give
     * somewhere to post to.
     *
     * @return string URL to post to
     */

    function action()
    {
    }

    /**
     * Class of the form. May include space-separated list of multiple classes.
     *
     * If 'ajax' is included, the form will automatically be submitted with
     * an 'ajax=1' parameter added, and the resulting form or error message
     * will replace the form after submission.
     *
     * It's up to you to make sure that the target action supports this!
     *
     * @return string the form's class
     */

    function formClass()
    {
        return 'form';
    }

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

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


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

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

/**
 * Form action extendable class
 *
 * @category Action
 * @package  StatusNet
 * @author   Evan Prodromou <evan@status.net>
 * @author   Mikael Nordfeldth <evan@status.net>
 * @license  http://www.fsf.org/licensing/licenses/agpl.html AGPLv3
 * @link     http://status.net/
 */
class FormAction extends ManagedAction
{
    protected $form = null;
    protected $formOpts = array();
    protected $type = null;
    protected $needLogin = true;
    protected $canPost = true;

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

        $this->form = $this->form ?: $this->action;
        $this->args['form'] = $this->form;

        $this->type = !is_null($this->type) ? $this->type : $this->trimmed('type');
        $this->args['context'] = $this->trimmed('action');  // reply for notice for example

        if (!$this->type) {
            $this->type = null;
        }

        return true;
    }

    public function isReadOnly($args) {
        return !$this->isPost();
    }

    public function showPageNotice()
    {
        $this->showInstructions();
        if ($msg = $this->getError()) {
            $this->element('div', 'error', $msg);
        }
        if ($msg = $this->getInfo()) {
            $this->element('div', 'info', $msg);
        }
    }

    /**
     * Outputs the instructions for the form
     *
     * SHOULD overload
     */
    public function showInstructions()
    {
        // instructions are nice, so users know what to do
        $this->raw(common_markup_to_html($this->getInstructions()));
    }

    /**
     * @return string with instructions to pass into common_markup_to_html()
     */
    protected function getInstructions()
    {
        return null;
    }

    public function showForm($msg=null, $success=false)
    {
        $this->msg = $msg;
        $this->success = $success;
        $this->showPage();
    }

    protected function showContent()
    {
        $form = $this->getForm();
        $form->show();
    }

    protected function getForm()
    {
        $class = $this->form.'Form';
        $form = new $class($this, $this->formOpts);
        return $form;
    }
}


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

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

define('GNUSOCIAL_ENGINE', 'GNU social');
define('GNUSOCIAL_ENGINE_URL', 'https://www.gnu.org/software/social/');

define('GNUSOCIAL_BASE_VERSION', '1.2.0');
define('GNUSOCIAL_LIFECYCLE', 'dev'); // 'dev', 'alpha[0-9]+', 'beta[0-9]+', 'rc[0-9]+', 'release'

define('GNUSOCIAL_VERSION', GNUSOCIAL_BASE_VERSION . '-' . GNUSOCIAL_LIFECYCLE);

define('GNUSOCIAL_CODENAME', 'Not decided yet');

define('AVATAR_PROFILE_SIZE', 96);
define('AVATAR_STREAM_SIZE', 48);
define('AVATAR_MINI_SIZE', 24);

define('NOTICES_PER_PAGE', 20);
define('PROFILES_PER_PAGE', 20);
define('MESSAGES_PER_PAGE', 20);
define('GROUPS_PER_PAGE', 20);

define('FOREIGN_NOTICE_SEND', 1);
define('FOREIGN_NOTICE_RECV', 2);
define('FOREIGN_NOTICE_SEND_REPLY', 4);

define('FOREIGN_FRIEND_SEND', 1);
define('FOREIGN_FRIEND_RECV', 2);

define('NOTICE_INBOX_SOURCE_SUB', 1);
define('NOTICE_INBOX_SOURCE_GROUP', 2);
define('NOTICE_INBOX_SOURCE_REPLY', 3);
define('NOTICE_INBOX_SOURCE_FORWARD', 4);
define('NOTICE_INBOX_SOURCE_PROFILE_TAG', 5);
define('NOTICE_INBOX_SOURCE_GATEWAY', -1);

// append our extlib dir as the last-resort place to find libs

set_include_path(get_include_path() . PATH_SEPARATOR . INSTALLDIR . '/extlib/');

// To protect against upstream libraries which haven't updated
// for PHP 5.3 where dl() function may not be present...
if (!function_exists('dl')) {
    // function_exists() returns false for things in disable_functions,
    // but they still exist and we'll die if we try to redefine them.
    //
    // Fortunately trying to call the disabled one will only trigger
    // a warning, not a fatal, so it's safe to leave it for our case.
    // Callers will be suppressing warnings anyway.
    $disabled = array_filter(array_map('trim', explode(',', ini_get('disable_functions'))));
    if (!in_array('dl', $disabled)) {
        function dl($library) {
            return false;
        }
    }
}

// global configuration object

require_once 'PEAR.php';
require_once 'PEAR/Exception.php';
global $_PEAR;
$_PEAR = new PEAR;
$_PEAR->setErrorHandling(PEAR_ERROR_CALLBACK, 'PEAR_ErrorToPEAR_Exception');

require_once 'DB.php';
require_once 'DB/DataObject.php';
require_once 'DB/DataObject/Cast.php'; # for dates
global $_DB;
$_DB = new DB;

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

// This gets included before the config file, so that admin code and plugins
// can use it

require_once(INSTALLDIR.'/lib/event.php');
require_once(INSTALLDIR.'/lib/plugin.php');

function addPlugin($name, array $attrs=array())
{
    return GNUsocial::addPlugin($name, $attrs);
}

function _have_config()
{
    return GNUsocial::haveConfig();
}

function GNUsocial_class_autoload($cls)
{
    if (file_exists(INSTALLDIR.'/classes/' . $cls . '.php')) {
        require_once(INSTALLDIR.'/classes/' . $cls . '.php');
    } else if (file_exists(INSTALLDIR.'/lib/' . strtolower($cls) . '.php')) {
        require_once(INSTALLDIR.'/lib/' . strtolower($cls) . '.php');
    } else if (mb_substr($cls, -6) == 'Action' &&
               file_exists(INSTALLDIR.'/actions/' . strtolower(mb_substr($cls, 0, -6)) . '.php')) {
        require_once(INSTALLDIR.'/actions/' . strtolower(mb_substr($cls, 0, -6)) . '.php');
    } else if ($cls === 'OAuthRequest' || $cls === 'OAuthException') {
        require_once('OAuth.php');
    } else {
        Event::handle('Autoload', array(&$cls));
    }
}

// Autoload function queue, starting with our own discovery method
spl_autoload_register('GNUsocial_class_autoload');

/**
 * Extlibs with namespaces (or directly in extlib/)
 * This covers libraries such as: Validate and \Michelf\Markdown
 *
 * The namespaced based structure is called "PSR-0 autoloading standard":
 *    \<Vendor Name>\(<Namespace>\)*<Class Name>
 * and is available here: http://www.php-fig.org/psr/psr-0/
*/
spl_autoload_register(function($class){
    $file = INSTALLDIR.'/extlib/'.preg_replace('{\\\\|_(?!.*\\\\)}', DIRECTORY_SEPARATOR, ltrim($class, '\\')).'.php';
    if (file_exists($file)) {
        require_once $file;
    }
});

require_once INSTALLDIR.'/lib/util.php';
require_once INSTALLDIR.'/lib/action.php';
require_once INSTALLDIR.'/lib/mail.php';

//set PEAR error handling to use regular PHP exceptions
function PEAR_ErrorToPEAR_Exception(PEAR_Error $err)
{
    //DB_DataObject throws error when an empty set would be returned
    //That behavior is weird, and not how the rest of StatusNet works.
    //So just ignore those errors.
    if ($err->getCode() == DB_DATAOBJECT_ERROR_NODATA) {
        return;
    }

    $msg      = $err->getMessage();
    $userInfo = $err->getUserInfo();

    // Log this; push the message up as an exception

    common_log(LOG_ERR, "PEAR Error: $msg ($userInfo)");

    // HACK: queue handlers get kicked by the long-query killer, and
    // keep the same broken connection. We die here to get a new
    // process started.

    if (php_sapi_name() == 'cli' && preg_match('/nativecode=2006/', $userInfo)) {
        common_log(LOG_ERR, "Lost DB connection; dying.");
        exit(100);
    }

    if ($err->getCode()) {
        throw new PEAR_Exception($err->getMessage(), $err->getCode());
    }
    throw new PEAR_Exception($err->getMessage());
}


code:
<?php
/**
 * StatusNet - the distributed open-source microblogging tool
 * Copyright (C) 2011, StatusNet, Inc.
 *
 * A threaded notice list that shows all 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  Cache
 * @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);
}

/**
 * A threaded notice list that shows all notices
 *
 * @category  General
 * @package   StatusNet
 * @author    Evan Prodromou <evan@status.net>
 * @author    Brion Vibber <brion@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 FullThreadedNoticeList extends ThreadedNoticeList
{
    function newListItem($notice)
    {
        return new FullThreadedNoticeListItem($notice, $this->out, $this->userProfile);
    }
}

/**
 * A threaded notice list item that shows everything
 *
 * @category  General
 * @package   StatusNet
 * @author    Evan Prodromou <evan@status.net>
 * @author    Brion Vibber <brion@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 FullThreadedNoticeListItem extends ThreadedNoticeListItem
{
    function initialItems()
    {
        return 1000; // @fixme
    }
}


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

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

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

// 10x8

define('AVATARS_PER_PAGE', 80);

// @todo FIXME: Class documentation missing.
class GalleryAction extends ProfileAction
{
    protected function handle()
    {
        // Post from the tag dropdown; redirect to a GET
        if ($this->isPost()) {
            common_redirect($this->selfUrl(), 303);
        }

        parent::handle();
    }

    function showContent()
    {
        $this->showTagsDropdown();
    }

    function showTagsDropdown()
    {
        $tag = $this->trimmed('tag');

        $tags = $this->getAllTags();

        $content = array();

        foreach ($tags as $t) {
            $content[$t] = $t;
        }
        if ($tags) {
            $this->elementStart('dl', array('id' => 'filter_tags'));
            $this->element('dt', null, _('Tags'));
            $this->elementStart('dd');
            $this->elementStart('ul');
            $this->elementStart('li', array('id' => 'filter_tags_all',
                                             'class' => 'child_1'));
            $this->element('a',
                           array('href' =>
                                 common_local_url($this->trimmed('action'),
                                                  array('nickname' =>
                                                        $this->target->getNickname()))),
                           // TRANS: List element on gallery action page to show all tags.
                           _m('TAGS','All'));
            $this->elementEnd('li');
            $this->elementStart('li', array('id'=>'filter_tags_item'));
            $this->elementStart('form', array('name' => 'bytag',
                                               'id' => 'form_filter_bytag',
                                              'action' => common_path('?action=' . $this->getActionName()),
                                               'method' => 'post'));
            $this->elementStart('fieldset');
            // TRANS: Fieldset legend on gallery action page.
            $this->element('legend', null, _('Select tag to filter'));
            // TRANS: Dropdown field label on gallery action page for a list containing tags.
            $this->dropdown('tag', _('Tag'), $content,
                            // TRANS: Dropdown field title on gallery action page for a list containing tags.
                            _('Choose a tag to narrow list.'), false, $tag);
            $this->hidden('nickname', $this->target->getNickname());
            // TRANS: Submit button text on gallery action page.
            $this->submit('submit', _m('BUTTON','Go'));
            $this->elementEnd('fieldset');
            $this->elementEnd('form');
            $this->elementEnd('li');
            $this->elementEnd('ul');
            $this->elementEnd('dd');
            $this->elementEnd('dl');
        }
    }

    // Get list of tags we tagged other users with
    function getTags($lst, $usr)
    {
        $profile_tag = new Notice_tag();
        $profile_tag->query('SELECT DISTINCT(tag) ' .
                            'FROM profile_tag, subscription ' .
                            'WHERE tagger = ' . $this->target->id . ' ' .
                            'AND ' . $usr . ' = ' . $this->target->id . ' ' .
                            'AND ' . $lst . ' = tagged ' .
                            'AND tagger != tagged');
        $tags = array();
        while ($profile_tag->fetch()) {
            $tags[] = $profile_tag->tag;
        }
        $profile_tag->free();
        return $tags;
    }

    function getAllTags()
    {
        return array();
    }

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


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

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

global $config, $_server, $_path;

/**
 * Global configuration setup and management.
 */
class GNUsocial
{
    protected static $config_files = array();
    protected static $have_config;
    protected static $is_api;
    protected static $is_ajax;
    protected static $plugins = array();

    /**
     * Configure and instantiate a plugin into the current configuration.
     * Class definitions will be loaded from standard paths if necessary.
     * Note that initialization events won't be fired until later.
     *
     * @param string $name class name & plugin file/subdir name
     * @param array $attrs key/value pairs of public attributes to set on plugin instance
     *
     * @throws ServerException if plugin can't be found
     */
    public static function addPlugin($name, array $attrs=array())
    {
        $name = ucfirst($name);

        if (isset(self::$plugins[$name])) {
            // We have already loaded this plugin. Don't try to
            // do it again with (possibly) different values.
            // Försten till kvarn får mala.
            return true;
        }

        $pluginclass = "{$name}Plugin";

        if (!class_exists($pluginclass)) {

            $files = array("local/plugins/{$pluginclass}.php",
                           "local/plugins/{$name}/{$pluginclass}.php",
                           "local/{$pluginclass}.php",
                           "local/{$name}/{$pluginclass}.php",
                           "plugins/{$pluginclass}.php",
                           "plugins/{$name}/{$pluginclass}.php");

            foreach ($files as $file) {
                $fullpath = INSTALLDIR.'/'.$file;
                if (@file_exists($fullpath)) {
                    include_once($fullpath);
                    break;
                }
            }
            if (!class_exists($pluginclass)) {
                throw new ServerException("Plugin $name not found.", 500);
            }
        }

        // Doesn't this $inst risk being garbage collected or something?
        // TODO: put into a static array that makes sure $inst isn't lost.
        $inst = new $pluginclass();
        foreach ($attrs as $aname => $avalue) {
            $inst->$aname = $avalue;
        }

        // Record activated plugins for later display/config dump
        self::$plugins[$name] = $attrs;

        return true;
    }

    public static function delPlugin($name)
    {
        // Remove our plugin if it was previously loaded
        $name = ucfirst($name);
        if (isset(self::$plugins[$name])) {
            unset(self::$plugins[$name]);
        }

        // make sure initPlugins will avoid this
        common_config_set('plugins', 'disable-'.$name, true);

        return true;
    }

    /**
     * Get a list of activated plugins in this process.
     * @return array of (string $name, array $args) pairs
     */
    public static function getActivePlugins()
    {
        return self::$plugins;
    }

    /**
     * Initialize, or re-initialize, GNU social global configuration
     * and plugins.
     *
     * If switching site configurations during script execution, be
     * careful when working with leftover objects -- global settings
     * affect many things and they may not behave as you expected.
     *
     * @param $server optional web server hostname for picking config
     * @param $path optional URL path for picking config
     * @param $conffile optional configuration file path
     *
     * @throws NoConfigException if config file can't be found
     */
    public static function init($server=null, $path=null, $conffile=null)
    {
        Router::clear();

        self::initDefaults($server, $path);
        self::loadConfigFile($conffile);

        $sprofile = common_config('site', 'profile');
        if (!empty($sprofile)) {
            self::loadSiteProfile($sprofile);
        }
        // Load settings from database; note we need autoload for this
        Config::loadSettings();

        self::initPlugins();
    }

    /**
     * Get identifier of the currently active site configuration
     * @return string
     */
    public static function currentSite()
    {
        return common_config('site', 'nickname');
    }

    /**
     * Change site configuration to site specified by nickname,
     * if set up via Status_network. If not, sites other than
     * the current will fail horribly.
     *
     * May throw exception or trigger a fatal error if the given
     * site is missing or configured incorrectly.
     *
     * @param string $nickname
     */
    public static function switchSite($nickname)
    {
        if ($nickname == self::currentSite()) {
            return true;
        }

        $sn = Status_network::getKV('nickname', $nickname);
        if (empty($sn)) {
            return false;
            throw new Exception("No such site nickname '$nickname'");
        }

        $server = $sn->getServerName();
        self::init($server);
    }

    /**
     * Pull all local sites from status_network table.
     *
     * Behavior undefined if site is not configured via Status_network.
     *
     * @return array of nicknames
     */
    public static function findAllSites()
    {
        $sites = array();
        $sn = new Status_network();
        $sn->find();
        while ($sn->fetch()) {
            $sites[] = $sn->nickname;
        }
        return $sites;
    }

    /**
     * Fire initialization events for all instantiated plugins.
     */
    protected static function initPlugins()
    {
        // User config may have already added some of these plugins, with
        // maybe configured parameters. The self::addPlugin function will
        // ignore the new call if it has already been instantiated.

        // Load core plugins
        foreach (common_config('plugins', 'core') as $name => $params) {
            call_user_func('self::addPlugin', $name, $params);
        }

        // Load default plugins
        foreach (common_config('plugins', 'default') as $name => $params) {
            $key = 'disable-' . $name;
            if (common_config('plugins', $key)) {
                continue;
            }

            // TODO: We should be able to avoid this is_null and assume $params
            // is an array, since that's how it is typed in addPlugin
            if (is_null($params)) {
                self::addPlugin($name);
            } else if (is_array($params)) {
                if (count($params) == 0) {
                    self::addPlugin($name);
                } else {
                    $keys = array_keys($params);
                    if (is_string($keys[0])) {
                        self::addPlugin($name, $params);
                    } else {
                        foreach ($params as $paramset) {
                            self::addPlugin($name, $paramset);
                        }
                    }
                }
            }
        }

        // XXX: if plugins should check the schema at runtime, do that here.
        if (common_config('db', 'schemacheck') == 'runtime') {
            Event::handle('CheckSchema');
        }

        // Give plugins a chance to initialize in a fully-prepared environment
        Event::handle('InitializePlugin');
    }

    /**
     * Quick-check if configuration has been established.
     * Useful for functions which may get used partway through
     * initialization to back off from fancier things.
     *
     * @return bool
     */
    public static function haveConfig()
    {
        return self::$have_config;
    }

    /**
     * Returns a list of configuration files that have
     * been loaded for this instance of GNU social.
     */
    public static function configFiles()
    {
        return self::$config_files;
    }

    public static function isApi()
    {
        return self::$is_api;
    }

    public static function setApi($mode)
    {
        self::$is_api = $mode;
    }

    public static function isAjax()
    {
        return self::$is_ajax;
    }

    public static function setAjax($mode)
    {
        self::$is_ajax = $mode;
    }

    /**
     * Build default configuration array
     * @return array
     */
    protected static function defaultConfig()
    {
        global $_server, $_path;
        require(INSTALLDIR.'/lib/default.php');
        return $default;
    }

    /**
     * Establish default configuration based on given or default server and path
     * Sets global $_server, $_path, and $config
     */
    public static function initDefaults($server, $path)
    {
        global $_server, $_path, $config, $_PEAR;

        Event::clearHandlers();
        self::$plugins = array();

        // try to figure out where we are. $server and $path
        // can be set by including module, else we guess based
        // on HTTP info.

        if (isset($server)) {
            $_server = $server;
        } else {
            $_server = array_key_exists('SERVER_NAME', $_SERVER) ?
              strtolower($_SERVER['SERVER_NAME']) :
            null;
        }

        if (isset($path)) {
            $_path = $path;
        } else {
            $_path = (array_key_exists('SERVER_NAME', $_SERVER) && array_key_exists('SCRIPT_NAME', $_SERVER)) ?
              self::_sn_to_path($_SERVER['SCRIPT_NAME']) :
            null;
        }

        // Set config values initially to default values
        $default = self::defaultConfig();
        $config = $default;

        // default configuration, overwritten in config.php
        // Keep DB_DataObject's db config synced to ours...

        $config['db'] = &$_PEAR->getStaticProperty('DB_DataObject','options');

        $config['db'] = $default['db'];

        if (function_exists('date_default_timezone_set')) {
            /* Work internally in UTC */
            date_default_timezone_set('UTC');
        }
    }

    public static function loadSiteProfile($name)
    {
        global $config;
        $settings = SiteProfile::getSettings($name);
        $config = array_replace_recursive($config, $settings);
    }

    protected static function _sn_to_path($sn)
    {
        $past_root = substr($sn, 1);
        $last_slash = strrpos($past_root, '/');
        if ($last_slash > 0) {
            $p = substr($past_root, 0, $last_slash);
        } else {
            $p = '';
        }
        return $p;
    }

    /**
     * Load the default or specified configuration file.
     * Modifies global $config and may establish plugins.
     *
     * @throws NoConfigException
     */
    protected static function loadConfigFile($conffile=null)
    {
        global $_server, $_path, $config;

        // From most general to most specific:
        // server-wide, then vhost-wide, then for a path,
        // finally for a dir (usually only need one of the last two).

        if (isset($conffile)) {
            $config_files = array($conffile);
        } else {
            $config_files = array('/etc/statusnet/statusnet.php',
                                  '/etc/statusnet/laconica.php',
                                  '/etc/laconica/laconica.php',
                                  '/etc/statusnet/'.$_server.'.php',
                                  '/etc/laconica/'.$_server.'.php');

            if (strlen($_path) > 0) {
                $config_files[] = '/etc/statusnet/'.$_server.'_'.$_path.'.php';
                $config_files[] = '/etc/laconica/'.$_server.'_'.$_path.'.php';
            }

            $config_files[] = INSTALLDIR.'/config.php';
        }

        self::$have_config = false;

        foreach ($config_files as $_config_file) {
            if (@file_exists($_config_file)) {
                // Ignore 0-byte config files
                if (filesize($_config_file) > 0) {
                    include($_config_file);
                    self::$config_files[] = $_config_file;
                    self::$have_config = true;
                }
            }
        }

        if (!self::$have_config) {
            throw new NoConfigException("No configuration file found.",
                                        $config_files);
        }

        // Check for database server; must exist!

        if (empty($config['db']['database'])) {
            throw new ServerException("No database server for this site.");
        }
    }

    /**
     * Are we running from the web with HTTPS?
     *
     * @return boolean true if we're running with HTTPS; else false
     */

    static function isHTTPS()
    {
        // There are some exceptions to this; add them here!
        if (empty($_SERVER['HTTPS'])) {
            return false;
        }

        // If it is _not_ "off", it is on, so "true".
        return strtolower($_SERVER['HTTPS']) !== 'off';
    }

    /**
     * Can we use HTTPS? Then do! Only return false if it's not configured ("never").
     */
    static function useHTTPS()
    {
        return self::isHTTPS() || common_config('site', 'ssl') != 'never';
    }
}

class NoConfigException extends Exception
{
    public $configFiles;

    function __construct($msg, $configFiles) {
        parent::__construct($msg);
        $this->configFiles = $configFiles;
    }
}


code:
<?php
/**
 * StatusNet, the distributed open-source microblogging tool
 *
 * Form for granting a role
 *
 * 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>, Brion Vibber <brion@status.net>
 * @copyright 2009-2010 StatusNet, Inc.
 * @license   http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
 * @link      http://status.net/
 */

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

/**
 * Form for sandboxing a user
 *
 * @category Form
 * @package  StatusNet
 * @author   Evan Prodromou <evan@status.net>
 * @license  http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
 * @link     http://status.net/
 *
 * @see      UnSandboxForm
 */
class GrantRoleForm extends ProfileActionForm
{
    function __construct($role, $label, $writer, $profile, $r2args)
    {
        parent::__construct($writer, $profile, $r2args);
        $this->role = $role;
        $this->label = $label;
    }

    /**
     * Action this form provides
     *
     * @return string Name of the action, lowercased.
     */
    function target()
    {
        return 'grantrole';
    }

    /**
     * Title of the form
     *
     * @return string Title of the form, internationalized
     */
    function title()
    {
        return $this->label;
    }

    function formData()
    {
        parent::formData();
        $this->out->hidden('role', $this->role);
    }

    /**
     * Description of the form
     *
     * @return string description of the form, internationalized
     */
    function description()
    {
        // TRANS: Description on form for granting a role.
        return sprintf(_('Grant this user the "%s" role'), $this->label);
    }
}


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

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

define('MEMBERS_PER_SECTION', 27);

/**
 * Base class for group actions, similar to ProfileAction
 *
 * @category Action
 * @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 GroupAction extends Action
{
    protected $group;

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

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

        // Permanent redirect on non-canonical nickname

        if ($nickname_arg != $nickname) {
            $args = array('nickname' => $nickname);
            if ($this->page != 1) {
                $args['page'] = $this->page;
            }
            common_redirect(common_local_url('showgroup', $args), 301);
        }

        if (!$nickname) {
            // TRANS: Client error displayed if no nickname argument was given requesting a group page.
            $this->clientError(_('No nickname.'), 404);
        }

        $local = Local_group::getKV('nickname', $nickname);

        if (!$local) {
            $alias = Group_alias::getKV('alias', $nickname);
            if ($alias) {
                $args = array('id' => $alias->group_id);
                if ($this->page != 1) {
                    $args['page'] = $this->page;
                }
                common_redirect(common_local_url('groupbyid', $args), 301);
            } else {
                common_log(LOG_NOTICE, "Couldn't find local group for nickname '$nickname'");
                // TRANS: Client error displayed if no remote group with a given name was found requesting group page.
                $this->clientError(_('No such group.'), 404);
            }
        }

        $this->group = User_group::getKV('id', $local->group_id);

        if (!$this->group) {
            // TRANS: Client error displayed if no local group with a given name was found requesting group page.
            $this->clientError(_('No such group.'), 404);
        }
    }

    function showProfileBlock()
    {
        $block = new GroupProfileBlock($this, $this->group);
        $block->show();
    }

    /**
     * Fill in the sidebar.
     *
     * @return void
     */
    function showSections()
    {
        $this->showMembers();
        $cur = common_current_user();
        if ($cur && $cur->isAdmin($this->group)) {
            $this->showPending();
            $this->showBlocked();
        }

        $this->showAdmins();

        if (!common_config('performance', 'high')) {
            $cloud = new GroupTagCloudSection($this, $this->group);
            $cloud->show();
        }
    }

    /**
     * Show mini-list of members
     *
     * @return void
     */
    function showMembers()
    {
        $member = $this->group->getMembers(0, MEMBERS_PER_SECTION);

        if (!$member) {
            return;
        }

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

        if (Event::handle('StartShowGroupMembersMiniList', array($this))) {
            $this->elementStart('h2');

            $this->element('a', array('href' => common_local_url('groupmembers', array('nickname' =>
                                                                                $this->group->nickname))),
                           // TRANS: Header for mini list of group members on a group page (h2).
                           _('Members'));

            $this->text(' ');

            $this->text($this->group->getMemberCount());

            $this->elementEnd('h2');

            $gmml = new GroupMembersMiniList($member, $this);
            $cnt = $gmml->show();
            if ($cnt == 0) {
                // TRANS: Description for mini list of group members on a group page when the group has no members.
                $this->element('p', null, _('(None)'));
            }

            // @todo FIXME: Should be shown if a group has more than 27 members, but I do not see it displayed at
            //              for example http://identi.ca/group/statusnet. Broken?
            if ($cnt > MEMBERS_PER_SECTION) {
                $this->element('a', array('href' => common_local_url('groupmembers',
                                                                     array('nickname' => $this->group->nickname))),
                               // TRANS: Link to all group members from mini list of group members if group has more than n members.
                               _('All members'));
            }

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

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

    function showPending()
    {
        if ($this->group->join_policy != User_group::JOIN_POLICY_MODERATE) {
            return;
        }

        $pending = $this->group->getQueueCount();

        if (!$pending) {
            return;
        }

        $request = $this->group->getRequests(0, MEMBERS_PER_SECTION);

        if (!$request) {
            return;
        }

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

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

            $this->elementStart('h2');

            $this->element('a', array('href' => common_local_url('groupqueue', array('nickname' =>
                                                                                $this->group->nickname))),
                           // TRANS: Header for mini list of users with a pending membership request on a group page (h2).
                           _('Pending'));

            $this->text(' ');

            $this->text($pending);

            $this->elementEnd('h2');

            $gmml = new ProfileMiniList($request, $this);
            $gmml->show();

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

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

    function showBlocked()
    {
        $blocked = $this->group->getBlocked(0, MEMBERS_PER_SECTION);

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

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

            $this->elementStart('h2');

            $this->element('a', array('href' => common_local_url('blockedfromgroup', array('nickname' =>
                                                                                $this->group->nickname))),
                           // TRANS: Header for mini list of users that are blocked in a group page (h2).
                           _('Blocked'));

            $this->text(' ');

            $this->text($this->group->getBlockedCount());

            $this->elementEnd('h2');

            $gmml = new GroupBlockedMiniList($blocked, $this);
            $cnt = $gmml->show();
            if ($cnt == 0) {
                // TRANS: Description for mini list of group members on a group page when the group has no members.
                $this->element('p', null, _('(None)'));
            }

            // @todo FIXME: Should be shown if a group has more than 27 members, but I do not see it displayed at
            //              for example http://identi.ca/group/statusnet. Broken?
            if ($cnt > MEMBERS_PER_SECTION) {
                $this->element('a', array('href' => common_local_url('blockedfromgroup',
                                                                     array('nickname' => $this->group->nickname))),
                               // TRANS: Link to all group members from mini list of group members if group has more than n members.
                               _('All members'));
            }

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

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

    /**
     * Show list of admins
     *
     * @return void
     */
    function showAdmins()
    {
        $adminSection = new GroupAdminSection($this, $this->group);
        $adminSection->show();
    }

    function noticeFormOptions()
    {
        $options = parent::noticeFormOptions();
        $cur = common_current_user();

        if (!empty($cur) && $cur->isMember($this->group)) {
            $options['to_group'] =  $this->group;
        }

        return $options;
    }

    function getGroup()
    {
        return $this->group;
    }
}

class GroupAdminSection extends ProfileSection
{
    var $group;

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

    function getProfiles()
    {
        return $this->group->getAdmins();
    }

    function title()
    {
        // TRANS: Title for list of group administrators on a group page.
        return _m('TITLE','Admins');
    }

    function divId()
    {
        return 'group_admins';
    }

    function moreUrl()
    {
        return null;
    }
}

class GroupMembersMiniList extends ProfileMiniList
{
    function newListItem($profile)
    {
        return new GroupMembersMiniListItem($profile, $this->action);
    }
}

class GroupMembersMiniListItem extends ProfileMiniListItem
{
    function linkAttributes()
    {
        $aAttrs = parent::linkAttributes();

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

        return $aAttrs;
    }
}

class GroupBlockedMiniList extends ProfileMiniList
{
    function newListItem($profile)
    {
        return new GroupBlockedMiniListItem($profile, $this->action);
    }
}

class GroupBlockedMiniListItem extends ProfileMiniListItem
{
    function linkAttributes()
    {
        $aAttrs = parent::linkAttributes();

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

        return $aAttrs;
    }
}

class ThreadingGroupNoticeStream extends ThreadingNoticeStream
{
    function __construct($group, $profile)
    {
        parent::__construct(new GroupNoticeStream($group, $profile));
    }
}


code:
<?php
// @todo FIXME: standard file header missing.
/**
 * Form for blocking a user from a group
 *
 * @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      BlockForm
 */
class GroupBlockForm extends Form
{
    /**
     * Profile of user to block
     */

    var $profile = null;

    /**
     * Group to block the user from
     */

    var $group = null;

    /**
     * Return-to args
     */

    var $args = null;

    /**
     * Constructor
     *
     * @param HTMLOutputter $out     output channel
     * @param Profile       $profile profile of user to block
     * @param User_group    $group   group to block user from
     * @param array         $args    return-to args
     */
    function __construct($out=null, $profile=null, $group=null, $args=null)
    {
        parent::__construct($out);

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

    /**
     * ID of the form
     *
     * @return int ID of the form
     */
    function id()
    {
        // This should be unique for the page.
        return 'block-' . $this->profile->id;
    }

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

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

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

    /**
     * Data elements of the form
     *
     * @return void
     */
    function formData()
    {
        $this->out->hidden('blockto-' . $this->profile->id,
                           $this->profile->id,
                           'blockto');
        $this->out->hidden('blockgroup-' . $this->group->id,
                           $this->group->id,
                           'blockgroup');
        if ($this->args) {
            foreach ($this->args as $k => $v) {
                $this->out->hidden('returnto-' . $k, $v);
            }
        }
    }

    /**
     * Action elements
     *
     * @return void
     */
    function formActions()
    {
        $this->out->submit(
            'submit',
            // TRANS: Button text for the form that will block a user from a group.
            _m('BUTTON','Block'),
            'submit',
            null,
            // TRANS: Submit button title.
            _m('TOOLTIP', 'Block this user so that they can no longer post messages to it.'));
    }
}