X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;f=classes%2FNotice.php;h=e46ed227a179cbb4cd4f9119a2b2bcb4a7e13ffd;hb=132be9950662ce0d5a1e859a766232cd7fdcb0e1;hp=4812dff91a29b5caf70fb9e2262154fcaef43889;hpb=34a6624452e8b7f60b40181441c6ea2c8158379a;p=quix0rs-gnu-social.git diff --git a/classes/Notice.php b/classes/Notice.php index 4812dff91a..e46ed227a1 100644 --- a/classes/Notice.php +++ b/classes/Notice.php @@ -29,18 +29,16 @@ * @author Robin Millette * @author Sarven Capadisli * @author Tom Adams + * @author Mikael Nordfeldth * @copyright 2009 Free Software Foundation, Inc http://www.fsf.org * @license GNU Affero General Public License http://www.gnu.org/licenses/ */ -if (!defined('STATUSNET') && !defined('LACONICA')) { - exit(1); -} +if (!defined('GNUSOCIAL')) { exit(1); } /** * Table Definition for notice */ -require_once INSTALLDIR.'/classes/Memcached_DataObject.php'; /* We keep 200 notices, the max number of notices available per API request, * in the memcached cache. */ @@ -144,28 +142,24 @@ class Notice extends Managed_DataObject const FOLLOWER_SCOPE = 8; protected $_profile = -1; - - function getProfile() + + public function getProfile() { - if (is_int($this->_profile) && $this->_profile == -1) { + if ($this->_profile === -1) { $this->_setProfile(Profile::getKV('id', $this->profile_id)); - - if (empty($this->_profile)) { - // TRANS: Server exception thrown when a user profile for a notice cannot be found. - // TRANS: %1$d is a profile ID (number), %2$d is a notice ID (number). - throw new ServerException(sprintf(_('No such profile (%1$d) for notice (%2$d).'), $this->profile_id, $this->id)); - } } - return $this->_profile; } - function _setProfile($profile) + public function _setProfile(Profile $profile=null) { + if (!$profile instanceof Profile) { + throw new NoProfileException($this->profile_id); + } $this->_profile = $profile; } - function delete() + function delete($useWhere=false) { // For auditing purposes, save a record that the notice // was deleted. @@ -174,11 +168,11 @@ class Notice extends Managed_DataObject // insert fails. $deleted = Deleted_notice::getKV('id', $this->id); - if (!$deleted) { + if (!$deleted instanceof Deleted_notice) { $deleted = Deleted_notice::getKV('uri', $this->uri); } - if (!$deleted) { + if (!$deleted instanceof Deleted_notice) { $deleted = new Deleted_notice(); $deleted->id = $this->id; @@ -200,12 +194,12 @@ class Notice extends Managed_DataObject $this->clearTags(); $this->clearGroupInboxes(); $this->clearFiles(); + $this->clearAttentions(); - // NOTE: we don't clear inboxes // NOTE: we don't clear queue items } - $result = parent::delete(); + $result = parent::delete($useWhere); $this->blowOnDelete(); return $result; @@ -216,6 +210,40 @@ class Notice extends Managed_DataObject return $this->uri; } + public function getUrl() + { + // The risk is we start having empty urls and non-http uris... + // and we can't really handle any other protocol right now. + switch (true) { + case common_valid_http_url($this->url): // should we allow non-http/https URLs? + return $this->url; + case $this->isLocal(): + // let's generate a valid link to our locally available notice on demand + return common_local_url('shownotice', array('notice' => $this->id), null, null, false); + case common_valid_http_url($this->uri): + return $this->uri; + default: + common_debug('No URL available for notice: id='.$this->id); + throw new InvalidUrlException($this->url); + } + } + + public function get_object_type($canonical=false) { + return $canonical + ? ActivityObject::canonicalType($this->object_type) + : $this->object_type; + } + + public static function getByUri($uri) + { + $notice = new Notice(); + $notice->uri = $uri; + if (!$notice->find(true)) { + throw new NoResultException($notice); + } + return $notice; + } + /** * Extract #hashtags from this notice's content and save them to the database. */ @@ -298,7 +326,7 @@ class Notice extends Managed_DataObject * int 'location_ns' geoname namespace to interpret location_id * int 'reply_to'; notice ID this is a reply to * int 'repeat_of'; notice ID this is a repeat of - * string 'uri' unique ID for notice; defaults to local notice URL + * string 'uri' unique ID for notice; a unique tag uri (can be url or anything too) * string 'url' permalink to notice; defaults to local notice URL * string 'rendered' rendered HTML version of content * array 'replies' list of profile URIs for reply delivery in @@ -341,8 +369,13 @@ class Notice extends Managed_DataObject } $profile = Profile::getKV('id', $profile_id); + if (!$profile instanceof Profile) { + // TRANS: Client exception thrown when trying to save a notice for an unknown user. + throw new ClientException(_('Problem saving notice. Unknown user.')); + } + $user = User::getKV('id', $profile_id); - if ($user) { + if ($user instanceof User) { // Use the local user's shortening preferences, if applicable. $final = $user->shortenLinks($content); } else { @@ -354,11 +387,6 @@ class Notice extends Managed_DataObject throw new ClientException(_('Problem saving notice. Too long.')); } - if (empty($profile)) { - // TRANS: Client exception thrown when trying to save a notice for an unknown user. - throw new ClientException(_('Problem saving notice. Unknown user.')); - } - if (common_config('throttle', 'enabled') && !Notice::checkEditThrottle($profile_id)) { common_log(LOG_WARNING, 'Excessive posting by profile #' . $profile_id . '; throttled.'); // TRANS: Client exception thrown when a user tries to post too many notices in a given time frame. @@ -400,6 +428,16 @@ class Notice extends Managed_DataObject $notice->created = common_sql_now(); } + if (!$notice->isLocal()) { + // Only do these checks for non-local notices. Local notices will generate these values later. + if (!common_valid_http_url($url)) { + common_debug('Bad notice URL: ['.$url.'], URI: ['.$uri.']. Cannot link back to original! This is normal for shared notices etc.'); + } + if (empty($uri)) { + throw new ServerException('No URI for remote notice. Cannot accept that.'); + } + } + $notice->content = $final; $notice->source = $source; @@ -407,9 +445,8 @@ class Notice extends Managed_DataObject $notice->url = $url; // Get the groups here so we can figure out replies and such - if (!isset($groups)) { - $groups = self::groupsFromText($notice->content, $profile); + $groups = User_group::idsFromText($notice->content, $profile); } $reply = null; @@ -543,7 +580,7 @@ class Notice extends Managed_DataObject foreach ($groups as $groupId) { $group = User_group::getKV('id', $groupId); - if (!empty($group)) { + if ($group instanceof User_group) { if ($group->force_scope) { $notice->scope |= Notice::GROUP_SCOPE; break; @@ -569,8 +606,13 @@ class Notice extends Managed_DataObject $changed = false; - if (empty($uri)) { - $notice->uri = common_notice_uri($notice); + // We can only get here if it's a local notice, since remote notices + // should've bailed out earlier due to lacking a URI. + if (empty($notice->uri)) { + $notice->uri = sprintf('%s%s=%d:%s=%s', + TagURI::mint(), + 'noticeId', $notice->id, + 'objectType', $notice->get_object_type(true)); $changed = true; } @@ -578,13 +620,13 @@ class Notice extends Managed_DataObject // the beginning of a new conversation. if (empty($notice->conversation)) { - $conv = Conversation::create(); + $conv = Conversation::create($notice); $notice->conversation = $conv->id; $changed = true; } if ($changed) { - if (!$notice->update($orig)) { + if ($notice->update($orig) === false) { common_log_db_error($notice, 'UPDATE', __FILE__); // TRANS: Server exception thrown when a notice cannot be updated. throw new ServerException(_('Problem saving notice.')); @@ -651,16 +693,16 @@ class Notice extends Managed_DataObject $original = Notice::getKV('id', $this->repeat_of); - if (!empty($original)) { + if ($original instanceof Notice) { $originalUser = User::getKV('id', $original->profile_id); - if (!empty($originalUser)) { + if ($originalUser instanceof User) { $this->blowStream('user:repeats_of_me:%d', $originalUser->id); } } $profile = Profile::getKV($this->profile_id); - if (!empty($profile)) { + if ($profile instanceof Profile) { $profile->blowNoticeCount(); } @@ -726,7 +768,7 @@ class Notice extends Managed_DataObject $window = explode(',', $lastStr); $lastID = $window[0]; $lastNotice = Notice::getKV('id', $lastID); - if (empty($lastNotice) // just weird + if (!$lastNotice instanceof Notice // just weird || strtotime($lastNotice->created) >= strtotime($this->created)) { $c->delete($lastKey); } @@ -773,7 +815,7 @@ class Notice extends Managed_DataObject static function checkDupes($profile_id, $content) { $profile = Profile::getKV($profile_id); - if (empty($profile)) { + if (!$profile instanceof Profile) { return false; } $notice = $profile->getNotices(0, CachingNoticeStream::CACHE_WINDOW); @@ -801,7 +843,7 @@ class Notice extends Managed_DataObject static function checkEditThrottle($profile_id) { $profile = Profile::getKV($profile_id); - if (empty($profile)) { + if (!$profile instanceof Profile) { return false; } // Get the Nth notice @@ -970,30 +1012,23 @@ class Notice extends Managed_DataObject } } - if (is_null($groups)) { - $groups = $this->getGroups(); - } - if (is_null($recipients)) { $recipients = $this->getReplies(); } - $users = $this->getSubscribedUsers(); - $ptags = $this->getProfileTags(); - - // FIXME: kind of ignoring 'transitional'... - // we'll probably stop supporting inboxless mode - // in 0.9.x - $ni = array(); // Give plugins a chance to add folks in at start... if (Event::handle('StartNoticeWhoGets', array($this, &$ni))) { + $users = $this->getSubscribedUsers(); foreach ($users as $id) { $ni[$id] = NOTICE_INBOX_SOURCE_SUB; } + if (is_null($groups)) { + $groups = $this->getGroups(); + } foreach ($groups as $group) { $users = $group->getUserMembers(); foreach ($users as $id) { @@ -1003,12 +1038,10 @@ class Notice extends Managed_DataObject } } - foreach ($ptags as $ptag) { - $users = $ptag->getUserSubscribers(); - foreach ($users as $id) { - if (!array_key_exists($id, $ni)) { - $ni[$id] = NOTICE_INBOX_SOURCE_PROFILE_TAG; - } + $ptAtts = $this->getAttentionsFromProfileTags(); + foreach ($ptAtts as $key=>$val) { + if (!array_key_exists($key, $ni)) { + $ni[$key] = $val; } } @@ -1024,7 +1057,7 @@ class Notice extends Managed_DataObject if ($this->repeat_of) { // Check blocks against the original notice's poster as well. $original = Notice::getKV('id', $this->repeat_of); - if ($original) { + if ($original instanceof Notice) { $originalProfile = $original->getProfile(); } } @@ -1032,7 +1065,7 @@ class Notice extends Managed_DataObject foreach ($ni as $id => $source) { try { $user = User::getKV('id', $id); - if (empty($user) || + if (!$user instanceof User || $user->hasBlocked($profile) || ($originalProfile && $user->hasBlocked($originalProfile))) { unset($ni[$id]); @@ -1055,43 +1088,6 @@ class Notice extends Managed_DataObject return $ni; } - /** - * Adds this notice to the inboxes of each local user who should receive - * it, based on author subscriptions, group memberships, and @-replies. - * - * Warning: running a second time currently will make items appear - * multiple times in users' inboxes. - * - * @fixme make more robust against errors - * @fixme break up massive deliveries to smaller background tasks - * - * @param array $groups optional list of Group objects; - * if left empty, will be loaded from group_inbox records - * @param array $recipient optional list of reply profile ids - * if left empty, will be loaded from reply records - */ - function addToInboxes(array $groups=null, array $recipients=null) - { - $ni = $this->whoGets($groups, $recipients); - - $ids = array_keys($ni); - - // We remove the author (if they're a local user), - // since we'll have already done this in distribute() - - $i = array_search($this->profile_id, $ids); - - if ($i !== false) { - unset($ids[$i]); - } - - // Bulk insert - - Inbox::bulkInsert($this->id, $ids); - - return; - } - function getSubscribedUsers() { $user = new User(); @@ -1132,6 +1128,19 @@ class Notice extends Managed_DataObject return $ptags; } + public function getAttentionsFromProfileTags() + { + $ni = array(); + $ptags = $this->getProfileTags(); + foreach ($ptags as $ptag) { + $users = $ptag->getUserSubscribers(); + foreach ($users as $id) { + $ni[$id] = NOTICE_INBOX_SOURCE_PROFILE_TAG; + } + } + return $ni; + } + /** * Record this notice to the given group inboxes for delivery. * Overrides the regular parsing of !group markup. @@ -1151,7 +1160,7 @@ class Notice extends Managed_DataObject $groups = array(); foreach (array_unique($group_ids) as $id) { $group = User_group::getKV('id', $id); - if ($group) { + if ($group instanceof User_group) { common_log(LOG_ERR, "Local delivery to group id $id, $group->nickname"); $result = $this->addToGroupInbox($group); if (!$result) { @@ -1178,53 +1187,12 @@ class Notice extends Managed_DataObject return $groups; } - /** - * Parse !group delivery and record targets into group_inbox. - * @return array of Group objects - */ - function saveGroups() - { - // Don't save groups for repeats - - if (!empty($this->repeat_of)) { - return array(); - } - - $profile = $this->getProfile(); - - $groups = self::groupsFromText($this->content, $profile); - - /* Add them to the database */ - - foreach ($groups as $group) { - /* XXX: remote groups. */ - - if (empty($group)) { - continue; - } - - - if ($profile->isMember($group)) { - - $result = $this->addToGroupInbox($group); - - if (!$result) { - common_log_db_error($gi, 'INSERT', __FILE__); - } - - $groups[] = clone($group); - } - } - - return $groups; - } - - function addToGroupInbox($group) + function addToGroupInbox(User_group $group) { $gi = Group_inbox::pkeyGet(array('group_id' => $group->id, 'notice_id' => $this->id)); - if (empty($gi)) { + if (!$gi instanceof Group_inbox) { $gi = new Group_inbox(); @@ -1270,7 +1238,7 @@ class Notice extends Managed_DataObject $profile = Profile::fromURI($uri); - if (empty($profile)) { + if (!$profile instanceof Profile) { common_log(LOG_WARNING, "Unable to determine profile for URI '$uri'"); continue; } @@ -1311,7 +1279,8 @@ class Notice extends Managed_DataObject // If it's a reply, save for the replied-to author try { - $author = $this->getParent()->getProfile(); + $parent = $this->getParent(); + $author = $parent->getProfile(); if ($author instanceof Profile) { $this->saveReply($author->id); $replied[$author->id] = 1; @@ -1342,7 +1311,7 @@ class Notice extends Managed_DataObject // Don't save replies from blocked profile to local user $mentioned_user = User::getKV('id', $mentioned->id); - if (!empty($mentioned_user) && $mentioned_user->hasBlocked($sender)) { + if ($mentioned_user instanceof User && $mentioned_user->hasBlocked($sender)) { continue; } @@ -1433,7 +1402,7 @@ class Notice extends Managed_DataObject foreach ($recipientIds as $recipientId) { $user = User::getKV('id', $recipientId); - if (!empty($user)) { + if ($user instanceof User) { mail_notify_attn($user, $this); } } @@ -1441,7 +1410,7 @@ class Notice extends Managed_DataObject /** * Pull list of groups this notice needs to be delivered to, - * as previously recorded by saveGroups() or saveKnownGroups(). + * as previously recorded by saveKnownGroups(). * * @return array of Group objects */ @@ -1494,15 +1463,16 @@ class Notice extends Managed_DataObject { $act = self::cacheGet(Cache::codeKey('notice:as-activity:'.$this->id)); - if (!empty($act)) { + if ($act instanceof Activity) { return $act; } $act = new Activity(); if (Event::handle('StartNoticeAsActivity', array($this, &$act))) { - $act->id = TagURI::mint("post:".$this->id); + $act->id = $this->uri; $act->time = strtotime($this->created); + $act->link = $this->bestUrl(); $act->content = common_xml_safe_str($this->rendered); $profile = $this->getProfile(); @@ -1514,7 +1484,7 @@ class Notice extends Managed_DataObject if ($this->repeat_of) { $repeated = Notice::getKV('id', $this->repeat_of); - if (!empty($repeated)) { + if ($repeated instanceof Notice) { $act->objects[] = $repeated->asActivity($cur); } } else { @@ -1548,12 +1518,12 @@ class Notice extends Managed_DataObject $ctx = new ActivityContext(); - if (!empty($this->reply_to)) { - $reply = Notice::getKV('id', $this->reply_to); - if (!empty($reply)) { - $ctx->replyToID = $reply->uri; - $ctx->replyToUrl = $reply->bestUrl(); - } + try { + $reply = $this->getParent(); + $ctx->replyToID = $reply->uri; + $ctx->replyToUrl = $reply->bestUrl(); + } catch (Exception $e) { + // This is not a reply to something } $ctx->location = $this->getLocation(); @@ -1562,7 +1532,7 @@ class Notice extends Managed_DataObject if (!empty($this->conversation)) { $conv = Conversation::getKV('id', $this->conversation); - if (!empty($conv)) { + if ($conv instanceof Conversation) { $ctx->conversation = $conv->uri; } } @@ -1571,48 +1541,32 @@ class Notice extends Managed_DataObject foreach ($reply_ids as $id) { $rprofile = Profile::getKV('id', $id); - if (!empty($rprofile)) { - $ctx->attention[] = $rprofile->getUri(); - $ctx->attentionType[$rprofile->getUri()] = ActivityObject::PERSON; + if ($rprofile instanceof Profile) { + $ctx->attention[$rprofile->getUri()] = ActivityObject::PERSON; } } $groups = $this->getGroups(); foreach ($groups as $group) { - $ctx->attention[] = $group->getUri(); - $ctx->attentionType[$group->getUri()] = ActivityObject::GROUP; + $ctx->attention[$group->getUri()] = ActivityObject::GROUP; } switch ($this->scope) { case Notice::PUBLIC_SCOPE: - $ctx->attention[] = "http://activityschema.org/collection/public"; - $ctx->attentionType["http://activityschema.org/collection/public"] = ActivityObject::COLLECTION; + $ctx->attention[ActivityContext::ATTN_PUBLIC] = ActivityObject::COLLECTION; break; case Notice::FOLLOWER_SCOPE: $surl = common_local_url("subscribers", array('nickname' => $profile->nickname)); - $ctx->attention[] = $surl; - $ctx->attentionType[$surl] = ActivityObject::COLLECTION; + $ctx->attention[$surl] = ActivityObject::COLLECTION; break; } - // XXX: deprecated; use ActivityVerb::SHARE instead - - $repeat = null; - - if (!empty($this->repeat_of)) { - $repeat = Notice::getKV('id', $this->repeat_of); - if (!empty($repeat)) { - $ctx->forwardID = $repeat->uri; - $ctx->forwardUrl = $repeat->bestUrl(); - } - } - $act->context = $ctx; $source = $this->getSource(); - if ($source) { + if ($source instanceof Notice_source) { $act->generator = ActivityObject::fromNoticeSource($source); } @@ -1639,13 +1593,13 @@ class Notice extends Managed_DataObject $notice = $profile->getCurrentNotice(); - if (!empty($notice)) { + if ($notice instanceof Notice) { $act->source->updated = self::utcDate($notice->created); } $user = User::getKV('id', $profile->id); - if (!empty($user)) { + if ($user instanceof User) { $act->source->links['license'] = common_config('license', 'url'); } } @@ -1698,7 +1652,7 @@ class Notice extends Managed_DataObject $ns = $this->getSource(); - if (!empty($ns)) { + if ($ns instanceof Notice_source) { $noticeInfoAttr['source'] = $ns->code; if (!empty($ns->url)) { $noticeInfoAttr['source_link'] = $ns->url; @@ -1788,7 +1742,7 @@ class Notice extends Managed_DataObject if (!empty($reply_to)) { $reply_notice = Notice::getKV('id', $reply_to); - if (!empty($reply_notice)) { + if ($reply_notice instanceof Notice) { return $reply_notice; } } @@ -1813,13 +1767,13 @@ class Notice extends Managed_DataObject // Figure out who that is. $sender = Profile::getKV('id', $profile_id); - if (empty($sender)) { + if (!$sender instanceof Profile) { return null; } $recipient = common_relative_profile($sender, $nickname, common_sql_now()); - if (empty($recipient)) { + if (!$recipient instanceof Profile) { return null; } @@ -1827,7 +1781,7 @@ class Notice extends Managed_DataObject $last = $recipient->getCurrentNotice(); - if (!empty($last)) { + if ($last instanceof Notice) { return $last; } @@ -1963,7 +1917,7 @@ class Notice extends Managed_DataObject $location = Location::fromId($location_id, $location_ns); - if (!empty($location)) { + if ($location instanceof Location) { $options['lat'] = $location->lat; $options['lon'] = $location->lon; } @@ -1974,7 +1928,7 @@ class Notice extends Managed_DataObject $location = Location::fromLatLon($lat, $lon); - if (!empty($location)) { + if ($location instanceof Location) { $options['location_id'] = $location->location_id; $options['location_ns'] = $location->location_ns; } @@ -1993,6 +1947,20 @@ class Notice extends Managed_DataObject return $options; } + function clearAttentions() + { + $att = new Attention(); + $att->notice_id = $this->getID(); + + if ($att->find()) { + while ($att->fetch()) { + // Can't do delete() on the object directly since it won't remove all of it + $other = clone($att); + $other->delete(); + } + } + } + function clearReplies() { $replyNotice = new Notice(); @@ -2112,33 +2080,23 @@ class Notice extends Managed_DataObject // have to wait Event::handle('StartNoticeDistribute', array($this)); - $user = User::getKV('id', $this->profile_id); - if (!empty($user)) { - Inbox::insertNotice($user->id, $this->id); - } - - if (common_config('queue', 'inboxes')) { - // If there's a failure, we want to _force_ - // distribution at this point. + // If there's a failure, we want to _force_ + // distribution at this point. + try { + $qm = QueueManager::get(); + $qm->enqueue($this, 'distrib'); + } catch (Exception $e) { + // If the exception isn't transient, this + // may throw more exceptions as DQH does + // its own enqueueing. So, we ignore them! try { - $qm = QueueManager::get(); - $qm->enqueue($this, 'distrib'); + $handler = new DistribQueueHandler(); + $handler->handle($this); } catch (Exception $e) { - // If the exception isn't transient, this - // may throw more exceptions as DQH does - // its own enqueueing. So, we ignore them! - try { - $handler = new DistribQueueHandler(); - $handler->handle($this); - } catch (Exception $e) { - common_log(LOG_ERR, "emergency redistribution resulted in " . $e->getMessage()); - } - // Re-throw so somebody smarter can handle it. - throw $e; + common_log(LOG_ERR, "emergency redistribution resulted in " . $e->getMessage()); } - } else { - $handler = new DistribQueueHandler(); - $handler->handle($this); + // Re-throw so somebody smarter can handle it. + throw $e; } } @@ -2146,7 +2104,7 @@ class Notice extends Managed_DataObject { $result = parent::insert(); - if ($result) { + if ($result !== false) { // Profile::hasRepeated() abuses pkeyGet(), so we // have to clear manually if (!empty($this->repeat_of)) { @@ -2436,10 +2394,10 @@ class Notice extends Managed_DataObject if ($scope & Notice::ADDRESSEE_SCOPE) { - $repl = Reply::pkeyGet(array('notice_id' => $this->id, + $reply = Reply::pkeyGet(array('notice_id' => $this->id, 'profile_id' => $profile->id)); - if (empty($repl)) { + if (!$reply instanceof Reply) { return false; } } @@ -2502,7 +2460,7 @@ class Notice extends Managed_DataObject } if ($author->hasRole(Profile_role::SILENCED)) { - if (empty($profile) || (($profile->id !== $author->id) && (!$profile->hasRight(Right::REVIEWSPAM)))) { + if (!$profile instanceof Profile || (($profile->id !== $author->id) && (!$profile->hasRight(Right::REVIEWSPAM)))) { return true; } } @@ -2511,44 +2469,15 @@ class Notice extends Managed_DataObject return false; } - static function groupsFromText($text, $profile) - { - $groups = array(); - - /* extract all !group */ - $count = preg_match_all('/(?:^|\s)!(' . Nickname::DISPLAY_FMT . ')/', - strtolower($text), - $match); - - if (!$count) { - return $groups; - } - - foreach (array_unique($match[1]) as $nickname) { - $group = User_group::getForNickname($nickname, $profile); - if (!empty($group) && $profile->isMember($group)) { - $groups[] = $group->id; - } - } - - return $groups; - } - - protected $_parent = -1; - public function getParent() { - if (empty($this->reply_to)) { - // Should this also be NoResultException? I don't think so. - throw new Exception('Notice has no parent'); - } elseif ($this->_parent === -1) { // local object cache - $this->_parent = Notice::getKV('id', $this->reply_to); - } + $parent = Notice::getKV('id', $this->reply_to); - if (!($this->_parent instanceof Notice)) { - throw new NoResultException($this->_parent); + if (!$parent instanceof Notice) { + throw new ServerException('Notice has no parent'); } - return $this->_parent; + + return $parent; } /** @@ -2564,7 +2493,7 @@ class Notice extends Managed_DataObject function __sleep() { $vars = parent::__sleep(); - $skip = array('_parent', '_profile', '_groups', '_attachments', '_faves', '_replies', '_repeats'); + $skip = array('_profile', '_groups', '_attachments', '_faves', '_replies', '_repeats'); return array_diff($vars, $skip); } @@ -2585,10 +2514,15 @@ class Notice extends Managed_DataObject { $map = self::getProfiles($notices); - foreach ($notices as $notice) { - if (array_key_exists($notice->profile_id, $map)) { - $notice->_setProfile($map[$notice->profile_id]); - } + foreach ($notices as $entry=>$notice) { + try { + if (array_key_exists($notice->profile_id, $map)) { + $notice->_setProfile($map[$notice->profile_id]); + } + } catch (NoProfileException $e) { + common_log(LOG_WARNING, "Failed to fill profile in Notice with non-existing entry for profile_id: {$e->id}"); + unset($notices[$entry]); + } } return array_values($map);