$notice->saveKnownGroups($groups);
- if (isset($peopletags)) {
- $notice->saveProfileTags($peopletags);
- } else {
- $notice->saveProfileTags();
- }
-
if (isset($urls)) {
$notice->saveKnownUrls($urls);
} else {
if (!empty($profile)) {
$profile->blowNoticeCount();
}
+
+ $ptags = $this->getProfileTags();
+ foreach ($ptags as $ptag) {
+ $ptag->blowNoticeStreamCache();
+ }
}
/**
// In case we're the first, will need to calc a new root.
self::blow('notice:conversation_root:%d', $this->conversation);
}
+
+ $ptags = $this->getProfileTags();
+ foreach ($ptags as $ptag) {
+ $ptag->blowNoticeStreamCache(true);
+ }
}
/** save all urls in the notice to the db
*
* @return Notice or null
*/
- function conversationRoot()
+ function conversationRoot($profile=-1)
{
- if (!empty($this->conversation)) {
- $c = self::memcache();
+ // XXX: can this happen?
- $key = Cache::key('notice:conversation_root:' . $this->conversation);
- $notice = $c->get($key);
- if ($notice) {
- return $notice;
- }
+ if (empty($this->conversation)) {
+ return null;
+ }
- $notice = new Notice();
- $notice->conversation = $this->conversation;
- $notice->orderBy('CREATED');
- $notice->limit(1);
- $notice->find(true);
+ // Get the current profile if not specified
- if ($notice->N) {
- $c->set($key, $notice);
- return $notice;
- }
+ if (is_int($profile) && $profile == -1) {
+ $profile = Profile::current();
}
- return null;
+
+ // If this notice is out of scope, no root for you!
+
+ if (!$this->inScope($profile)) {
+ return null;
+ }
+
+ // If this isn't a reply to anything, then it's its own
+ // root.
+
+ if (empty($this->reply_to)) {
+ return $this;
+ }
+
+ if (is_null($profile)) {
+ $keypart = sprintf('notice:conversation_root:%d:null', $this->id);
+ } else {
+ $keypart = sprintf('notice:conversation_root:%d:%d',
+ $this->id,
+ $profile->id);
+ }
+
+ $root = self::cacheGet($keypart);
+
+ if ($root !== false && $root->inScope($profile)) {
+ return $root;
+ } else {
+ $last = $this;
+
+ do {
+ $parent = $last->getOriginal();
+ if (!empty($parent) && $parent->inScope($profile)) {
+ $last = $parent;
+ continue;
+ } else {
+ $root = $last;
+ break;
+ }
+ } while (!empty($parent));
+
+ self::cacheSet($keypart, $root);
+ }
+
+ return $root;
}
+
/**
* Pull up a full list of local recipients who will be getting
* this notice in their inbox. Results will be cached, so don't
function getProfileTags()
{
- // Don't save ptags for repeats, for now.
-
- if (!empty($this->repeat_of)) {
- return array();
- }
-
- // XXX: cache me
-
- $ptags = array();
-
- $ptagi = new Profile_tag_inbox();
-
- $ptagi->selectAdd();
- $ptagi->selectAdd('profile_tag_id');
-
- $ptagi->notice_id = $this->id;
+ $profile = $this->getProfile();
+ $list = $profile->getOtherTags($profile);
+ $ptags = array();
- if ($ptagi->find()) {
- while ($ptagi->fetch()) {
- $profile_list = Profile_list::staticGet('id', $ptagi->profile_tag_id);
- if ($profile_list) {
- $ptags[] = $profile_list;
- }
- }
+ while($list->fetch()) {
+ $ptags[] = clone($list);
}
- $ptagi->free();
-
return $ptags;
}
return true;
}
- /**
- * record targets into profile_tag_inbox.
- * @return array of Profile_list objects
- */
- function saveProfileTags($known=array())
- {
- // Don't save ptags for repeats, for now
-
- if (!empty($this->repeat_of)) {
- return array();
- }
-
- if (is_array($known)) {
- $ptags = $known;
- } else {
- $ptags = array();
- }
-
- $ptag = new Profile_tag();
- $ptag->tagged = $this->profile_id;
-
- if($ptag->find()) {
- while($ptag->fetch()) {
- $plist = Profile_list::getByTaggerAndTag($ptag->tagger, $ptag->tag);
- if (!empty($plist)) {
- $ptags[] = clone($plist);
- }
- }
- }
-
- foreach ($ptags as $target) {
- $this->addToProfileTagInbox($target);
- }
-
- return $ptags;
- }
-
- function addToProfileTagInbox($plist)
- {
- $ptagi = Profile_tag_inbox::pkeyGet(array('profile_tag_id' => $plist->id,
- 'notice_id' => $this->id));
-
- if (empty($ptagi)) {
-
- $ptagi = new Profile_tag_inbox();
-
- $ptagi->query('BEGIN');
- $ptagi->profile_tag_id = $plist->id;
- $ptagi->notice_id = $this->id;
- $ptagi->created = $this->created;
-
- $result = $ptagi->insert();
- if (!$result) {
- common_log_db_error($ptagi, 'INSERT', __FILE__);
- // TRANS: Server exception thrown when saving profile_tag inbox fails.
- throw new ServerException(_('Problem saving profile_tag inbox.'));
- }
-
- $ptagi->query('COMMIT');
-
- self::blow('profile_tag:notice_ids:%d', $ptagi->profile_tag_id);
- }
-
- return true;
- }
-
/**
* Save reply records indicating that this notice needs to be
* delivered to the local users with the given URIs.
return $ids;
}
+ /**
+ * Pull the complete list of @-reply targets for this notice.
+ *
+ * @return array of Profiles
+ */
+ function getReplyProfiles()
+ {
+ $ids = $this->getReplies();
+ $profiles = array();
+
+ foreach ($ids as $id) {
+ $profile = Profile::staticGet('id', $id);
+ if (!empty($profile)) {
+ $profiles[] = $profile;
+ }
+ }
+
+ return $profiles;
+ }
+
/**
* Send e-mail notifications to local @-reply targets.
*
return $groups;
}
+
+ protected $_original = -1;
+
+ function getOriginal()
+ {
+ if (is_int($this->_original) && $this->_original == -1) {
+ if (empty($this->reply_to)) {
+ $this->_original = null;
+ } else {
+ $this->_original = Notice::staticGet('id', $this->reply_to);
+ }
+ }
+ return $this->_original;
+ }
+
+ /**
+ * Magic function called at serialize() time.
+ *
+ * We use this to drop a couple process-specific references
+ * from DB_DataObject which can cause trouble in future
+ * processes.
+ *
+ * @return array of variable names to include in serialization.
+ */
+
+ function __sleep()
+ {
+ $vars = parent::__sleep();
+ $skip = array('_original', '_profile');
+ return array_diff($vars, $skip);
+ }
+
}