X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;f=classes%2FNotice.php;h=3891f431e460a04cd947e80edfb78dba3d8b43d3;hb=15d466ebe6576aa34efa7d4b5bb008e0d2cbc116;hp=e029880f8d2c6900ced425878479c26ceef3258c;hpb=01c2c31c1e701f6946282dfcc23502464483d12d;p=quix0rs-gnu-social.git diff --git a/classes/Notice.php b/classes/Notice.php index e029880f8d..3891f431e4 100644 --- a/classes/Notice.php +++ b/classes/Notice.php @@ -87,12 +87,12 @@ 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'), 'uri' => array('type' => 'varchar', 'length' => 255, 'description' => 'universally unique identifier, usually a tag URI'), - 'content' => array('type' => 'text', 'description' => 'update content'), + 'content' => array('type' => 'text', 'description' => 'update content', 'collate' => 'utf8_general_ci'), 'rendered' => array('type' => 'text', 'description' => 'HTML version of the content'), 'url' => array('type' => 'varchar', 'length' => 255, 'description' => 'URL of any attachment (image, video, bookmark, whatever)'), 'created' => array('type' => 'datetime', 'not null' => true, 'description' => 'date this record was created'), @@ -107,9 +107,9 @@ class Notice extends Managed_DataObject 'location_ns' => array('type' => 'int', 'description' => 'namespace for location'), 'repeat_of' => array('type' => 'int', 'description' => 'notice this is a repeat of'), '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( @@ -122,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) @@ -504,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; } @@ -642,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 @@ -1005,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; } } } @@ -1017,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]); } } @@ -1486,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)); @@ -1501,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(); @@ -1512,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); } @@ -1584,8 +1592,10 @@ 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; @@ -2360,7 +2370,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); } @@ -2370,77 +2384,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; + } + } + + // Only for users mentioned in the notice - if ($this->scope & Notice::ADDRESSEE_SCOPE) { + if ($scope & Notice::ADDRESSEE_SCOPE) { - $repl = Reply::pkeyGet(array('notice_id' => $this->id, - 'profile_id' => $profile->id)); + $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); } + } + + function isHiddenSpam($profile) { + + // Hide posts by silenced users from everyone but moderators. - // Only for followers of the author + if (common_config('notice', 'hidespam')) { - if ($this->scope & Notice::FOLLOWER_SCOPE) { - $author = $this->getProfile(); - if (!Subscription::exists($profile, $author)) { - return false; + 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) @@ -2623,7 +2678,7 @@ class Notice extends Managed_DataObject return $this->_faves; } - function _setFaves(&$faves) + function _setFaves($faves) { $this->_faves = $faves; } @@ -2641,7 +2696,8 @@ class Notice extends Managed_DataObject } } foreach ($notices as $notice) { - $notice->_setFaves($faveMap[$notice->id]); + $faves = $faveMap[$notice->id]; + $notice->_setFaves($faves); } } @@ -2671,7 +2727,7 @@ class Notice extends Managed_DataObject return $this->_repeats; } - function _setRepeats(&$repeats) + function _setRepeats($repeats) { $this->_repeats = $repeats; } @@ -2681,7 +2737,8 @@ class Notice extends Managed_DataObject $ids = self::_idsOf($notices); $repeatMap = Memcached_DataObject::listGet('Notice', 'repeat_of', $ids); foreach ($notices as $notice) { - $notice->_setRepeats($repeatMap[$notice->id]); + $repeats = $repeatMap[$notice->id]; + $notice->_setRepeats($repeats); } } }