PluginProbe
FluentCommunity – Ultra-Fast High-Performance Social Network, Community, LMS & Online Courses / 1.0.97
FluentCommunity – Ultra-Fast High-Performance Social Network, Community, LMS & Online Courses v1.0.97
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 / FeedsController.php

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

802 lines 26.6 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\Functions\Utility;
6 use FluentCommunity\App\Models\Media;
7 use FluentCommunity\App\Models\NotificationSubscriber;
8 use FluentCommunity\App\Models\Space;
9 use FluentCommunity\App\Models\User;
10 use FluentCommunity\App\Services\CustomSanitizer;
11 use FluentCommunity\App\Services\FeedsHelper;
12 use FluentCommunity\App\Services\Helper;
13 use FluentCommunity\App\Services\Libs\FileSystem;
14 use FluentCommunity\App\Services\ProfileHelper;
15 use FluentCommunity\App\Services\RemoteUrlParser;
16 use FluentCommunity\Framework\Http\Request\Request;
17 use FluentCommunity\App\Models\Comment;
18 use FluentCommunity\App\Models\Feed;
19 use FluentCommunity\App\Models\Reaction;
20 use FluentCommunity\App\Models\BaseSpace;
21 use FluentCommunity\Framework\Support\Arr;
22
23 class FeedsController extends Controller
24 {
25 public function get(Request $request)
26 {
27 $bySpace = $request->get('space');
28 $userId = $request->getSafe('user_id', 'intval', '');
29 $selectedTopic = $request->getSafe('topic_slug', 'sanitize_text_field', '');
30 $search = $request->get('search');
31 if ($bySpace) {
32 // just for validation
33 $space = BaseSpace::where('slug', $bySpace)->first();
34 if (!$space) {
35 return $this->sendError('Invalid space slug');
36 }
37 }
38
39 $feedsQuery = Feed::where('status', 'published')
40 ->select(Feed::$publicColumns)
41 ->with([
42 'xprofile' => function ($q) {
43 $q->select(ProfileHelper::getXProfilePublicFields());
44 },
45 'comments.xprofile' => function ($q) {
46 $q->select(ProfileHelper::getXProfilePublicFields());
47 },
48 'space',
49 'reactions' => function ($q) {
50 $q->with([
51 'xprofile' => function ($query) {
52 $query->select(['user_id', 'avatar']);
53 }
54 ])
55 ->where('type', 'like')
56 ->limit(3);
57 },
58 'terms' => function ($q) {
59 $q->select(['title', 'slug'])
60 ->where('taxonomy_name', 'post_topic');
61 }
62 ]
63 )
64 ->searchBy($search)
65 ->byTopicSlug($selectedTopic)
66 ->customOrderBy($request->get('type', ''));
67
68 $stickyFeed = null;
69
70 $disableSticky = $request->get('disable_sticky', '') == 'yes' || !!$search || !!$selectedTopic;
71
72 if ($bySpace && !$disableSticky) {
73 $feedsQuery = $feedsQuery->filterBySpaceSlug($bySpace)
74 ->where('is_sticky', 0);
75 if ($request->page == 1) {
76 $stickyFeed = Feed::where('space_id', $space->id)
77 ->where('is_sticky', 1)
78 ->with([
79 'xprofile' => function ($q) {
80 $q->select(ProfileHelper::getXProfilePublicFields());
81 },
82 'comments.xprofile' => function ($q) {
83 $q->select(ProfileHelper::getXProfilePublicFields());
84 },
85 'space'
86 ]
87 )
88 ->first();
89 }
90 }
91
92 if ($userId) {
93 $feedsQuery = $feedsQuery->where('user_id', $userId);
94 if ($userId != get_current_user_id()) {
95 $feedsQuery = $feedsQuery->byUserAccess(get_current_user_id());
96 }
97 } else {
98 $feedsQuery->byUserAccess(get_current_user_id());
99 }
100
101 do_action_ref_array('fluent_community/feeds_query', [&$feedsQuery, $request->all()]);
102
103 $feeds = $feedsQuery->paginate();
104
105 // add $stickyFeed to the first page
106 if ($stickyFeed) {
107 $stickyFeed = $this->transformFeed($stickyFeed);
108 }
109
110 $feeds->getCollection()->each(function ($feed) {
111 $this->transformFeed($feed);
112 });
113
114 $data = [
115 'feeds' => $feeds,
116 'sticky' => $stickyFeed
117 ];
118
119 $isMainFeed = $request->get('page') == 1 && !$search && !$userId;
120 if ($isMainFeed && get_current_user_id()) {
121 $data['last_fetched_timestamp'] = current_time('timestamp');
122 }
123
124 return $data;
125 }
126
127 public function getFeedBySlug(Request $request, $feed_slug)
128 {
129 if ($request->get('context') == 'edit') {
130 $feed = Feed::where('slug', $feed_slug)->first();
131
132 if (!$feed || !$feed->hasEditAccess(get_current_user_id())) {
133 return $this->sendError([
134 'message' => 'You do not have permission to edit this feed'
135 ]);
136 }
137
138 return [
139 'feed' => FeedsHelper::transformForEdit($feed)
140 ];
141 }
142
143 $feed = Feed::where('slug', $feed_slug)
144 ->select(Feed::$publicColumns)
145 ->with([
146 'xprofile' => function ($q) {
147 $q->select(ProfileHelper::getXProfilePublicFields());
148 },
149 'space',
150 'comments.xprofile' => function ($q) {
151 $q->select(ProfileHelper::getXProfilePublicFields());
152 },
153 'reactions' => function ($q) {
154 $q->with([
155 'xprofile' => function ($query) {
156 $query->select(['user_id', 'avatar']);
157 }
158 ])
159 ->where('type', 'like')
160 ->limit(3);
161 },
162 'terms' => function ($q) {
163 $q->select(['title', 'slug'])
164 ->where('taxonomy_name', 'post_topic');
165 }
166 ])
167 ->byUserAccess($this->getUserId())
168 ->first();
169
170 if (!$feed) {
171 return $this->sendError([
172 'message' => __('The feed could not be found', 'fluent-commuity')
173 ], 404);
174 }
175
176 $this->transformFeed($feed);
177
178 return [
179 'feed' => $feed
180 ];
181 }
182
183 public function getBookmarks(Request $request)
184 {
185 $userId = get_current_user_id();
186
187 $feedsQuery = Feed::where('status', 'published')
188 ->select(Feed::$publicColumns)
189 ->with([
190 'xprofile' => function ($q) {
191 $q->select(ProfileHelper::getXProfilePublicFields());
192 },
193 'comments.xprofile' => function ($q) {
194 $q->select(ProfileHelper::getXProfilePublicFields());
195 },
196 'space'
197 ]
198 )
199 ->byBookMarked($userId)
200 ->byUserAccess($userId)
201 ->searchBy($request->get('search'));
202
203
204 if ($type = $request->get('type')) {
205 $feedsQuery = $feedsQuery->where('type', $type);
206 }
207
208 $feeds = $feedsQuery->orderBy('id', 'DESC')
209 ->paginate();
210
211 $feeds->getCollection()->each(function ($feed) {
212 $this->transformFeed($feed);
213 });
214
215 $data = [
216 'feeds' => $feeds
217 ];
218
219 if ($request->get('page') == 1) {
220 $lastItem = FeedsHelper::getLastFeedId();
221 if ($lastItem) {
222 $data['last_id'] = $lastItem;
223 }
224 }
225
226 return $data;
227 }
228
229 public function store(Request $request)
230 {
231 $user = $this->getUser(true);
232 do_action('fluent_community/check_rate_limit/create_post', $user);
233 $requestData = $request->all();
234
235 $data = $this->sanitizeAndValidateData($requestData);
236
237
238 if ($isDulicate = $this->checkForDuplicatePost($user->ID, $data['message'])) {
239 return $isDulicate;
240 }
241
242 $feed = new Feed();
243 $feed->user_id = $user->ID;
244
245 if ($spaceSlug = $request->get('space')) {
246 $data['space_id'] = $this->validateAndSetSpace($spaceSlug, $user);
247 } else if (!Helper::hasGlobalPost()) {
248 return $this->sendError([
249 'message' => __('Please select a valid space to post in.', 'fluent-community')
250 ]);
251 }
252
253 $message = $data['message'];
254 $mentions = FeedsHelper::getMentions($data['message'], Arr::get($data, 'space_id'));
255 if ($mentions) {
256 $data['message'] = $message;
257 $message = $mentions['text'];
258 }
259
260 // replace new line with br
261 $data['message_rendered'] = wp_kses_post(FeedsHelper::mdToHtml($message));
262
263 [$data, $mediaItems] = FeedsHelper::processFeedMetaData($data, $requestData);
264
265 $data = apply_filters('fluent_community/feed/new_feed_data', $data, $requestData);
266
267 $feed->fill($data);
268
269 $feed->save();
270
271 if ($mediaItems) {
272 $this->saveMediaItems($feed, $mediaItems);
273 }
274
275 $this->handleMentions($feed, $mentions ?? []);
276
277 $feed->load(['xprofile', 'comments.xprofile']);
278 if ($feed->space_id) {
279 $feed->load(['space']);
280 $topicIds = (array)$request->get('topic_ids', []);
281 // take only max topics per post
282 if ($topicIds) {
283 $topicsConfig = Helper::getTopicsConfig();
284 $topicIds = array_slice($topicIds, 0, $topicsConfig['max_topics_per_post']);
285 $feed->attachTopics($topicIds, false);
286 }
287 }
288
289 do_action('fluent_community/feed/created', $feed);
290 if ($feed->space_id) {
291 do_action('fluent_community/space_feed/created', $feed);
292 }
293
294 return [
295 'feed' => $this->transformFeed($feed),
296 'message' => __('Your post has been published', 'fluent-community'),
297 'last_fetched_timestamp' => current_time('timestamp')
298 ];
299 }
300
301 public function update(Request $request, $feedId)
302 {
303 $requestData = $request->all();
304 $data = $this->sanitizeAndValidateData($requestData);
305 $user = $this->getUser(true);
306 $existingFeed = Feed::findOrFail($feedId);
307 $user->canEditFeed($existingFeed, true);
308
309 $message = $data['message'];
310 $mentions = FeedsHelper::getMentions($data['message'], Arr::get($data, 'space_id'));
311 if ($mentions) {
312 $data['message'] = $message;
313 $message = $mentions['text'];
314 }
315
316 // replace new line with br
317 $data['message_rendered'] = wp_kses_post(FeedsHelper::mdToHtml($message));
318
319 [$data, $mediaItems] = FeedsHelper::processFeedMetaData($data, $requestData, $existingFeed);
320
321 $data = apply_filters('fluent_community/feed/update_feed_data', $data, $requestData);
322
323 if ($message != $existingFeed->message) {
324 $data['meta']['last_edited'] = [
325 'user_id' => $user->ID,
326 'time' => current_time('mysql')
327 ];
328 }
329
330 $data = apply_filters('fluent_community/feed/update_data', $data, $existingFeed);
331 $existingFeed->fill($data);
332 $dirty = $existingFeed->getDirty();
333
334 $existingFeed->fill($data);
335 $existingFeed->save();
336
337 if ($message != $existingFeed->message) {
338 $editHistory = $existingFeed->getCustomMeta('_edit_history', []);
339 if (!$editHistory) {
340 $editHistory = [];
341 }
342
343 $editHistory[] = array_filter([
344 'user_id' => $user->ID,
345 'time' => current_time('mysql'),
346 'prev_message' => $existingFeed->message,
347 'prev_title' => $existingFeed->title
348 ]);
349
350 // get last 5 edit history
351 $editHistory = array_slice($editHistory, -5);
352 $existingFeed->updateCustomMeta('_edit_history', $editHistory);
353 }
354
355 if ($mediaItems) {
356 $this->saveMediaItems($existingFeed, $mediaItems);
357 }
358
359 $existingFeed->load(['xprofile', 'comments.xprofile']);
360
361 if ($existingFeed->space_id) {
362 $existingFeed->load(['space']);
363 $topicIds = (array)Arr::get($requestData, 'topic_ids', []);
364 // take only max topics per post
365 if ($topicIds) {
366 $topicsConfig = Helper::getTopicsConfig();
367 $topicIds = array_slice($topicIds, 0, $topicsConfig['max_topics_per_post']);
368 $existingFeed->attachTopics($topicIds, true);
369 }
370 }
371
372 if ($dirty) {
373 do_action('fluent_community/feed/updated', $existingFeed, $dirty);
374 if ($existingFeed->space_id) {
375 do_action('fluent_community/space_feed/updated', $existingFeed);
376 }
377 }
378
379 return [
380 'feed' => $this->transformFeed($existingFeed),
381 'message' => __('Your post has been updated', 'fluent-community')
382 ];
383 }
384
385 public function patchFeed(Request $request, $feedId)
386 {
387 $feed = Feed::findOrFail($feedId);
388 $user = $this->getUser(true);
389
390 $isMod = $user->isCommunityModerator();
391 $isAuthor = $feed->user_id == $user->ID;
392
393 if (!$isMod && !$isAuthor) {
394 return $this->sendError([
395 'message' => __('You do not have permission to perform this action', 'fluent-community')
396 ]);
397 }
398
399 $allData = $request->all();
400 $validKeys = ['is_sticky', 'priority', 'comments_disabled'];
401
402 if (!$isMod) {
403 $validKeys = ['comments_disabled'];
404 }
405
406 $data = Arr::only($allData, $validKeys);
407
408 $data = array_map('intval', $data);
409
410 if (isset($data['is_sticky'])) {
411 $data['is_sticky'] = $data['is_sticky'] ? 1 : 0;
412 if ($data['is_sticky'] && $feed->space_id) {
413 // remove all the sticky posts from the space
414 Feed::where('space_id', $feed->space_id)->update(['is_sticky' => 0]);
415 }
416 }
417
418 if (isset($data['comments_disabled'])) {
419 $meta = $feed->meta;
420 $meta['comments_disabled'] = $data['comments_disabled'] ? 'yes' : 'no';
421 $data['meta'] = $meta;
422 }
423
424
425 if ($data) {
426 $feed->fill($data);
427 $dirty = $feed->getDirty();
428 if ($dirty) {
429 $feed->save();
430 do_action('fluent_community/feed/updated', $feed, $dirty);
431 }
432 }
433
434 return [
435 'feed' => $feed,
436 'message' => __('Feed updated', 'fluent-community')
437 ];
438 }
439
440 public function getLinks(Request $request)
441 {
442 return [
443 'links' => Helper::getFeedLinks()
444 ];
445 }
446
447 public function updateLinks(Request $request)
448 {
449 $links = $request->get('links', []);
450
451 $links = array_map(function ($link) {
452 return CustomSanitizer::santizeLinkItem($link);
453 }, $links);
454
455 Helper::updateFeedLinks($links);
456
457 return [
458 'message' => __('Links have been updated.', 'fluent-community'),
459 'links' => $links
460 ];
461 }
462
463 private function saveMediaItems($feed, $mediaItems)
464 {
465 foreach ($mediaItems as $media) {
466 $media->feed_id = $feed->id;
467 $media->is_active = 1;
468 $media->object_source = 'feed';
469 $media->save();
470 }
471 }
472
473 private function handleMentions($feed, $mentions)
474 {
475 if ($mentions) {
476 do_action('fluent_community/feed_mentioned', $feed, $mentions['users']);
477 }
478 }
479
480 private function sanitizeAndValidateData($data)
481 {
482 $data['type'] = 'text';
483
484 $this->validate($data, [
485 'message' => 'required',
486 'type' => 'required'
487 ]);
488
489 return FeedsHelper::sanitizeAndValidateData($data);
490 }
491
492 private function checkForDuplicatePost($userId, $message)
493 {
494 $message = trim($message);
495
496 $exist = Feed::where('user_id', $userId)
497 ->where('message', $message)
498 ->where('created_at', '>', gmdate('Y-m-d H:i:s', current_time('timestamp') - 7 * 24 * 60 * 60))
499 ->first();
500
501 if ($exist) {
502 return $this->sendError(['message' => 'No duplicate post please!']);
503 }
504
505 return false;
506 }
507
508 private function validateAndSetSpace($spaceSlug, $user)
509 {
510 if ($spaceSlug == '__self__post__') {
511 if (!Helper::hasGlobalPost()) {
512 throw new \Exception(__('Please select a valid space to post in', 'fluent-community'));
513 }
514
515 return null;
516 }
517
518 $space = Space::where('slug', $spaceSlug)->first();
519
520 if (!$space) {
521 throw new \Exception(__('Please select a valid space to post in', 'fluent-community'));
522 }
523
524 $user->verifySpacePermission('can_create_post', $space);
525
526 return $space->id;
527 }
528
529 public function deleteFeed(Request $request, $feed_id)
530 {
531 $feed = Feed::findOrFail($feed_id);
532
533 $user = User::find(get_current_user_id());
534 $user->canDeleteFeed($feed, true);
535 do_action('fluent_community/feed/before_deleted', $feed);
536 $feed->delete();
537
538 do_action('fluent_community/feed/deleted', $feed_id);
539
540 return [
541 'message' => 'Feed has been deleted successfully'
542 ];
543 }
544
545 public function deleteMediaPreview(Request $request, $feed_id)
546 {
547 $feed = Feed::findOrFail($feed_id);
548 $user = User::find(get_current_user_id());
549 $user->canDeleteFeed($feed, true);
550
551 do_action('fluent_community/feed/media_deleted', $feed->media);
552
553 $meta = $feed->meta;
554 $meta['media_preview'] = null;
555
556 $feed->meta = $meta;
557 $feed->save();
558
559 return [
560 'message' => __('Media preview image has been removed successfully.', 'fluent-community')
561 ];
562 }
563
564 public function handleMediaUpload(Request $request)
565 {
566 $allowedTypes = implode(
567 ',',
568 apply_filters('fluent_community/support_attachment_types', [
569 'image/jpeg',
570 'image/pjpeg',
571 'image/jpeg',
572 'image/pjpeg',
573 'image/png',
574 'image/gif',
575 'image/webp'
576 ])
577 );
578
579 $files = $this->validate($this->request->files(), [
580 'file' => 'mimetypes:' . $allowedTypes,
581 // 'source' => 'required|in:feed,avatar,comment,cover,space'
582 ], [
583 'file.mimetypes' => __('The file must be an image type.', 'fluent-community')
584 ]);
585
586 $uploadedFiles = FileSystem::put($files);
587
588 $file = $uploadedFiles[0];
589
590 $willWebPConvert = apply_filters('fluent_community/convert_image_to_webp', true, $file);
591
592 if ($request->get('resize') && $maxWidth = $request->get('max_width')) {
593 $upload_dir = wp_upload_dir();
594 $fileUrl = str_replace($upload_dir['baseurl'], $upload_dir['basedir'], $file['url']);
595 $editor = wp_get_image_editor($fileUrl);
596 if (!is_wp_error($editor) && $editor->get_size()['width'] > $maxWidth) {
597 // Current file extension
598 $ext = pathinfo($file['url'], PATHINFO_EXTENSION);
599 $imageExtensions = ['jpg', 'jpeg', 'png', 'gif'];
600
601 $willConvert = in_array($ext, $imageExtensions) && $willWebPConvert;
602
603 if ($willConvert) {
604 $imageExtensions = array_map(function ($ext) {
605 return '.' . $ext;
606 }, $imageExtensions);
607 $fileUrl = str_replace($imageExtensions, '.webp', $fileUrl);
608 $file['file'] = str_replace($imageExtensions, '.webp', $file['file']);
609 $file['url'] = str_replace($imageExtensions, '.webp', $file['url']);
610 $file['type'] = 'image/webp';
611 }
612
613 // resize the image
614 $editor->resize($maxWidth, null, false);
615 $editor->set_quality(90);
616 if ($willConvert) {
617 $editor->save($fileUrl, 'image/webp');
618 // remove original file now
619 wp_delete_file(str_replace('.webp', '.' . $ext, $fileUrl));
620 $file['is_converted'] = true;
621 } else {
622 $editor->save($fileUrl);
623 }
624
625 $file['meta'] = [
626 'width' => $editor->get_size()['width'],
627 'height' => $editor->get_size()['height']
628 ];
629 }
630 $file['path'] = $upload_dir['basedir'] . '/fluent-community/' . $file['file'];
631 } else {
632 $upload_dir = wp_upload_dir();
633 $file['path'] = $upload_dir['basedir'] . '/fluent-community/' . $file['file'];
634 }
635
636 if ($willWebPConvert && empty($file['is_converted']) && !$request->get('skip_convert')) {
637 $path = $file['path'];
638 $extension = pathinfo($path, PATHINFO_EXTENSION);
639
640 $convertFromExtensions = ['png', 'jpg', 'jpeg', 'gif'];
641 if ($extension != 'webp' && in_array($extension, $convertFromExtensions)) {
642 // Let's convert to webp
643 $editor = wp_get_image_editor($file['path']);
644 if (!is_wp_error($editor)) {
645 $orginalPath = $file['path'];
646 $file['path'] = str_replace('.' . $extension, '.webp', $file['path']);
647 $file['url'] = str_replace('.' . $extension, '.webp', $file['url']);
648 $file['type'] = 'image/webp';
649 $editor->save($file['path'], 'image/webp');
650 wp_delete_file($orginalPath);
651
652 $file['meta'] = [
653 'width' => $editor->get_size()['width'],
654 'height' => $editor->get_size()['height']
655 ];
656 }
657 }
658 }
659
660 $mediaData = [
661 'media_type' => $file['type'],
662 'driver' => 'local',
663 'media_path' => $file['path'],
664 'media_url' => $file['url'],
665 'settings' => Arr::get($file, 'meta', [])
666 ];
667
668 $mediaData = apply_filters('fluent_community/media_upload_data', $mediaData, $file);
669
670 if (is_wp_error($mediaData)) {
671 return $this->sendError([
672 'message' => $mediaData->get_error_message(),
673 'errors' => $mediaData->get_error_data()
674 ]);
675 }
676
677 if (!$mediaData) {
678 return $this->sendError([
679 'message' => 'Error while uploading the media'
680 ]);
681 }
682
683 // Let's create the media now
684 $media = Media::create($mediaData);
685
686 $mediaUrl = $media->public_url;
687
688 $mediaUrl = add_query_arg([
689 'media_key' => $media->media_key,
690 ], $mediaUrl);
691
692 return [
693 'media' => [
694 'url' => $mediaUrl,
695 'media_key' => $media->media_key,
696 'type' => $media->media_type,
697 'width' => Arr::get($media->settings, 'width'),
698 'height' => Arr::get($media->settings, 'height')
699 ]
700 ];
701 }
702
703 public function getTicker(Request $request)
704 {
705 do_action('fluent_communit/track_activity');
706 $lastLoadedTimeStamp = $request->get('last_fetched_timestamp');
707
708 //check if $lastLoadedTimeStamp is valid date
709 if (!$lastLoadedTimeStamp || (current_time('timestamp') - $lastLoadedTimeStamp) > HOUR_IN_SECONDS) {
710 return [
711 'last_fetched_timestamp' => current_time('timestamp'),
712 'error' => 'Invalid timestamp',
713 'given' => $lastLoadedTimeStamp
714 ];
715 }
716
717 $userId = get_current_user_id();
718 if (!$userId) {
719 return [
720 'last_fetched_timestamp' => current_time('timestamp'),
721 'error' => 'Invalid user'
722 ];
723 }
724
725 $newItemsCount = Feed::where('created_at', '>', date('Y-m-d H:i:s', $lastLoadedTimeStamp))
726 ->where('status', 'published')
727 ->byUserAccess(get_current_user_id())
728 ->count();
729
730 $notificationCount = NotificationSubscriber::unread()->where('user_id', $userId)->count();
731
732 return apply_filters('fluent_community/feed_ticker', [
733 'last_fetched_timestamp' => current_time('timestamp'),
734 'new_items_count' => $newItemsCount > 10 ? 10 : $newItemsCount,
735 'unread_notification_count' => $notificationCount
736 ]);
737 }
738
739 public function getOembed(Request $request)
740 {
741 $url = $request->get('url');
742 // check if the url is valid
743 $metaData = RemoteUrlParser::parse($url);
744
745 if ($metaData && !is_wp_error($metaData)) {
746 return [
747 'oembed' => $metaData
748 ];
749 }
750
751 return $this->send([
752 'message' => 'No oembed data found',
753 'url' => $url
754 ]);
755 }
756
757 public function markdownToHtml(Request $request)
758 {
759 $message = trim(sanitize_textarea_field($request->get('text', '')));
760
761 $html = FeedsHelper::mdToHtml($message);
762
763 return [
764 'html' => $html
765 ];
766 }
767
768 private function transformFeed(Feed $feed)
769 {
770 $userId = $this->getUserId();
771 if ($userId) {
772 $feed->has_user_react = $feed->hasUserReact($userId, 'like');
773 $feed->bookmarked = $feed->hasUserReact($userId, 'bookmark');
774
775 $likedIds = FeedsHelper::getLikedIdsByUserFeedId($feed->id, get_current_user_id());
776 $feed->comments->each(function ($comment) use ($likedIds) {
777 if ($likedIds && in_array($comment->id, $likedIds)) {
778 $comment->liked = 1;
779 }
780 });
781
782 if ($feed->content_type == 'survey') {
783 $votedOptions = $feed->getSurveyCastsByUserId($userId);
784
785 if ($votedOptions) {
786 $surveyConfig = Arr::get($feed->meta, 'survey_config', []);
787 foreach ($surveyConfig['options'] as $index => $option) {
788 if (in_array($option['slug'], $votedOptions)) {
789 $surveyConfig['options'][$index]['voted'] = true;
790 }
791 }
792 $meta = $feed->meta;
793 $meta['survey_config'] = $surveyConfig;
794 $feed->meta = $meta;
795 }
796 }
797 }
798
799 return $feed;
800 }
801 }
802