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;
}
}