PluginProbe
FluentCommunity – Ultra-Fast High-Performance Social Network, Community, LMS & Online Courses / 2.7.0
FluentCommunity – Ultra-Fast High-Performance Social Network, Community, LMS & Online Courses v2.7.0
2.11.0 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 All 78 releases
fluent-community / app / Http / Controllers / CommentsController.php

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

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