summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorBrion Vibber <brion@pobox.com>2010-04-30 13:15:53 -0700
committerBrion Vibber <brion@pobox.com>2010-04-30 13:16:13 -0700
commitcae1329f3bca1f5f1fbfdb1d96b38cbb790fbe00 (patch)
tree21ae74d08b6496c7d7fafbe95a9b147a9ac56cc0 /lib
parent5c05cd2b1a93d360bde7cb7dfc9ba39e5a5a7624 (diff)
parentf8883367184e4fd31dc819d5e1257d0eee11eb10 (diff)
Merge branch '0.9.x' into 1.0.x
Conflicts: lib/util.php
Diffstat (limited to 'lib')
-rw-r--r--lib/action.php2
-rw-r--r--lib/activity.php14
-rw-r--r--lib/activityutils.php12
-rw-r--r--lib/apiaction.php61
-rw-r--r--lib/apiauth.php18
-rw-r--r--lib/common.php4
-rw-r--r--lib/distribqueuehandler.php17
-rw-r--r--lib/installer.php14
-rw-r--r--lib/mail.php4
-rw-r--r--lib/plugin.php1
-rw-r--r--lib/util.php35
11 files changed, 157 insertions, 25 deletions
diff --git a/lib/action.php b/lib/action.php
index 4296ae7de..98e5ec2c9 100644
--- a/lib/action.php
+++ b/lib/action.php
@@ -467,7 +467,7 @@ class Action extends HTMLOutputter // lawsuit
_m('MENU', 'Logout'), $tooltip, false, 'nav_logout');
}
else {
- if (!common_config('site', 'closed')) {
+ if (!common_config('site', 'closed') && !common_config('site', 'inviteonly')) {
// TRANS: Tooltip for main menu option "Register"
$tooltip = _m('TOOLTIP', 'Create an account');
$this->menuItem(common_local_url('register'),
diff --git a/lib/activity.php b/lib/activity.php
index 365bb6258..8e2da99bb 100644
--- a/lib/activity.php
+++ b/lib/activity.php
@@ -83,6 +83,7 @@ class Activity
const CREATOR = 'creator';
const CONTENTNS = 'http://purl.org/rss/1.0/modules/content/';
+ const ENCODED = 'encoded';
public $actor; // an ActivityObject
public $verb; // a string (the URL)
@@ -269,14 +270,21 @@ class Activity
$this->title = ActivityUtils::childContent($item, ActivityObject::TITLE, self::RSS);
- $contentEl = ActivityUtils::child($item, ActivityUtils::CONTENT, self::CONTENTNS);
+ $contentEl = ActivityUtils::child($item, self::ENCODED, self::CONTENTNS);
if (!empty($contentEl)) {
- $this->content = htmlspecialchars_decode($contentEl->textContent, ENT_QUOTES);
+ // <content:encoded> XML node's text content is HTML; no further processing needed.
+ $this->content = $contentEl->textContent;
} else {
$descriptionEl = ActivityUtils::child($item, self::DESCRIPTION, self::RSS);
if (!empty($descriptionEl)) {
- $this->content = htmlspecialchars_decode($descriptionEl->textContent, ENT_QUOTES);
+ // Per spec, <description> must be plaintext.
+ // In practice, often there's HTML... but these days good
+ // feeds are using <content:encoded> which is explicitly
+ // real HTML.
+ // We'll treat this following spec, and do HTML escaping
+ // to convert from plaintext to HTML.
+ $this->content = htmlspecialchars($descriptionEl->textContent);
}
}
diff --git a/lib/activityutils.php b/lib/activityutils.php
index a7e99fb11..401fd7fc2 100644
--- a/lib/activityutils.php
+++ b/lib/activityutils.php
@@ -213,11 +213,19 @@ class ActivityUtils
// slavishly following http://atompub.org/rfc4287.html#rfc.section.4.1.3.3
if (empty($type) || $type == 'text') {
- return $el->textContent;
+ // We have plaintext saved as the XML text content.
+ // Since we want HTML, we need to escape any special chars.
+ return htmlspecialchars($el->textContent);
} else if ($type == 'html') {
+ // We have HTML saved as the XML text content.
+ // No additional processing required once we've got it.
$text = $el->textContent;
- return htmlspecialchars_decode($text, ENT_QUOTES);
+ return $text;
} else if ($type == 'xhtml') {
+ // Per spec, the <content type="xhtml"> contains a single
+ // HTML <div> with XHTML namespace on it as a child node.
+ // We need to pull all of that <div>'s child nodes and
+ // serialize them back to an (X)HTML source fragment.
$divEl = ActivityUtils::child($el, 'div', 'http://www.w3.org/1999/xhtml');
if (empty($divEl)) {
return null;
diff --git a/lib/apiaction.php b/lib/apiaction.php
index d5580abd3..a3c34a91b 100644
--- a/lib/apiaction.php
+++ b/lib/apiaction.php
@@ -32,6 +32,67 @@
* @link http://status.net/
*/
+/* External API usage documentation. Please update when you change how the API works. */
+
+/*! @mainpage StatusNet REST API
+
+ @section Introduction
+
+ Some explanatory text about the API would be nice.
+
+ @section API Methods
+
+ @subsection timelinesmethods_sec Timeline Methods
+
+ @li @ref publictimeline
+ @li @ref friendstimeline
+
+ @subsection statusmethods_sec Status Methods
+
+ @li @ref statusesupdate
+
+ @subsection usermethods_sec User Methods
+
+ @subsection directmessagemethods_sec Direct Message Methods
+
+ @subsection friendshipmethods_sec Friendship Methods
+
+ @subsection socialgraphmethods_sec Social Graph Methods
+
+ @subsection accountmethods_sec Account Methods
+
+ @subsection favoritesmethods_sec Favorites Methods
+
+ @subsection blockmethods_sec Block Methods
+
+ @subsection oauthmethods_sec OAuth Methods
+
+ @subsection helpmethods_sec Help Methods
+
+ @subsection groupmethods_sec Group Methods
+
+ @page apiroot API Root
+
+ The URLs for methods referred to in this API documentation are
+ relative to the StatusNet API root. The API root is determined by the
+ site's @b server and @b path variables, which are generally specified
+ in config.php. For example:
+
+ @code
+ $config['site']['server'] = 'example.org';
+ $config['site']['path'] = 'statusnet'
+ @endcode
+
+ The pattern for a site's API root is: @c protocol://server/path/api E.g:
+
+ @c http://example.org/statusnet/api
+
+ The @b path can be empty. In that case the API root would simply be:
+
+ @c http://example.org/api
+
+*/
+
if (!defined('STATUSNET')) {
exit(1);
}
diff --git a/lib/apiauth.php b/lib/apiauth.php
index d6ad7e021..8c3998888 100644
--- a/lib/apiauth.php
+++ b/lib/apiauth.php
@@ -34,6 +34,24 @@
* @link http://status.net/
*/
+/* External API usage documentation. Please update when you change how this method works. */
+
+/*! @page authentication Authentication
+
+ StatusNet supports HTTP Basic Authentication and OAuth for API calls.
+
+ @warning Currently, users who have created accounts without setting a
+ password via OpenID, Facebook Connect, etc., cannot use the API until
+ they set a password with their account settings panel.
+
+ @section HTTP Basic Auth
+
+
+
+ @section OAuth
+
+*/
+
if (!defined('STATUSNET')) {
exit(1);
}
diff --git a/lib/common.php b/lib/common.php
index 45946c216..2bda88c97 100644
--- a/lib/common.php
+++ b/lib/common.php
@@ -22,10 +22,10 @@ if (!defined('STATUSNET') && !defined('LACONICA')) { exit(1); }
//exit with 200 response, if this is checking fancy from the installer
if (isset($_REQUEST['p']) && $_REQUEST['p'] == 'check-fancy') { exit; }
-define('STATUSNET_VERSION', '0.9.1');
+define('STATUSNET_VERSION', '0.9.2');
define('LACONICA_VERSION', STATUSNET_VERSION); // compatibility
-define('STATUSNET_CODENAME', 'Everybody Hurts');
+define('STATUSNET_CODENAME', 'King of Birds');
define('AVATAR_PROFILE_SIZE', 96);
define('AVATAR_STREAM_SIZE', 48);
diff --git a/lib/distribqueuehandler.php b/lib/distribqueuehandler.php
index d2be7a92c..8f4b72d5c 100644
--- a/lib/distribqueuehandler.php
+++ b/lib/distribqueuehandler.php
@@ -49,19 +49,22 @@ class DistribQueueHandler
}
/**
- * Here's the meat of your queue handler -- you're handed a Notice
- * object, which you may do as you will with.
+ * 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.
*
+ * @fixme addToInboxes is known to fail sometimes with large recipient sets
+ *
* @param Notice $notice
* @return boolean true on success, false on failure
*/
function handle($notice)
{
- // XXX: do we need to change this for remote users?
-
try {
$notice->addToInboxes();
} catch (Exception $e) {
@@ -69,6 +72,12 @@ class DistribQueueHandler
}
try {
+ $notice->sendReplyNotifications();
+ } catch (Exception $e) {
+ $this->logit($notice, $e);
+ }
+
+ try {
Event::handle('EndNoticeSave', array($notice));
// Enqueue for other handlers
} catch (Exception $e) {
diff --git a/lib/installer.php b/lib/installer.php
index d0e46f95c..589a19a66 100644
--- a/lib/installer.php
+++ b/lib/installer.php
@@ -51,7 +51,7 @@ abstract class Installer
public static $dbModules = array(
'mysql' => array(
'name' => 'MySQL',
- 'check_module' => 'mysql', // mysqli?
+ 'check_module' => 'mysqli',
'installer' => 'mysql_db_installer',
),
'pgsql' => array(
@@ -341,7 +341,6 @@ abstract class Installer
* @param string $password
* @return mixed array of database connection params on success, false on failure
*
- * @fixme be consistent about using mysqli vs mysql!
* @fixme escape things in the connection string in case we have a funny pass etc
*/
function Mysql_Db_installer($host, $database, $username, $password)
@@ -349,14 +348,13 @@ abstract class Installer
$this->updateStatus("Starting installation...");
$this->updateStatus("Checking database...");
- $conn = mysql_connect($host, $username, $password);
- if (!$conn) {
+ $conn = mysqli_init();
+ if (!$conn->real_connect($host, $username, $password)) {
$this->updateStatus("Can't connect to server '$host' as '$username'.", true);
return false;
}
$this->updateStatus("Changing to database...");
- $res = mysql_select_db($database, $conn);
- if (!$res) {
+ if (!$conn->select_db($database)) {
$this->updateStatus("Can't change to database.", true);
return false;
}
@@ -438,9 +436,9 @@ abstract class Installer
// FIXME: use PEAR::DB or PDO instead of our own switch
switch ($type) {
case 'mysqli':
- $res = mysql_query($stmt, $conn);
+ $res = $conn->query($stmt);
if ($res === false) {
- $error = mysql_error();
+ $error = $conn->error();
}
break;
case 'pgsql':
diff --git a/lib/mail.php b/lib/mail.php
index c38d9f2f5..5fc584e28 100644
--- a/lib/mail.php
+++ b/lib/mail.php
@@ -636,7 +636,7 @@ function mail_notify_attn($user, $notice)
$bestname = $sender->getBestName();
- common_init_locale($user->language);
+ common_switch_locale($user->language);
if ($notice->hasConversation()) {
$conversationUrl = common_local_url('conversation',
@@ -679,7 +679,7 @@ function mail_notify_attn($user, $notice)
$headers = _mail_prepare_headers('mention', $user->nickname, $sender->nickname);
- common_init_locale();
+ common_switch_locale();
mail_to_user($user, $subject, $body, $headers);
}
diff --git a/lib/plugin.php b/lib/plugin.php
index 65ccdafbb..f63bdf309 100644
--- a/lib/plugin.php
+++ b/lib/plugin.php
@@ -91,6 +91,7 @@ class Plugin
$path = INSTALLDIR . "/plugins/$name/locale";
if (file_exists($path) && is_dir($path)) {
bindtextdomain($name, $path);
+ bind_textdomain_codeset($name, 'UTF-8');
}
}
}
diff --git a/lib/util.php b/lib/util.php
index 1f3aaf711..e7ea9df61 100644
--- a/lib/util.php
+++ b/lib/util.php
@@ -41,11 +41,13 @@ function common_init_locale($language=null)
}
putenv('LANGUAGE='.$language);
putenv('LANG='.$language);
- return setlocale(LC_ALL, $language . ".utf8",
+ $ok = setlocale(LC_ALL, $language . ".utf8",
$language . ".UTF8",
$language . ".utf-8",
$language . ".UTF-8",
$language);
+
+ return $ok;
}
function common_init_language()
@@ -89,6 +91,32 @@ function common_init_language()
$locale_set = common_init_locale($language);
}
+ common_init_gettext();
+}
+
+/**
+ * @access private
+ */
+function common_init_gettext()
+{
+ setlocale(LC_CTYPE, 'C');
+ // So we do not have to make people install the gettext locales
+ $path = common_config('site','locale_path');
+ bindtextdomain("statusnet", $path);
+ bind_textdomain_codeset("statusnet", "UTF-8");
+ textdomain("statusnet");
+}
+
+/**
+ * Switch locale during runtime, and poke gettext until it cries uncle.
+ * Otherwise, sometimes it doesn't actually switch away from the old language.
+ *
+ * @param string $language code for locale ('en', 'fr', 'pt_BR' etc)
+ */
+function common_switch_locale($language=null)
+{
+ common_init_locale($language);
+
setlocale(LC_CTYPE, 'C');
// So we do not have to make people install the gettext locales
$path = common_config('site','locale_path');
@@ -97,6 +125,7 @@ function common_init_language()
textdomain("statusnet");
}
+
function common_timezone()
{
if (common_logged_in()) {
@@ -826,7 +855,7 @@ function common_linkify($url) {
return XMLStringer::estring('a', $attrs, $url);
}
-function common_shorten_links($text)
+function common_shorten_links($text, $always = false)
{
common_debug("common_shorten_links() called");
@@ -836,7 +865,7 @@ function common_shorten_links($text)
common_debug("maxLength = $maxLength");
- if (mb_strlen($text) > $maxLength) {
+ if ($always || mb_strlen($text) > $maxLength) {
common_debug("Forcing shortening");
return common_replace_urls_callback($text, array('File_redirection', 'forceShort'));
} else {