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

711 lines 26.0 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 $user = $this->getUser(true);
190
191 $requestData['is_admin'] = $user->hasPermissionOrInCurrentSpace('community_moderator', $feed->space);
192
193 if ($comment->user_id != get_current_user_id() && !$user->can('edit_any_comment', $feed->space)) {
194 return $this->sendError([
195 'message' => __('You are not allowed to edit this comment', 'fluent-community')
196 ]);
197 }
198
199 [$markdown, $inlineMedias] = FeedsHelper::replaceImageUrlsWithRealMediaArchive($text, $feed);
200
201 $mentions = FeedsHelper::getMentions($markdown, $feed->space_id);
202
203 $commentHtml = $this->generateCommentHtml($markdown, $mentions);
204
205 $commentData = $this->prepareCommentData($feed->id, $text, $commentHtml);
206
207 [$commentData, $mediaItems] = $this->prepareCommentMedia($commentData, $requestData, $comment);
208
209 $commentData = apply_filters('fluent_community/comment/update_comment_data', $commentData, $feed, $requestData, $comment);
210
211 $comment->fill($commentData);
212
213 $dirty = $comment->getDirty();
214
215 if ($dirty) {
216 $comment->save();
217 }
218
219 // Merge and save all media in one loop
220 $mediaItems = $mediaItems ? (is_array($mediaItems) ? $mediaItems : [$mediaItems]) : [];
221
222 if ($inlineMedias) {
223 $mediaItems = array_merge($mediaItems, $inlineMedias);
224 }
225
226 $allMediaIds = [];
227
228 if ($mediaItems) {
229 foreach ($mediaItems as $media) {
230 $media->fill([
231 'is_active' => 1,
232 'feed_id' => $feed->id,
233 'object_source' => 'comment',
234 'sub_object_id' => $comment->id
235 ]);
236 $media->save();
237 $allMediaIds[] = $media->id;
238 }
239 }
240
241 // Remove old media not in current list
242 $otherMedias = Media::where('object_source', 'comment')
243 ->when($allMediaIds, function ($q) use ($allMediaIds) {
244 $q->whereNotIn('id', $allMediaIds);
245 })
246 ->where('sub_object_id', $comment->id)
247 ->get();
248
249 if (!$otherMedias->isEmpty()) {
250 do_action('fluent_community/comment/media_deleted', $otherMedias);
251 }
252
253 $this->loadCommentRelations($comment);
254
255 if ($dirty) {
256 do_action('fluent_community/comment_updated', $comment, $feed);
257 do_action('fluent_community/comment_updated_' . $feed->type, $comment, $feed);
258 }
259
260 return [
261 'comment' => $comment,
262 'message' => __('Comment has been updated', 'fluent-community'),
263 ];
264 }
265
266 public function patchComment(Request $request, $feedId, $commentId)
267 {
268 $feed = Feed::withoutGlobalScopes()->findOrFail($feedId);
269
270 $comment = Comment::findOrFail($commentId);
271
272 $user = $this->getUser(true);
273
274 $isMod = $user && $user->hasPermissionOrInCurrentSpace('community_moderator', $feed->space);
275 $isAdmin = $user && $user->hasPermissionOrInCurrentSpace('community_admin', $feed->space);
276
277 if (!$isMod && !$isAdmin) {
278 return $this->sendError([
279 'message' => __('You do not have permission to perform this action', 'fluent-community')
280 ]);
281 }
282
283 $allData = $request->all();
284 $validKeys = ['is_sticky'];
285
286 $data = Arr::only($allData, $validKeys);
287
288 $data = array_map('intval', $data);
289
290 if (isset($data['is_sticky'])) {
291 if ($comment->parent_id) {
292 return $this->sendError([
293 'message' => __('You cannot pin a reply comment', 'fluent-community')
294 ]);
295 }
296
297 $data['is_sticky'] = $data['is_sticky'] ? 1 : 0;
298 if ($data['is_sticky']) {
299 Comment::where('post_id', $feed->id)->update(['is_sticky' => 0]);
300 }
301 }
302
303 if ($data) {
304 $comment->fill($data);
305 $dirty = $comment->getDirty();
306 if ($dirty) {
307 $comment->save();
308 do_action('fluent_community/comment/updated', $comment, $dirty);
309 }
310 }
311
312 return apply_filters('fluent_community/comment/patch_comment_response', [
313 'comment' => $comment,
314 'message' => __('Comment updated', 'fluent-community')
315 ], $comment, $feed, $request->all());
316 }
317
318 private function prepareCommentMedia($commentData, $requestData, $exisitngComment = null)
319 {
320 $mediaImages = Arr::get($requestData, 'media_images', []);
321
322 if ($mediaImages) {
323 if ($exisitngComment) {
324 $mediaItems = [];
325 $mediaData = [];
326 foreach ($mediaImages as $mediaImage) {
327 $id = Arr::get($mediaImage, 'media_id');
328 if ($id) {
329 $media = Media::where('sub_object_id', $exisitngComment->id)
330 ->where('object_source', 'comment')
331 ->find($id);
332 } else {
333 $media = Helper::getMediaFromUrl($mediaImage);
334 }
335
336 if ($media) {
337 $mediaItems[] = $media;
338 $mediaData[] = [
339 'media_id' => $media->id,
340 'url' => $media->public_url,
341 'type' => 'image',
342 'width' => Arr::get($media->settings, 'width'),
343 'height' => Arr::get($media->settings, 'height'),
344 'provider' => Arr::get($media->settings, 'provider', 'uploader')
345 ];
346 }
347 }
348 $commentData['meta']['media_items'] = $mediaData;
349 return [$commentData, $mediaItems];
350 }
351
352 $uploadedImages = Helper::getMediaByProvider($mediaImages);
353 if ($uploadedImages) {
354 $mediaItems = Helper::getMediaItemsFromUrl($uploadedImages);
355 if ($mediaItems) {
356 $mediaPreviews = [];
357 foreach ($mediaItems as $mediaItem) {
358 $mediaData = [
359 'media_id' => $mediaItem->id,
360 'url' => $mediaItem->public_url,
361 'type' => 'image',
362 'width' => Arr::get($mediaItem->settings, 'width'),
363 'height' => Arr::get($mediaItem->settings, 'height'),
364 'provider' => Arr::get($mediaItem->settings, 'provider', 'uploader')
365 ];
366
367 $mediaPreviews[] = array_filter($mediaData);
368 }
369 $commentData['meta']['media_items'] = $mediaPreviews;
370 return [$commentData, $mediaItems];
371 }
372 }
373 }
374
375 if (empty($requestData['meta']['media_preview']['image'])) {
376 return [$commentData, []];
377 }
378
379 if ($exisitngComment) {
380 $image = sanitize_url(Arr::get($requestData, 'meta.media_preview.image', ''));
381 $existingMedia = Media::where('media_url', $image)
382 ->where('object_source', 'comment')
383 ->where('sub_object_id', $exisitngComment->id)
384 ->first();
385
386 if ($existingMedia) {
387 $commentData['meta'] = $exisitngComment->meta;
388 return [$commentData, [$existingMedia]];
389 }
390 }
391
392 $commentData['meta']['media_preview'] = array_filter([
393 'image' => sanitize_url(Arr::get($requestData, 'meta.media_preview.image', '')),
394 'type' => Arr::get($requestData, 'meta.media_preview.type', 'image'),
395 'provider' => Arr::get($requestData, 'meta.media_preview.provider', ''),
396 'height' => Arr::get($requestData, 'meta.media_preview.height', 0),
397 'width' => Arr::get($requestData, 'meta.media_preview.width', 0),
398 ]);
399
400 return [$commentData, []];
401 }
402
403 private function validateCommentText($data)
404 {
405 $text = trim(Arr::get($data, 'comment'));
406 $text = CustomSanitizer::unslashMarkdown($text);
407
408 // Decode HTML entities (e.g., &#x20; for space) and strip all whitespace for validation
409 $textForValidation = html_entity_decode($text, ENT_QUOTES | ENT_HTML5, 'UTF-8');
410 $textForValidation = preg_replace('/\s+/u', '', $textForValidation);
411
412 $hasMedia = Arr::get($data, 'media_images', []) || Arr::get($data, 'meta.media_preview.image', false);
413
414 $isReply = !empty($data['parent_id']);
415 if (!$textForValidation && !$hasMedia) {
416 if ($isReply) {
417 throw new \Exception(esc_html__('Reply cannot be empty.', 'fluent-community'), 422);
418 } else {
419 throw new \Exception(esc_html__('Comment cannot be empty.', 'fluent-community'), 422);
420 }
421 }
422
423 $maxCommentLength = apply_filters('fluent_community/max_comment_char_length', 10000);
424 if ($text && strlen($text) > $maxCommentLength) {
425 /* translators: %s is the maximum allowed character count */
426 throw new \Exception(esc_html(sprintf(__('The comment is too long. Please keep it under %s characters.', 'fluent-community'), number_format($maxCommentLength))), 422);
427 }
428
429 return $text;
430 }
431
432 private function verifyCreateCommentPermission($feed)
433 {
434 if (Arr::get($feed->meta, 'comments_disabled') === 'yes') {
435 throw new \Exception(esc_html__('Comments are disabled for this post', 'fluent-community'));
436 }
437
438 $this->verifySpacePermission($feed);
439 }
440
441 private function verifySpacePermission($feed)
442 {
443 if ($feed->space_id && $feed->space) {
444 $user = $this->getUser(true);
445 $user->verifySpacePermission('can_comment', $feed->space);
446
447 if ($feed->space->type == 'course' && Arr::get($feed->space->settings, 'disable_comments') === 'yes') {
448 throw new \Exception(esc_html__('Comments are disabled for this course', 'fluent-community'));
449 }
450 }
451 }
452
453 private function generateCommentHtml($text, $mentions)
454 {
455 $htmlText = $mentions ? $mentions['text'] : $text;
456 return wp_kses_post(FeedsHelper::mdToHtml($htmlText));
457 }
458
459 private function prepareCommentData($feedId, $text, $commentHtml)
460 {
461 return [
462 'post_id' => $feedId,
463 'message' => $text,
464 'message_rendered' => $commentHtml,
465 'type' => 'comment',
466 'meta' => [],
467 ];
468 }
469
470 private function loadCommentRelations($comment)
471 {
472 $comment->load('media');
473 $comment->load([
474 'xprofile' => function ($q) {
475 $q->select(ProfileHelper::getXProfilePublicFields());
476 }
477 ]);
478 }
479
480 public function addOrRemovePostReact(Request $request, $feed_id)
481 {
482 $userId = get_current_user_id();
483 $feed = Feed::withoutGlobalScopes()->byUserAccess($userId)->findOrFail($feed_id);
484 $type = $request->get('react_type', 'like');
485 $willRemove = $request->get('remove');
486
487 if ($feed->status != 'published') {
488 return $this->sendError([
489 'message' => __('This post is not published yet', 'fluent-community')
490 ]);
491 }
492
493 if ($userId === $feed->user_id && apply_filters('fluent_community/disable_self_post_react', false, $feed)) {
494 return $this->sendError([
495 'message' => __('You cannot react to your own post', 'fluent-community')
496 ]);
497 }
498
499 $react = Reaction::where('user_id', $userId)
500 ->where('object_id', $feed->id)
501 ->where('type', $type)
502 ->objectType('feed')
503 ->first();
504
505 if ($willRemove) {
506 if ($react) {
507 $react->delete();
508 if ($type == 'like') {
509 $feed->reactions_count = $feed->reactions_count - 1;
510 $feed->timestamps = false; // Don't update the updated_at timestamp
511 $feed->save();
512 do_action('fluent_community/feed/react_removed', $feed);
513 }
514 }
515
516 return [
517 'message' => __('Reaction has been removed', 'fluent-community'),
518 'new_count' => $feed->reactions_count
519 ];
520 }
521
522 if ($react) {
523 return [
524 'message' => __('You have already reacted to this post', 'fluent-community'),
525 'new_count' => $feed->reactions_count
526 ];
527 }
528
529 $react = Reaction::create([
530 'user_id' => get_current_user_id(),
531 'object_id' => $feed->id,
532 'type' => $type,
533 'object_type' => 'feed'
534 ]);
535
536 if ($type == 'like') {
537 $feed->reactions_count = $feed->reactions_count + 1;
538 $feed->timestamps = false; // Don't update the updated_at timestamp
539 $feed->save();
540
541 $react->load('xprofile');
542 do_action('fluent_community/feed/react_added', $react, $feed);
543 }
544
545 return [
546 'message' => __('Reaction has been added', 'fluent-community'),
547 'new_count' => $feed->reactions_count
548 ];
549 }
550
551 public function deleteComment(Request $request, $feedId, $commentId)
552 {
553 $feed = Feed::withoutGlobalScopes()->findOrFail($feedId);
554 $comment = Comment::findOrFail($commentId);
555
556 if ($comment->post_id != $feed->id) {
557 return $this->sendError([
558 'message' => __('Invalid comment', 'fluent-community')
559 ]);
560 }
561
562 $user = User::find(get_current_user_id());
563 if ($comment->user_id != get_current_user_id() && !$user->can('delete_any_comment', $feed->space)) {
564 return $this->sendError([
565 'message' => __('You are not allowed to delete this comment', 'fluent-community')
566 ]);
567 }
568
569 do_action('fluent_community/before_comment_delete', $comment);
570
571 if ($comment->media) {
572 do_action('fluent_community/comment/media_deleted', $comment->media);
573 }
574
575 $comment->delete();
576
577 $feed->comments_count = Comment::where('post_id', $feed->id)->count();
578 $feed->timestamps = false; // Don't update the updated_at timestamp
579 $feed->save();
580
581 do_action('fluent_community/comment_deleted_' . $feed->type, $commentId, $feed);
582 do_action('fluent_community/comment_deleted', $commentId, $feed);
583
584 return [
585 'message' => __('Selected comment has been deleted', 'fluent-community')
586 ];
587 }
588
589 public function toggleReaction(Request $request, $feedId, $commentId)
590 {
591 $feed = Feed::withoutGlobalScopes()->findOrFail($feedId);
592 $comment = Comment::findOrFail($commentId);
593
594 if ($comment->post_id != $feed->id) {
595 return $this->sendError([
596 'message' => __('Invalid comment', 'fluent-community')
597 ]);
598 }
599
600 $user = User::findOrFail(get_current_user_id());
601
602 if ($feed->space_id) {
603 $user->verifySpacePermission('registered', $feed->space);
604 }
605
606 $userId = get_current_user_id();
607 if ($userId === $comment->user_id && apply_filters('fluent_community/disable_self_comment_react', false, $feed)) {
608 return $this->sendError([
609 'message' => __('You cannot react to your own comment', 'fluent-community')
610 ]);
611 }
612
613 $reactionState = !!$request->get('state', false);
614
615 if ($reactionState) {
616 // add or update the reaction
617 $reaction = Reaction::firstOrCreate([
618 'user_id' => get_current_user_id(),
619 'object_id' => $comment->id,
620 'object_type' => 'comment',
621 'parent_id' => $feed->id
622 ]);
623
624 if ($reaction->wasRecentlyCreated) {
625 $comment->reactions_count = $comment->reactions_count + 1;
626 $comment->save();
627 do_action('fluent_community/comment/react_added', $reaction, $comment, $feed);
628 }
629 } else {
630 // remove the reaction
631 $deleted = Reaction::where('user_id', get_current_user_id())
632 ->where('object_id', $comment->id)
633 ->where('object_type', 'comment')
634 ->delete();
635
636 if ($deleted) {
637 $comment->reactions_count = $comment->reactions_count - 1;
638 $comment->save();
639 do_action('fluent_community/comment/react_removed', $comment, $feed);
640 }
641 }
642
643 return [
644 'message' => __('Reaction has been toggled', 'fluent-community'),
645 'reactions_count' => $comment->reactions_count,
646 'liked' => $reactionState
647 ];
648 }
649
650 public function show(Request $request, $id)
651 {
652
653 $testComment = Comment::query()->findOrFail($id);
654
655 $comment = Comment::byContentModerationAccessStatus($this->getUser(), $testComment->space)
656 ->with([
657 'xprofile' => function ($q) {
658 return $q->select(ProfileHelper::getXProfilePublicFields());
659 }
660 ])->findOrFail($id);
661
662 // Just to verify the permission
663 Feed::withoutGlobalScopes()
664 ->byUserAccess($this->getUserId())
665 ->findOrFail($comment->post_id);
666
667 if ($request->get('context') == 'edit') {
668 $meta = $comment->meta;
669 unset($comment->meta);
670 $images = Arr::get($meta, 'media_items', []);
671 if ($images) {
672 $comment->media_images = $images;
673 } else {
674 $preview = Arr::get($meta, 'media_preview', []);
675 if ($preview) {
676 $previewUrl = Arr::get($preview, 'image');
677 $provider = Arr::get($preview, 'provider');
678 if ($previewUrl && $provider == 'uploader') {
679 $media = Media::where('media_url', $previewUrl)
680 ->where('object_source', 'comment')
681 ->where('sub_object_id', $comment->id)
682 ->first();
683 if ($media) {
684 $comment->media_images = [
685 [
686 'media_id' => $media->id,
687 'url' => $media->public_url,
688 'type' => $media->media_type,
689 'width' => Arr::get($media->settings, 'width'),
690 'height' => Arr::get($media->settings, 'height'),
691 'provider' => Arr::get($media->settings, 'provider', 'uploader')
692 ]
693 ];
694 }
695 } else {
696 $comment->meta = [
697 'media_preview' => $preview
698 ];
699 }
700 }
701 }
702 }
703
704 $data = [
705 'comment' => $comment
706 ];
707
708 return apply_filters('fluent_community/comment_api_response', $data, $request->all());
709 }
710 }
711