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 / User.php

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

652 lines 19.2 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\Services\Helper;
6 use FluentCommunity\App\Services\ProfileHelper;
7 use FluentCommunity\Framework\Support\Arr;
8 use FluentCommunity\Modules\Course\Model\Course;
9 use FluentCrm\App\Models\Subscriber;
10
11 /**
12 * User Model - DB Model for WordPress Users Table
13 *
14 * Database Model
15 *
16 * @package FluentCrm\App\Models
17 *
18 * @version 1.0.0
19 */
20 class User extends Model
21 {
22 protected $table = 'users';
23
24 protected $primaryKey = 'ID';
25
26 protected $hidden = ['user_pass', 'user_activation_key'];
27
28 protected $appends = ['photo'];
29
30 protected $searchable = [
31 'display_name',
32 'user_email'
33 ];
34
35 public function scopeSearchBy($query, $search)
36 {
37 if ($search) {
38 $fields = $this->searchable;
39 $query->where(function ($query) use ($fields, $search) {
40 $query->where(array_shift($fields), 'LIKE', "%$search%");
41 foreach ($fields as $field) {
42 $query->orWhere($field, 'LIKE', "$search%");
43 }
44 });
45 }
46
47 return $query;
48 }
49
50 public function scopeMentionBy($query, $search)
51 {
52 if ($search) {
53 $fields = [
54 'display_name',
55 'user_login'
56 ];
57 $query->where(function ($query) use ($fields, $search) {
58 $query->where(array_shift($fields), 'LIKE', "$search%");
59 foreach ($fields as $field) {
60 $query->orWhere($field, 'LIKE', "$search%");
61 }
62 });
63 }
64
65 return $query;
66 }
67
68 /**
69 * Accessor to get dynamic photo attribute
70 * @return string
71 */
72 public function getPhotoAttribute()
73 {
74 if ($photo = get_user_meta($this->ID, '_fcom_user_photo', true)) {
75 return $photo;
76 }
77
78 if ($contact = $this->getContact()) {
79 return $contact->photo;
80 }
81
82 if (empty($this->attributes['user_email'])) {
83 if (defined('FLUENTCRM')) {
84 $contact = Subscriber::where('user_id', $this->ID)->first();
85 if ($contact) {
86 return $contact->photo;
87 }
88 }
89 return '';
90 }
91
92 $hash = md5(strtolower(trim($this->attributes['user_email'])));
93
94 /**
95 * Gravatar URL by Email
96 *
97 * @return string $gravatar url of the gravatar image
98 */
99 $name = $this->attributes['display_name'];
100
101 $fallback = '';
102 if ($name) {
103 $fallback = '&d=https%3A%2F%2Fui-avatars.com%2Fapi%2F' . urlencode($name) . '/128';
104 }
105
106 return apply_filters('fluent_crm/get_avatar',
107 "https://www.gravatar.com/avatar/{$hash}?s=128" . $fallback,
108 $this->attributes['user_email']
109 );
110 }
111
112 public function getIsVerifiedAttribute()
113 {
114 return $this->isVerified();
115 }
116
117 public function getContact()
118 {
119 if (!defined('FLUENTCRM')) {
120 return null;
121 }
122
123 if ($this->user_email) {
124 return Subscriber::where('user_id', $this->ID)
125 ->orWhere('email', $this->user_email)
126 ->first();
127 }
128
129 return Subscriber::where('user_id', $this->ID)
130 ->first();
131 }
132
133 public function xprofile()
134 {
135 return $this->belongsTo(XProfile::class, 'ID', 'user_id');
136 }
137
138 public function getGeneralData()
139 {
140 $user = get_user_by('ID', $this->ID);
141
142 $fullName = '';
143 if ($user->first_name || $user->last_name) {
144 $fullName = trim($user->first_name . ' ' . $user->last_name);
145 }
146
147 if (!$fullName) {
148 $fullName = $user->display_name;
149 }
150
151 $contact = $this->getContact();
152
153 return [
154 'is_contact' => (bool)$contact,
155 'first_name' => $user->first_name,
156 'last_name' => $user->last_name,
157 'full_name' => $fullName,
158 'display_name' => $fullName,
159 'bio' => $user->description,
160 'website' => $user->user_url,
161 'id' => $user->ID,
162 'user_id' => $user->ID,
163 'created_at' => $user->user_registered,
164 'photo' => $this->photo,
165 'username' => $this->username,
166 'is_verified' => $this->isVerified()
167 ];
168 }
169
170 public function spaces()
171 {
172 return $this->belongsToMany(BaseSpace::class, 'fcom_space_user', 'user_id', 'space_id')
173 ->withPivot(['role', 'status', 'created_at']);
174 }
175
176 public function courses()
177 {
178 return $this->belongsToMany(Course::class, 'fcom_space_user', 'user_id', 'space_id')
179 ->withPivot(['role', 'created_at']);
180 }
181
182 public function notificationSubscriptions()
183 {
184 return $this->hasMany(NotificationSubscription::class, 'user_id');
185 }
186
187 public function space_pivot()
188 {
189 return $this->belongsTo(SpaceUserPivot::class, 'ID', 'user_id')->withoutGlobalScopes();
190 }
191
192 public function notification_records()
193 {
194 return $this->hasMany(NotificationSubscriber::class, 'user_id', 'ID')->withoutGlobalScopes();
195 }
196
197 public function crm_contact()
198 {
199 return $this->belongsTo(Contact::class, 'ID', 'user_id')->withoutGlobalScopes();
200 }
201
202 public function community_role()
203 {
204 return $this->belongsTo(Meta::class, 'ID', 'object_id')
205 ->where('meta_key', '_user_community_roles');
206 }
207
208 public function updateCustomData($updateData, $removeSrc = false)
209 {
210 if (isset($updateData['first_name'])) {
211 $firstName = sanitize_text_field($updateData['first_name']);
212 $lastName = sanitize_text_field($updateData['last_name']);
213
214 $userData = [
215 'first_name' => $firstName,
216 'last_name' => $lastName,
217 'display_name' => trim($firstName . ' ' . $lastName),
218 'description' => isset($updateData['short_description']) ? sanitize_textarea_field($updateData['short_description']) : '',
219 'user_url' => isset($updateData['website']) ? esc_url($updateData['website']) : '',
220 'ID' => $this->ID
221 ];
222
223 wp_update_user($userData);
224
225 if ($contact = $this->getContact()) {
226 $contact->fill(array_filter([
227 'first_name' => $firstName,
228 'last_name' => $lastName
229 ]));
230
231 $dirtyFields = $contact->getDirty();
232 if ($dirtyFields) {
233 $contact->save();
234 do_action('fluent_crm/contact_updated', $contact, $dirtyFields);
235 }
236
237 }
238
239 }
240
241 return $this;
242 }
243
244 public function getDisplayName()
245 {
246 $user = get_user_by('ID', $this->ID);
247 $name = '';
248 if ($user->first_name || $user->last_name) {
249 $name = trim($user->first_name . ' ' . $user->last_name);
250 }
251 if ($name) {
252 return $name;
253 }
254 return $user->display_name;
255 }
256
257 public function getCustomMeta($key, $default = null)
258 {
259 $exist = Meta::where('object_type', 'user')
260 ->where('object_id', $this->ID)
261 ->where('meta_key', $key)
262 ->first();
263
264 if ($exist && $exist->value) {
265 return $exist->value;
266 }
267
268 return $default;
269 }
270
271 public function updateCustomMeta($key, $value)
272 {
273 $exist = Meta::where('object_type', 'user')
274 ->where('object_id', $this->ID)
275 ->where('meta_key', $key)
276 ->first();
277
278 if ($exist) {
279 $exist->value = $value;
280 $exist->save();
281 return $exist;
282 }
283
284 return Meta::create([
285 'object_type' => 'user',
286 'object_id' => $this->ID,
287 'meta_key' => $key,
288 'value' => $value
289 ]);
290 }
291
292 public function getSpaceIds($cached = true)
293 {
294 if ($cached) {
295 $ids = get_user_meta($this->ID, '_fcom_space_ids', true);
296 if (!$ids || !is_array($ids)) {
297 $ids = [];
298 }
299 return $ids;
300 }
301
302 $this->cacheAccessSpaces();
303
304 return get_user_meta($this->ID, '_fcom_space_ids', true);
305 }
306
307 public function getCommunityRoles()
308 {
309 if (Helper::isSiteAdmin($this->ID)) {
310 return ['admin'];
311 }
312
313 return (array)$this->getCustomMeta('_user_community_roles', []);
314 }
315
316 public function isCommunityAdmin()
317 {
318 return in_array('admin', $this->getCommunityRoles());
319 }
320
321 public function isCommunityModerator()
322 {
323 return !!array_intersect(['moderator', 'admin'], $this->getCommunityRoles());
324 }
325
326 public function hasCourseManageAccess()
327 {
328 return !!array_intersect(['admin', 'course_creator', 'course_admin'], $this->getCommunityRoles());
329 }
330
331 public function getSpaceRole($space)
332 {
333 $globalRoles = $this->getCommunityRoles();
334
335 if ($globalRoles) {
336 if (in_array('admin', $globalRoles)) {
337 return 'admin';
338 }
339 }
340
341 if ($space) {
342 $spacePivot = SpaceUserPivot::where('space_id', $space->id)
343 ->where('user_id', $this->ID)
344 ->first();
345
346 if ($spacePivot) {
347 if ($spacePivot->role != 'member') {
348 return $spacePivot->role;
349 }
350
351 if (!in_array('moderator', $globalRoles)) {
352 if ($spacePivot->status == 'pending') {
353 return 'pending';
354 }
355 return $spacePivot->role;
356 }
357 }
358 }
359
360 if (in_array('moderator', $globalRoles)) {
361 return 'moderator';
362 }
363
364 return '';
365 }
366
367 public function cacheAccessSpaces()
368 {
369 $globalRoles = $this->getCommunityRoles();
370
371 if (array_intersect($globalRoles, ['admin', 'moderator'])) {
372 $spaces = Space::all();
373 } else {
374 $spaces = Space::whereHas('members', function ($query) {
375 $query->where('user_id', $this->ID)
376 ->where('status', 'active');
377 })->orWhere('privacy', 'public')->get();
378 }
379
380 $spaceIds = $spaces->pluck('id')->toArray();
381
382 update_user_meta($this->ID, '_fcom_space_ids', $spaceIds);
383
384 return $spaces;
385 }
386
387 protected function getRolePermissions($roles)
388 {
389 if (!$roles) {
390 return apply_filters('fluent_community/user/permissions', [
391 'read' => true
392 ], $roles, $this);
393 }
394
395 $isAdmin = in_array('admin', $roles);
396 $isModerator = array_intersect($roles, ['admin', 'moderator']);
397
398 $permissions = [
399 'community_admin' => $isAdmin ? 'admin' : false,
400 'community_moderator' => $isModerator,
401 'super_admin' => Helper::isSiteAdmin(),
402 'delete_any_feed' => $isModerator,
403 'edit_any_feed' => $isModerator,
404 'delete_any_comment' => $isModerator,
405 'edit_any_comment' => $isModerator,
406 'read' => true
407 ];
408
409 if ($isAdmin || in_array('course_admin', $roles)) {
410 $permissions['course_creator'] = true;
411 $permissions['course_admin'] = true;
412 } else if (in_array('course_creatror', $roles)) {
413 $permissions['course_creator'] = true;
414 }
415
416 return apply_filters('fluent_community/user/permissions', $permissions, $roles, $this);
417 }
418
419 public function getPermissions($cached = true)
420 {
421 static $permissions;
422
423 if ($permissions && $cached) {
424 return $permissions;
425 }
426
427 $roles = $this->getCommunityRoles();
428
429 $permissions = $this->getRolePermissions($roles);
430
431 return $permissions;
432 }
433
434 public function getSpacePermissions($space)
435 {
436 if (!$space) {
437 return [];
438 }
439
440 $role = $this->getSpaceRole($space);
441 $isRestrictedPost = Arr::get($space->settings, 'restricted_post_only') == 'yes';
442
443 if (!$role) {
444 $permissions = [
445 'can_create_post' => false,
446 'registered' => true,
447 'can_view_posts' => true,
448 'can_view_members' => true,
449 'is_pending' => false,
450 'is_non_member' => true,
451 'can_view_info' => $space->privacy !== 'secret'
452 ];
453
454 if ($space->privacy === 'secret' || $space->privacy === 'private') {
455 $permissions['can_view_posts'] = false;
456 $permissions['can_view_members'] = false;
457 }
458 } else if ($role == 'pending') {
459 $permissions = [
460 'can_create_post' => false,
461 'registered' => true,
462 'can_view_posts' => true,
463 'can_view_members' => true,
464 'is_pending' => true,
465 'can_view_info' => $space->privacy !== 'secret'
466 ];
467
468 if ($space->privacy === 'secret' || $space->privacy === 'private') {
469 $permissions['can_view_posts'] = false;
470 $permissions['can_view_members'] = false;
471 }
472 } else if ($role == 'member' || $role == 'student') {
473 $permissions = [
474 'can_create_post' => $isRestrictedPost ? false : true,
475 'registered' => true,
476 'can_view_posts' => true,
477 'can_view_members' => true,
478 'can_comment' => true,
479 'can_view_info' => true
480 ];
481 } else {
482 $permissions = [
483 'can_create_post' => $isRestrictedPost ? in_array($role, ['admin', 'moderator']) : true,
484 'can_view_posts' => true,
485 'can_view_members' => true,
486 'registered' => true,
487 'community_admin' => $role === 'admin',
488 'community_moderator' => in_array($role, ['admin', 'moderator']),
489 'edit_any_feed' => $role === 'admin',
490 'delete_any_feed' => in_array($role, ['admin', 'moderator']),
491 'super_admin' => Helper::isSiteAdmin(),
492 'read' => true,
493 'can_remove_member' => $role === 'admin',
494 'can_add_member' => $role === 'admin',
495 'can_comment' => in_array($role, ['admin', 'moderator']),
496 'can_view_info' => true
497 ];
498 }
499
500 return apply_filters('fluent_community/user/space/permissions', $permissions, $space, $role, $this);
501 }
502
503 public function hasCommunityPermission($permission)
504 {
505 $permissions = $this->getPermissions();
506
507 if (isset($permissions[$permission])) {
508 return $permissions[$permission];
509 }
510
511 return false;
512 }
513
514 public function hasSpacePermission($permission, $space)
515 {
516 $permissions = $this->getSpacePermissions($space);
517
518 if (isset($permissions[$permission])) {
519 return $permissions[$permission];
520 }
521
522 return false;
523 }
524
525 public function verifyCommunityPermission($permission)
526 {
527 if (!$this->hasCommunityPermission($permission)) {
528 throw new \Exception('You do not have permission to do this action');
529 }
530
531 return true;
532 }
533
534 public function verifySpacePermission($permission, $space)
535 {
536 if (!$space || !$this->hasSpacePermission($permission, $space)) {
537 throw new \Exception('You do not have permission to do this action');
538 }
539
540 return true;
541 }
542
543 public function canEditFeed($feed, $throwException = false)
544 {
545 $result = $feed->user_id == $this->ID || $this->hasCommunityPermission('edit_any_feed') || $this->hasSpacePermission('edit_any_feed', $feed->space_id);
546
547 if (!$result && $throwException) {
548 throw new \Exception('You do not have permission to do this action');
549 }
550
551 return $result;
552 }
553
554 public function canDeleteFeed($feed, $throwException = false)
555 {
556 $result = $feed->user_id == $this->ID || $this->hasCommunityPermission('delete_any_feed') || $this->hasSpacePermission('delete_any_feed', $feed->space_id);
557
558 if (!$result && $throwException) {
559 throw new \Exception('You do not have permission to do this action');
560 }
561 return $result;
562 }
563
564 public function can($permission, $space = null)
565 {
566 if ($space) {
567 return $this->hasSpacePermission($permission, $space);
568 }
569
570 return $this->hasCommunityPermission($permission);
571 }
572
573 public function getUnreadNotificationCount()
574 {
575 return NotificationSubscriber::where('user_id', $this->ID)
576 ->unread()
577 ->count();
578 }
579
580 public function getUnreadNotificationFeedIds()
581 {
582 $ids = Notification::whereHas('subscribers', function ($query) {
583 return $query->where('user_id', $this->ID)
584 ->unread();
585 })->pluck('feed_id')->toArray();
586
587 return array_values(array_unique($ids));
588 }
589
590 public function isVerified()
591 {
592 return get_user_meta($this->ID, '_fcom_is_verified', true) == 'yes';
593 }
594
595 public function syncXProfile($force = false)
596 {
597 $exist = $this->xprofile;
598
599 if ($exist && !$force) {
600 return $exist;
601 }
602
603 $createdAt = $this->user_registered;
604 if (!$createdAt || $createdAt == '0000-00-00 00:00:00' || !strtotime($createdAt)) {
605 $createdAt = gmdate('Y-m-d H:i:s');
606 } else {
607 $timeDiff = time() - current_time('timestamp');
608 $createdAt = gmdate('Y-m-d H:i:s', strtotime($createdAt) - $timeDiff);
609 }
610
611 $data = [
612 'user_id' => $this->ID,
613 'username' => ProfileHelper::generateUserName($this->ID),
614 'display_name' => $this->getDisplayName(),
615 'avatar' => $this->getPhotoAttribute(),
616 'is_verified' => $this->isVerified() ? 1 : 0,
617 'created_at' => $createdAt,
618 'short_description' => get_user_meta($this->ID, 'description', true),
619 'meta' => [
620 'website' => $this->user_url,
621 'cover_photo' => get_user_meta($this->ID, '_fluent_cover_photo', true)
622 ]
623 ];
624
625 if ($exist) {
626 unset($data['avatar']);
627 unset($data['username']);
628 $data['meta'] = wp_parse_args($exist->meta, $data['meta']);
629 $exist->fill($data);
630 $exist->save();
631 return $exist;
632 }
633
634
635 $counter = 1;
636 $initialUserName = $data['username'];
637 while (XProfile::where('username', $initialUserName)->first()) {
638 $initialUserName = $data['username'] . '_' . $counter;
639 $counter++;
640 }
641
642 $data['username'] = $initialUserName;
643
644 return XProfile::create($data);
645 }
646
647 public function getUserMeta($metaKey, $default = null)
648 {
649 return get_user_meta($this->ID, $metaKey, true) ?? $default;
650 }
651 }
652