spaces()->pluck('slug')->toArray(); } public static function getLastFeedId() { $lastItem = Feed::where('status', 'published') ->byUserAccess(get_current_user_id()) ->orderBy('id', 'DESC') ->first(); if ($lastItem) { return $lastItem->id; } return 1; } public static function mdToHtml($text, $options = []) { if (!$text) { return ''; } $text = str_replace(' ', '', $text); // hide markdown empty content $html = (new \FluentCommunity\App\Services\Parsedown([ ])) ->setBreaksEnabled(true) ->text($text); if (!Arr::get($options, 'disable_link_process')) { // add nofollow to all links. But check if nofollow is already there $html = self::addNoFollowToLinks($html); } return $html; } public static function addNoFollowToLinks($html) { if(!$html) { return ''; } $current_domain = parse_url(home_url(), PHP_URL_HOST); // Regular expression to match tags $pattern = '/]*href=("|\')(https?:\/\/(?!'. preg_quote($current_domain, '/') .').*?)("|\')\s?([^>]*)>/i'; // Callback function to modify each matched tag $callback = function($matches) { $url = $matches[2]; $attr = $matches[4]; // Remove existing rel attribute if present $attr = preg_replace('/\srel=("|\').*?("|\')/i', '', $attr); // Add nofollow return ''; }; // Perform the replacement return preg_replace_callback($pattern, $callback, $html); } public static function findFirstUrl($html) { // use regular expression to find the first URL in a href tag // do not take the url which contains /u/ in it $pattern = '/]*?\s+)?href=([\'"])(?!.*\/u\/)(.*?)\1/'; preg_match($pattern, $html, $matches); if (isset($matches[2])) { return $matches[2]; } return ''; } public static function extractHashTags($text, $limit = 5) { // Extract hashtag including - and _ preg_match_all('/#([a-zA-Z0-9_-]+)/', $text, $matches); $tags = array_unique($matches[1]); if (!$tags) { return []; } $tags = array_slice($tags, 0, $limit); $lowerCaseTags = array_map('strtolower', $tags); $terms = Term::whereIn('slug', $lowerCaseTags) ->where('taxonomy_name', 'hashtag') ->get(); $termIds = []; foreach ($terms as $term) { $termIds[$term->slug] = $term->id; } if (count($termIds) == count($tags)) { return array_values($termIds); } $excepts = array_diff($tags, array_keys($termIds)); foreach ($excepts as $except) { $term = Term::create([ 'taxonomy_name' => 'hashtag', 'slug' => strtolower($except), 'title' => $except ]); $termIds[$term->slug] = $term->id; } return array_values($termIds); } public static function getMentions($text, $spaceId = null) { // the mention may have . or _ or - in the username preg_match_all('/@([a-zA-Z0-9_.-]+)/', $text, $matches); $mentions = array_unique($matches[1]); if (!$mentions) { return null; } if ($spaceId) { $xProfiles = XProfile::whereIn('username', $mentions) ->whereHas('spaces', function ($query) use ($spaceId) { $query->where('space_id', $spaceId); }) ->get(); } else { $xProfiles = XProfile::whereIn('username', $mentions) ->get(); } if ($xProfiles->isEmpty()) { return null; } $userMentions = []; $userIds = []; foreach ($xProfiles as $xProfile) { $userIds[] = $xProfile->user_id; $html = '' . $xProfile->display_name . ''; $userMentions['@' . $xProfile->username] = $html; } $users = User::whereIn('ID', $userIds)->get(); return [ 'users' => $users, 'text' => strtr($text, $userMentions) ]; } public static function getLikedIdsByUserFeedId($feedId, $userId) { return Reaction::select('object_id') ->where('object_type', 'comment') ->where('parent_id', $feedId) ->where('user_id', $userId) ->get() ->pluck('object_id') ->toArray(); } public static function castSurveyVote($newVoteIndexes, Feed $feed, $userId) { $surveyConfig = Arr::get($feed->meta, 'survey_config', []); $slugs = array_map(function ($item) { return $item['slug']; }, $surveyConfig['options']); $newVoteIndexes = array_filter(array_intersect($slugs, $newVoteIndexes)); $previousVotes = Reaction::where('type', 'survey_vote') ->where('user_id', $userId) ->where('object_id', $feed->id) ->get(); $removedIndexes = []; $alreadyIndexes = []; foreach ($previousVotes as $previousVote) { if (!in_array($previousVote->object_type, $newVoteIndexes)) { // This vote need to be deleted $removedIndexes[] = $previousVote->object_type; $previousVote->delete(); } else { $alreadyIndexes[] = $previousVote->object_type; } } $newSyncIndexes = array_diff($newVoteIndexes, $alreadyIndexes); foreach ($newSyncIndexes as $newSyncIndex) { Reaction::create([ 'user_id' => $userId, 'object_id' => $feed->id, 'type' => 'survey_vote', 'object_type' => $newSyncIndex ]); } foreach ($surveyConfig['options'] as $index => $option) { $slug = $option['slug']; if (in_array($slug, $removedIndexes)) { $newCount = (int)Arr::get($option, 'vote_counts', 0) - 1; $option['vote_counts'] = $newCount > 0 ? $newCount : 0; } else if (in_array($slug, $newSyncIndexes)) { $newCount = (int)Arr::get($option, 'vote_counts', 0) + 1; $option['vote_counts'] = $newCount > 0 ? $newCount : 0; } $surveyConfig['options'][$index] = $option; } $meta = $feed->meta; $meta['survey_config'] = $surveyConfig; $feed->meta = $meta; $feed->save(); Utility::forgetCache('survey_cast_' . $feed->id . '_' . $userId); return $feed; } }