PluginProbe
FluentCommunity – Ultra-Fast High-Performance Social Network, Community, LMS & Online Courses / 2.10.0
FluentCommunity – Ultra-Fast High-Performance Social Network, Community, LMS & Online Courses v2.10.0
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
← All changes | app/Models/XProfile.php +144 -16 1.1.02.10.0 View file →
@@ -6,10 +6,12 @@
6 6 use FluentCommunity\App\Functions\Utility;
7 7 use FluentCommunity\App\Models\Contact;
8 8 use FluentCommunity\App\Models\Feed;
9 9 use FluentCommunity\App\Models\User;
10 +use FluentCommunity\App\Services\Helper;
10 11 use FluentCommunity\Framework\Support\Arr;
11 12 use FluentCommunity\Modules\Course\Model\Course;
13 +use FluentCommunityPro\App\Models\Follow;
12 14 use FluentCrm\App\Models\Subscriber;
13 15
14 16 /**
15 17 * FluentCommunity XProfile Model
@@ -18,14 +20,34 @@
18 20 *
19 21 * @package FluentCommunity\App\Models
20 22 *
21 23 * @version 1.1.0
24 + *
25 + * @property int $id
26 + * @property int $user_id
27 + * @property int $total_points
28 + * @property string|null $username
29 + * @property string $status
30 + * @property int $is_verified
31 + * @property string|null $display_name
32 + * @property string|null $avatar
33 + * @property string|null $short_description
34 + * @property string|null $last_activity
35 + * @property mixed $meta
36 + * @property mixed $custom_fields
37 + * @property object|null $created_at
38 + * @property-read mixed $badge
39 + * @property-read string $permalink
40 + * @property-read \FluentCommunity\App\Models\User|null $user
41 + * @property int|null $compilation_score
42 + * @property string|null $user_email
43 + * @property int|null $ID
22 44 */
23 45 class XProfile extends Model
24 46 {
25 47 protected $table = 'fcom_xprofile';
26 48
27 - protected $guarded = ['id'];
49 + protected $guarded = [ 'id' ];
28 50
29 51 protected $primaryKey = 'user_id';
30 52
31 53 protected $casts = [
@@ -44,17 +66,18 @@
44 66 'avatar',
45 67 'short_description',
46 68 'last_activity',
47 69 'meta',
48 - 'created_at'
70 + 'custom_fields',
71 + 'created_at',
49 72 ];
50 73
51 74 protected $searchable = [
52 75 'display_name',
53 - 'username'
76 + 'username',
54 77 ];
55 78
56 - protected $appends = ['badge'];
79 + protected $appends = [ 'badge', 'permalink' ];
57 80
58 81 public function scopeSearchBy($query, $search)
59 82 {
60 83 if ($search) {
@@ -66,9 +89,9 @@
66 89 $q->orWhere($field, 'LIKE', "%$search%");
67 90 }
68 91 });
69 92 }
70 -
93 +
71 94 return $query;
72 95 }
73 96
74 97 public function scopeMentionBy($query, $search)
@@ -74,10 +97,10 @@
74 97 public function scopeMentionBy($query, $search)
75 98 {
76 99 if ($search) {
77 100 $query->where(function ($q) use ($search) {
78 - $q->where('display_name', 'LIKE', "$search%")
79 - ->orWhere('username', 'LIKE', "$search%");
101 + $q->where('display_name', 'LIKE', "%$search%")
102 + ->orWhere('username', 'LIKE', "%$search%");
80 103 });
81 104 }
82 105
83 106 return $query;
@@ -95,9 +118,9 @@
95 118
96 119 public function spaces()
97 120 {
98 121 return $this->belongsToMany(BaseSpace::class, 'fcom_space_user', 'user_id', 'space_id')
99 - ->withPivot(['role', 'status', 'created_at']);
122 + ->withPivot([ 'role', 'status', 'created_at' ]);
100 123 }
101 124
102 125 public function posts()
103 126 {
@@ -103,12 +126,34 @@
103 126 {
104 127 return $this->hasMany(Feed::class, 'user_id', 'user_id');
105 128 }
106 129
130 + // Relationship: Users this user follows
131 + public function follows()
132 + {
133 + return $this->hasMany(Follow::class, 'follower_id', 'user_id');
134 + }
135 +
136 + // Relationship: Users following this user
137 + public function followers()
138 + {
139 + return $this->hasMany(Follow::class, 'followed_id', 'user_id');
140 + }
141 +
142 + public function scheduledPosts()
143 + {
144 + return $this->posts()->where('status', 'scheduled')->where('scheduled_at', '!=', null);
145 + }
146 +
147 + public function comments()
148 + {
149 + return $this->hasMany(Comment::class, 'user_id', 'user_id');
150 + }
151 +
107 152 public function courses()
108 153 {
109 154 return $this->belongsToMany(Course::class, 'fcom_space_user', 'user_id', 'space_id')
110 - ->withPivot(['role', 'status', 'created_at']);
155 + ->withPivot([ 'role', 'status', 'created_at' ]);
111 156 }
112 157
113 158 public function space_pivot()
114 159 {
@@ -117,8 +162,9 @@
117 162
118 163 public function community_role()
119 164 {
120 165 return $this->belongsTo(Meta::class, 'user_id', 'object_id')
166 + ->where('object_type', 'user')
121 167 ->where('meta_key', '_user_community_roles');
122 168 }
123 169
124 170 /**
@@ -126,31 +172,75 @@
126 172 * @return string
127 173 */
128 174 public function getAvatarAttribute()
129 175 {
176 + $gravatarEnabled = Utility::getPrivacySetting('enable_gravatar') != 'no';
177 +
130 178 if (!empty($this->attributes['avatar'])) {
131 - return $this->attributes['avatar'];
179 + $url = $this->attributes['avatar'];
180 + if (!$gravatarEnabled && strpos($url, 'gravatar.com')) {
181 + $url = apply_filters('fluent_community/default_avatar', FLUENT_COMMUNITY_PLUGIN_URL . 'assets/images/placeholder.png', $this->user_id);
182 + }
183 +
184 + if (!$url) {
185 + $url = FLUENT_COMMUNITY_PLUGIN_URL . 'assets/images/placeholder.png';
186 + }
187 +
188 + return $url;
132 189 }
133 190
191 + if (!$gravatarEnabled) {
192 + $url = apply_filters('fluent_community/default_avatar', FLUENT_COMMUNITY_PLUGIN_URL . 'assets/images/placeholder.png', $this->user_id);
193 +
194 + if (!$url) {
195 + $url = FLUENT_COMMUNITY_PLUGIN_URL . 'assets/images/placeholder.png';
196 + }
197 +
198 + return $url;
199 + }
200 +
134 201 $url = Utility::getFromCache('user_avatar_' . $this->user_id, function () {
202 + $displayName = $this->display_name;
203 +
204 + if ($displayName) {
205 + $names = explode(' ', $displayName);
206 + // take the first letter of each name
207 + $displayName = '';
208 + foreach ($names as $name) {
209 + $name = (string)$name;
210 + $firstLetter = mb_substr($name, 0, 1, 'UTF-8');
211 + $displayName .= $firstLetter . '+';
212 + }
213 + }
214 +
135 215 return get_avatar_url($this->user_id, [
136 216 'size' => 128,
137 - 'default' => apply_filters('fluent_community/default_avatar', 'https://ui-avatars.com/api/?name=' . $this->display_name . '/128', $this)
217 + 'default' => apply_filters('fluent_community/default_avatar', 'https://ui-avatars.com/api/' . esc_attr($displayName) . '/128', $this->user_id),
138 218 ]);
139 219 }, WEEK_IN_SECONDS);
140 220
141 221 if (!$url) {
142 - $url = apply_filters('fluent_community/default_avatar', FLUENT_COMMUNITY_PLUGIN_URL . 'assets/images/placeholder.png', $this);
222 + $url = FLUENT_COMMUNITY_PLUGIN_URL . 'assets/images/placeholder.png';
143 223 }
144 224
145 225 return $url;
146 226 }
147 227
228 + public function hasCustomAvatar()
229 + {
230 + return !empty($this->attributes['avatar']);
231 + }
232 +
148 233 public function getBadgeAttribute()
149 234 {
150 235 return apply_filters('fluent_community/xprofile/badge', null, $this);
151 236 }
152 237
238 + public function getPermalinkAttribute()
239 + {
240 + return $this->getPermalink();
241 + }
242 +
153 243 public function getCrmContact()
154 244 {
155 245 if (!defined('FLUENTCRM')) {
156 246 return null;
@@ -167,17 +257,25 @@
167 257 }
168 258
169 259 public function getMetaAttribute($value)
170 260 {
171 - $settings = maybe_unserialize($value);
261 + $settings = Utility::safeUnserialize($value);
172 262
173 263 if (!$settings) {
174 264 $settings = [
175 265 'cover_photo' => '',
176 - 'website' => ''
266 + 'badge_slug' => [],
267 + 'website' => '',
177 268 ];
178 269 }
179 270
271 + if (!Utility::canViewUserProfile($this->user_id)) {
272 + return [
273 + 'cover_photo' => Arr::get($settings, 'cover_photo', ''),
274 + 'badge_slug' => Arr::get($settings, 'badge_slug', []),
275 + ];
276 + }
277 +
180 278 return $settings;
181 279 }
182 280
183 281 public function setMetaAttribute($value)
@@ -184,9 +282,9 @@
184 282 {
185 283 if (!$value) {
186 284 $value = [
187 285 'cover_photo' => '',
188 - 'website' => ''
286 + 'website' => '',
189 287 ];
190 288 }
191 289
192 290 $this->attributes['meta'] = maybe_serialize($value);
@@ -191,8 +289,24 @@
191 289
192 290 $this->attributes['meta'] = maybe_serialize($value);
193 291 }
194 292
293 + public function getCustomFieldsAttribute($value)
294 + {
295 + if (!$value) {
296 + return [];
297 + }
298 +
299 + $data = json_decode($value, true);
300 +
301 + return is_array($data) ? $data : [];
302 + }
303 +
304 + public function setCustomFieldsAttribute($value)
305 + {
306 + $this->attributes['custom_fields'] = is_array($value) ? json_encode($value) : $value;
307 + }
308 +
195 309 public function getFirstName()
196 310 {
197 311 if (!$this->display_name) {
198 312 return '';
@@ -227,9 +341,9 @@
227 341 'website' => 30,
228 342 'cover_photo' => 20,
229 343 'avatar' => 20,
230 344 'short_description' => 30,
231 - 'social_links' => 20
345 + 'social_links' => 20,
232 346 ];
233 347
234 348 $score = 0;
235 349
@@ -268,5 +382,19 @@
268 382
269 383 return $score > 100 ? 100 : $score;
270 384 }
271 385
386 + public function getPermalink()
387 + {
388 + return Helper::baseUrl('u/' . $this->username);
389 + }
390 +
391 + public function getJsRoute()
392 + {
393 + return [
394 + 'name' => 'user_profile',
395 + 'params' => [
396 + 'username' => $this->username,
397 + ],
398 + ];
399 + }
272 400 }