RemoteStatusDelete.php 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188
  1. <?php
  2. namespace App\Jobs\StatusPipeline;
  3. use DB, Cache, Storage;
  4. use App\{
  5. AccountInterstitial,
  6. Bookmark,
  7. CollectionItem,
  8. DirectMessage,
  9. Like,
  10. Media,
  11. MediaTag,
  12. Mention,
  13. Notification,
  14. Report,
  15. Status,
  16. StatusArchived,
  17. StatusHashtag,
  18. StatusView
  19. };
  20. use Illuminate\Bus\Queueable;
  21. use Illuminate\Contracts\Queue\ShouldQueue;
  22. use Illuminate\Contracts\Queue\ShouldBeUniqueUntilProcessing;
  23. use Illuminate\Foundation\Bus\Dispatchable;
  24. use Illuminate\Queue\InteractsWithQueue;
  25. use Illuminate\Queue\SerializesModels;
  26. use Illuminate\Queue\Middleware\WithoutOverlapping;
  27. use League\Fractal;
  28. use Illuminate\Support\Str;
  29. use League\Fractal\Serializer\ArraySerializer;
  30. use App\Transformer\ActivityPub\Verb\DeleteNote;
  31. use App\Util\ActivityPub\Helpers;
  32. use GuzzleHttp\Pool;
  33. use GuzzleHttp\Client;
  34. use GuzzleHttp\Promise;
  35. use App\Util\ActivityPub\HttpSignature;
  36. use App\Services\AccountService;
  37. use App\Services\CollectionService;
  38. use App\Services\StatusService;
  39. use App\Jobs\MediaPipeline\MediaDeletePipeline;
  40. use App\Jobs\ProfilePipeline\DecrementPostCount;
  41. use App\Services\NotificationService;
  42. class RemoteStatusDelete implements ShouldQueue, ShouldBeUniqueUntilProcessing
  43. {
  44. use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
  45. protected $status;
  46. /**
  47. * Delete the job if its models no longer exist.
  48. *
  49. * @var bool
  50. */
  51. public $deleteWhenMissingModels = true;
  52. public $tries = 3;
  53. public $maxExceptions = 3;
  54. public $timeout = 180;
  55. public $failOnTimeout = true;
  56. /**
  57. * The number of seconds after which the job's unique lock will be released.
  58. *
  59. * @var int
  60. */
  61. public $uniqueFor = 3600;
  62. /**
  63. * Get the unique ID for the job.
  64. */
  65. public function uniqueId(): string
  66. {
  67. return 'status:remote:delete:' . $this->status->id;
  68. }
  69. /**
  70. * Get the middleware the job should pass through.
  71. *
  72. * @return array<int, object>
  73. */
  74. public function middleware(): array
  75. {
  76. return [(new WithoutOverlapping("status-remote-delete-{$this->status->id}"))->shared()->dontRelease()];
  77. }
  78. /**
  79. * Create a new job instance.
  80. *
  81. * @return void
  82. */
  83. public function __construct(Status $status)
  84. {
  85. $this->status = $status->withoutRelations();
  86. }
  87. /**
  88. * Execute the job.
  89. *
  90. * @return void
  91. */
  92. public function handle()
  93. {
  94. $status = $this->status;
  95. if($status->deleted_at) {
  96. return;
  97. }
  98. StatusService::del($status->id, true);
  99. DecrementPostCount::dispatch($status->profile_id)->onQueue('inbox');
  100. return $this->unlinkRemoveMedia($status);
  101. }
  102. public function unlinkRemoveMedia($status)
  103. {
  104. if($status->in_reply_to_id) {
  105. $parent = Status::find($status->in_reply_to_id);
  106. if($parent) {
  107. --$parent->reply_count;
  108. $parent->save();
  109. StatusService::del($parent->id);
  110. }
  111. }
  112. AccountInterstitial::where('item_type', 'App\Status')
  113. ->where('item_id', $status->id)
  114. ->delete();
  115. Bookmark::whereStatusId($status->id)->delete();
  116. CollectionItem::whereObjectType('App\Status')
  117. ->whereObjectId($status->id)
  118. ->get()
  119. ->each(function($col) {
  120. CollectionService::removeItem($col->collection_id, $col->object_id);
  121. $col->delete();
  122. });
  123. $dms = DirectMessage::whereStatusId($status->id)->get();
  124. foreach($dms as $dm) {
  125. $not = Notification::whereItemType('App\DirectMessage')
  126. ->whereItemId($dm->id)
  127. ->first();
  128. if($not) {
  129. NotificationService::del($not->profile_id, $not->id);
  130. $not->forceDeleteQuietly();
  131. }
  132. $dm->delete();
  133. }
  134. Like::whereStatusId($status->id)->forceDelete();
  135. Media::whereStatusId($status->id)
  136. ->get()
  137. ->each(function($media) {
  138. MediaDeletePipeline::dispatch($media)->onQueue('mmo');
  139. });
  140. $mediaTags = MediaTag::where('status_id', $status->id)->get();
  141. foreach($mediaTags as $mtag) {
  142. $not = Notification::whereItemType('App\MediaTag')
  143. ->whereItemId($mtag->id)
  144. ->first();
  145. if($not) {
  146. NotificationService::del($not->profile_id, $not->id);
  147. $not->forceDeleteQuietly();
  148. }
  149. $mtag->delete();
  150. }
  151. Mention::whereStatusId($status->id)->forceDelete();
  152. Notification::whereItemType('App\Status')
  153. ->whereItemId($status->id)
  154. ->forceDelete();
  155. Report::whereObjectType('App\Status')
  156. ->whereObjectId($status->id)
  157. ->delete();
  158. StatusArchived::whereStatusId($status->id)->delete();
  159. StatusHashtag::whereStatusId($status->id)->delete();
  160. StatusView::whereStatusId($status->id)->delete();
  161. Status::whereInReplyToId($status->id)->update(['in_reply_to_id' => null]);
  162. $status->delete();
  163. StatusService::del($status->id, true);
  164. AccountService::del($status->profile_id);
  165. return 1;
  166. }
  167. }