X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;f=classes%2FNotice.php;h=71d4d4ff23bff6f225a9eec6d4e2c507b840f63a;hb=8b0f45d0a715fd25beb0aef9d42de3b91c5cd1ca;hp=73d27c815410f51b2b58e2342fa60e407ed2a4ff;hpb=fc21e5c76bf6fd6fa8947360b5e6e4b3f26d43de;p=quix0rs-gnu-social.git diff --git a/classes/Notice.php b/classes/Notice.php index 73d27c8154..71d4d4ff23 100644 --- a/classes/Notice.php +++ b/classes/Notice.php @@ -208,7 +208,7 @@ class Notice extends Memcached_DataObject if (!$id) { // TRANS: Server exception. %s are the error details. - throw new ServerException(sprintf(_('Database error inserting hashtag: %s'), + throw new ServerException(sprintf(_('Database error inserting hashtag: %s.'), $last_error->message)); return; } @@ -545,12 +545,6 @@ class Notice extends Memcached_DataObject $notice->saveKnownGroups($groups); - if (isset($peopletags)) { - $notice->saveProfileTags($peopletags); - } else { - $notice->saveProfileTags(); - } - if (isset($urls)) { $notice->saveKnownUrls($urls); } else { @@ -596,6 +590,11 @@ class Notice extends Memcached_DataObject if (!empty($profile)) { $profile->blowNoticeCount(); } + + $ptags = $this->getProfileTags(); + foreach ($ptags as $ptag) { + $ptag->blowNoticeStreamCache(); + } } /** @@ -618,6 +617,11 @@ class Notice extends Memcached_DataObject // 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 @@ -802,30 +806,65 @@ class Notice extends Memcached_DataObject * * @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 @@ -995,34 +1034,14 @@ class Notice extends Memcached_DataObject 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; } @@ -1138,69 +1157,6 @@ class Notice extends Memcached_DataObject 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); - $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__); - 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. @@ -1353,6 +1309,26 @@ class Notice extends Memcached_DataObject 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. * @@ -2289,7 +2265,7 @@ class Notice extends Memcached_DataObject /** * Check that the given profile is allowed to read, respond to, or otherwise * act on this notice. - * + * * The $scope member is a bitmask of scopes, representing a logical AND of the * scope requirement. So, 0x03 (Notice::ADDRESSEE_SCOPE | Notice::SITE_SCOPE) means * "only visible to people who are mentioned in the notice AND are users on this site." @@ -2302,7 +2278,11 @@ class Notice extends Memcached_DataObject */ function inScope($profile) { - $keypart = sprintf('notice:in-scope-for:%d:%d', $this->id, $profile->id); + if (is_null($profile)) { + $keypart = sprintf('notice:in-scope-for:%d:null', $this->id); + } else { + $keypart = sprintf('notice:in-scope-for:%d:%d', $this->id, $profile->id); + } $result = self::cacheGet($keypart); @@ -2413,4 +2393,36 @@ class Notice extends Memcached_DataObject 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); + } + }