PluginProbe
FluentCommunity – Ultra-Fast High-Performance Social Network, Community, LMS & Online Courses / 1.0.93
FluentCommunity – Ultra-Fast High-Performance Social Network, Community, LMS & Online Courses v1.0.93
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 / Models / Feed.php

Feed.php in FluentCommunity – Ultra-Fast High-Performance Social Network, Community, LMS & Online Courses 1.0.93, at app/Models/Feed.php

473 lines 11.5 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\Models;
4
5 use FluentCommunity\App\Functions\Utility;
6 use FluentCommunity\App\Services\Helper;
7
8 class Feed extends Model
9 {
10 protected $table = 'fcom_posts';
11
12 protected $guarded = ['id'];
13
14 protected $casts = [
15 'comments_count' => 'int',
16 'reactions_count' => 'int',
17 'is_sticky' => 'int',
18 'priority' => 'int',
19 ];
20
21 protected $fillable = [
22 'user_id',
23 'title',
24 'slug',
25 'message',
26 'message_rendered',
27 'type',
28 'content_type',
29 'space_id',
30 'privacy',
31 'status',
32 'priority',
33 'featured_image',
34 'is_sticky',
35 'expired_at',
36 'scheduled_at',
37 'comments_count',
38 'reactions_count',
39 'meta',
40 'created_at',
41 'updated_at'
42 ];
43
44 protected $searchable = [
45 'message',
46 'title'
47 ];
48
49 public static $publicColumns = [
50 'id',
51 'slug',
52 'message_rendered',
53 'meta',
54 'title',
55 'featured_image',
56 'created_at',
57 'privacy',
58 'priority',
59 'type',
60 'content_type',
61 'slug',
62 'space_id',
63 'user_id',
64 'is_sticky',
65 'comments_count',
66 'reactions_count'
67 ];
68
69 public static $scopeType = 'text';
70
71 public static function boot()
72 {
73 parent::boot();
74
75 static::creating(function ($model) {
76 if (empty($model->user_id)) {
77 $model->user_id = get_current_user_id();
78 }
79 if (empty($model->slug)) {
80 $model->slug = self::generateNewSlug($model);
81 }
82
83 if (empty($model->meta)) {
84 $model->meta = self::getDefaultMeta();
85 }
86 });
87
88 static::addGlobalScope('type', function ($builder) {
89 $builder->where('type', self::$scopeType);
90 });
91
92 static::deleting(function ($feed) {
93 Media::where('feed_id', $feed->id)
94 ->update([
95 'is_active' => 0
96 ]);
97 });
98
99 }
100
101 protected static function generateNewSlug($newModel)
102 {
103 if ($newModel->title) {
104 // Remove the emojis
105 $feedTitle = preg_replace('/[\x{10000}-\x{10FFFF}]/u', '', $newModel->title);
106 $title = sanitize_title($feedTitle, $newModel->user_id . '-' . time());
107 } else {
108 // get the first 25 char from the message
109 $title = sanitize_title(substr($newModel->message, 0, 25), $newModel->user_id . '-' . time());
110 }
111
112 $title = strtolower($title);
113 // only allow alphanumeric, dash, and underscore
114 $title = preg_replace('/[^a-z0-9-_]/', '', $title);
115
116 // check if the slug is already exists
117 $slug = $title;
118 $count = 1;
119 while (self::where('slug', $slug)->exists()) {
120 if ($count == 5) {
121 $count = time();
122 }
123 $slug = $title . '-' . $count;
124 $count++;
125 }
126
127 return $slug;
128 }
129
130 protected static function getDefaultMeta()
131 {
132 return [
133 'preview_data' => null
134 ];
135 }
136
137 public function setMetaAttribute($value)
138 {
139 $this->attributes['meta'] = maybe_serialize($value);
140 }
141
142 public function getMetaAttribute($value)
143 {
144 $meta = maybe_unserialize($value);
145
146 if (!$meta) {
147 $meta = [];
148 }
149
150 return $meta;
151 }
152
153 public function scopeSearchBy($query, $search)
154 {
155 if (!$search) {
156 return $query;
157 }
158
159 $fields = $this->searchable;
160 $query->where(function ($query) use ($fields, $search) {
161 $query->where(array_shift($fields), 'LIKE', "%$search%");
162 foreach ($fields as $field) {
163 $query->orWhere($field, 'LIKE', "$search%");
164 }
165 });
166
167 return $query;
168 }
169
170 public function scopeByUserAccess($query, $userId)
171 {
172 if ($userId) {
173 return $query->where('user_id', $userId)->orWhereNull('space_id')
174 ->orWhereHas('space', function ($q) use ($userId) {
175 $spaceIds = get_user_meta($userId, '_fcom_space_ids', true);
176 if ($spaceIds) {
177 $q->whereIn('id', $spaceIds);
178 return $q;
179 }
180 return $q->where('privacy', 'public');
181 });
182 }
183
184 return $query->whereNull('space_id')
185 ->orWhereHas('space', function ($q) {
186 $q->where('privacy', 'public');
187 });
188 }
189
190 public function scopeByBookMarked($query, $userId)
191 {
192 return $query->whereHas('reactions', function ($q) use ($userId) {
193 $q->where('user_id', $userId)
194 ->where('type', 'bookmark');
195 });
196 }
197
198 public function scopeByTopicSlug($query, $topicSlug)
199 {
200 if (!$topicSlug) {
201 return $query;
202 }
203
204 return $query->whereHas('terms', function ($q) use ($topicSlug) {
205 $topic = Term::where('slug', $topicSlug)->first();
206 if($topic) {
207 $q->where('term_id', $topic->id);
208 }
209 });
210 }
211
212 public function scopeFilterBySpaceSlug($query, $space)
213 {
214 if (!$space) {
215 return $query;
216 }
217
218 $query->whereHas('space', function ($q) use ($space) {
219 $q->where('slug', $space);
220 });
221
222 return $query;
223 }
224
225 public function scopeByType($query, $type)
226 {
227 if (!$type) {
228 return $query;
229 }
230
231 $query->where('type', $type);
232
233 return $query;
234 }
235
236 public function scopeCustomOrderBy($query, $type)
237 {
238 $acceptedTypes = ['new_activity', 'oldest', 'popular', 'likes', 'alphabetical', 'unanswered'];
239
240 if (!in_array($type, $acceptedTypes)) {
241 return $query->orderBy('created_at', 'DESC');
242 }
243
244 if ($type == 'new_activity') {
245 return $query->orderBy('updated_at', 'DESC');
246 }
247
248 if ($type == 'oldest') {
249 return $query->orderBy('created_at', 'ASC');
250 }
251
252 if ($type == 'likes') {
253 return $query->orderBy('reactions_count', 'DESC');
254 }
255
256 if ($type == 'unanswered') {
257 return $query->where('comments_count', 0)
258 ->orderBy('created_at', 'DESC');
259 }
260
261 if ($type == 'alphabetical') {
262 return $query->orderBy('slug', 'ASC');
263 }
264
265 if ($type == 'popular') {
266 // sort by comments_count + reactions_count desc
267 return $query->orderByRaw('(reactions_count + (comments_count * 2)) DESC');
268 }
269
270 return $query;
271 }
272
273 public function scopeByStatus($query, $status)
274 {
275 if (!$status) {
276 return $query->where('status', 'published');
277 }
278
279 $query->where('status', $status);
280
281 return $query;
282 }
283
284 public function scopeFilterByUserId($query, $userId)
285 {
286 if (!$userId) {
287 return $query;
288 }
289
290 $query->where('user_id', $userId);
291
292 return $query;
293 }
294
295 public function user()
296 {
297 return $this->belongsTo(User::class, 'user_id', 'ID');
298 }
299
300 public function xprofile()
301 {
302 return $this->belongsTo(XProfile::class, 'user_id', 'user_id');
303 }
304
305 public function space()
306 {
307 return $this->belongsTo(BaseSpace::class, 'space_id', 'id')
308 ->withoutGlobalScopes();
309 }
310
311 public function comments()
312 {
313 return $this->hasMany(Comment::class, 'post_id', 'id');
314 }
315
316 public function reactions()
317 {
318 return $this->hasMany(Reaction::class, 'object_id', 'id')
319 ->where('object_type', 'feed');
320 }
321
322 public function surveyVotes()
323 {
324 return $this->hasMany(Reaction::class, 'object_id', 'id')
325 ->where('type', 'survey_vote');
326 }
327
328 public function terms()
329 {
330 return $this->belongsToMany(Term::class, 'fcom_term_feed', 'post_id', 'term_id');
331 }
332
333 public function hasUserReact($userId, $type = 'like')
334 {
335 if (!$userId) {
336 return false;
337 }
338
339 return (bool)Reaction::where('object_id', $this->id)
340 ->select(['id'])
341 ->where('object_type', 'feed')
342 ->where('user_id', $userId)
343 ->where('type', $type)
344 ->first();
345 }
346
347 public function hasEditAccess($userId)
348 {
349 if (!$userId) {
350 return false;
351 }
352
353 if ($this->user_id == $userId) {
354 return true;
355 }
356
357 $userModel = User::find($userId);
358
359 return $userModel && $userModel->isCommunityModerator();
360 }
361
362 public function getHumanExcerpt($length = 40)
363 {
364 $content = $this->title;
365 if (!$content) {
366 $content = $this->message;
367 }
368
369 return Helper::getHumanExcerpt($content, $length);
370 }
371
372 public function getPermalink()
373 {
374 if ($this->space_id && $this->space) {
375 $path = 'space/' . $this->space->slug . '/post/' . $this->slug;
376 } else {
377 $path = 'post/' . $this->slug;
378 }
379
380 return Helper::baseUrl($path);
381 }
382
383 public function activities()
384 {
385 return $this->hasMany(Activity::class, 'feed_id', 'id');
386 }
387
388 public function notifications()
389 {
390 return $this->hasMany(Notification::class, 'feed_id', 'id');
391 }
392
393 public function media()
394 {
395 return $this->hasMany(Media::class, 'feed_id', 'id');
396 }
397
398 public function getSurveyCastsByUserId($userId = null)
399 {
400 if (!$userId || $this->content_type != 'survey') {
401 return [];
402 }
403
404 return Utility::getFromCache('survey_cast_' . $this->id . '_' . $userId, function () use ($userId) {
405 return Reaction::where('type', 'survey_vote')
406 ->where('user_id', $userId)
407 ->where('object_id', $this->id)
408 ->pluck('object_type')->toArray();
409 }, 86400);
410 }
411
412 public function updateCustomMeta($key, $value)
413 {
414 $exist = Meta::where('object_id', $this->id)
415 ->where('object_type', 'feed')
416 ->where('meta_key', $key)
417 ->first();
418
419 if ($exist) {
420 $exist->value = $value;
421 $exist->save();
422 } else {
423 Meta::create([
424 'object_id' => $this->id,
425 'object_type' => 'feed',
426 'meta_key' => $key,
427 'value' => $value
428 ]);
429 }
430
431 return true;
432 }
433
434 public function getCustomMeta($key, $default = null)
435 {
436 $exist = Meta::where('object_id', $this->id)
437 ->where('object_type', 'feed')
438 ->where('meta_key', $key)
439 ->first();
440
441 if ($exist) {
442 return $exist->value;
443 }
444
445 return $default;
446 }
447
448 public function attachTopics($topicIds, $sync = false)
449 {
450 if ((!$topicIds && !$sync) || !$this->space_id) {
451 return $this;
452 }
453
454 // let's find the valid topics for this space
455 $spaceTopics = Utility::getTopicsBySpaceId($this->space_id);
456 $spaceTopicIds = array_map(function ($topic) {
457 return $topic['id'];
458 }, $spaceTopics);
459
460 $validTopicIds = array_filter($topicIds, function ($topicId) use ($spaceTopicIds) {
461 return in_array($topicId, $spaceTopicIds);
462 });
463
464 if ($sync) {
465 $this->terms()->sync($validTopicIds);
466 } else {
467 $this->terms()->attach($validTopicIds);
468 }
469
470 return $this;
471 }
472 }
473