PluginProbe
FluentCommunity – Ultra-Fast High-Performance Social Network, Community, LMS & Online Courses / 2.7.5
FluentCommunity – Ultra-Fast High-Performance Social Network, Community, LMS & Online Courses v2.7.5
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.5, at app/Http/Controllers/CommentsController.php

727 lines 26.5 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 $commentData['meta']['media_preview'] = array_filter([
409 'image' => sanitize_url(Arr::get($requestData, 'meta.media_preview.image', '')),
410 'type' => Arr::get($requestData, 'meta.media_preview.type', 'image'),
411 'provider' => Arr::get($requestData, 'meta.media_preview.provider', ''),
412 'height' => Arr::get($requestData, 'meta.media_preview.height', 0),
413 'width' => Arr::get($requestData, 'meta.media_preview.width', 0),
414 ]);
415
416 return [$commentData, []];
417 }
418
419 private function validateCommentText($data)
420 {
421 $text = trim(Arr::get($data, 'comment'));
422 $text = CustomSanitizer::unslashMarkdown($text);
423
424 // Decode HTML entities (e.g., &#x20; for space) and strip all whitespace for validation
425 $textForValidation = html_entity_decode($text, ENT_QUOTES | ENT_HTML5, 'UTF-8');
426 $textForValidation = preg_replace('/\s+/u', '', $textForValidation);
427
428 $hasMedia = Arr::get($data, 'media_images', []) || Arr::get($data, 'meta.media_preview.image', false);
429
430 $isReply = !empty($data['parent_id']);
431 if (!$textForValidation && !$hasMedia) {
432 if ($isReply) {
433 throw new \Exception(esc_html__('Reply cannot be empty.', 'fluent-community'), 422);
434 } else {
435 throw new \Exception(esc_html__('Comment cannot be empty.', 'fluent-community'), 422);
436 }
437 }
438
439 $maxCommentLength = apply_filters('fluent_community/max_comment_char_length', 10000);
440 if ($text && strlen($text) > $maxCommentLength) {
441 /* translators: %s is the maximum allowed character count */
442 throw new \Exception(esc_html(sprintf(__('The comment is too long. Please keep it under %s characters.', 'fluent-community'), number_format($maxCommentLength))), 422);
443 }
444
445 return $text;
446 }
447
448 private function verifyCreateCommentPermission($feed)
449 {
450 if (Arr::get($feed->meta, 'comments_disabled') === 'yes') {
451 throw new \Exception(esc_html__('Comments are disabled for this post', 'fluent-community'));
452 }
453
454 $this->verifySpacePermission($feed);
455 }
456
457 private function verifySpacePermission($feed)
458 {
459 if ($feed->space_id && $feed->space) {
460 $user = $this->getUser(true);
461 $user->verifySpacePermission('can_comment', $feed->space);
462
463 if ($feed->space->type == 'course' && Arr::get($feed->space->settings, 'disable_comments') === 'yes') {
464 throw new \Exception(esc_html__('Comments are disabled for this course', 'fluent-community'));
465 }
466 }
467 }
468
469 private function generateCommentHtml($text, $mentions)
470 {
471 $htmlText = $mentions ? $mentions['text'] : $text;
472 return wp_kses_post(FeedsHelper::mdToHtml($htmlText));
473 }
474
475 private function prepareCommentData($feedId, $text, $commentHtml)
476 {
477 return [
478 'post_id' => $feedId,
479 'message' => $text,
480 'message_rendered' => $commentHtml,
481 'type' => 'comment',
482 'meta' => [],
483 ];
484 }
485
486 private function loadCommentRelations($comment)
487 {
488 $comment->load('media');
489 $comment->load([
490 'xprofile' => function ($q) {
491 $q->select(ProfileHelper::getXProfilePublicFields());
492 }
493 ]);
494 }
495
496 public function addOrRemovePostReact(Request $request, $feed_id)
497 {
498 $userId = get_current_user_id();
499 $feed = Feed::withoutGlobalScopes()->byUserAccess($userId)->findOrFail($feed_id);
500 $type = $request->get('react_type', 'like');
501 $willRemove = $request->get('remove');
502
503 if ($feed->status != 'published') {
504 return $this->sendError([
505 'message' => __('This post is not published yet', 'fluent-community')
506 ]);
507 }
508
509 if ($userId === $feed->user_id && apply_filters('fluent_community/disable_self_post_react', false, $feed)) {
510 return $this->sendError([
511 'message' => __('You cannot react to your own post', 'fluent-community')
512 ]);
513 }
514
515 $react = Reaction::where('user_id', $userId)
516 ->where('object_id', $feed->id)
517 ->where('type', $type)
518 ->objectType('feed')
519 ->first();
520
521 if ($willRemove) {
522 if ($react) {
523 $react->delete();
524 if ($type == 'like') {
525 $feed->reactions_count = $feed->reactions_count - 1;
526 $feed->timestamps = false; // Don't update the updated_at timestamp
527 $feed->save();
528 do_action('fluent_community/feed/react_removed', $feed);
529 }
530 }
531
532 return [
533 'message' => __('Reaction has been removed', 'fluent-community'),
534 'new_count' => $feed->reactions_count
535 ];
536 }
537
538 if ($react) {
539 return [
540 'message' => __('You have already reacted to this post', 'fluent-community'),
541 'new_count' => $feed->reactions_count
542 ];
543 }
544
545 $react = Reaction::create([
546 'user_id' => get_current_user_id(),
547 'object_id' => $feed->id,
548 'type' => $type,
549 'object_type' => 'feed'
550 ]);
551
552 if ($type == 'like') {
553 $feed->reactions_count = $feed->reactions_count + 1;
554 $feed->timestamps = false; // Don't update the updated_at timestamp
555 $feed->save();
556
557 $react->load('xprofile');
558 do_action('fluent_community/feed/react_added', $react, $feed);
559 }
560
561 return [
562 'message' => __('Reaction has been added', 'fluent-community'),
563 'new_count' => $feed->reactions_count
564 ];
565 }
566
567 public function deleteComment(Request $request, $feedId, $commentId)
568 {
569 $feed = Feed::withoutGlobalScopes()->findOrFail($feedId);
570 $comment = Comment::findOrFail($commentId);
571
572 if ($comment->post_id != $feed->id) {
573 return $this->sendError([
574 'message' => __('Invalid comment', 'fluent-community')
575 ]);
576 }
577
578 $user = User::find(get_current_user_id());
579 if ($comment->user_id != get_current_user_id() && !$user->can('delete_any_comment', $feed->space)) {
580 return $this->sendError([
581 'message' => __('You are not allowed to delete this comment', 'fluent-community')
582 ]);
583 }
584
585 do_action('fluent_community/before_comment_delete', $comment);
586
587 if ($comment->media) {
588 do_action('fluent_community/comment/media_deleted', $comment->media);
589 }
590
591 $comment->delete();
592
593 $feed->comments_count = Comment::where('post_id', $feed->id)->count();
594 $feed->timestamps = false; // Don't update the updated_at timestamp
595 $feed->save();
596
597 do_action('fluent_community/comment_deleted_' . $feed->type, $commentId, $feed);
598 do_action('fluent_community/comment_deleted', $commentId, $feed);
599
600 return [
601 'message' => __('Selected comment has been deleted', 'fluent-community')
602 ];
603 }
604
605 public function toggleReaction(Request $request, $feedId, $commentId)
606 {
607 $feed = Feed::withoutGlobalScopes()->findOrFail($feedId);
608 $comment = Comment::findOrFail($commentId);
609
610 if ($comment->post_id != $feed->id) {
611 return $this->sendError([
612 'message' => __('Invalid comment', 'fluent-community')
613 ]);
614 }
615
616 $user = User::findOrFail(get_current_user_id());
617
618 if ($feed->space_id) {
619 $user->verifySpacePermission('registered', $feed->space);
620 }
621
622 $userId = get_current_user_id();
623 if ($userId === $comment->user_id && apply_filters('fluent_community/disable_self_comment_react', false, $feed)) {
624 return $this->sendError([
625 'message' => __('You cannot react to your own comment', 'fluent-community')
626 ]);
627 }
628
629 $reactionState = !!$request->get('state', false);
630
631 if ($reactionState) {
632 // add or update the reaction
633 $reaction = Reaction::firstOrCreate([
634 'user_id' => get_current_user_id(),
635 'object_id' => $comment->id,
636 'object_type' => 'comment',
637 'parent_id' => $feed->id
638 ]);
639
640 if ($reaction->wasRecentlyCreated) {
641 $comment->reactions_count = $comment->reactions_count + 1;
642 $comment->save();
643 do_action('fluent_community/comment/react_added', $reaction, $comment, $feed);
644 }
645 } else {
646 // remove the reaction
647 $deleted = Reaction::where('user_id', get_current_user_id())
648 ->where('object_id', $comment->id)
649 ->where('object_type', 'comment')
650 ->delete();
651
652 if ($deleted) {
653 $comment->reactions_count = $comment->reactions_count - 1;
654 $comment->save();
655 do_action('fluent_community/comment/react_removed', $comment, $feed);
656 }
657 }
658
659 return [
660 'message' => __('Reaction has been toggled', 'fluent-community'),
661 'reactions_count' => $comment->reactions_count,
662 'liked' => $reactionState
663 ];
664 }
665
666 public function show(Request $request, $id)
667 {
668
669 $testComment = Comment::query()->findOrFail($id);
670
671 $comment = Comment::byContentModerationAccessStatus($this->getUser(), $testComment->space)
672 ->with([
673 'xprofile' => function ($q) {
674 return $q->select(ProfileHelper::getXProfilePublicFields());
675 }
676 ])->findOrFail($id);
677
678 // Just to verify the permission
679 Feed::withoutGlobalScopes()
680 ->byUserAccess($this->getUserId())
681 ->findOrFail($comment->post_id);
682
683 if ($request->get('context') == 'edit') {
684 $meta = $comment->meta;
685 unset($comment->meta);
686 $images = Arr::get($meta, 'media_items', []);
687 if ($images) {
688 $comment->media_images = $images;
689 } else {
690 $preview = Arr::get($meta, 'media_preview', []);
691 if ($preview) {
692 $previewUrl = Arr::get($preview, 'image');
693 $provider = Arr::get($preview, 'provider');
694 if ($previewUrl && $provider == 'uploader') {
695 $media = Media::where('media_url', $previewUrl)
696 ->where('object_source', 'comment')
697 ->where('sub_object_id', $comment->id)
698 ->first();
699 if ($media) {
700 $comment->media_images = [
701 [
702 'media_id' => $media->id,
703 'url' => $media->public_url,
704 'type' => $media->media_type,
705 'width' => Arr::get($media->settings, 'width'),
706 'height' => Arr::get($media->settings, 'height'),
707 'provider' => Arr::get($media->settings, 'provider', 'uploader')
708 ]
709 ];
710 }
711 } else {
712 $comment->meta = [
713 'media_preview' => $preview
714 ];
715 }
716 }
717 }
718 }
719
720 $data = [
721 'comment' => $comment
722 ];
723
724 return apply_filters('fluent_community/comment_api_response', $data, $request->all());
725 }
726 }
727