PluginProbe
FluentCommunity – Ultra-Fast High-Performance Social Network, Community, LMS & Online Courses / 2.7.7
FluentCommunity – Ultra-Fast High-Performance Social Network, Community, LMS & Online Courses v2.7.7
2.10.0 2.10.01 2.9.1 2.9.0 2.8.1 2.8.0 2.7.7 2.7.5 2.7.0 2.6.01 2.6.0 2.5.0 2.4.01 trunk 1.0.90 1.0.91 1.0.92 1.0.93 1.0.94 1.0.95 1.0.96 1.0.97 1.0.98 1.0.99 1.1.0 All 77 releases
fluent-community / app / Http / Controllers / CommentsController.php

CommentsController.php in FluentCommunity – Ultra-Fast High-Performance Social Network, Community, LMS & Online Courses 2.7.7, at app/Http/Controllers/CommentsController.php

730 lines 26.7 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace FluentCommunity\App\Http\Controllers;
4
5 use FluentCommunity\App\Models\Media;
6 use FluentCommunity\App\Models\User;
7 use FluentCommunity\App\Services\CustomSanitizer;
8 use FluentCommunity\App\Services\FeedsHelper;
9 use FluentCommunity\App\Services\Helper;
10 use FluentCommunity\App\Services\ProfileHelper;
11 use FluentCommunity\Framework\Http\Request\Request;
12 use FluentCommunity\App\Models\Comment;
13 use FluentCommunity\App\Models\Feed;
14 use FluentCommunity\App\Models\Reaction;
15 use FluentCommunity\Framework\Support\Arr;
16
17 class CommentsController extends Controller
18 {
19 public function getComments(Request $request, $feed_id)
20 {
21 $feed = Feed::withoutGlobalScopes()
22 ->byUserAccess(get_current_user_id())
23 ->findOrFail($feed_id);
24
25 if ($feed->status != 'published' && !$feed->hasEditAccess($this->getUserId())) {
26 return $this->sendError([
27 'message' => __('Sorry, you do not have permission to view this post', 'fluent-community')
28 ], 404);
29 }
30
31 $canViewComments = apply_filters('fluent_community/can_view_comments_' . $feed->type, true, $feed);
32
33 if (!$canViewComments) {
34 return [
35 'comments' => []
36 ];
37 }
38
39 $comments = Comment::where('post_id', $feed->id)
40 ->byContentModerationAccessStatus($this->getUser())
41 ->orderBy('created_at', 'asc')
42 ->with([
43 'xprofile' => function ($q) {
44 $q->select(ProfileHelper::getXProfilePublicFields());
45 }
46 ])
47 ->whereHas('xprofile', function ($q) {
48 $q->where('status', 'active');
49 })
50 ->get();
51
52 $comments = apply_filters('fluent_community/comments_query_response', $comments, $request->all());
53
54 $userId = $this->getUserId();
55
56 if ($userId) {
57 $likedIds = FeedsHelper::getLikedIdsByUserFeedId($feed->id, get_current_user_id());
58 if ($likedIds) {
59 $comments->each(function ($comment) use ($likedIds) {
60 if (in_array($comment->id, $likedIds)) {
61 $comment->liked = 1;
62 }
63 });
64 }
65 }
66
67 $data = [
68 'comments' => $comments
69 ];
70
71 return apply_filters('fluent_community/comments_api_response', $data, $request->all());
72 }
73
74 public function store(Request $request, $feedId)
75 {
76 $user = $this->getUser(true);
77 do_action('fluent_community/check_rate_limit/create_comment', $user);
78
79 $text = $this->validateCommentText($request->all());
80 $feed = Feed::withoutGlobalScopes()->findOrFail($feedId);
81
82 if ($feed->status != 'published') {
83 return $this->sendError([
84 'message' => __('This post is not published yet', 'fluent-community')
85 ]);
86 }
87
88 $this->verifyCreateCommentPermission($feed);
89
90 $requestData = $request->all();
91
92 // Check for duplicate (only for comments with text)
93 if ($text) {
94 $skipDuplicateCheck = apply_filters('fluent_community/disable_duplicate_comment_check', false, get_current_user_id(), $feed->id);
95 if (!$skipDuplicateCheck) {
96 $exist = Comment::where('user_id', get_current_user_id())
97 ->where('message', $text)
98 ->where('post_id', $feed->id)
99 ->first();
100
101 if ($exist) {
102 return $this->sendError([
103 'message' => __('No duplicate comment please!', 'fluent-community')
104 ]);
105 }
106 }
107 }
108
109 [$markdown, $inlineMedias] = FeedsHelper::replaceImageUrlsWithRealMediaArchive($text);
110 $mentions = FeedsHelper::getMentions($markdown, $feed->space_id, true);
111 $commentHtml = $this->generateCommentHtml($markdown, $mentions);
112
113 $commentData = $this->prepareCommentData($feed->id, $text, $commentHtml);
114
115 if (!empty($requestData['parent_id'])) {
116 $parentId = (int)$requestData['parent_id'];
117 $parentComment = Comment::where('id', $parentId)
118 ->where('post_id', $feed->id)
119 ->first();
120
121 if (!$parentComment) {
122 return $this->sendError([
123 'message' => __('Invalid parent comment', 'fluent-community')
124 ]);
125 }
126
127 $commentData['parent_id'] = $parentId;
128 }
129
130 [$commentData, $mediaItems] = $this->prepareCommentMedia($commentData, $requestData);
131
132 $commentData['is_admin'] = $user->hasSpacePermission('community_moderator', $feed->space);
133
134 if ($mentionUserIds = Arr::get($mentions, 'user_ids', [])) {
135 $commentData['meta']['mentioned_user_ids'] = $mentionUserIds;
136 }
137
138 do_action('fluent_community/before_comment_create', $commentData, $feed);
139
140 $commentData = apply_filters('fluent_community/comment/comment_data', $commentData, $feed);
141
142 $comment = Comment::create($commentData);
143
144 $feed->comments_count = $feed->comments_count + 1;
145 $feed->save();
146
147
148 // Merge and save all media in one loop
149 $mediaItems = $mediaItems ? (is_array($mediaItems) ? $mediaItems : [$mediaItems]) : [];
150
151 if ($inlineMedias) {
152 $mediaItems = array_merge($mediaItems, $inlineMedias);
153 }
154
155 if ($mediaItems) {
156 foreach ($mediaItems as $media) {
157 $media->fill([
158 'is_active' => 1,
159 'feed_id' => $feed->id,
160 'object_source' => 'comment',
161 'sub_object_id' => $comment->id
162 ]);
163 $media->save();
164 }
165 }
166
167 $this->loadCommentRelations($comment);
168
169 if ($comment->status != 'published') {
170 do_action('fluent_community/comment/new_comment_' . $comment->status, $comment, $feed);
171 /* translators: %$s is replaced by the status of the comment */
172 $message = sprintf(__('Your comment has been marked as %s', 'fluent-community'), $comment->status);
173 $response = [
174 'comment' => $comment,
175 'message' => $message
176 ];
177 return apply_filters('fluent_community/comment/new_comment_response', $response, $comment);
178 }
179
180 do_action('fluent_community/comment_added_' . $feed->type, $comment, $feed);
181 do_action('fluent_community/comment_added', $comment, $feed, Arr::get($mentions, 'users', []));
182
183 return [
184 'comment' => $comment,
185 'message' => __('Comment has been added', 'fluent-community'),
186 ];
187 }
188
189 public function update(Request $request, $feedId, $commentId)
190 {
191 $text = $this->validateCommentText($request->all());
192
193 $feed = Feed::withoutGlobalScopes()->findOrFail($feedId);
194 $this->verifySpacePermission($feed);
195
196 $requestData = $request->all();
197 $comment = Comment::findOrFail($commentId);
198
199 if ($comment->post_id != $feed->id) {
200 return $this->sendError([
201 'message' => __('Invalid comment', 'fluent-community')
202 ]);
203 }
204
205 $user = $this->getUser(true);
206
207 $requestData['is_admin'] = $user->hasPermissionOrInCurrentSpace('community_moderator', $feed->space);
208
209 if ($comment->user_id != get_current_user_id() && !$user->can('edit_any_comment', $feed->space)) {
210 return $this->sendError([
211 'message' => __('You are not allowed to edit this comment', 'fluent-community')
212 ]);
213 }
214
215 [$markdown, $inlineMedias] = FeedsHelper::replaceImageUrlsWithRealMediaArchive($text, $feed);
216
217 $mentions = FeedsHelper::getMentions($markdown, $feed->space_id);
218
219 $commentHtml = $this->generateCommentHtml($markdown, $mentions);
220
221 $commentData = $this->prepareCommentData($feed->id, $text, $commentHtml);
222
223 [$commentData, $mediaItems] = $this->prepareCommentMedia($commentData, $requestData, $comment);
224
225 $commentData = apply_filters('fluent_community/comment/update_comment_data', $commentData, $feed, $requestData, $comment);
226
227 $comment->fill($commentData);
228
229 $dirty = $comment->getDirty();
230
231 if ($dirty) {
232 $comment->save();
233 }
234
235 // Merge and save all media in one loop
236 $mediaItems = $mediaItems ? (is_array($mediaItems) ? $mediaItems : [$mediaItems]) : [];
237
238 if ($inlineMedias) {
239 $mediaItems = array_merge($mediaItems, $inlineMedias);
240 }
241
242 $allMediaIds = [];
243
244 if ($mediaItems) {
245 foreach ($mediaItems as $media) {
246 $media->fill([
247 'is_active' => 1,
248 'feed_id' => $feed->id,
249 'object_source' => 'comment',
250 'sub_object_id' => $comment->id
251 ]);
252 $media->save();
253 $allMediaIds[] = $media->id;
254 }
255 }
256
257 // Remove old media not in current list
258 $otherMedias = Media::where('object_source', 'comment')
259 ->when($allMediaIds, function ($q) use ($allMediaIds) {
260 $q->whereNotIn('id', $allMediaIds);
261 })
262 ->where('sub_object_id', $comment->id)
263 ->get();
264
265 if (!$otherMedias->isEmpty()) {
266 do_action('fluent_community/comment/media_deleted', $otherMedias);
267 }
268
269 $this->loadCommentRelations($comment);
270
271 if ($dirty) {
272 do_action('fluent_community/comment_updated', $comment, $feed);
273 do_action('fluent_community/comment_updated_' . $feed->type, $comment, $feed);
274 }
275
276 return [
277 'comment' => $comment,
278 'message' => __('Comment has been updated', 'fluent-community'),
279 ];
280 }
281
282 public function patchComment(Request $request, $feedId, $commentId)
283 {
284 $feed = Feed::withoutGlobalScopes()->findOrFail($feedId);
285
286 $comment = Comment::findOrFail($commentId);
287
288 $user = $this->getUser(true);
289
290 $isMod = $user && $user->hasPermissionOrInCurrentSpace('community_moderator', $feed->space);
291 $isAdmin = $user && $user->hasPermissionOrInCurrentSpace('community_admin', $feed->space);
292
293 if (!$isMod && !$isAdmin) {
294 return $this->sendError([
295 'message' => __('You do not have permission to perform this action', 'fluent-community')
296 ]);
297 }
298
299 $allData = $request->all();
300 $validKeys = ['is_sticky'];
301
302 $data = Arr::only($allData, $validKeys);
303
304 $data = array_map('intval', $data);
305
306 if (isset($data['is_sticky'])) {
307 if ($comment->parent_id) {
308 return $this->sendError([
309 'message' => __('You cannot pin a reply comment', 'fluent-community')
310 ]);
311 }
312
313 $data['is_sticky'] = $data['is_sticky'] ? 1 : 0;
314 if ($data['is_sticky']) {
315 Comment::where('post_id', $feed->id)->update(['is_sticky' => 0]);
316 }
317 }
318
319 if ($data) {
320 $comment->fill($data);
321 $dirty = $comment->getDirty();
322 if ($dirty) {
323 $comment->save();
324 do_action('fluent_community/comment/updated', $comment, $dirty);
325 }
326 }
327
328 return apply_filters('fluent_community/comment/patch_comment_response', [
329 'comment' => $comment,
330 'message' => __('Comment updated', 'fluent-community')
331 ], $comment, $feed, $request->all());
332 }
333
334 private function prepareCommentMedia($commentData, $requestData, $exisitngComment = null)
335 {
336 $mediaImages = Arr::get($requestData, 'media_images', []);
337
338 if ($mediaImages) {
339 if ($exisitngComment) {
340 $mediaItems = [];
341 $mediaData = [];
342 foreach ($mediaImages as $mediaImage) {
343 $id = Arr::get($mediaImage, 'media_id');
344 if ($id) {
345 $media = Media::where('sub_object_id', $exisitngComment->id)
346 ->where('object_source', 'comment')
347 ->find($id);
348 } else {
349 $media = Helper::getMediaFromUrl($mediaImage);
350 }
351
352 if ($media) {
353 $mediaItems[] = $media;
354 $mediaData[] = [
355 'media_id' => $media->id,
356 'url' => $media->public_url,
357 'type' => 'image',
358 'width' => Arr::get($media->settings, 'width'),
359 'height' => Arr::get($media->settings, 'height'),
360 'provider' => Arr::get($media->settings, 'provider', 'uploader')
361 ];
362 }
363 }
364 $commentData['meta']['media_items'] = $mediaData;
365 return [$commentData, $mediaItems];
366 }
367
368 $uploadedImages = Helper::getMediaByProvider($mediaImages);
369 if ($uploadedImages) {
370 $mediaItems = Helper::getMediaItemsFromUrl($uploadedImages);
371 if ($mediaItems) {
372 $mediaPreviews = [];
373 foreach ($mediaItems as $mediaItem) {
374 $mediaData = [
375 'media_id' => $mediaItem->id,
376 'url' => $mediaItem->public_url,
377 'type' => 'image',
378 'width' => Arr::get($mediaItem->settings, 'width'),
379 'height' => Arr::get($mediaItem->settings, 'height'),
380 'provider' => Arr::get($mediaItem->settings, 'provider', 'uploader')
381 ];
382
383 $mediaPreviews[] = array_filter($mediaData);
384 }
385 $commentData['meta']['media_items'] = $mediaPreviews;
386 return [$commentData, $mediaItems];
387 }
388 }
389 }
390
391 if (empty($requestData['meta']['media_preview']['image'])) {
392 return [$commentData, []];
393 }
394
395 if ($exisitngComment) {
396 $image = sanitize_url(Arr::get($requestData, 'meta.media_preview.image', ''));
397 $existingMedia = Media::where('media_url', $image)
398 ->where('object_source', 'comment')
399 ->where('sub_object_id', $exisitngComment->id)
400 ->first();
401
402 if ($existingMedia) {
403 $commentData['meta'] = $exisitngComment->meta;
404 return [$commentData, [$existingMedia]];
405 }
406 }
407
408 // type/provider reach :class bindings and width/height a :style binding in
409 // _MediaPreview.vue. Neither is an executable sink, but the stored values are
410 // request-supplied so they are normalised here rather than trusted.
411 $commentData['meta']['media_preview'] = array_filter([
412 'image' => sanitize_url(Arr::get($requestData, 'meta.media_preview.image', '')),
413 'type' => sanitize_text_field(Arr::get($requestData, 'meta.media_preview.type', 'image')),
414 'provider' => sanitize_text_field(Arr::get($requestData, 'meta.media_preview.provider', '')),
415 'height' => (int) Arr::get($requestData, 'meta.media_preview.height', 0),
416 'width' => (int) Arr::get($requestData, 'meta.media_preview.width', 0),
417 ]);
418
419 return [$commentData, []];
420 }
421
422 private function validateCommentText($data)
423 {
424 $text = trim(Arr::get($data, 'comment'));
425 $text = CustomSanitizer::unslashMarkdown($text);
426
427 // Decode HTML entities (e.g., &#x20; for space) and strip all whitespace for validation
428 $textForValidation = html_entity_decode($text, ENT_QUOTES | ENT_HTML5, 'UTF-8');
429 $textForValidation = preg_replace('/\s+/u', '', $textForValidation);
430
431 $hasMedia = Arr::get($data, 'media_images', []) || Arr::get($data, 'meta.media_preview.image', false);
432
433 $isReply = !empty($data['parent_id']);
434 if (!$textForValidation && !$hasMedia) {
435 if ($isReply) {
436 throw new \Exception(esc_html__('Reply cannot be empty.', 'fluent-community'), 422);
437 } else {
438 throw new \Exception(esc_html__('Comment cannot be empty.', 'fluent-community'), 422);
439 }
440 }
441
442 $maxCommentLength = apply_filters('fluent_community/max_comment_char_length', 10000);
443 if ($text && strlen($text) > $maxCommentLength) {
444 /* translators: %s is the maximum allowed character count */
445 throw new \Exception(esc_html(sprintf(__('The comment is too long. Please keep it under %s characters.', 'fluent-community'), number_format($maxCommentLength))), 422);
446 }
447
448 return $text;
449 }
450
451 private function verifyCreateCommentPermission($feed)
452 {
453 if (Arr::get($feed->meta, 'comments_disabled') === 'yes') {
454 throw new \Exception(esc_html__('Comments are disabled for this post', 'fluent-community'));
455 }
456
457 $this->verifySpacePermission($feed);
458 }
459
460 private function verifySpacePermission($feed)
461 {
462 if ($feed->space_id && $feed->space) {
463 $user = $this->getUser(true);
464 $user->verifySpacePermission('can_comment', $feed->space);
465
466 if ($feed->space->type == 'course' && Arr::get($feed->space->settings, 'disable_comments') === 'yes') {
467 throw new \Exception(esc_html__('Comments are disabled for this course', 'fluent-community'));
468 }
469 }
470 }
471
472 private function generateCommentHtml($text, $mentions)
473 {
474 $htmlText = $mentions ? $mentions['text'] : $text;
475 return wp_kses_post(FeedsHelper::mdToHtml($htmlText));
476 }
477
478 private function prepareCommentData($feedId, $text, $commentHtml)
479 {
480 return [
481 'post_id' => $feedId,
482 'message' => $text,
483 'message_rendered' => $commentHtml,
484 'type' => 'comment',
485 'meta' => [],
486 ];
487 }
488
489 private function loadCommentRelations($comment)
490 {
491 $comment->load('media');
492 $comment->load([
493 'xprofile' => function ($q) {
494 $q->select(ProfileHelper::getXProfilePublicFields());
495 }
496 ]);
497 }
498
499 public function addOrRemovePostReact(Request $request, $feed_id)
500 {
501 $userId = get_current_user_id();
502 $feed = Feed::withoutGlobalScopes()->byUserAccess($userId)->findOrFail($feed_id);
503 $type = $request->get('react_type', 'like');
504 $willRemove = $request->get('remove');
505
506 if ($feed->status != 'published') {
507 return $this->sendError([
508 'message' => __('This post is not published yet', 'fluent-community')
509 ]);
510 }
511
512 if ($userId === $feed->user_id && apply_filters('fluent_community/disable_self_post_react', false, $feed)) {
513 return $this->sendError([
514 'message' => __('You cannot react to your own post', 'fluent-community')
515 ]);
516 }
517
518 $react = Reaction::where('user_id', $userId)
519 ->where('object_id', $feed->id)
520 ->where('type', $type)
521 ->objectType('feed')
522 ->first();
523
524 if ($willRemove) {
525 if ($react) {
526 $react->delete();
527 if ($type == 'like') {
528 $feed->reactions_count = $feed->reactions_count - 1;
529 $feed->timestamps = false; // Don't update the updated_at timestamp
530 $feed->save();
531 do_action('fluent_community/feed/react_removed', $feed);
532 }
533 }
534
535 return [
536 'message' => __('Reaction has been removed', 'fluent-community'),
537 'new_count' => $feed->reactions_count
538 ];
539 }
540
541 if ($react) {
542 return [
543 'message' => __('You have already reacted to this post', 'fluent-community'),
544 'new_count' => $feed->reactions_count
545 ];
546 }
547
548 $react = Reaction::create([
549 'user_id' => get_current_user_id(),
550 'object_id' => $feed->id,
551 'type' => $type,
552 'object_type' => 'feed'
553 ]);
554
555 if ($type == 'like') {
556 $feed->reactions_count = $feed->reactions_count + 1;
557 $feed->timestamps = false; // Don't update the updated_at timestamp
558 $feed->save();
559
560 $react->load('xprofile');
561 do_action('fluent_community/feed/react_added', $react, $feed);
562 }
563
564 return [
565 'message' => __('Reaction has been added', 'fluent-community'),
566 'new_count' => $feed->reactions_count
567 ];
568 }
569
570 public function deleteComment(Request $request, $feedId, $commentId)
571 {
572 $feed = Feed::withoutGlobalScopes()->findOrFail($feedId);
573 $comment = Comment::findOrFail($commentId);
574
575 if ($comment->post_id != $feed->id) {
576 return $this->sendError([
577 'message' => __('Invalid comment', 'fluent-community')
578 ]);
579 }
580
581 $user = User::find(get_current_user_id());
582 if ($comment->user_id != get_current_user_id() && !$user->can('delete_any_comment', $feed->space)) {
583 return $this->sendError([
584 'message' => __('You are not allowed to delete this comment', 'fluent-community')
585 ]);
586 }
587
588 do_action('fluent_community/before_comment_delete', $comment);
589
590 if ($comment->media) {
591 do_action('fluent_community/comment/media_deleted', $comment->media);
592 }
593
594 $comment->delete();
595
596 $feed->comments_count = Comment::where('post_id', $feed->id)->count();
597 $feed->timestamps = false; // Don't update the updated_at timestamp
598 $feed->save();
599
600 do_action('fluent_community/comment_deleted_' . $feed->type, $commentId, $feed);
601 do_action('fluent_community/comment_deleted', $commentId, $feed);
602
603 return [
604 'message' => __('Selected comment has been deleted', 'fluent-community')
605 ];
606 }
607
608 public function toggleReaction(Request $request, $feedId, $commentId)
609 {
610 $feed = Feed::withoutGlobalScopes()->findOrFail($feedId);
611 $comment = Comment::findOrFail($commentId);
612
613 if ($comment->post_id != $feed->id) {
614 return $this->sendError([
615 'message' => __('Invalid comment', 'fluent-community')
616 ]);
617 }
618
619 $user = User::findOrFail(get_current_user_id());
620
621 if ($feed->space_id) {
622 $user->verifySpacePermission('registered', $feed->space);
623 }
624
625 $userId = get_current_user_id();
626 if ($userId === $comment->user_id && apply_filters('fluent_community/disable_self_comment_react', false, $feed)) {
627 return $this->sendError([
628 'message' => __('You cannot react to your own comment', 'fluent-community')
629 ]);
630 }
631
632 $reactionState = !!$request->get('state', false);
633
634 if ($reactionState) {
635 // add or update the reaction
636 $reaction = Reaction::firstOrCreate([
637 'user_id' => get_current_user_id(),
638 'object_id' => $comment->id,
639 'object_type' => 'comment',
640 'parent_id' => $feed->id
641 ]);
642
643 if ($reaction->wasRecentlyCreated) {
644 $comment->reactions_count = $comment->reactions_count + 1;
645 $comment->save();
646 do_action('fluent_community/comment/react_added', $reaction, $comment, $feed);
647 }
648 } else {
649 // remove the reaction
650 $deleted = Reaction::where('user_id', get_current_user_id())
651 ->where('object_id', $comment->id)
652 ->where('object_type', 'comment')
653 ->delete();
654
655 if ($deleted) {
656 $comment->reactions_count = $comment->reactions_count - 1;
657 $comment->save();
658 do_action('fluent_community/comment/react_removed', $comment, $feed);
659 }
660 }
661
662 return [
663 'message' => __('Reaction has been toggled', 'fluent-community'),
664 'reactions_count' => $comment->reactions_count,
665 'liked' => $reactionState
666 ];
667 }
668
669 public function show(Request $request, $id)
670 {
671
672 $testComment = Comment::query()->findOrFail($id);
673
674 $comment = Comment::byContentModerationAccessStatus($this->getUser(), $testComment->space)
675 ->with([
676 'xprofile' => function ($q) {
677 return $q->select(ProfileHelper::getXProfilePublicFields());
678 }
679 ])->findOrFail($id);
680
681 // Just to verify the permission
682 Feed::withoutGlobalScopes()
683 ->byUserAccess($this->getUserId())
684 ->findOrFail($comment->post_id);
685
686 if ($request->get('context') == 'edit') {
687 $meta = $comment->meta;
688 unset($comment->meta);
689 $images = Arr::get($meta, 'media_items', []);
690 if ($images) {
691 $comment->media_images = $images;
692 } else {
693 $preview = Arr::get($meta, 'media_preview', []);
694 if ($preview) {
695 $previewUrl = Arr::get($preview, 'image');
696 $provider = Arr::get($preview, 'provider');
697 if ($previewUrl && $provider == 'uploader') {
698 $media = Media::where('media_url', $previewUrl)
699 ->where('object_source', 'comment')
700 ->where('sub_object_id', $comment->id)
701 ->first();
702 if ($media) {
703 $comment->media_images = [
704 [
705 'media_id' => $media->id,
706 'url' => $media->public_url,
707 'type' => $media->media_type,
708 'width' => Arr::get($media->settings, 'width'),
709 'height' => Arr::get($media->settings, 'height'),
710 'provider' => Arr::get($media->settings, 'provider', 'uploader')
711 ]
712 ];
713 }
714 } else {
715 $comment->meta = [
716 'media_preview' => $preview
717 ];
718 }
719 }
720 }
721 }
722
723 $data = [
724 'comment' => $comment
725 ];
726
727 return apply_filters('fluent_community/comment_api_response', $data, $request->all());
728 }
729 }
730