StatusRemoteUpdatePipeline.php 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159
  1. <?php
  2. namespace App\Jobs\StatusPipeline;
  3. use Illuminate\Bus\Queueable;
  4. use Illuminate\Contracts\Queue\ShouldBeUnique;
  5. use Illuminate\Contracts\Queue\ShouldQueue;
  6. use Illuminate\Foundation\Bus\Dispatchable;
  7. use Illuminate\Queue\InteractsWithQueue;
  8. use Illuminate\Queue\SerializesModels;
  9. use App\Media;
  10. use App\ModLog;
  11. use App\Profile;
  12. use App\Status;
  13. use App\Models\StatusEdit;
  14. use App\Services\StatusService;
  15. use Purify;
  16. class StatusRemoteUpdatePipeline implements ShouldQueue
  17. {
  18. use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
  19. public $activity;
  20. /**
  21. * Create a new job instance.
  22. */
  23. public function __construct($activity)
  24. {
  25. $this->activity = $activity;
  26. }
  27. /**
  28. * Execute the job.
  29. */
  30. public function handle(): void
  31. {
  32. $activity = $this->activity;
  33. $status = Status::with('media')->whereObjectUrl($activity['id'])->first();
  34. if(!$status) {
  35. return;
  36. }
  37. $this->createPreviousEdit($status);
  38. $this->updateMedia($status, $activity);
  39. $this->updateImmediateAttributes($status, $activity);
  40. $this->createEdit($status, $activity);
  41. }
  42. protected function createPreviousEdit($status)
  43. {
  44. if(!$status->edits()->count()) {
  45. StatusEdit::create([
  46. 'status_id' => $status->id,
  47. 'profile_id' => $status->profile_id,
  48. 'caption' => $status->caption,
  49. 'spoiler_text' => $status->cw_summary,
  50. 'is_nsfw' => $status->is_nsfw,
  51. 'ordered_media_attachment_ids' => $status->media()->orderBy('order')->pluck('id')->toArray(),
  52. 'created_at' => $status->created_at
  53. ]);
  54. }
  55. }
  56. protected function updateMedia($status, $activity)
  57. {
  58. if(!isset($activity['attachment'])) {
  59. return;
  60. }
  61. $ogm = $status->media->count() ? $status->media()->orderBy('order')->get() : collect([]);
  62. $nm = collect($activity['attachment'])->filter(function($nm) {
  63. return isset(
  64. $nm['type'],
  65. $nm['mediaType'],
  66. $nm['url']
  67. ) &&
  68. in_array($nm['type'], ['Document', 'Image', 'Video']) &&
  69. in_array($nm['mediaType'], explode(',', config('pixelfed.media_types')));
  70. });
  71. // Skip when no media
  72. if(!$ogm->count() && !$nm->count()) {
  73. return;
  74. }
  75. Media::whereProfileId($status->profile_id)
  76. ->whereStatusId($status->id)
  77. ->update([
  78. 'status_id' => null
  79. ]);
  80. $nm->each(function($n, $key) use($status) {
  81. $m = new Media;
  82. $m->status_id = $status->id;
  83. $m->profile_id = $status->profile_id;
  84. $m->remote_media = true;
  85. $m->media_path = $n['url'];
  86. $m->caption = isset($n['name']) && !empty($n['name']) ? Purify::clean($n['name']) : null;
  87. $m->remote_url = $n['url'];
  88. $m->width = isset($n['width']) && !empty($n['width']) ? $n['width'] : null;
  89. $m->height = isset($n['height']) && !empty($n['height']) ? $n['height'] : null;
  90. $m->skip_optimize = true;
  91. $m->order = $key + 1;
  92. $m->save();
  93. });
  94. }
  95. protected function updateImmediateAttributes($status, $activity)
  96. {
  97. if(isset($activity['content'])) {
  98. $status->caption = strip_tags($activity['content']);
  99. $status->rendered = Purify::clean($activity['content']);
  100. }
  101. if(isset($activity['sensitive'])) {
  102. if((bool) $activity['sensitive'] == false) {
  103. $status->is_nsfw = false;
  104. $exists = ModLog::whereObjectType('App\Status::class')
  105. ->whereObjectId($status->id)
  106. ->whereAction('admin.status.moderate')
  107. ->exists();
  108. if($exists == true) {
  109. $status->is_nsfw = true;
  110. }
  111. $profile = Profile::find($status->profile_id);
  112. if(!$profile || $profile->cw == true) {
  113. $status->is_nsfw = true;
  114. }
  115. } else {
  116. $status->is_nsfw = true;
  117. }
  118. }
  119. if(isset($activity['summary'])) {
  120. $status->cw_summary = Purify::clean($activity['summary']);
  121. } else {
  122. $status->cw_summary = null;
  123. }
  124. $status->edited_at = now();
  125. $status->save();
  126. StatusService::del($status->id);
  127. }
  128. protected function createEdit($status, $activity)
  129. {
  130. $cleaned = isset($activity['content']) ? Purify::clean($activity['content']) : null;
  131. $spoiler_text = isset($activity['summary']) ? Purify::clean($activity['summary']) : null;
  132. $sensitive = isset($activity['sensitive']) ? $activity['sensitive'] : null;
  133. $mids = $status->media()->count() ? $status->media()->orderBy('order')->pluck('id')->toArray() : null;
  134. StatusEdit::create([
  135. 'status_id' => $status->id,
  136. 'profile_id' => $status->profile_id,
  137. 'caption' => $cleaned,
  138. 'spoiler_text' => $spoiler_text,
  139. 'is_nsfw' => $sensitive,
  140. 'ordered_media_attachment_ids' => $mids
  141. ]);
  142. }
  143. }