reformat Notice.php

This commit is contained in:
Evan Prodromou 2009-10-03 20:34:40 -04:00
parent bcdf31c639
commit 18f4a7eaea

View File

@ -37,8 +37,8 @@ if (!defined('STATUSNET') && !defined('LACONICA')) {
} }
/** /**
* Table Definition for notice * Table Definition for notice
*/ */
require_once INSTALLDIR.'/classes/Memcached_DataObject.php'; require_once INSTALLDIR.'/classes/Memcached_DataObject.php';
/* We keep the first three 20-notice pages, plus one for pagination check, /* We keep the first three 20-notice pages, plus one for pagination check,
@ -165,141 +165,141 @@ class Notice extends Memcached_DataObject
static function saveNew($profile_id, $content, $source=null, static function saveNew($profile_id, $content, $source=null,
$is_local=Notice::LOCAL_PUBLIC, $reply_to=null, $uri=null, $created=null) { $is_local=Notice::LOCAL_PUBLIC, $reply_to=null, $uri=null, $created=null) {
$profile = Profile::staticGet($profile_id); $profile = Profile::staticGet($profile_id);
$final = common_shorten_links($content); $final = common_shorten_links($content);
if (Notice::contentTooLong($final)) { if (Notice::contentTooLong($final)) {
throw new ClientException(_('Problem saving notice. Too long.')); throw new ClientException(_('Problem saving notice. Too long.'));
} }
if (!$profile) { if (!$profile) {
throw new ClientException(_('Problem saving notice. Unknown user.')); throw new ClientException(_('Problem saving notice. Unknown user.'));
} }
if (common_config('throttle', 'enabled') && !Notice::checkEditThrottle($profile_id)) { if (common_config('throttle', 'enabled') && !Notice::checkEditThrottle($profile_id)) {
common_log(LOG_WARNING, 'Excessive posting by profile #' . $profile_id . '; throttled.'); common_log(LOG_WARNING, 'Excessive posting by profile #' . $profile_id . '; throttled.');
throw new ClientException(_('Too many notices too fast; take a breather '. throw new ClientException(_('Too many notices too fast; take a breather '.
'and post again in a few minutes.')); 'and post again in a few minutes.'));
} }
if (common_config('site', 'dupelimit') > 0 && !Notice::checkDupes($profile_id, $final)) { if (common_config('site', 'dupelimit') > 0 && !Notice::checkDupes($profile_id, $final)) {
common_log(LOG_WARNING, 'Dupe posting by profile #' . $profile_id . '; throttled.'); common_log(LOG_WARNING, 'Dupe posting by profile #' . $profile_id . '; throttled.');
throw new ClientException(_('Too many duplicate messages too quickly;'. throw new ClientException(_('Too many duplicate messages too quickly;'.
' take a breather and post again in a few minutes.')); ' take a breather and post again in a few minutes.'));
} }
$banned = common_config('profile', 'banned'); $banned = common_config('profile', 'banned');
if ( in_array($profile_id, $banned) || in_array($profile->nickname, $banned)) { if ( in_array($profile_id, $banned) || in_array($profile->nickname, $banned)) {
common_log(LOG_WARNING, "Attempted post from banned user: $profile->nickname (user id = $profile_id)."); common_log(LOG_WARNING, "Attempted post from banned user: $profile->nickname (user id = $profile_id).");
throw new ClientException(_('You are banned from posting notices on this site.')); throw new ClientException(_('You are banned from posting notices on this site.'));
} }
$notice = new Notice(); $notice = new Notice();
$notice->profile_id = $profile_id; $notice->profile_id = $profile_id;
$blacklist = common_config('public', 'blacklist'); $blacklist = common_config('public', 'blacklist');
$autosource = common_config('public', 'autosource'); $autosource = common_config('public', 'autosource');
# Blacklisted are non-false, but not 1, either # Blacklisted are non-false, but not 1, either
if (($blacklist && in_array($profile_id, $blacklist)) || if (($blacklist && in_array($profile_id, $blacklist)) ||
($source && $autosource && in_array($source, $autosource))) { ($source && $autosource && in_array($source, $autosource))) {
$notice->is_local = Notice::LOCAL_NONPUBLIC; $notice->is_local = Notice::LOCAL_NONPUBLIC;
} else { } else {
$notice->is_local = $is_local; $notice->is_local = $is_local;
} }
if (!empty($created)) { if (!empty($created)) {
$notice->created = $created; $notice->created = $created;
} else { } else {
$notice->created = common_sql_now(); $notice->created = common_sql_now();
} }
$notice->content = $final; $notice->content = $final;
$notice->rendered = common_render_content($final, $notice); $notice->rendered = common_render_content($final, $notice);
$notice->source = $source; $notice->source = $source;
$notice->uri = $uri; $notice->uri = $uri;
$notice->reply_to = self::getReplyTo($reply_to, $profile_id, $source, $final); $notice->reply_to = self::getReplyTo($reply_to, $profile_id, $source, $final);
if (!empty($notice->reply_to)) { if (!empty($notice->reply_to)) {
$reply = Notice::staticGet('id', $notice->reply_to); $reply = Notice::staticGet('id', $notice->reply_to);
$notice->conversation = $reply->conversation; $notice->conversation = $reply->conversation;
} }
if (Event::handle('StartNoticeSave', array(&$notice))) { if (Event::handle('StartNoticeSave', array(&$notice))) {
// XXX: some of these functions write to the DB // XXX: some of these functions write to the DB
$notice->query('BEGIN'); $notice->query('BEGIN');
$id = $notice->insert(); $id = $notice->insert();
if (!$id) { if (!$id) {
common_log_db_error($notice, 'INSERT', __FILE__); common_log_db_error($notice, 'INSERT', __FILE__);
throw new ServerException(_('Problem saving notice.')); throw new ServerException(_('Problem saving notice.'));
} }
// Update ID-dependent columns: URI, conversation // Update ID-dependent columns: URI, conversation
$orig = clone($notice); $orig = clone($notice);
$changed = false; $changed = false;
if (empty($uri)) { if (empty($uri)) {
$notice->uri = common_notice_uri($notice); $notice->uri = common_notice_uri($notice);
$changed = true; $changed = true;
} }
// If it's not part of a conversation, it's // If it's not part of a conversation, it's
// the beginning of a new conversation. // the beginning of a new conversation.
if (empty($notice->conversation)) { if (empty($notice->conversation)) {
$notice->conversation = $notice->id; $notice->conversation = $notice->id;
$changed = true; $changed = true;
} }
if ($changed) { if ($changed) {
if (!$notice->update($orig)) { if (!$notice->update($orig)) {
common_log_db_error($notice, 'UPDATE', __FILE__); common_log_db_error($notice, 'UPDATE', __FILE__);
throw new ServerException(_('Problem saving notice.')); throw new ServerException(_('Problem saving notice.'));
} }
} }
// XXX: do we need to change this for remote users? // XXX: do we need to change this for remote users?
$notice->saveReplies(); $notice->saveReplies();
$notice->saveTags(); $notice->saveTags();
$notice->addToInboxes(); $notice->addToInboxes();
$notice->saveUrls(); $notice->saveUrls();
$notice->query('COMMIT'); $notice->query('COMMIT');
Event::handle('EndNoticeSave', array($notice)); Event::handle('EndNoticeSave', array($notice));
} }
# Clear the cache for subscribed users, so they'll update at next request # Clear the cache for subscribed users, so they'll update at next request
# XXX: someone clever could prepend instead of clearing the cache # XXX: someone clever could prepend instead of clearing the cache
$notice->blowCaches(); $notice->blowCaches();
return $notice; return $notice;
} }
/** save all urls in the notice to the db /** save all urls in the notice to the db
* *
* follow redirects and save all available file information * follow redirects and save all available file information
* (mimetype, date, size, oembed, etc.) * (mimetype, date, size, oembed, etc.)
* *
* @return void * @return void
*/ */
function saveUrls() { function saveUrls() {
common_replace_urls_callback($this->content, array($this, 'saveUrl'), $this->id); common_replace_urls_callback($this->content, array($this, 'saveUrl'), $this->id);
} }
function saveUrl($data) { function saveUrl($data) {
list($url, $notice_id) = $data; list($url, $notice_id) = $data;
@ -328,9 +328,9 @@ class Notice extends Memcached_DataObject
$notice->profile_id = $profile_id; $notice->profile_id = $profile_id;
$notice->content = $content; $notice->content = $content;
if (common_config('db','type') == 'pgsql') if (common_config('db','type') == 'pgsql')
$notice->whereAdd('extract(epoch from now() - created) < ' . common_config('site', 'dupelimit')); $notice->whereAdd('extract(epoch from now() - created) < ' . common_config('site', 'dupelimit'));
else else
$notice->whereAdd('now() - created < ' . common_config('site', 'dupelimit')); $notice->whereAdd('now() - created < ' . common_config('site', 'dupelimit'));
$cnt = $notice->count(); $cnt = $notice->count();
return ($cnt == 0); return ($cnt == 0);
@ -692,7 +692,7 @@ class Notice extends Memcached_DataObject
# bet with our DB. # bet with our DB.
$new_notice = Notice::getStreamDirect($qry, 0, NOTICE_CACHE_WINDOW, $new_notice = Notice::getStreamDirect($qry, 0, NOTICE_CACHE_WINDOW,
$last_id, null, $order, null); $last_id, null, $order, null);
if ($new_notice) { if ($new_notice) {
$new_notices = array(); $new_notices = array();
@ -951,14 +951,14 @@ class Notice extends Memcached_DataObject
$user = new User(); $user = new User();
if(common_config('db','quote_identifiers')) if(common_config('db','quote_identifiers'))
$user_table = '"user"'; $user_table = '"user"';
else $user_table = 'user'; else $user_table = 'user';
$qry = $qry =
'SELECT id ' . 'SELECT id ' .
'FROM '. $user_table .' JOIN subscription '. 'FROM '. $user_table .' JOIN subscription '.
'ON '. $user_table .'.id = subscription.subscriber ' . 'ON '. $user_table .'.id = subscription.subscriber ' .
'WHERE subscription.subscribed = %d '; 'WHERE subscription.subscribed = %d ';
$user->query(sprintf($qry, $this->profile_id)); $user->query(sprintf($qry, $this->profile_id));
@ -1152,8 +1152,8 @@ class Notice extends Memcached_DataObject
if (!empty($user)) { if (!empty($user)) {
$atom_feed = common_local_url('api', $atom_feed = common_local_url('api',
array('apiaction' => 'statuses', array('apiaction' => 'statuses',
'method' => 'user_timeline', 'method' => 'user_timeline',
'argument' => $profile->nickname.'.atom')); 'argument' => $profile->nickname.'.atom'));
$xs->element('link', array('rel' => 'self', $xs->element('link', array('rel' => 'self',
'type' => 'application/atom+xml', 'type' => 'application/atom+xml',
'href' => $profile->profileurl)); 'href' => $profile->profileurl));
@ -1246,9 +1246,9 @@ class Notice extends Memcached_DataObject
$since_id != 0 || $max_id != 0 || (!is_null($since) && $since > 0) || $since_id != 0 || $max_id != 0 || (!is_null($since) && $since > 0) ||
is_null($limit) || is_null($limit) ||
($offset + $limit) > NOTICE_CACHE_WINDOW) { ($offset + $limit) > NOTICE_CACHE_WINDOW) {
return call_user_func_array($fn, array_merge($args, array($offset, $limit, $since_id, return call_user_func_array($fn, array_merge($args, array($offset, $limit, $since_id,
$max_id, $since))); $max_id, $since)));
} }
$idkey = common_cache_key($cachekey); $idkey = common_cache_key($cachekey);
@ -1267,7 +1267,7 @@ class Notice extends Memcached_DataObject
$window = explode(',', $laststr); $window = explode(',', $laststr);
$last_id = $window[0]; $last_id = $window[0];
$new_ids = call_user_func_array($fn, array_merge($args, array(0, NOTICE_CACHE_WINDOW, $new_ids = call_user_func_array($fn, array_merge($args, array(0, NOTICE_CACHE_WINDOW,
$last_id, 0, null))); $last_id, 0, null)));
$new_window = array_merge($new_ids, $window); $new_window = array_merge($new_ids, $window);
@ -1282,7 +1282,7 @@ class Notice extends Memcached_DataObject
} }
$window = call_user_func_array($fn, array_merge($args, array(0, NOTICE_CACHE_WINDOW, $window = call_user_func_array($fn, array_merge($args, array(0, NOTICE_CACHE_WINDOW,
0, 0, null))); 0, 0, null)));
$windowstr = implode(',', $window); $windowstr = implode(',', $window);
@ -1295,29 +1295,29 @@ class Notice extends Memcached_DataObject
} }
/** /**
* Determine which notice, if any, a new notice is in reply to. * Determine which notice, if any, a new notice is in reply to.
* *
* For conversation tracking, we try to see where this notice fits * For conversation tracking, we try to see where this notice fits
* in the tree. Rough algorithm is: * in the tree. Rough algorithm is:
* *
* if (reply_to is set and valid) { * if (reply_to is set and valid) {
* return reply_to; * return reply_to;
* } else if ((source not API or Web) and (content starts with "T NAME" or "@name ")) { * } else if ((source not API or Web) and (content starts with "T NAME" or "@name ")) {
* return ID of last notice by initial @name in content; * return ID of last notice by initial @name in content;
* } * }
* *
* Note that all @nickname instances will still be used to save "reply" records, * Note that all @nickname instances will still be used to save "reply" records,
* so the notice shows up in the mentioned users' "replies" tab. * so the notice shows up in the mentioned users' "replies" tab.
* *
* @param integer $reply_to ID passed in by Web or API * @param integer $reply_to ID passed in by Web or API
* @param integer $profile_id ID of author * @param integer $profile_id ID of author
* @param string $source Source tag, like 'web' or 'gwibber' * @param string $source Source tag, like 'web' or 'gwibber'
* @param string $content Final notice content * @param string $content Final notice content
* *
* @return integer ID of replied-to notice, or null for not a reply. * @return integer ID of replied-to notice, or null for not a reply.
*/ */
static function getReplyTo($reply_to, $profile_id, $source, $content) static function getReplyTo($reply_to, $profile_id, $source, $content)
{ {
static $lb = array('xmpp', 'mail', 'sms', 'omb'); static $lb = array('xmpp', 'mail', 'sms', 'omb');
@ -1343,10 +1343,10 @@ class Notice extends Memcached_DataObject
if (preg_match('/^T ([A-Z0-9]{1,64}) /', $content, $match) || if (preg_match('/^T ([A-Z0-9]{1,64}) /', $content, $match) ||
preg_match('/^@([a-z0-9]{1,64})\s+/', $content, $match)) { preg_match('/^@([a-z0-9]{1,64})\s+/', $content, $match)) {
$nickname = common_canonical_nickname($match[1]); $nickname = common_canonical_nickname($match[1]);
} else { } else {
return null; return null;
} }
// Figure out who that is. // Figure out who that is.