Notice::getReplyTo more specific now (getInlineReplyTo)

This commit is contained in:
Mikael Nordfeldth 2014-06-04 23:20:20 +02:00
parent de53e74f40
commit 90cc6b4d3b
2 changed files with 30 additions and 59 deletions

View File

@ -509,10 +509,19 @@ class Notice extends Managed_DataObject
$notice->repeat_of = $repeat_of; $notice->repeat_of = $repeat_of;
} else { } else {
$reply = self::getReplyTo($reply_to, $profile_id, $source, $final); $reply = null;
if (!empty($reply)) { // If $reply_to is specified, we check that it exists, and then
// return it if it does
if (!empty($reply_to)) {
$reply = Notice::getKV('id', $reply_to);
} elseif (in_array($source, array('xmpp', 'mail', 'sms'))) {
// If the source lacks capability of sending the "reply_to"
// metadata, let's try to find an inline replyto-reference.
$reply = self::getInlineReplyTo($profile, $final);
}
if ($reply instanceof Notice) {
if (!$reply->inScope($profile)) { if (!$reply->inScope($profile)) {
// TRANS: Client error displayed when trying to reply to a notice a the target has no access to. // TRANS: Client error displayed when trying to reply to a notice a the target has no access to.
// TRANS: %1$s is a user nickname, %2$d is a notice ID (number). // TRANS: %1$s is a user nickname, %2$d is a notice ID (number).
@ -523,8 +532,8 @@ class Notice extends Managed_DataObject
$notice->reply_to = $reply->id; $notice->reply_to = $reply->id;
$notice->conversation = $reply->conversation; $notice->conversation = $reply->conversation;
// If the original is private to a group, and notice has no group specified, // If the original is private to a group, and notice has
// make it to the same group(s) // no group specified, make it to the same group(s)
if (empty($groups) && ($reply->scope & Notice::GROUP_SCOPE)) { if (empty($groups) && ($reply->scope & Notice::GROUP_SCOPE)) {
$groups = array(); $groups = array();
@ -1734,76 +1743,38 @@ class Notice extends Managed_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. Beware that this may very well give false positives
* and add replies to wrong threads (if there have been newer posts
* by the same user as we're replying to).
* *
* if (reply_to is set and valid) { * @param Profile $sender Author profile
* return reply_to;
* } 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;
* }
*
* Note that all @nickname instances will still be used to save "reply" records,
* so the notice shows up in the mentioned users' "replies" tab.
*
* @param integer $reply_to ID passed in by Web or API
* @param integer $profile_id ID of author
* @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 getInlineReplyTo(Profile $sender, $content)
{ {
static $lb = array('xmpp', 'mail', 'sms', 'omb');
// If $reply_to is specified, we check that it exists, and then
// return it if it does
if (!empty($reply_to)) {
$reply_notice = Notice::getKV('id', $reply_to);
if ($reply_notice instanceof Notice) {
return $reply_notice;
}
}
// If it's not a "low bandwidth" source (one where you can't set
// a reply_to argument), we return. This is mostly web and API
// clients.
if (!in_array($source, $lb)) {
return null;
}
// Is there an initial @ or T? // Is there an initial @ or T?
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.
$sender = Profile::getKV('id', $profile_id);
if (!$sender instanceof Profile) {
return null;
}
$recipient = common_relative_profile($sender, $nickname, common_sql_now()); $recipient = common_relative_profile($sender, $nickname, common_sql_now());
if (!$recipient instanceof Profile) { if ($recipient instanceof Profile) {
return null;
}
// Get their last notice // Get their last notice
$last = $recipient->getCurrentNotice(); $last = $recipient->getCurrentNotice();
if ($last instanceof Notice) { if ($last instanceof Notice) {
return $last; return $last;
} }
// Maybe in the future we want to handle something else below
// so don't return getCurrentNotice() immediately.
}
return null; return null;
} }

View File

@ -226,9 +226,9 @@ class Profile extends Managed_DataObject
return $notice->_items[0]; return $notice->_items[0];
} }
return $notice; return $notice;
} else {
return null;
} }
return null;
} }
function getTaggedNotices($tag, $offset=0, $limit=NOTICES_PER_PAGE, $since_id=0, $max_id=0) function getTaggedNotices($tag, $offset=0, $limit=NOTICES_PER_PAGE, $since_id=0, $max_id=0)