X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;f=classes%2FNotice.php;h=9a4b6db7fffadf8d5b62ee573f5b32bc003e99aa;hb=96d7b68c50291c4768f331f6693d8afb8cbb4afa;hp=60958c9e6a25e0557d378a748dec005d1b60d3d6;hpb=e26d3b0ede3edcfe004745c90cece3e36c6096d4;p=quix0rs-gnu-social.git diff --git a/classes/Notice.php b/classes/Notice.php index 60958c9e6a..9a4b6db7ff 100644 --- a/classes/Notice.php +++ b/classes/Notice.php @@ -87,7 +87,7 @@ class Notice extends Managed_DataObject public static function schemaDef() { - return array( + $def = array( 'fields' => array( 'id' => array('type' => 'serial', 'not null' => true, 'description' => 'unique identifier'), 'profile_id' => array('type' => 'int', 'not null' => true, 'description' => 'who made the update'), @@ -109,8 +109,7 @@ class Notice extends Managed_DataObject 'object_type' => array('type' => 'varchar', 'length' => 255, 'description' => 'URI representing activity streams object type', 'default' => 'http://activitystrea.ms/schema/1.0/note'), 'verb' => array('type' => 'varchar', 'length' => 255, 'description' => 'URI representing activity streams verb', 'default' => 'http://activitystrea.ms/schema/1.0/post'), 'scope' => array('type' => 'int', - 'default' => '1', - 'description' => 'bit map for distribution scope; 0 = everywhere; 1 = this server only; 2 = addressees; 4 = followers'), + 'description' => 'bit map for distribution scope; 0 = everywhere; 1 = this server only; 2 = addressees; 4 = followers; null = default'), ), 'primary key' => array('id'), 'unique keys' => array( @@ -123,16 +122,19 @@ class Notice extends Managed_DataObject 'notice_repeat_of_fkey' => array('notice', array('repeat_of' => 'id')), # @fixme: what about repeats of deleted notices? ), 'indexes' => array( + 'notice_created_id_is_local_idx' => array('created', 'id', 'is_local'), 'notice_profile_id_idx' => array('profile_id', 'created', 'id'), - 'notice_conversation_idx' => array('conversation'), - 'notice_created_idx' => array('created'), - 'notice_replyto_idx' => array('reply_to'), - 'notice_repeatof_idx' => array('repeat_of'), - ), - 'fulltext indexes' => array( - 'content' => array('content'), + 'notice_repeat_of_created_id_idx' => array('repeat_of', 'created', 'id'), + 'notice_conversation_created_id_idx' => array('conversation', 'created', 'id'), + 'notice_replyto_idx' => array('reply_to') ) ); + + if (common_config('search', 'type') == 'fulltext') { + $def['fulltext indexes'] = array('content' => array('content')); + } + + return $def; } function multiGet($kc, $kvs, $skipNulls=true) @@ -505,7 +507,7 @@ class Notice extends Managed_DataObject if (empty($verb)) { if (!empty($notice->repeat_of)) { $notice->verb = ActivityVerb::SHARE; - $notice->object_type = ActivityVerb::ACTIVITY; + $notice->object_type = ActivityObject::ACTIVITY; } else { $notice->verb = ActivityVerb::POST; } @@ -643,7 +645,7 @@ class Notice extends Managed_DataObject } self::blow('notice:list-ids:conversation:%s', $this->conversation); - self::blow('conversation::notice_count:%d', $this->conversation); + self::blow('conversation:notice_count:%d', $this->conversation); if (!empty($this->repeat_of)) { // XXX: we should probably only use one of these @@ -1006,10 +1008,7 @@ class Notice extends Managed_DataObject $users = $ptag->getUserSubscribers(); foreach ($users as $id) { if (!array_key_exists($id, $ni)) { - $user = User::staticGet('id', $id); - if (!$user->hasBlocked($profile)) { - $ni[$id] = NOTICE_INBOX_SOURCE_PROFILE_TAG; - } + $ni[$id] = NOTICE_INBOX_SOURCE_PROFILE_TAG; } } } @@ -1018,23 +1017,30 @@ class Notice extends Managed_DataObject if (!array_key_exists($recipient, $ni)) { $ni[$recipient] = NOTICE_INBOX_SOURCE_REPLY; } + } - // Exclude any deleted, non-local, or blocking recipients. - $profile = $this->getProfile(); - $originalProfile = null; - if ($this->repeat_of) { - // Check blocks against the original notice's poster as well. - $original = Notice::staticGet('id', $this->repeat_of); - if ($original) { - $originalProfile = $original->getProfile(); - } + // Exclude any deleted, non-local, or blocking recipients. + $profile = $this->getProfile(); + $originalProfile = null; + if ($this->repeat_of) { + // Check blocks against the original notice's poster as well. + $original = Notice::staticGet('id', $this->repeat_of); + if ($original) { + $originalProfile = $original->getProfile(); } - foreach ($ni as $id => $source) { + } + + foreach ($ni as $id => $source) { + try { $user = User::staticGet('id', $id); - if (empty($user) || $user->hasBlocked($profile) || + if (empty($user) || + $user->hasBlocked($profile) || ($originalProfile && $user->hasBlocked($originalProfile))) { unset($ni[$id]); } + } catch (UserNoProfileException $e) { + // User doesn't have a profile; invalid; skip them. + unset($ni[$id]); } } @@ -1487,7 +1493,7 @@ class Notice extends Managed_DataObject * @return Activity activity object representing this Notice. */ - function asActivity($cur) + function asActivity($cur=null) { $act = self::cacheGet(Cache::codeKey('notice:as-activity:'.$this->id)); @@ -1502,7 +1508,6 @@ class Notice extends Managed_DataObject $act->time = strtotime($this->created); $act->link = $this->bestUrl(); $act->content = common_xml_safe_str($this->rendered); - $act->title = common_xml_safe_str($this->content); $profile = $this->getProfile(); @@ -1513,7 +1518,9 @@ class Notice extends Managed_DataObject if ($this->repeat_of) { $repeated = Notice::staticGet('id', $this->repeat_of); - $act->objects[] = $repeated->asActivity($cur); + if (!empty($repeated)) { + $act->objects[] = $repeated->asActivity($cur); + } } else { $act->objects[] = ActivityObject::fromNotice($this); } @@ -1537,9 +1544,9 @@ class Notice extends Managed_DataObject $attachments = $this->attachments(); foreach ($attachments as $attachment) { - $enclosure = $attachment->getEnclosure(); - if ($enclosure) { - $act->enclosures[] = $enclosure; + // Save local attachments + if (!empty($attachment->filename)) { + $act->attachments[] = ActivityObject::fromFile($attachment); } } @@ -1570,6 +1577,7 @@ class Notice extends Managed_DataObject $rprofile = Profile::staticGet('id', $id); if (!empty($rprofile)) { $ctx->attention[] = $rprofile->getUri(); + $ctx->attentionType[$rprofile->getUri()] = ActivityObject::PERSON; } } @@ -1577,6 +1585,19 @@ class Notice extends Managed_DataObject foreach ($groups as $group) { $ctx->attention[] = $group->getUri(); + $ctx->attentionType[$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; + break; + case Notice::FOLLOWER_SCOPE: + $surl = common_local_url("subscribers", array('nickname' => $profile->nickname)); + $ctx->attention[] = $surl; + $ctx->attentionType[$surl] = ActivityObject::COLLECTION; + break; } // XXX: deprecated; use ActivityVerb::SHARE instead @@ -1585,12 +1606,20 @@ class Notice extends Managed_DataObject if (!empty($this->repeat_of)) { $repeat = Notice::staticGet('id', $this->repeat_of); - $ctx->forwardID = $repeat->uri; - $ctx->forwardUrl = $repeat->bestUrl(); + if (!empty($repeat)) { + $ctx->forwardID = $repeat->uri; + $ctx->forwardUrl = $repeat->bestUrl(); + } } $act->context = $ctx; + $source = $this->getSource(); + + if ($source) { + $act->generator = ActivityObject::fromNoticeSource($source); + } + // Source $atom_feed = $profile->getAtomFeed(); @@ -2361,7 +2390,11 @@ class Notice extends Managed_DataObject $result = self::cacheGet($keypart); if ($result === false) { - $bResult = $this->_inScope($profile); + $bResult = false; + if (Event::handle('StartNoticeInScope', array($this, $profile, &$bResult))) { + $bResult = $this->_inScope($profile); + Event::handle('EndNoticeInScope', array($this, $profile, &$bResult)); + } $result = ($bResult) ? 1 : 0; self::cacheSet($keypart, $result, 0, 300); } @@ -2371,77 +2404,118 @@ class Notice extends Managed_DataObject protected function _inScope($profile) { - // If there's no scope, anyone (even anon) is in scope. - - if ($this->scope == 0) { - return true; + if (!is_null($this->scope)) { + $scope = $this->scope; + } else { + $scope = self::defaultScope(); } - // If there's scope, anon cannot be in scope + // If there's no scope, anyone (even anon) is in scope. - if (empty($profile)) { - return false; - } + if ($scope == 0) { // Not private - // Author is always in scope + return !$this->isHiddenSpam($profile); - if ($this->profile_id == $profile->id) { - return true; - } + } else { // Private, somehow - // Only for users on this site + // If there's scope, anon cannot be in scope - if ($this->scope & Notice::SITE_SCOPE) { - $user = $profile->getUser(); - if (empty($user)) { + if (empty($profile)) { return false; } - } - // Only for users mentioned in the notice + // Author is always in scope + + if ($this->profile_id == $profile->id) { + return true; + } + + // Only for users on this site + + if ($scope & Notice::SITE_SCOPE) { + $user = $profile->getUser(); + if (empty($user)) { + return false; + } + } - if ($this->scope & Notice::ADDRESSEE_SCOPE) { + // Only for users mentioned in the notice - $repl = Reply::pkeyGet(array('notice_id' => $this->id, - 'profile_id' => $profile->id)); + if ($scope & Notice::ADDRESSEE_SCOPE) { + + $repl = Reply::pkeyGet(array('notice_id' => $this->id, + 'profile_id' => $profile->id)); - if (empty($repl)) { - return false; + if (empty($repl)) { + return false; + } } - } - // Only for members of the given group + // Only for members of the given group - if ($this->scope & Notice::GROUP_SCOPE) { + if ($scope & Notice::GROUP_SCOPE) { - // XXX: just query for the single membership + // XXX: just query for the single membership - $groups = $this->getGroups(); + $groups = $this->getGroups(); - $foundOne = false; + $foundOne = false; - foreach ($groups as $group) { - if ($profile->isMember($group)) { - $foundOne = true; - break; + foreach ($groups as $group) { + if ($profile->isMember($group)) { + $foundOne = true; + break; + } + } + + if (!$foundOne) { + return false; } } - if (!$foundOne) { - return false; + // Only for followers of the author + + $author = null; + + if ($scope & Notice::FOLLOWER_SCOPE) { + + try { + $author = $this->getProfile(); + } catch (Exception $e) { + return false; + } + + if (!Subscription::exists($profile, $author)) { + return false; + } } + + return !$this->isHiddenSpam($profile); } + } - // Only for followers of the author + function isHiddenSpam($profile) { + + // Hide posts by silenced users from everyone but moderators. - if ($this->scope & Notice::FOLLOWER_SCOPE) { - $author = $this->getProfile(); - if (!Subscription::exists($profile, $author)) { - return false; + if (common_config('notice', 'hidespam')) { + + try { + $author = $this->getProfile(); + } catch(Exception $e) { + // If we can't get an author, keep it hidden. + // XXX: technically not spam, but, whatever. + return true; + } + + if ($author->hasRole(Profile_role::SILENCED)) { + if (empty($profile) || (($profile->id !== $author->id) && (!$profile->hasRight(Right::REVIEWSPAM)))) { + return true; + } } } - return true; + return false; } static function groupsFromText($text, $profile)