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

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

380 lines 9.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
6 use FluentCommunity\App\Functions\Utility;
7 use FluentCommunity\App\Models\Contact;
8 use FluentCommunity\App\Models\Feed;
9 use FluentCommunity\App\Models\User;
10 use FluentCommunity\App\Services\Helper;
11 use FluentCommunity\Framework\Support\Arr;
12 use FluentCommunity\Modules\Course\Model\Course;
13 use FluentCommunityPro\App\Models\Follow;
14 use FluentCrm\App\Models\Subscriber;
15
16 /**
17 * FluentCommunity XProfile Model
18 *
19 * Database Model
20 *
21 * @package FluentCommunity\App\Models
22 *
23 * @version 1.1.0
24 */
25 class XProfile extends Model
26 {
27 protected $table = 'fcom_xprofile';
28
29 protected $guarded = ['id'];
30
31 protected $primaryKey = 'user_id';
32
33 protected $casts = [
34 'user_id' => 'integer',
35 'total_points' => 'integer',
36 'is_verified' => 'integer',
37 ];
38
39 protected $fillable = [
40 'user_id',
41 'total_points',
42 'username',
43 'status',
44 'is_verified',
45 'display_name',
46 'avatar',
47 'short_description',
48 'last_activity',
49 'meta',
50 'custom_fields',
51 'created_at'
52 ];
53
54 protected $searchable = [
55 'display_name',
56 'username'
57 ];
58
59 protected $appends = ['badge', 'permalink'];
60
61 public function scopeSearchBy($query, $search)
62 {
63 if ($search) {
64 $fields = $this->searchable;
65
66 $query->where(function ($q) use ($fields, $search) {
67 $q->where(array_shift($fields), 'LIKE', "%$search%");
68 foreach ($fields as $field) {
69 $q->orWhere($field, 'LIKE', "%$search%");
70 }
71 });
72 }
73
74 return $query;
75 }
76
77 public function scopeMentionBy($query, $search)
78 {
79 if ($search) {
80 $query->where(function ($q) use ($search) {
81 $q->where('display_name', 'LIKE', "%$search%")
82 ->orWhere('username', 'LIKE', "%$search%");
83 });
84 }
85
86 return $query;
87 }
88
89 public function user()
90 {
91 return $this->belongsTo(User::class, 'user_id', 'ID');
92 }
93
94 public function contact()
95 {
96 return $this->hasOne(Contact::class, 'user_id', 'user_id');
97 }
98
99 public function spaces()
100 {
101 return $this->belongsToMany(BaseSpace::class, 'fcom_space_user', 'user_id', 'space_id')
102 ->withPivot(['role', 'status', 'created_at']);
103 }
104
105 public function posts()
106 {
107 return $this->hasMany(Feed::class, 'user_id', 'user_id');
108 }
109
110 // Relationship: Users this user follows
111 public function follows()
112 {
113 return $this->hasMany(Follow::class, 'follower_id', 'user_id');
114 }
115
116 // Relationship: Users following this user
117 public function followers()
118 {
119 return $this->hasMany(Follow::class, 'followed_id', 'user_id');
120 }
121
122 public function scheduledPosts()
123 {
124 return $this->posts()->where('status', 'scheduled')->where('scheduled_at', '!=', null);
125 }
126
127 public function comments()
128 {
129 return $this->hasMany(Comment::class, 'user_id', 'user_id');
130 }
131
132 public function courses()
133 {
134 return $this->belongsToMany(Course::class, 'fcom_space_user', 'user_id', 'space_id')
135 ->withPivot(['role', 'status', 'created_at']);
136 }
137
138 public function space_pivot()
139 {
140 return $this->belongsTo(SpaceUserPivot::class, 'user_id', 'user_id')->withoutGlobalScopes();
141 }
142
143 public function community_role()
144 {
145 return $this->belongsTo(Meta::class, 'user_id', 'object_id')
146 ->where('meta_key', '_user_community_roles');
147 }
148
149 /**
150 * Accessor to get dynamic photo attribute
151 * @return string
152 */
153 public function getAvatarAttribute()
154 {
155 $gravatarEnabled = Utility::getPrivacySetting('enable_gravatar') != 'no';
156
157 if (!empty($this->attributes['avatar'])) {
158 $url = $this->attributes['avatar'];
159 if (!$gravatarEnabled && strpos($url, 'gravatar.com')) {
160 $url = apply_filters('fluent_community/default_avatar', FLUENT_COMMUNITY_PLUGIN_URL . 'assets/images/placeholder.png', $this->user_id);
161 }
162
163 if (!$url) {
164 $url = FLUENT_COMMUNITY_PLUGIN_URL . 'assets/images/placeholder.png';
165 }
166
167 return $url;
168 }
169
170 if (!$gravatarEnabled) {
171 $url = apply_filters('fluent_community/default_avatar', FLUENT_COMMUNITY_PLUGIN_URL . 'assets/images/placeholder.png', $this->user_id);
172
173 if (!$url) {
174 $url = FLUENT_COMMUNITY_PLUGIN_URL . 'assets/images/placeholder.png';
175 }
176
177 return $url;
178 }
179
180 $url = Utility::getFromCache('user_avatar_' . $this->user_id, function () {
181 $displayName = $this->display_name;
182
183 if ($displayName) {
184 $names = explode(' ', $displayName);
185 // take the first letter of each name
186 $displayName = '';
187 foreach ($names as $name) {
188 $name = (string)$name;
189 $firstLetter = mb_substr($name, 0, 1, 'UTF-8');
190 $displayName .= $firstLetter . '+';
191 }
192 }
193
194 return get_avatar_url($this->user_id, [
195 'size' => 128,
196 'default' => apply_filters('fluent_community/default_avatar', 'https://ui-avatars.com/api/' . esc_attr($displayName) . '/128', $this->user_id)
197 ]);
198 }, WEEK_IN_SECONDS);
199
200 if (!$url) {
201 $url = FLUENT_COMMUNITY_PLUGIN_URL . 'assets/images/placeholder.png';
202 }
203
204 return $url;
205 }
206
207 public function hasCustomAvatar()
208 {
209 return !empty($this->attributes['avatar']);
210 }
211
212 public function getBadgeAttribute()
213 {
214 return apply_filters('fluent_community/xprofile/badge', null, $this);
215 }
216
217 public function getPermalinkAttribute()
218 {
219 return $this->getPermalink();
220 }
221
222 public function getCrmContact()
223 {
224 if (!defined('FLUENTCRM')) {
225 return null;
226 }
227
228 if ($this->user_email) {
229 return Subscriber::where('user_id', $this->ID)
230 ->orWhere('email', $this->user_email)
231 ->first();
232 }
233
234 return Subscriber::where('user_id', $this->ID)
235 ->first();
236 }
237
238 public function getMetaAttribute($value)
239 {
240 $settings = Utility::safeUnserialize($value);
241
242 if (!$settings) {
243 $settings = [
244 'cover_photo' => '',
245 'badge_slug' => [],
246 'website' => ''
247 ];
248 }
249
250 if (!Utility::canViewUserProfile($this->user_id)) {
251 return [
252 'cover_photo' => Arr::get($settings, 'cover_photo', ''),
253 'badge_slug' => Arr::get($settings, 'badge_slug', [])
254 ];
255 }
256
257 return $settings;
258 }
259
260 public function setMetaAttribute($value)
261 {
262 if (!$value) {
263 $value = [
264 'cover_photo' => '',
265 'website' => ''
266 ];
267 }
268
269 $this->attributes['meta'] = maybe_serialize($value);
270 }
271
272 public function getCustomFieldsAttribute($value)
273 {
274 if (!$value) {
275 return [];
276 }
277
278 $data = json_decode($value, true);
279
280 return is_array($data) ? $data : [];
281 }
282
283 public function setCustomFieldsAttribute($value)
284 {
285 $this->attributes['custom_fields'] = is_array($value) ? json_encode($value) : $value;
286 }
287
288 public function getFirstName()
289 {
290 if (!$this->display_name) {
291 return '';
292 }
293 $fullName = explode(' ', $this->display_name);
294 return $fullName[0];
295 }
296
297 public function getLastName()
298 {
299
300 if (!$this->display_name) {
301 return '';
302 }
303
304 $fullName = explode(' ', $this->display_name);
305
306 // remove the first name
307 array_shift($fullName);
308
309 if (count($fullName) == 0) {
310 return '';
311 }
312 return implode(' ', $fullName);
313 }
314
315 public function getCompletionScore()
316 {
317 $scores = [
318 'first_name' => 20,
319 'last_name' => 20,
320 'website' => 30,
321 'cover_photo' => 20,
322 'avatar' => 20,
323 'short_description' => 30,
324 'social_links' => 20
325 ];
326
327 $score = 0;
328
329 if ($this->getFirstName()) {
330 $score += $scores['first_name'];
331 }
332
333 if ($this->getLastName()) {
334 $score += $scores['last_name'];
335 }
336
337 $meta = $this->meta;
338 if (Arr::get($meta, 'website')) {
339 $score += $scores['website'];
340 }
341
342 if (Arr::get($meta, 'cover_photo')) {
343 $score += $scores['cover_photo'];
344 }
345
346 if ($this->short_description) {
347 $score += $scores['short_description'];
348 }
349
350 if ($score >= 100) {
351 return 100;
352 }
353
354 if (!empty($meta['social_links']) && array_filter(Arr::get($meta, 'social_links', []))) {
355 $score += $scores['social_links'];
356 }
357
358 if (!empty($this->attributes['avatar'])) {
359 $score += $scores['avatar'];
360 }
361
362 return $score > 100 ? 100 : $score;
363 }
364
365 public function getPermalink()
366 {
367 return Helper::baseUrl('u/' . $this->username);
368 }
369
370 public function getJsRoute()
371 {
372 return [
373 'name' => 'user_profile',
374 'params' => [
375 'username' => $this->username
376 ]
377 ];
378 }
379 }
380