$this->elementEnd('div');
}
- function isReadOnly(array $args=array())
- public function isReadOnly($args)
++ public function isReadOnly(array $args = array())
{
return true;
}
$ids = array();
- foreach ($gis[$this->id] as $gi)
- {
+ foreach ($gis[$this->id] as $gi) {
$ids[] = $gi->group_id;
}
-
+
$groups = User_group::multiGet('id', $ids);
- $this->_groups[$this->id] = $groups->fetchAll();
+ $this->_setGroups($groups->fetchAll());
return $this->_groups[$this->id];
}
}
}
- // Only for followers of the author
-
- $author = null;
+ if (!$foundOne) {
+ return false;
+ }
+ }
- if ($scope & Notice::FOLLOWER_SCOPE) {
+ if ($scope & Notice::FOLLOWER_SCOPE || $this->getProfile()->isPrivateStream()) {
- try {
- $author = $this->getProfile();
- } catch (Exception $e) {
- return false;
- }
-
- if (!Subscription::exists($profile, $author)) {
- return false;
- }
+ if (!Subscription::exists($profile, $this->getProfile())) {
+ return false;
}
-
- return !$this->isHiddenSpam($profile);
}
+
+ return !$this->isHiddenSpam($profile);
}
- function isHiddenSpam($profile) {
+ function isHiddenSpam(Profile $profile=null) {
// Hide posts by silenced users from everyone but moderators.
return $scope;
}
- static function fillProfiles($notices)
+ static function fillProfiles(array $notices)
{
$map = self::getProfiles($notices);
-
foreach ($notices as $entry=>$notice) {
try {
if (array_key_exists($notice->profile_id, $map)) {
foreach ($notices as $notice) {
$ids[] = $notice->profile_id;
}
-
$ids = array_unique($ids);
-
- return Profile::pivotGet('id', $ids);
+ return Profile::pivotGet('id', $ids);
}
- static function fillGroups(&$notices)
+ static function fillGroups(array &$notices)
{
$ids = self::_idsOf($notices);
-
$gis = Group_inbox::listGet('notice_id', $ids);
-
$gids = array();
- foreach ($gis as $id => $gi)
- {
+ foreach ($gis as $id => $gi) {
foreach ($gi as $g)
{
$gids[] = $g->group_id;
return array_keys($ids);
}
- static function fillAttachments(&$notices)
+ static function fillAttachments(array &$notices)
{
$ids = self::_idsOf($notices);
-
$f2pMap = File_to_post::listGet('post_id', $ids);
-
$fileIds = array();
-
foreach ($f2pMap as $noticeId => $f2ps) {
foreach ($f2ps as $f2p) {
- $fileIds[] = $f2p->file_id;
+ $fileIds[] = $f2p->file_id;
}
}
$paths = array(INSTALLDIR.'/local/doc-src/',
INSTALLDIR.'/doc-src/');
- $site = StatusNet::currentSite();
+ $site = GNUsocial::currentSite();
-
+
if (!empty($site)) {
array_unshift($paths, INSTALLDIR.'/local/doc-src/'.$site.'/');
}
$paths = array(INSTALLDIR.'/local/mail-src/',
INSTALLDIR.'/mail-src/');
- $site = StatusNet::currentSite();
+ $site = GNUsocial::currentSite();
-
+
if (!empty($site)) {
array_unshift($paths, INSTALLDIR.'/local/mail-src/'.$site.'/');
}
function _have_config()
{
- return StatusNet::haveConfig();
+ return GNUsocial::haveConfig();
}
+function common_get_temp_dir()
+{
+ // Try to get it from php.ini first
+ $temp_path = trim(ini_get('upload_tmp_dir'));
+
+ // Is it empty?
+ if (strlen($temp_path) == 0) {
+ // Then try sys_get_temp_dir()
+ $temp_path = trim(sys_get_temp_dir());
+
+ // Still empty?
+ if (strlen($temp_path) == 0) {
+ // Then set it to /tmp (ugly)
+ // @TODO Hard-coded non-Windows stuff!
+ $temp_path = '/tmp';
+ }
+ }
+
+ // Return found path
+ return $temp_path;
+}
+
function GNUsocial_class_autoload($cls)
{
if (file_exists(INSTALLDIR.'/classes/' . $cls . '.php')) {
*
* @return boolean hook return
*/
- function onEndInitializeQueueManager($manager)
+ function onEndInitializeQueueManager(QueueManager $manager)
{
- $manager->connect($this->transport . '-in', new ImReceiverQueueHandler($this), 'im');
- $manager->connect($this->transport, new ImQueueHandler($this));
- $manager->connect($this->transport . '-out', new ImSenderQueueHandler($this), 'im');
+ // If we don't require CLI mode, or if we do and GNUSOCIAL_CLI _is_ set, then connect the transports
+ // This check is made mostly because some IM plugins can't deliver to transports unless they
+ // have continously running daemons (such as XMPP) and we can't have that over HTTP requests.
+ if (!$this->requires_cli || defined('GNUSOCIAL_CLI')) {
+ $manager->connect($this->transport . '-in', new ImReceiverQueueHandler($this), 'im');
+ $manager->connect($this->transport, new ImQueueHandler($this));
+ $manager->connect($this->transport . '-out', new ImSenderQueueHandler($this), 'im');
+ }
return true;
}
// When creating a notice form we don't want to collide with
// possibly existing HTML elements, as naming conventions are similar.
- $this->id_suffix = rand();
+ $this->id_suffix = mt_rand();
- parent::__construct($action);
-
if (is_null($options)) {
$options = array();
}
'type' => 'checkbox',
'class' => 'checkbox',
'id' => $this->id() . '-notice_data-geo',
- 'checked' => true, // ?
+ 'checked' => false, // Must be unchecked by default
));
- $this->out->text(' ');
- // TRANS: Field label to add location to a notice.
- $this->out->text(_('Share my location'));
- $this->out->elementEnd('label');
+ $this->out->element('label', array('class' => 'notice_data-geo',
+ 'for' => $this->id().'-notice_data-geo'),
+ // TRANS: Checkbox label to allow sharing geo location in notices.
+ _('Share my location'));
$this->out->elementEnd('div');
// TRANS: Text to not share location for a notice in notice form.
* @return boolean continuation flag
*/
- function prepare($args)
+ function prepare(array $args=array())
{
- StatusNet::setApi(true); // reduce exception reports to aid in debugging
+ GNUsocial::setApi(true); // reduce exception reports to aid in debugging
parent::prepare($args);
*/
class OembedproxyAction extends OembedAction
{
- function handle($args)
+ function handle(array $args=array())
{
// Trigger short error responses; not a human-readable web page.
- StatusNet::setApi(true);
+ GNUsocial::setApi(true);
// We're not a general oEmbed proxy service; limit to valid sessions.
$token = $this->trimmed('token');
--- /dev/null
- function prepare($args)
+ <?php
+ /**
+ * StatusNet, the distributed open-source microblogging tool
+ *
+ * Show up to 100 repeats of a notice
+ *
+ * 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 API
+ * @package StatusNet
+ * @author Evan Prodromou <evan@status.net>
+ * @copyright 2009 StatusNet, Inc.
+ * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
+ * @link http://status.net/
+ */
+
+ if (!defined('STATUSNET')) {
+ exit(1);
+ }
+
+ /**
+ * Show up to 100 repeats of a notice
+ *
+ * @category API
+ * @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 ApiStatusesRetweetsAction extends ApiAuthAction
+ {
+ const MAXCOUNT = 100;
+
+ var $original = null;
+ var $cnt = self::MAXCOUNT;
+
+ /**
+ * Take arguments for running
+ *
+ * @param array $args $_REQUEST args
+ *
+ * @return boolean success flag
+ */
- function handle($args)
++ function prepare(array $args=array())
+ {
+ parent::prepare($args);
+
+ $id = $this->trimmed('id');
+
+ $this->original = Notice::getKV('id', $id);
+
+ if (empty($this->original)) {
+ // TRANS: Client error displayed trying to display redents of a non-exiting notice.
+ $this->clientError(_('No such notice.'),
+ 400, $this->format);
+ return false;
+ }
+
+ $cnt = $this->trimmed('count');
+
+ if (empty($cnt) || !is_integer($cnt)) {
+ $cnt = 100;
+ } else {
+ $this->cnt = min((int)$cnt, self::MAXCOUNT);
+ }
+
+ return true;
+ }
+
+ /**
+ * Handle the request
+ *
+ * Make a new notice for the update, save it, and show it
+ *
+ * @param array $args $_REQUEST data (unused)
+ *
+ * @return void
+ */
- function isReadOnly($args)
++ function handle(array $args=array())
+ {
+ parent::handle($args);
+
+ $strm = $this->original->repeatStream($this->cnt);
+
+ switch ($this->format) {
+ case 'xml':
+ $this->showXmlTimeline($strm);
+ break;
+ case 'json':
+ $this->showJsonTimeline($strm);
+ break;
+ default:
+ // TRANS: Client error displayed when coming across a non-supported API method.
+ $this->clientError(_('API method not found.'), $code = 404);
+ break;
+ }
+ }
+
+ /**
+ * Return true if read only.
+ *
+ * MAY override
+ *
+ * @param array $args other arguments
+ *
+ * @return boolean is read only action?
+ */
+
++ function isReadOnly(array $args=array())
+ {
+ return true;
+ }
+ }
--- /dev/null
- function prepare($args)
+ <?php
+ /**
+ * StatusNet, the distributed open-source microblogging tool
+ *
+ * Show authenticating user's most recent repeats
+ *
+ * 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 API
+ * @package StatusNet
+ * @author Evan Prodromou <evan@status.net>
+ * @copyright 2009 StatusNet, Inc.
+ * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
+ * @link http://status.net/
+ */
+
+ if (!defined('STATUSNET')) {
+ exit(1);
+ }
+
+ /**
+ * Show authenticating user's most recent repeats
+ *
+ * @category API
+ * @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 ApiTimelineRetweetedByMeAction extends ApiAuthAction
+ {
+ const DEFAULTCOUNT = 20;
+ const MAXCOUNT = 200;
+ const MAXNOTICES = 3200;
+
+ var $repeats = null;
+ var $cnt = self::DEFAULTCOUNT;
+ var $page = 1;
+ var $since_id = null;
+ var $max_id = null;
+
+ /**
+ * Take arguments for running
+ *
+ * @param array $args $_REQUEST args
+ *
+ * @return boolean success flag
+ *
+ */
- function isReadOnly($args)
++ function prepare(array $args=array())
+ {
+ parent::prepare($args);
+
+ // TRANS: Server error displayed calling unimplemented API method for 'retweeted by me'.
+ $this->serverError(_('Unimplemented.'), 503);
+
+ return false;
+ }
+
+ /**
+ * Return true if read only.
+ *
+ * @param array $args other arguments
+ *
+ * @return boolean is read only action?
+ */
++ function isReadOnly(array $args=array())
+ {
+ return true;
+ }
+ }
--- /dev/null
- function isReadOnly($args)
+ <?php
+ /**
+ * StatusNet, the distributed open-source microblogging tool
+ *
+ * Show most recent notices that are repeats in user's inbox
+ *
+ * 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 API
+ * @package StatusNet
+ * @author Evan Prodromou <evan@status.net>
+ * @copyright 2009 StatusNet, Inc.
+ * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
+ * @link http://status.net/
+ */
+
+ if (!defined('GNUSOCIAL')) { exit(1); }
+
+ /**
+ * Show most recent notices that are repeats in user's inbox
+ *
+ * @category API
+ * @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 ApiTimelineRetweetedToMeAction extends ApiAuthAction
+ {
+ const DEFAULTCOUNT = 20;
+ const MAXCOUNT = 200;
+ const MAXNOTICES = 3200;
+
+ var $repeats = null;
+ var $cnt = self::DEFAULTCOUNT;
+ var $page = 1;
+ var $since_id = null;
+ var $max_id = null;
+
+ /**
+ * Take arguments for running
+ *
+ * @param array $args $_REQUEST args
+ *
+ * @return boolean success flag
+ */
+ protected function prepare(array $args=array())
+ {
+ parent::prepare($args);
+
+ $cnt = $this->int('count', self::DEFAULTCOUNT, self::MAXCOUNT, 1);
+
+ $page = $this->int('page', 1, (self::MAXNOTICES/$this->cnt));
+
+ $since_id = $this->int('since_id');
+
+ $max_id = $this->int('max_id');
+
+ return true;
+ }
+
+ /**
+ * Handle the request
+ *
+ * show a timeline of the user's repeated notices
+ *
+ * @return void
+ */
+ protected function handle()
+ {
+ parent::handle();
+
+ $offset = ($this->page-1) * $this->cnt;
+ $limit = $this->cnt;
+
+ // TRANS: Title for Atom feed "repeated to me". %s is the user nickname.
+ $title = sprintf(_("Repeated to %s"), $this->scoped->getNickname());
+ $subtitle = sprintf(
+ // @todo FIXME: $profile is not defined.
+ // TRANS: Subtitle for API action that shows most recent notices that are repeats in user's inbox.
+ // TRANS: %1$s is the sitename, %2$s is a user nickname, %3$s is a user profile name.
+ _('%1$s notices that were to repeated to %2$s / %3$s.'),
+ $sitename, $this->scoped->getNickname(), $profile->getBestName()
+ );
+ $taguribase = TagURI::base();
+ $id = "tag:$taguribase:RepeatedToMe:" . $this->scoped->id;
+
+ $link = common_local_url(
+ 'all',
+ array('nickname' => $this->scoped->getNickname())
+ );
+
+ $strm = $this->scoped->repeatedToMe($offset, $limit, $this->since_id, $this->max_id);
+
+ switch ($this->format) {
+ case 'xml':
+ $this->showXmlTimeline($strm);
+ break;
+ case 'json':
+ $this->showJsonTimeline($strm);
+ break;
+ case 'atom':
+ header('Content-Type: application/atom+xml; charset=utf-8');
+
+ $atom = new AtomNoticeFeed($this->scoped->getUser());
+
+ $atom->setId($id);
+ $atom->setTitle($title);
+ $atom->setSubtitle($subtitle);
+ $atom->setUpdated('now');
+ $atom->addLink($link);
+
+ $id = $this->arg('id');
+
+ $atom->setSelfLink($self);
+ $atom->addEntryFromNotices($strm);
+
+ $this->raw($atom->getString());
+
+ break;
+ case 'as':
+ header('Content-Type: ' . ActivityStreamJSONDocument::CONTENT_TYPE);
+ $doc = new ActivityStreamJSONDocument($this->scoped->getUser());
+ $doc->setTitle($title);
+ $doc->addLink($link, 'alternate', 'text/html');
+ $doc->addItemsFromNotices($strm);
+ $this->raw($doc->asString());
+ break;
+ default:
+ // TRANS: Client error displayed when coming across a non-supported API method.
+ $this->clientError(_('API method not found.'), $code = 404);
+ break;
+ }
+ }
+
+ /**
+ * Return true if read only.
+ *
+ * MAY override
+ *
+ * @param array $args other arguments
+ *
+ * @return boolean is read only action?
+ */
++ function isReadOnly(array $args=array())
+ {
+ return true;
+ }
+ }
--- /dev/null
- function prepare($args)
+ <?php
+ /**
+ * StatusNet, the distributed open-source microblogging tool
+ *
+ * Show authenticating user's most recent notices that have been repeated
+ *
+ * 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 API
+ * @package StatusNet
+ * @author Evan Prodromou <evan@status.net>
+ * @copyright 2009 StatusNet, Inc.
+ * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
+ * @link http://status.net/
+ */
+
+ if (!defined('STATUSNET')) {
+ exit(1);
+ }
+
+ /**
+ * Show authenticating user's most recent notices that have been repeated
+ *
+ * @category API
+ * @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 ApiTimelineRetweetsOfMeAction extends ApiAuthAction
+ {
+ const DEFAULTCOUNT = 20;
+ const MAXCOUNT = 200;
+ const MAXNOTICES = 3200;
+
+ var $repeats = null;
+ var $cnt = self::DEFAULTCOUNT;
+ var $page = 1;
+ var $since_id = null;
+ var $max_id = null;
+
+ /**
+ * Take arguments for running
+ *
+ * @param array $args $_REQUEST args
+ *
+ * @return boolean success flag
+ */
- function handle($args)
++ function prepare(array $args=array())
+ {
+ parent::prepare($args);
+
+ $cnt = $this->int('count', self::DEFAULTCOUNT, self::MAXCOUNT, 1);
+
+ $page = $this->int('page', 1, (self::MAXNOTICES/$this->cnt));
+
+ $since_id = $this->int('since_id');
+
+ $max_id = $this->int('max_id');
+
+ return true;
+ }
+
+ /**
+ * Handle the request
+ *
+ * show a timeline of the user's repeated notices
+ *
+ * @param array $args $_REQUEST data (unused)
+ *
+ * @return void
+ */
- function isReadOnly($args)
++ function handle(array $args=array())
+ {
+ parent::handle($args);
+
+ $offset = ($this->page-1) * $this->cnt;
+ $limit = $this->cnt;
+
+ // TRANS: Title of list of repeated notices of the logged in user.
+ // TRANS: %s is the nickname of the logged in user.
+ $title = sprintf(_("Repeats of %s"), $this->auth_user->nickname);
+ $sitename = common_config('site', 'name');
+
+ $profile = $this->auth_user->getProfile();
+
+ $subtitle = sprintf(
+ // TRANS: Subtitle of API time with retweets of me.
+ // TRANS: %1$s is the StatusNet sitename, %2$s is the user nickname, %3$s is the user profile name.
+ _('%1$s notices that %2$s / %3$s has repeated.'),
+ $sitename, $this->auth_user->nickname, $profile->getBestName()
+ );
+
+ $taguribase = TagURI::base();
+ $id = "tag:$taguribase:RepeatsOfMe:" . $this->auth_user->id;
+
+ $link = common_local_url(
+ 'all',
+ array('nickname' => $this->auth_user->nickname)
+ );
+
+ // This is a really bad query for some reason
+
+ if (!common_config('performance', 'high')) {
+ $strm = $this->auth_user->repeatsOfMe($offset, $limit, $this->since_id, $this->max_id);
+ } else {
+ $strm = new Notice();
+ $strm->whereAdd('0 = 1');
+ $strm->find();
+ }
+
+ switch ($this->format) {
+ case 'xml':
+ $this->showXmlTimeline($strm);
+ break;
+ case 'json':
+ $this->showJsonTimeline($strm);
+ break;
+ case 'atom':
+ header('Content-Type: application/atom+xml; charset=utf-8');
+ $atom = new AtomNoticeFeed($this->auth_user);
+ $atom->setId($id);
+ $atom->setTitle($title);
+ $atom->setSubtitle($subtitle);
+ $atom->setUpdated('now');
+ $atom->addLink($link);
+ $atom->setSelfLink($this->getSelfUri());
+ $atom->addEntryFromNotices($strm);
+ $this->raw($atom->getString());
+ break;
+ case 'as':
+ header('Content-Type: ' . ActivityStreamJSONDocument::CONTENT_TYPE);
+ $doc = new ActivityStreamJSONDocument($this->auth_user);
+ $doc->setTitle($title);
+ $doc->addLink($link, 'alternate', 'text/html');
+ $doc->addItemsFromNotices($strm);
+ $this->raw($doc->asString());
+ break;
+ default:
+ // TRANS: Client error displayed when coming across a non-supported API method.
+ $this->clientError(_('API method not found.'), 404);
+ break;
+ }
+ }
+
+ /**
+ * Return true if read only.
+ *
+ * MAY override
+ *
+ * @param array $args other arguments
+ *
+ * @return boolean is read only action?
+ */
++ function isReadOnly(array $args=array())
+ {
+ return true;
+ }
+ }
--- /dev/null
+<?php
+/*
+ * StatusNet - a 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/>.
+ */
+
+// -*- mode: php -*-
+
+# Abort if called from a web server
+
+if (isset($_SERVER) && array_key_exists('REQUEST_METHOD', $_SERVER)) {
+ print "This script must be run from the command line\n";
+ exit();
+}
+
+define('GNUSOCIAL', true);
+define('STATUSNET', true); //compatibility
+
++define('GNUSOCIAL_CLI', true); // to know we're in a CLI environment
++
+// Set various flags so we don't time out on long-running processes
+
+ini_set("max_execution_time", "0");
+ini_set("max_input_time", "0");
+set_time_limit(0);
+mb_internal_encoding('UTF-8');
+error_reporting(0);
+# DEBUG: error_reporting(E_ALL & ~E_STRICT & ~E_DEPRECATED);
+
+// Add extlib to our path so we can get Console_Getopt
+
+$_extra_path = array(INSTALLDIR.'/extlib/');
+
+set_include_path(implode(PATH_SEPARATOR, $_extra_path) . PATH_SEPARATOR . get_include_path());
+
+require_once 'Console/Getopt.php';
+
+// Note: $shortoptions and $longoptions should be pre-defined!
+
+$_default_shortoptions = 'qvhc:s:p:';
+
+$_default_longoptions = array('quiet', 'verbose', 'help', 'conf=', 'server=', 'path=');
+
+if (isset($shortoptions)) {
+ $shortoptions .= $_default_shortoptions;
+} else {
+ $shortoptions = $_default_shortoptions;
+}
+
+if (isset($longoptions)) {
+ $longoptions = array_merge($longoptions, $_default_longoptions);
+} else {
+ $longoptions = $_default_longoptions;
+}
+
+$parser = new Console_Getopt();
+
+$result = $parser->getopt($argv, $shortoptions, $longoptions);
+
+if (PEAR::isError($result)) {
+ print $result->getMessage()."\n";
+ exit(1);
+} else {
+ list($options, $args) = $result;
+}
+
+function show_help()
+{
+ global $helptext;
+
+ $_default_help_text = <<<END_OF_DEFAULT
+ General options:
+
+ -q --quiet Quiet (little output)
+ -v --verbose Verbose (lots of output)
+ -c --conf=<filename> Use <filename> as config file
+ -s --server=<name> Use <name> as server name
+ -p --path=<path> Use <path> as path name
+ -h --help Show this message and quit.
+
+END_OF_DEFAULT;
+ if (isset($helptext)) {
+ print $helptext;
+ }
+ print $_default_help_text;
+ exit(0);
+}
+
+foreach ($options as $option) {
+
+ switch ($option[0]) {
+ case '--server':
+ case 's':
+ $server = $option[1];
+ break;
+
+ case '--path':
+ case 'p':
+ $path = $option[1];
+ break;
+
+ case '--conf':
+ case 'c':
+ $conffile = $option[1];
+ break;
+
+ case '--help':
+ case 'h':
+ show_help();
+ }
+}
+
+require_once INSTALLDIR . '/lib/common.php';
+
+set_error_handler('common_error_handler');
+
+// Set up the language infrastructure so we can localize anything that
+// needs to be sent out to users, such as mail notifications.
+common_init_language();
+
+function _make_matches($opt, $alt)
+{
+ $matches = array();
+
+ if (strlen($opt) > 1 && 0 != strncmp($opt, '--', 2)) {
+ $matches[] = '--'.$opt;
+ } else {
+ $matches[] = $opt;
+ }
+
+ if (!empty($alt)) {
+ if (strlen($alt) > 1 && 0 != strncmp($alt, '--', 2)) {
+ $matches[] = '--'.$alt;
+ } else {
+ $matches[] = $alt;
+ }
+ }
+
+ return $matches;
+}
+
+function have_option($opt, $alt=null)
+{
+ global $options;
+
+ $matches = _make_matches($opt, $alt);
+
+ foreach ($options as $option) {
+ if (in_array($option[0], $matches)) {
+ return true;
+ }
+ }
+
+ return false;
+}
+
+function get_option_value($opt, $alt=null)
+{
+ global $options;
+
+ $matches = _make_matches($opt, $alt);
+
+ foreach ($options as $option) {
+ if (in_array($option[0], $matches)) {
+ return $option[1];
+ }
+ }
+
+ return null;
+}
+
+class NoUserArgumentException extends Exception
+{
+}
+
+function getUser()
+{
+ $user = null;
+
+ if (have_option('i', 'id')) {
+ $id = get_option_value('i', 'id');
+ $user = User::getKV('id', $id);
+ if (empty($user)) {
+ throw new Exception("Can't find user with id '$id'.");
+ }
+ } else if (have_option('n', 'nickname')) {
+ $nickname = get_option_value('n', 'nickname');
+ $user = User::getKV('nickname', $nickname);
+ if (empty($user)) {
+ throw new Exception("Can't find user with nickname '$nickname'");
+ }
+ } else {
+ throw new NoUserArgumentException("No user argument specified.");
+ }
+
+ return $user;
+}
+
+/** "Printf not quiet" */
+
+function printfnq()
+{
+ if (have_option('q', 'quiet')) {
+ return null;
+ }
+
+ $cargs = func_num_args();
+
+ if ($cargs == 0) {
+ return 0;
+ }
+
+ $args = func_get_args();
+ $format = array_shift($args);
+
+ return vprintf($format, $args);
+}
+
+/** "Print when verbose" */
+
+function printfv()
+{
+ if (!have_option('v', 'verbose')) {
+ return null;
+ }
+
+ $cargs = func_num_args();
+
+ if ($cargs == 0) {
+ return 0;
+ }
+
+ $args = func_get_args();
+ $format = array_shift($args);
+
+ return vprintf($format, $args);
+}
--- /dev/null
--- /dev/null
++Subproject commit 441a38c20487faf6078e70f1055f20a5412a2fa1