get('space'); $userId = $request->getSafe('user_id', 'intval', ''); $selectedTopic = $request->getSafe('topic_slug', 'sanitize_text_field', ''); $search = $request->get('search'); if ($bySpace) { // just for validation $space = BaseSpace::where('slug', $bySpace)->first(); if (!$space) { return $this->sendError('Invalid space slug'); } } $feedsQuery = Feed::where('status', 'published') ->select(Feed::$publicColumns) ->with([ 'xprofile' => function ($q) { $q->select(ProfileHelper::getXProfilePublicFields()); }, 'comments.xprofile' => function ($q) { $q->select(ProfileHelper::getXProfilePublicFields()); }, 'space', 'reactions' => function ($q) { $q->with([ 'xprofile' => function ($query) { $query->select(['user_id', 'avatar']); } ]) ->where('type', 'like') ->limit(3); } ] ) ->searchBy($search) ->byTopicSlug($selectedTopic) ->customOrderBy($request->get('type', '')); $stickyFeed = null; $disableSticky = $request->get('disable_sticky', '') == 'yes' || !!$search || !!$selectedTopic; if ($bySpace && !$disableSticky) { $feedsQuery = $feedsQuery->filterBySpaceSlug($bySpace) ->where('is_sticky', 0); if ($request->page == 1) { $stickyFeed = Feed::where('space_id', $space->id) ->where('is_sticky', 1) ->with([ 'xprofile' => function ($q) { $q->select(ProfileHelper::getXProfilePublicFields()); }, 'comments.xprofile' => function ($q) { $q->select(ProfileHelper::getXProfilePublicFields()); }, 'space' ] ) ->first(); } } if ($userId) { $feedsQuery = $feedsQuery->where('user_id', $userId); if ($userId != get_current_user_id()) { $feedsQuery = $feedsQuery->byUserAccess(get_current_user_id()); } } else { $feedsQuery->byUserAccess(get_current_user_id()); } do_action_ref_array('fluent_community/feeds_query', [&$feedsQuery, $request->all()]); $feeds = $feedsQuery->paginate(); // add $stickyFeed to the first page if ($stickyFeed) { $stickyFeed = $this->transformFeed($stickyFeed); } $feeds->getCollection()->each(function ($feed) { $this->transformFeed($feed); }); $data = [ 'feeds' => $feeds, 'sticky' => $stickyFeed ]; if ($request->get('page') == 1) { $lastItem = FeedsHelper::getLastFeedId(); if ($lastItem) { $data['last_id'] = $lastItem; } } return $data; } public function getFeedBySlug(Request $request, $feed_slug) { if ($request->get('context') == 'edit') { $feed = Feed::where('slug', $feed_slug)->with(['space'])->first(); if (!$feed || !$feed->hasEditAccess(get_current_user_id())) { return $this->sendError([ 'message' => 'You do not have permission to edit this feed' ]); } return [ 'feed' => $feed ]; } $feed = Feed::where('slug', $feed_slug) ->select(Feed::$publicColumns) ->with([ 'xprofile' => function ($q) { $q->select(ProfileHelper::getXProfilePublicFields()); }, 'space', 'comments.xprofile' => function ($q) { $q->select(ProfileHelper::getXProfilePublicFields()); }, 'reactions' => function ($q) { $q->with([ 'xprofile' => function ($query) { $query->select(['user_id', 'avatar']); } ]) ->where('type', 'like') ->limit(3); } ]) ->byUserAccess($this->getUserId()) ->first(); if (!$feed) { return $this->sendError([ 'message' => __('The feed could not be found', 'fluent-commuity') ], 404); } $this->transformFeed($feed); return [ 'feed' => $feed ]; } public function getBookmarks(Request $request) { $userId = get_current_user_id(); $feedsQuery = Feed::where('status', 'published') ->select(Feed::$publicColumns) ->with([ 'xprofile' => function ($q) { $q->select(ProfileHelper::getXProfilePublicFields()); }, 'comments.xprofile' => function ($q) { $q->select(ProfileHelper::getXProfilePublicFields()); }, 'space' ] ) ->byBookMarked($userId) ->byUserAccess($userId) ->searchBy($request->get('search')); if ($type = $request->get('type')) { $feedsQuery = $feedsQuery->where('type', $type); } $feeds = $feedsQuery->orderBy('id', 'DESC') ->paginate(); $feeds->getCollection()->each(function ($feed) { $this->transformFeed($feed); }); $data = [ 'feeds' => $feeds ]; if ($request->get('page') == 1) { $lastItem = FeedsHelper::getLastFeedId(); if ($lastItem) { $data['last_id'] = $lastItem; } } return $data; } public function store(Request $request) { $userId = get_current_user_id(); $user = $this->getUser(true); do_action('fluent_community/check_rate_limit/create_post', $user); $requestData = $request->all(); $data = $this->sanitizeAndValidateData($requestData); if ($isDulicate = $this->checkForDuplicatePost($userId, $data['message'])) { return $isDulicate; } $feed = new Feed(); $feed->user_id = $userId; if ($spaceSlug = $request->get('space')) { $data['space_id'] = $this->validateAndSetSpace($spaceSlug, $user); } else { // Check if the user has global post permission if (!Helper::hasGlobalPost()) { return $this->sendError([ 'message' => __('Please select a valid space to post in', 'fluent-community') ]); } } $message = $data['message']; $mentions = FeedsHelper::getMentions($data['message'], Arr::get($data, 'space_id')); if ($mentions) { $data['message'] = $message; $message = $mentions['text']; } // replace new line with br $data['message_rendered'] = wp_kses_post(FeedsHelper::mdToHtml($message)); $mediaItems = null; if (!empty($data['survey'])) { $this->handleSurveyConfig($data); } elseif (Arr::get($requestData, 'meta.media_preview.provider') == 'giphy') { $this->setGiphyMediaPreview($data, $requestData); } else { $mediaItems = $this->processNewMedia($requestData, $data); } $data = apply_filters('fluent_community/feed_data/new', $data); $feed->fill($data); $feed->save(); if ($mediaItems) { $this->saveMediaItems($feed, $mediaItems); } $this->handleMentions($feed, $mentions ?? []); $this->syncHashTags($feed, $data['message']); $feed->load(['xprofile', 'comments.xprofile']); if ($feed->space_id) { $feed->load(['space']); $topicIds = $request->get('topic_ids', []); // take only first 5 topics if ($topicIds) { $topicIds = array_slice($topicIds, 0, apply_filters('fluent_community/max_topic_per_post', 5)); $feed->attachTopics($topicIds, false); } } do_action('fluent_community/feed/created', $feed); if ($feed->space_id) { do_action('fluent_community/space_feed/created', $feed); } return [ 'feed' => $feed, 'message' => __('Feed added', 'fluent-community') ]; } public function update(Request $request, $feedId) { $requestData = $request->all(); $data = $this->sanitizeAndValidateData($requestData); $userId = get_current_user_id(); $user = User::findOrFail($userId); $feed = Feed::find($feedId); if (!$feed) { return $this->sendError(['message' => __('Feed not found', 'fluent-community')]); } $user->canEditFeed($feed, false); if (!$feed->hasEditAccess($userId)) { return $this->send('You do not have permission to edit this feed', 403); } if ($spaceSlug = $request->get('space')) { $data['space_id'] = $this->validateAndSetSpace($spaceSlug, $user); } $message = $data['message']; $mentions = FeedsHelper::getMentions($data['message'], Arr::get($data, 'space_id')); if ($mentions) { $data['message'] = $message; $message = $mentions['text']; } // replace new line with br $data['message_rendered'] = wp_kses_post(FeedsHelper::mdToHtml($message)); $mediaItems = null; if (!empty($data['survey'])) { $this->handleSurveyConfig($data); } elseif (Arr::get($requestData, 'meta.media_preview.provider') == 'giphy') { $this->setGiphyMediaPreview($data, $requestData); } else { $mediaItems = $this->processExistingMedia($feed, $requestData, $data); } if ($message != $feed->message) { $meta = $feed->meta; $meta['last_edited'] = [ 'user_id' => $userId, 'time' => current_time('mysql') ]; $editHistory = $feed->getCustomMeta('_edit_history', []); if (!$editHistory) { $editHistory = []; } $editHistory[] = array_filter([ 'user_id' => $userId, 'time' => current_time('mysql'), 'prev_message' => $feed->message, 'prev_title' => $feed->title ]); // get last 5 edit history $editHistory = array_slice($editHistory, -5); $feed->updateCustomMeta('_edit_history', $editHistory); $data['meta'] = $meta; } $data = apply_filters('fluent_community/feed_data/update', $data, $feed); $feed->fill($data); $feed->save(); if ($mediaItems) { $this->saveMediaItems($feed, $mediaItems); } $this->syncHashTags($feed, $data['message']); $feed->load(['xprofile', 'comments.xprofile']); if ($feed->space_id) { $feed->load(['space']); } return [ 'feed' => $feed, 'message' => __('Feed updated', 'fluent-community') ]; } public function patchFeed(Request $request, $feedId) { $feed = Feed::findOrFail($feedId); $user = $this->getUser(true); $isMod = $user->isCommunityModerator(); $isAuthor = $feed->user_id == $user->ID; if (!$isMod && !$isAuthor) { return $this->sendError([ 'message' => __('You do not have permission to perform this action', 'fluent-community') ]); } $allData = $request->all(); $validKeys = ['is_sticky', 'priority', 'comments_disabled']; if (!$isMod) { $validKeys = ['comments_disabled']; } $data = Arr::only($allData, $validKeys); $data = array_map('intval', $data); if (isset($data['is_sticky'])) { $data['is_sticky'] = $data['is_sticky'] ? 1 : 0; if ($data['is_sticky'] && $feed->space_id) { // remove all the sticky posts from the space Feed::where('space_id', $feed->space_id)->update(['is_sticky' => 0]); } } if (isset($data['comments_disabled'])) { $meta = $feed->meta; $meta['comments_disabled'] = $data['comments_disabled'] ? 'yes' : 'no'; $data['meta'] = $meta; } if ($data) { $feed->fill($data); $feed->save(); } return [ 'feed' => $feed, 'message' => __('Feed updated', 'fluent-community') ]; } public function getLinks(Request $request) { return [ 'links' => Helper::getFeedLinks() ]; } public function updateLinks(Request $request) { $links = $request->get('links', []); $links = array_map(function ($link) { return CustomSanitizer::santizeLinkItem($link); }, $links); Helper::updateFeedLinks($links); return [ 'message' => __('Links has been updated', 'fluent-community'), 'links' => $links ]; } private function setGiphyMediaPreview(&$data, $requestData) { if (empty(Arr::get($requestData, 'meta.media_preview.image'))) { return; } $data['meta']['media_preview'] = array_filter([ 'image' => sanitize_url($requestData['meta']['media_preview']['image']), 'type' => Arr::get($requestData, 'meta.media_preview.type', 'image'), 'provider' => Arr::get($requestData, 'meta.media_preview.provider', ''), 'height' => Arr::get($requestData, 'meta.media_preview.height', 0), 'width' => Arr::get($requestData, 'meta.media_preview.width', 0), ]); } private function handleSurveyConfig(&$data) { if (empty($data['meta'])) { $data['meta'] = []; } $data['meta']['survey_config'] = $data['survey']; $data['content_type'] = 'survey'; } private function processNewMedia($requestData, &$data) { if ($mediaImages = Arr::get($requestData, 'media_images')) { $uploadedImages = Helper::getMediaByProvider($mediaImages); $uploadedMediaItems = Helper::getMediaItemsFromUrl($uploadedImages); $mediaPreviews = $this->generateMediaPreviews($uploadedMediaItems); $this->formatMediaMeta($mediaPreviews, $data, $mediaImages); return $uploadedMediaItems; } if ($media = Arr::get($requestData, 'media')) { $type = Arr::get($media, 'type', 'oembed'); if ($type == 'oembed') { $url = Arr::get($media, 'url'); $metaData = RemoteUrlParser::parse($url); if ($metaData && !is_wp_error($metaData) && (!empty($metaData['image']) || !empty($metaData['html']))) { $data['meta']['media_preview'] = $metaData; return []; } } } $urlMeta = $this->parseFirstUrl($data['message_rendered']); if ($urlMeta) { $data['meta'] = $urlMeta; return []; } // Let's give option to the user to check if there is any fallback do_action_ref_array('fluent_community/feed/meta_fallback', [&$data]); return []; } private function processExistingMedia($feed, $requestData, &$data) { $images = (array)Arr::get($requestData, 'media_images', []); $mediaImages = Helper::getMediaByProvider($images); $metaMediaMetaItems = Helper::getMediaByProvider((array)Arr::get($requestData, 'meta.media_items', [])); $metaMediaPreview = array_filter((array)Arr::get($requestData, 'meta.media_preview', [])); $requestMediaIds = array_column($metaMediaMetaItems, 'media_id'); if (count($mediaImages) == 0 && count($metaMediaMetaItems) == 0) { if (count($metaMediaPreview) === 0) { do_action('fluent_community/feed/media_deleted', $feed->media); $data['meta']['media_preview'] = null; } $previewMeta = $this->parseFirstUrl($data['message_rendered']); if (count($metaMediaPreview) > 0) { $data['meta']['media_preview'] = $metaMediaPreview; } elseif (count($previewMeta) > 0) { $data['meta'] = $previewMeta; } return []; } if (count($mediaImages) == 1 && (count($metaMediaMetaItems) == 0 || count($metaMediaPreview) > 0)) { if (Arr::get($metaMediaPreview, 'is_uploaded')) { $mediaImages[] = $metaMediaPreview['image'] . '?media_key=' . $feed->media[0]->media_key; unset($data['meta']['media_preview']); } elseif (count($metaMediaPreview) > 0) { do_action('fluent_community/feed/media_deleted', $feed->media); } $mediaItems = Helper::getMediaItemsFromUrl($mediaImages); $mediaPreviews = $this->generateMediaPreviews($mediaItems); $this->formatMediaMeta($mediaPreviews, $data, $images); return $mediaItems; } $message = $data['message']; if ($mentions = FeedsHelper::getMentions($message, Arr::get($data, 'space_id'))) { $message = $mentions['text']; } $data['message_rendered'] = FeedsHelper::mdToHtml($message); if (count($mediaImages) > 1) { $mediaItems = $this->processNewMedia($requestData, $data); } $deletedMediaItems = $feed->media()->whereNotIn('id', $requestMediaIds)->get(); do_action('fluent_community/feed/media_deleted', $deletedMediaItems); if (!isset($data['meta']['media_items'])) { $data['meta']['media_items'] = []; } if (!isset($data['meta']['media_preview'])) { $data['meta']['media_preview'] = null; } if ($metaMediaMetaItems) { $filteredData = array_filter($metaMediaMetaItems, function ($item) use ($requestMediaIds) { return in_array($item['media_id'], $requestMediaIds); }); if (count($mediaImages) == 1 && count($filteredData) > 0) { $mediaItems = Helper::getMediaItemsFromUrl($mediaImages); $newMediaItems = $this->generateMediaPreviews($mediaItems); $filteredData = array_merge($filteredData, $newMediaItems); } $data['meta']['media_items'] = array_merge($filteredData, $data['meta']['media_items']); } if (isset($feed->meta['media_preview'])) { if (count($mediaImages) > 1) { $data['meta']['media_preview'] = null; } } return $mediaItems ?? []; } private function generateMediaPreviews($mediaItems) { $mediaPreviews = []; foreach ($mediaItems as $media) { if (!$media || !$media->is_active) { $this->sendError(['message' => 'Invalid media image. Please upload a new one.']); } $data = [ 'media_id' => $media->id, 'url' => $media->public_url, 'type' => 'image', 'width' => Arr::get($media->settings, 'width'), 'height' => Arr::get($media->settings, 'height'), 'provider' => Arr::get($media->settings, 'provider', 'uploader') ]; $mediaPreviews[] = array_filter($data); } return $mediaPreviews; } private function formatMediaMeta($mediaPreviews, &$data, $mediaImages) { $giphyImages = Helper::getMediaByProvider($mediaImages, 'giphy'); $metaMediaItems = Helper::getMediaByProvider($this->request->get('meta.media_items', []), 'giphy'); if (count($mediaPreviews) === 1 && empty($giphyImages) && empty($metaMediaItems)) { $mediaPreview = array_filter([ 'is_uploaded' => true, 'image' => $mediaPreviews[0]['url'], 'type' => 'meta_data', 'width' => Arr::get($mediaPreviews[0], 'width'), 'height' => Arr::get($mediaPreviews[0], 'height') ]); $data['meta']['media_preview'] = $mediaPreview; } elseif ($mediaPreviews) { $data['meta']['media_items'] = $mediaPreviews; } } private function processGiphyImages($requestData, &$data) { if (!isset($data['meta']['media_items'])) { $data['meta']['media_items'] = null; } if ($metaMediaItems = Arr::get($requestData, 'meta.media_items', [])) { $giphyMediaItems = Helper::getMediaByProvider($metaMediaItems, 'giphy'); if ($giphyMediaItems) { $data['meta']['media_items'] = array_merge($giphyMediaItems, (array)$data['meta']['media_items']); } } if ($giphyImages = Helper::getMediaByProvider(Arr::get($requestData, 'media_images', []), 'giphy')) { foreach ($giphyImages as $giphy) { $data['meta']['media_items'][] = [ 'url' => $giphy['url'], 'type' => 'image', 'provider' => 'giphy' ]; } } } private function parseFirstUrl($messageRendered) { $firstUrl = FeedsHelper::findFirstUrl($messageRendered); if ($firstUrl) { $metaData = RemoteUrlParser::parse($firstUrl); if ($metaData && !is_wp_error($metaData) && (!empty($metaData['image']) || !empty($metaData['html']))) { return [ 'media_preview' => $metaData ]; } } return []; } private function saveMediaItems($feed, $mediaItems) { foreach ($mediaItems as $media) { $media->feed_id = $feed->id; $media->is_active = 1; $media->object_source = 'feed'; $media->save(); } } private function handleMentions($feed, $mentions) { if ($mentions) { do_action('fluent_community/feed_mentioned', $feed, $mentions['users']); } } private function syncHashTags($feed, $message) { if ($feed->id) { do_action('fluent_community/feed/hashtags_deleted', $feed->terms); } $hashTags = FeedsHelper::extractHashTags($message); if ($hashTags) { $feed->terms()->sync($hashTags); } } private function sanitizeAndValidateData($data) { $message = CustomSanitizer::unslashMarkdown(trim(Arr::get($data, 'message'))); $type = sanitize_text_field(Arr::get($data, 'type', 'text')); $processedData = [ 'message' => $message, 'type' => $type ]; $survey = Arr::get($data, 'survey', []); if ($survey) { $options = Arr::get($survey, 'options', []); $formattedOptions = []; foreach ($options as $index => $option) { if (empty($option['label'])) { continue; } $formattedOptions[] = [ 'label' => sanitize_text_field($option['label']), 'slug' => 'opt_' . ($index + 1) ]; } if ($formattedOptions) { $processedData['survey'] = [ 'type' => Arr::get($survey, 'type') == 'single_choice' ? 'single_choice' : 'multi_choice', 'options' => $formattedOptions ]; } } $this->validate($processedData, [ 'message' => 'required|min:10', 'type' => 'required' ]); $maxlen = apply_filters('fluent_community/max_post_length', 15000); if (\strlen($message) > $maxlen) { throw new \Exception(esc_html__('Post message is too long', 'fluent-community')); } $titlePref = Utility::postTitlePref(); if ($titlePref) { $processedData['title'] = sanitize_text_field(Arr::get($data, 'title')); if ($titlePref == 'required' && empty($processedData['title'])) { throw new \Exception(esc_html__('Title is required. Please provide a title', 'fluent-community')); } // trim the title if it's too long to 150 char if (\strlen($processedData['title']) > 192) { $processedData['title'] = substr($processedData['title'], 0, 192); } } return $processedData; } private function checkForDuplicatePost($userId, $message) { $message = trim($message); $exist = Feed::where('user_id', $userId) ->where('message', $message) ->where('created_at', '>', gmdate('Y-m-d H:i:s', current_time('timestamp') - 7 * 24 * 60 * 60)) ->first(); if ($exist) { return $this->sendError(['message' => 'No duplicate post please!']); } return false; } private function validateAndSetSpace($spaceSlug, $user) { if ($spaceSlug == '__self__post__') { if (!Helper::hasGlobalPost()) { throw new \Exception(__('Please select a valid space to post in', 'fluent-community')); } return null; } $space = Space::where('slug', $spaceSlug)->first(); if (!$space) { throw new \Exception(__('Please select a valid space to post in', 'fluent-community')); } $user->verifySpacePermission('can_create_post', $space); return $space->id; } public function deleteFeed(Request $request, $feed_id) { $feed = Feed::findOrFail($feed_id); $user = User::find(get_current_user_id()); $user->canDeleteFeed($feed, true); do_action('fluent_community/feed/before_deleted', $feed); $feed->delete(); do_action('fluent_community/feed/deleted', $feed_id); return [ 'message' => 'Feed has been deleted successfully' ]; } public function deleteMediaPreview(Request $request, $feed_id) { $feed = Feed::findOrFail($feed_id); $user = User::find(get_current_user_id()); $user->canDeleteFeed($feed, true); do_action('fluent_community/feed/media_deleted', $feed->media); $meta = $feed->meta; $meta['media_preview'] = null; $feed->meta = $meta; $feed->save(); return [ 'message' => 'Media preview has been removed successfully' ]; } public function addComment(Request $request, $feed_id) { $feed = Feed::findOrFail($feed_id); $text = trim($request->getSafe('comment', 'sanitize_textarea_field', '')); if (!$text) { return $this->sendError([ 'message' => 'Please provide your reply text' ]); } // check for duplicate $exist = Comment::where('user_id', get_current_user_id()) ->where('message', $text) ->where('post_id', $feed->id) ->first(); if ($exist) { return $this->sendError([ 'message' => 'No duplicate comment please!' ]); } if ($feed->space_id) { $user = User::find(get_current_user_id()); $user->verifySpacePermission('registered', $feed->space); } $commentData = [ 'post_id' => $feed->id, 'message' => $text, 'message_rendered' => wp_kses_post(FeedsHelper::mdToHtml($text)), 'type' => 'comment' ]; if ($request->get('parent_id')) { $parentId = (int)$request->get('parent_id'); // verify the parent id $parentComment = Comment::where('id', $parentId) ->where('post_id', $feed->id) ->first(); if (!$parentComment || $parentComment->post_id != $feed->id) { return $this->sendError([ 'message' => 'Invalid parent comment' ]); } $commentData['parent_id'] = $parentId; } $comment = Comment::create($commentData); $feed->comments_count = $feed->comments_count + 1; $feed->save(); $comment->load([ 'xprofile' => function ($q) { $q->select(ProfileHelper::getXProfilePublicFields()); } ]); return [ 'comment' => $comment, 'message' => 'Comment has been added' ]; } public function addOrRemovePostReact(Request $request, $feed_id) { $feed = Feed::byUserAccess(get_current_user_id())->findOrFail($feed_id); $type = $request->get('react_type', 'like'); $willRemove = $request->get('remove'); $react = Reaction::where('user_id', get_current_user_id()) ->where('object_id', $feed->id) ->where('type', $type) ->objectType('feed') ->first(); if ($willRemove) { if ($react) { $react->delete(); $feed->reactions_count = $feed->reactions_count - 1; $feed->save(); } return [ 'message' => 'Reaction has been removed', 'new_count' => $feed->reactions_count ]; } if ($react) { return [ 'message' => 'You have already reacted to this post', 'new_count' => $feed->reactions_count ]; } $react = Reaction::create([ 'user_id' => get_current_user_id(), 'object_id' => $feed->id, 'type' => $type, 'object_type' => 'feed' ]); $feed->reactions_count = $feed->reactions_count + 1; $feed->save(); return [ 'message' => 'Reaction has been added', 'new_count' => $feed->reactions_count ]; } public function handleMediaUpload(Request $request) { $allowedTypes = implode( ',', apply_filters('fluent_community/support_attachment_types', [ 'image/jpeg', 'image/pjpeg', 'image/jpeg', 'image/pjpeg', 'image/png', 'image/gif', 'image/webp' ]) ); $files = $this->validate($this->request->files(), [ 'file' => 'mimetypes:' . $allowedTypes, // 'source' => 'required|in:feed,avatar,comment,cover,space' ], [ 'file.mimetypes' => __('The file must be a image type.', 'fluent-community') ]); $uploadedFiles = FileSystem::put($files); $file = $uploadedFiles[0]; $willWebPConvert = apply_filters('fluent_community/convert_image_to_webp', true, $file); if ($request->get('resize') && $maxWidth = $request->get('max_width')) { $upload_dir = wp_upload_dir(); $fileUrl = str_replace($upload_dir['baseurl'], $upload_dir['basedir'], $file['url']); $editor = wp_get_image_editor($fileUrl); if (!is_wp_error($editor) && $editor->get_size()['width'] > $maxWidth) { // Current file extension $ext = pathinfo($file['url'], PATHINFO_EXTENSION); $imageExtensions = ['jpg', 'jpeg', 'png', 'gif']; $willConvert = in_array($ext, $imageExtensions) && $willWebPConvert; if ($willConvert) { $imageExtensions = array_map(function ($ext) { return '.' . $ext; }, $imageExtensions); $fileUrl = str_replace($imageExtensions, '.webp', $fileUrl); $file['file'] = str_replace($imageExtensions, '.webp', $file['file']); $file['url'] = str_replace($imageExtensions, '.webp', $file['url']); $file['type'] = 'image/webp'; } // resize the image $editor->resize($maxWidth, null, false); $editor->set_quality(90); if ($willConvert) { $editor->save($fileUrl, 'image/webp'); // remove original file now wp_delete_file(str_replace('.webp', '.' . $ext, $fileUrl)); $file['is_converted'] = true; } else { $editor->save($fileUrl); } $file['meta'] = [ 'width' => $editor->get_size()['width'], 'height' => $editor->get_size()['height'] ]; } $file['path'] = $upload_dir['basedir'] . '/fluent-community/' . $file['file']; } else { $upload_dir = wp_upload_dir(); $file['path'] = $upload_dir['basedir'] . '/fluent-community/' . $file['file']; } if ($willWebPConvert && empty($file['is_converted']) && !$request->get('skip_convert')) { $path = $file['path']; $extension = pathinfo($path, PATHINFO_EXTENSION); $convertFromExtensions = ['png', 'jpg', 'jpeg', 'gif']; if ($extension != 'webp' && in_array($extension, $convertFromExtensions)) { // Let's convert to webp $editor = wp_get_image_editor($file['path']); if (!is_wp_error($editor)) { $orginalPath = $file['path']; $file['path'] = str_replace('.' . $extension, '.webp', $file['path']); $file['url'] = str_replace('.' . $extension, '.webp', $file['url']); $file['type'] = 'image/webp'; $editor->save($file['path'], 'image/webp'); wp_delete_file($orginalPath); $file['meta'] = [ 'width' => $editor->get_size()['width'], 'height' => $editor->get_size()['height'] ]; } } } $mediaData = apply_filters('fluent_community/media_upload_data', [ 'media_type' => $file['type'], 'driver' => 'local', 'media_path' => $file['path'], 'media_url' => $file['url'], 'settings' => Arr::get($file, 'meta', []) ], $file); // Let's create the media now $media = Media::create($mediaData); $mediaUrl = $media->public_url; $mediaUrl = add_query_arg([ 'media_key' => $media->media_key, ], $mediaUrl); return [ 'media' => [ 'url' => $mediaUrl, 'media_key' => $media->media_key, 'type' => $media->media_type, 'width' => Arr::get($media->settings, 'width'), 'height' => Arr::get($media->settings, 'height') ] ]; } public function getTicker(Request $request) { do_action('fluent_communit/track_activity'); $lastId = $request->get('last_feed_id'); $newItemsCount = Feed::where('id', '>', $lastId) ->where('status', 'published') ->byUserAccess(get_current_user_id()) ->count(); $notificationCount = NotificationSubscriber::unread()->where('user_id', get_current_user_id())->count(); return [ 'new_items_count' => $newItemsCount, 'last_checked' => current_time('mysql'), 'unread_notification_count' => $notificationCount ]; } public function getOembed(Request $request) { $url = $request->get('url'); // check if the url is valid $metaData = RemoteUrlParser::parse($url); if ($metaData && !is_wp_error($metaData)) { return [ 'oembed' => $metaData ]; } return $this->send([ 'message' => 'No oembed data found', 'url' => $url ]); } public function markdownToHtml(Request $request) { $message = trim(sanitize_textarea_field($request->get('text', ''))); $html = FeedsHelper::mdToHtml($message); return [ 'html' => $html ]; } private function transformFeed(Feed $feed) { $userId = $this->getUserId(); if ($userId) { $feed->has_user_react = $feed->hasUserReact($userId, 'like'); $feed->bookmarked = $feed->hasUserReact($userId, 'bookmark'); $likedIds = FeedsHelper::getLikedIdsByUserFeedId($feed->id, get_current_user_id()); $feed->comments->each(function ($comment) use ($likedIds) { if ($likedIds && in_array($comment->id, $likedIds)) { $comment->liked = 1; } }); if ($feed->content_type == 'survey') { $votedOptions = $feed->getSurveyCastsByUserId($userId); if ($votedOptions) { $surveyConfig = Arr::get($feed->meta, 'survey_config', []); foreach ($surveyConfig['options'] as $index => $option) { if (in_array($option['slug'], $votedOptions)) { $surveyConfig['options'][$index]['voted'] = true; } } $meta = $feed->meta; $meta['survey_config'] = $surveyConfig; $feed->meta = $meta; } } } return $feed; } }