PluginProbe
FluentCommunity – Ultra-Fast High-Performance Social Network, Community, LMS & Online Courses / 2.10.01
FluentCommunity – Ultra-Fast High-Performance Social Network, Community, LMS & Online Courses v2.10.01
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 / Comment.php

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

307 lines 9.3 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\Models\XProfile;
7 use FluentCommunity\App\Models\Activity;
8 use FluentCommunity\App\Services\FeedsHelper;
9 use FluentCommunity\App\Services\Helper;
10
11 /**
12 * @property int $id
13 * @property int|null $user_id
14 * @property int|null $post_id
15 * @property int|null $parent_id
16 * @property string|null $message
17 * @property string|null $message_rendered
18 * @property mixed $meta
19 * @property string|null $type
20 * @property string|null $content_type
21 * @property string|null $status
22 * @property int|null $is_sticky
23 * @property int $reactions_count
24 * @property string|null $created_at
25 * @property string|null $updated_at
26 * @property-read User|null $user
27 * @property-read XProfile|null $xprofile
28 * @property-read Feed|null $post
29 * @property-read mixed $media
30 */
31 class Comment extends Model
32 {
33 protected $table = 'fcom_post_comments';
34
35 protected $guarded = [ 'id' ];
36
37 protected $casts = [
38 'is_sticky' => 'int',
39 ];
40
41 protected $fillable = [
42 'user_id',
43 'post_id',
44 'parent_id',
45 'message',
46 'message_rendered',
47 'meta',
48 'type',
49 'content_type',
50 'status',
51 'is_sticky',
52 'reactions_count',
53 'created_at',
54 'updated_at',
55 ];
56
57 protected $searchable = [
58 'message',
59 ];
60
61 public static function boot()
62 {
63 parent::boot();
64
65 static::creating(function ($model) {
66 if (empty($model->user_id)) {
67 $model->user_id = get_current_user_id();
68 }
69 $model->type = 'comment';
70
71 if(empty($model->status)) {
72 $model->status = 'published';
73 }
74
75 });
76
77 static::deleting(function ($comment) {
78 Media::where('sub_object_id', $comment->id)
79 ->where('object_source', 'comment')
80 ->update([
81 'is_active' => 0,
82 ]);
83
84 $comment->reactions()->delete();
85
86 Activity::where('feed_id', $comment->post_id)
87 ->where('action_name', 'comment_added')
88 ->where('related_id', $comment->id)
89 ->delete();
90
91 $notifications = Notification::where('object_id', $comment->id)
92 ->where('src_object_type', 'comment')
93 ->get();
94
95 foreach ($notifications as $notification) {
96 $notification->delete();
97 }
98
99 $childComments = Comment::where('parent_id', $comment->id)
100 ->where('post_id', $comment->post_id)
101 ->get();
102
103 foreach ($childComments as $childComment) {
104 $childComment->delete();
105 }
106 });
107
108 static::addGlobalScope('type', function ($builder) {
109 $builder->where('type', 'comment');
110 });
111 }
112
113 public function scopeSearchBy($query, $search)
114 {
115 if ($search) {
116 $fields = $this->searchable;
117 $query->where(function ($query) use ($fields, $search) {
118 $query->where(array_shift($fields), 'LIKE', "%$search%");
119 foreach ($fields as $field) {
120 $query->orWhere($field, 'LIKE', "$search%");
121 }
122 });
123 }
124
125 return $query;
126 }
127
128 public function user()
129 {
130 return $this->belongsTo(User::class, 'user_id', 'ID');
131 }
132
133 public function xprofile()
134 {
135 return $this->belongsTo(XProfile::class, 'user_id', 'user_id');
136 }
137
138 public function media()
139 {
140 return $this->hasOne(Media::class, 'sub_object_id', 'id');
141 }
142
143 public function post()
144 {
145 return $this->belongsTo(Feed::class, 'post_id', 'id')->withoutGlobalScopes();
146 }
147
148 public function space()
149 {
150 return $this->hasOneThrough(
151 BaseSpace::class,
152 Feed::class,
153 'id', // Foreign key on the feeds table
154 'id', // Foreign key on the spaces table
155 'post_id', // Local key on the comments table
156 'space_id' // Local key on the feeds table
157 )->withoutGlobalScopes();
158 }
159
160 public function reactions()
161 {
162 return $this->hasMany(Reaction::class, 'object_id', 'id')
163 ->where('object_type', 'comment');
164 }
165
166 public function scopeByContentModerationAccessStatus($query, $user, $space = null)
167 {
168 if (!$user || !Helper::isFeatureEnabled('content_moderation')) {
169 return $query->where('status', 'published');
170 }
171
172 if (
173 $user->hasCommunityModeratorAccess() ||
174 ($space && $user->hasSpacePermission('edit_any_comment', $space))
175 ) {
176 return $query->whereIn('status', [ 'published', 'pending' ]);
177 }
178
179 // This is a normal User.
180 return $query->where(function ($q) use ($user) {
181 $q->where('status', 'published')
182 ->orWhere(function ($q) use ($user) {
183 $q->where('status', 'pending')
184 ->where('user_id', $user->ID);
185 });
186 });
187
188 }
189
190 /*
191 * Find all the user ids of a child comment who commented on the parent comment including the parent comment author
192 */
193 public function getCommentParentUserIds($lastUserId = 0)
194 {
195 if (!$this->parent_id) {
196 return [];
197 }
198
199 $parentComment = self::select([ 'user_id' ])->find($this->parent_id);
200 $allUserIds = self::where('parent_id', $this->parent_id)
201 ->select([ 'user_id' ])
202 ->distinct('user_id')
203 ->when($lastUserId, function ($query) use ($lastUserId) {
204 $query->where('user_id', '>', $lastUserId);
205 })
206 ->get()
207 ->pluck('user_id')
208 ->toArray();
209
210 if ($parentComment) {
211 if ($parentComment->user_id > $lastUserId) {
212 $allUserIds[] = $parentComment->user_id;
213 }
214 }
215
216 return array_values(array_unique($allUserIds));
217 }
218
219 public function setMetaAttribute($value)
220 {
221 $this->attributes['meta'] = maybe_serialize($value);
222 }
223
224 public function getMetaAttribute($value)
225 {
226 $meta = Utility::safeUnserialize($value);
227
228 if (!$meta) {
229 $meta = [];
230 }
231
232 return Helper::sanitizeStoredMediaPreview($meta);
233 }
234
235 public function getHumanExcerpt($length = 30)
236 {
237 $content = $this->message;
238
239 return Helper::getHumanExcerpt($content, $length);
240 }
241
242 public function getEmailSubject($feed = null)
243 {
244 if (!$feed) {
245 $feed = $this->post;
246 }
247
248 if ($this->parent_id) {
249 if ($feed->title) {
250 /* translators: %1$s is the feed title and %2$s is the comment author name */
251 $emailSubject = \sprintf(__('New reply on comment at %1$s - %2$s', 'fluent-community'), $feed->title, $this->xprofile->display_name);
252 } else {
253 /* translators: %1$s is the post title and %2$s is the comment author name */
254 $emailSubject = \sprintf(__('New reply of a comment in a post on %1$s - %2$s', 'fluent-community'), $this->post->getHumanExcerpt(40), $this->xprofile->display_name);
255 }
256 } elseif ($feed->title) {
257 /* translators: %1$s is the feed title and %2$s is the comment author name */
258 $emailSubject = \sprintf(__('New comment on %1$s - %2$s', 'fluent-community'), $feed->title, $this->xprofile->display_name);
259 } else {
260 /* translators: %1$s is the post title and %2$s is the comment author name */
261 $emailSubject = \sprintf(__('New comment on a post on %1$s - %2$s', 'fluent-community'), $this->post->getHumanExcerpt(40), $this->xprofile->display_name);
262 }
263
264 return $emailSubject;
265 }
266
267 public function getCommentHtml($withPlaceholder = false, $buttonText = null)
268 {
269 $emailComposer = new \FluentCommunity\App\Services\Libs\EmailComposer();
270 if ($withPlaceholder) {
271 $postPermalink = '##feed_permalink##';
272 } else {
273 $postPermalink = $this->post->getPermalink() . '?comment_id=' . $this->id;
274 }
275
276 if ($this->post->title) {
277 $postTitle = $this->post->title;
278 } else {
279 $postTitle = $this->post->getHumanExcerpt(120);
280 }
281
282 $renderedMessage = $this->message_rendered;
283
284 // Remove all the URLs with the text but make it underlined
285 $renderedMessage = preg_replace('/<a href="([^"]+)">([^<]+)<\/a>/', '<span style="text-decoration: underline !important;">$2</span>', $renderedMessage);
286
287 $renderedMessage .= FeedsHelper::getMediaHtml($this->meta, $postPermalink);
288
289 $buttonText = $buttonText ? $buttonText : __('View the comment', 'fluent-community');
290
291 $emailComposer->addBlock('boxed_content', $renderedMessage, [
292 'user' => $this->user,
293 'permalink' => $postPermalink,
294 'post_content' => $postTitle,
295 ]);
296
297 $emailComposer->addBlock('button', $buttonText, [
298 'link' => $postPermalink,
299 ]);
300
301 $emailComposer->setDefaultLogo();
302 $emailComposer->setDefaultFooter($withPlaceholder);
303
304 return $emailComposer->getHtml();
305 }
306 }
307