PluginProbe
FluentCommunity – Ultra-Fast High-Performance Social Network, Community, LMS & Online Courses / 1.0.96
FluentCommunity – Ultra-Fast High-Performance Social Network, Community, LMS & Online Courses v1.0.96
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.96, at app/Models/User.php

674 lines 19.9 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 hasCommunityModeratorAccess()
327 {
328 $permissions = $this->getPermissions(true);
329
330 return Arr::isTrue($permissions, 'community_moderator');
331 }
332
333 public function hasCourseCreatorAccess()
334 {
335 $permissions = $this->getPermissions(true);
336
337 return Arr::isTrue($permissions, 'course_creator');
338 }
339
340 public function isSpaceModerator()
341 {
342 return $this->hasCourseCreatorAccess() || $this->hasCommunityModeratorAccess();
343 }
344
345 public function hasSpaceManageAccess()
346 {
347 $permissions = array_filter($this->getPermissions(true));
348
349 return !!array_intersect(['community_admin', 'course_admin'], array_keys($permissions));
350 }
351
352 public function getSpaceRole($space)
353 {
354 $globalRoles = $this->getCommunityRoles();
355
356 if ($globalRoles) {
357 if (in_array('admin', $globalRoles)) {
358 return 'admin';
359 }
360 }
361
362 if ($space) {
363 $spacePivot = SpaceUserPivot::where('space_id', $space->id)
364 ->where('user_id', $this->ID)
365 ->first();
366
367 if ($spacePivot) {
368 if ($spacePivot->role != 'member') {
369 return $spacePivot->role;
370 }
371
372 if (!in_array('moderator', $globalRoles)) {
373 if ($spacePivot->status == 'pending') {
374 return 'pending';
375 }
376 return $spacePivot->role;
377 }
378 }
379 }
380
381 if (in_array('moderator', $globalRoles)) {
382 return 'moderator';
383 }
384
385 return '';
386 }
387
388 public function cacheAccessSpaces()
389 {
390 $globalRoles = $this->getCommunityRoles();
391
392 if (array_intersect($globalRoles, ['admin', 'moderator'])) {
393 $spaces = Space::all();
394 } else {
395 $spaces = Space::whereHas('members', function ($query) {
396 $query->where('user_id', $this->ID)
397 ->where('status', 'active');
398 })->orWhere('privacy', 'public')->get();
399 }
400
401 $spaceIds = $spaces->pluck('id')->toArray();
402
403 update_user_meta($this->ID, '_fcom_space_ids', $spaceIds);
404
405 return $spaces;
406 }
407
408 protected function getRolePermissions($roles)
409 {
410 if (!$roles) {
411 return apply_filters('fluent_community/user/permissions', [
412 'read' => true
413 ], $roles, $this);
414 }
415
416 $isAdmin = in_array('admin', $roles);
417 $isModerator = !!array_intersect($roles, ['admin', 'moderator']);
418
419 $permissions = [
420 'admin' => $isAdmin,
421 'super_admin' => Helper::isSiteAdmin(),
422 'community_admin' => $isAdmin,
423 'community_moderator' => $isModerator,
424 'delete_any_feed' => $isModerator,
425 'edit_any_feed' => $isModerator,
426 'delete_any_comment' => $isModerator,
427 'edit_any_comment' => $isModerator,
428 'read' => true
429 ];
430
431 if ($isAdmin || in_array('course_admin', $roles)) {
432 $permissions['course_creator'] = true;
433 $permissions['course_admin'] = true;
434 } else if (in_array('course_creatror', $roles)) {
435 $permissions['course_creator'] = true;
436 }
437
438 return apply_filters('fluent_community/user/permissions', $permissions, $roles, $this);
439 }
440
441 public function getPermissions($cached = true)
442 {
443 static $permissions;
444
445 if ($permissions && $cached) {
446 return $permissions;
447 }
448
449 $roles = $this->getCommunityRoles();
450
451 $permissions = $this->getRolePermissions($roles);
452
453 return $permissions;
454 }
455
456 public function getSpacePermissions($space)
457 {
458 if (!$space) {
459 return [];
460 }
461
462 $role = $this->getSpaceRole($space);
463 $isRestrictedPost = Arr::get($space->settings, 'restricted_post_only') == 'yes';
464
465 if (!$role) {
466 $permissions = [
467 'can_create_post' => false,
468 'registered' => true,
469 'can_view_posts' => true,
470 'can_view_members' => $space->canViewMembers($this),
471 'is_pending' => false,
472 'is_non_member' => true,
473 'can_view_info' => $space->privacy !== 'secret'
474 ];
475
476 if ($space->privacy === 'secret' || $space->privacy === 'private') {
477 $permissions['can_view_posts'] = false;
478 $permissions['can_view_members'] = false;
479 }
480 } else if ($role == 'pending') {
481 $permissions = [
482 'can_create_post' => false,
483 'registered' => true,
484 'can_view_posts' => true,
485 'can_view_members' => $space->canViewMembers($this),
486 'is_pending' => true,
487 'can_view_info' => $space->privacy !== 'secret'
488 ];
489
490 if ($space->privacy === 'secret' || $space->privacy === 'private') {
491 $permissions['can_view_posts'] = false;
492 $permissions['can_view_members'] = false;
493 }
494 } else if ($role == 'member' || $role == 'student') {
495 $permissions = [
496 'can_create_post' => $isRestrictedPost ? false : true,
497 'registered' => true,
498 'can_view_posts' => true,
499 'can_view_members' => $space->canViewMembers($this),
500 'can_comment' => true,
501 'can_view_info' => true
502 ];
503 } else {
504 $permissions = [
505 'can_create_post' => $isRestrictedPost ? in_array($role, ['admin', 'moderator']) : true,
506 'can_view_posts' => true,
507 'can_view_members' => $space->canViewMembers($this),
508 'registered' => true,
509 'community_admin' => $role === 'admin',
510 'community_moderator' => in_array($role, ['admin', 'moderator']),
511 'edit_any_feed' => $role === 'admin',
512 'delete_any_feed' => in_array($role, ['admin', 'moderator']),
513 'super_admin' => Helper::isSiteAdmin(),
514 'read' => true,
515 'can_remove_member' => $role === 'admin',
516 'can_add_member' => $role === 'admin',
517 'can_comment' => in_array($role, ['admin', 'moderator']),
518 'can_view_info' => true
519 ];
520 }
521
522 return apply_filters('fluent_community/user/space/permissions', $permissions, $space, $role, $this);
523 }
524
525 public function hasCommunityPermission($permission)
526 {
527 $permissions = $this->getPermissions();
528
529 if (isset($permissions[$permission])) {
530 return $permissions[$permission];
531 }
532
533 return false;
534 }
535
536 public function hasSpacePermission($permission, $space)
537 {
538 $permissions = $this->getSpacePermissions($space);
539
540 if (isset($permissions[$permission])) {
541 return $permissions[$permission];
542 }
543
544 return false;
545 }
546
547 public function verifyCommunityPermission($permission)
548 {
549 if (!$this->hasCommunityPermission($permission)) {
550 throw new \Exception('You do not have permission to do this action');
551 }
552
553 return true;
554 }
555
556 public function verifySpacePermission($permission, $space)
557 {
558 if (!$space || !$this->hasSpacePermission($permission, $space)) {
559 throw new \Exception('You do not have permission to do this action');
560 }
561
562 return true;
563 }
564
565 public function canEditFeed($feed, $throwException = false)
566 {
567 $result = $feed->user_id == $this->ID || $this->hasCommunityPermission('edit_any_feed') || $this->hasSpacePermission('edit_any_feed', $feed->space_id);
568
569 if (!$result && $throwException) {
570 throw new \Exception('You do not have permission to do this action');
571 }
572
573 return $result;
574 }
575
576 public function canDeleteFeed($feed, $throwException = false)
577 {
578 $result = $feed->user_id == $this->ID || $this->hasCommunityPermission('delete_any_feed') || $this->hasSpacePermission('delete_any_feed', $feed->space_id);
579
580 if (!$result && $throwException) {
581 throw new \Exception('You do not have permission to do this action');
582 }
583 return $result;
584 }
585
586 public function can($permission, $space = null)
587 {
588 if ($space) {
589 return $this->hasSpacePermission($permission, $space);
590 }
591
592 return $this->hasCommunityPermission($permission);
593 }
594
595 public function getUnreadNotificationCount()
596 {
597 return NotificationSubscriber::where('user_id', $this->ID)
598 ->unread()
599 ->count();
600 }
601
602 public function getUnreadNotificationFeedIds()
603 {
604 $ids = Notification::whereHas('subscribers', function ($query) {
605 return $query->where('user_id', $this->ID)
606 ->unread();
607 })->pluck('feed_id')->toArray();
608
609 return array_values(array_unique($ids));
610 }
611
612 public function isVerified()
613 {
614 return get_user_meta($this->ID, '_fcom_is_verified', true) == 'yes';
615 }
616
617 public function syncXProfile($force = false, $useUserName = false)
618 {
619 $exist = $this->xprofile;
620
621 if ($exist && !$force) {
622 return $exist;
623 }
624
625 $createdAt = $this->user_registered;
626 if (!$createdAt || $createdAt == '0000-00-00 00:00:00' || !strtotime($createdAt)) {
627 $createdAt = gmdate('Y-m-d H:i:s');
628 } else {
629 $timeDiff = time() - current_time('timestamp');
630 $createdAt = gmdate('Y-m-d H:i:s', strtotime($createdAt) - $timeDiff);
631 }
632
633 $data = [
634 'user_id' => $this->ID,
635 'username' => ProfileHelper::generateUserName($this->ID, $useUserName),
636 'display_name' => $this->getDisplayName(),
637 'avatar' => $this->getPhotoAttribute(),
638 'is_verified' => $this->isVerified() ? 1 : 0,
639 'created_at' => $createdAt,
640 'short_description' => get_user_meta($this->ID, 'description', true),
641 'meta' => [
642 'website' => $this->user_url,
643 'cover_photo' => get_user_meta($this->ID, '_fluent_cover_photo', true)
644 ]
645 ];
646
647 if ($exist) {
648 unset($data['avatar']);
649 unset($data['username']);
650 $data['meta'] = wp_parse_args($exist->meta, $data['meta']);
651 $exist->fill($data);
652 $exist->save();
653 return $exist;
654 }
655
656
657 $counter = 1;
658 $initialUserName = $data['username'];
659 while (XProfile::where('username', $initialUserName)->first()) {
660 $initialUserName = $data['username'] . '_' . $counter;
661 $counter++;
662 }
663
664 $data['username'] = $initialUserName;
665
666 return XProfile::create($data);
667 }
668
669 public function getUserMeta($metaKey, $default = null)
670 {
671 return get_user_meta($this->ID, $metaKey, true) ?? $default;
672 }
673 }
674