diff --git a/app/Jobs/StatusPipeline/StatusReplyPipeline.php b/app/Jobs/StatusPipeline/StatusReplyPipeline.php index 438d78eba..a64682cb2 100644 --- a/app/Jobs/StatusPipeline/StatusReplyPipeline.php +++ b/app/Jobs/StatusPipeline/StatusReplyPipeline.php @@ -68,6 +68,14 @@ class StatusReplyPipeline implements ShouldQueue return 1; } + if(config('database.default') === 'mysql') { + DB::transaction(function() use($reply) { + $count = DB::select( DB::raw("select id, in_reply_to_id from statuses, (select @pv := :kid) initialisation where id > @pv and find_in_set(in_reply_to_id, @pv) > 0 and @pv := concat(@pv, ',', id)"), [ 'kid' => $reply->id]); + $reply->reply_count = count($count); + $reply->save(); + }); + } + DB::transaction(function() use($target, $actor, $status) { $notification = new Notification(); $notification->profile_id = $target->id; @@ -83,6 +91,15 @@ class StatusReplyPipeline implements ShouldQueue NotificationService::set($notification->profile_id, $notification->id); }); + if($exists = Cache::get('status:replies:all:' . $reply->id)) { + if($exists && $exists->count() == 3) { + } else { + Cache::forget('status:replies:all:' . $reply->id); + } + } else { + Cache::forget('status:replies:all:' . $reply->id); + } + return 1; } diff --git a/app/Util/ActivityPub/Helpers.php b/app/Util/ActivityPub/Helpers.php index b9a4f26e1..b964fa26a 100644 --- a/app/Util/ActivityPub/Helpers.php +++ b/app/Util/ActivityPub/Helpers.php @@ -434,39 +434,126 @@ class Helpers { ); return $status; } - return DB::transaction(function() use($profile, $res, $url, $ts, $reply_to, $cw, $scope, $id) { - $status = new Status; - $status->profile_id = $profile->id; - $status->url = isset($res['url']) && is_string($res['url']) ? $res['url'] : $url; - $status->uri = isset($res['url']) && is_string($res['url']) ? $res['url'] : $url; - $status->object_url = $id; - $status->caption = strip_tags($res['content']); - $status->rendered = Purify::clean($res['content']); - $status->created_at = Carbon::parse($ts); - $status->in_reply_to_id = $reply_to; - $status->local = false; - $status->is_nsfw = $cw; - $status->scope = $scope; - $status->visibility = $scope; - $status->cw_summary = $cw == true && isset($res['summary']) ? - Purify::clean(strip_tags($res['summary'])) : null; - $status->save(); - if($reply_to == null) { - self::importNoteAttachment($res, $status); - } else { - StatusReplyPipeline::dispatch($status); - } - if(isset($res['tag']) && is_array($res['tag']) && !empty($res['tag'])) { - StatusTagsPipeline::dispatch($res, $status); - } - return $status; - }); + return self::storeStatus($url, $profile, $res); }); return $status; } + public static function storeStatus($url, $profile, $activity) + { + $id = isset($activity['id']) ? self::pluckval($activity['id']) : self::pluckval($activity['url']); + $url = isset($activity['url']) && is_string($activity['url']) ? $activity['url'] : $id; + $idDomain = parse_url($id, PHP_URL_HOST); + $urlDomain = parse_url($url, PHP_URL_HOST); + if(!self::validateUrl($id) || !self::validateUrl($url)) { + return; + } + + $reply_to = self::getReplyTo($activity); + + return DB::transaction(function() use($url, $profile, $activity, $reply_to, $id) { + $ts = self::pluckval($activity['published']); + $scope = self::getScope($activity); + $cw = self::getSensitive($activity); + + $status = new Status; + $status->profile_id = $profile->id; + $status->url = $url; + $status->uri = $url; + $status->object_url = $id; + $status->caption = strip_tags($activity['content']); + $status->rendered = Purify::clean($activity['content']); + $status->created_at = Carbon::parse($ts); + $status->in_reply_to_id = $reply_to; + $status->local = false; + $status->is_nsfw = $cw; + $status->scope = $scope; + $status->visibility = $scope; + $status->cw_summary = $cw == true && isset($activity['summary']) ? + Purify::clean(strip_tags($activity['summary'])) : null; + $status->save(); + + if($reply_to == null) { + self::importNoteAttachment($activity, $status); + } else { + StatusReplyPipeline::dispatch($status); + } + + if(isset($activity['tag']) && is_array($activity['tag']) && !empty($activity['tag'])) { + StatusTagsPipeline::dispatch($activity, $status); + } + return $status; + }); + } + + public static function getSensitive($activity) + { + $id = isset($activity['id']) ? self::pluckval($activity['id']) : self::pluckval($url); + $url = isset($activity['url']) ? self::pluckval($activity['url']) : $id; + $urlDomain = parse_url($url, PHP_URL_HOST); + + $cw = isset($activity['sensitive']) ? (bool) $activity['sensitive'] : false; + + if(in_array($urlDomain, InstanceService::getNsfwDomains())) { + $cw = true; + } + + return $cw; + } + + public static function getReplyTo($activity) + { + $reply_to = null; + $inReplyTo = isset($activity['inReplyTo']) && !empty($activity['inReplyTo']) ? + self::pluckval($activity['inReplyTo']) : + false; + + if($inReplyTo) { + $reply_to = self::statusFirstOrFetch($inReplyTo); + if($reply_to) { + $reply_to = optional($reply_to)->id; + } + } else { + $reply_to = null; + } + + return $reply_to; + } + + public static function getScope($activity) + { + $id = isset($activity['id']) ? self::pluckval($activity['id']) : self::pluckval($url); + $url = isset($activity['url']) ? self::pluckval($activity['url']) : $id; + $urlDomain = parse_url($url, PHP_URL_HOST); + $scope = 'private'; + + if(isset($activity['to']) == true) { + if(is_array($activity['to']) && in_array('https://www.w3.org/ns/activitystreams#Public', $activity['to'])) { + $scope = 'public'; + } + if(is_string($activity['to']) && 'https://www.w3.org/ns/activitystreams#Public' == $activity['to']) { + $scope = 'public'; + } + } + + if(isset($activity['cc']) == true) { + if(is_array($activity['cc']) && in_array('https://www.w3.org/ns/activitystreams#Public', $activity['cc'])) { + $scope = 'unlisted'; + } + if(is_string($activity['cc']) && 'https://www.w3.org/ns/activitystreams#Public' == $activity['cc']) { + $scope = 'unlisted'; + } + } + + if($scope == 'public' && in_array($urlDomain, InstanceService::getUnlistedDomains())) { + $scope = 'unlisted'; + } + + return $scope; + } + private static function storePoll($profile, $res, $url, $ts, $reply_to, $cw, $scope, $id) { if(!isset($res['endTime']) || !isset($res['oneOf']) || !is_array($res['oneOf']) || count($res['oneOf']) > 4) { diff --git a/app/Util/ActivityPub/Inbox.php b/app/Util/ActivityPub/Inbox.php index 749d0ceaa..dd0182d2c 100644 --- a/app/Util/ActivityPub/Inbox.php +++ b/app/Util/ActivityPub/Inbox.php @@ -262,10 +262,16 @@ class Inbox } $url = isset($activity['url']) ? $activity['url'] : $activity['id']; + if(Status::whereUrl($url)->exists()) { return; } - Helpers::statusFetch($url); + + Helpers::storeStatus( + $url, + $actor, + $activity + ); return; }