PluginProbe
FluentCommunity – Ultra-Fast High-Performance Social Network, Community, LMS & Online Courses / 1.0.97
FluentCommunity – Ultra-Fast High-Performance Social Network, Community, LMS & Online Courses v1.0.97
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 / Http / Controllers / ProfileController.php

ProfileController.php in FluentCommunity – Ultra-Fast High-Performance Social Network, Community, LMS & Online Courses 1.0.97, at app/Http/Controllers/ProfileController.php

499 lines 18.8 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\Http\Controllers;
4
5 use FluentCommunity\App\Functions\Utility;
6 use FluentCommunity\App\Models\Comment;
7 use FluentCommunity\App\Models\NotificationSubscription;
8 use FluentCommunity\App\Models\Space;
9 use FluentCommunity\App\Models\SpaceGroup;
10 use FluentCommunity\App\Models\User;
11 use FluentCommunity\App\Models\XProfile;
12 use FluentCommunity\App\Services\CustomSanitizer;
13 use FluentCommunity\App\Services\FeedsHelper;
14 use FluentCommunity\App\Services\Helper;
15 use FluentCommunity\App\Services\NotificationPref;
16 use FluentCommunity\App\Services\ProfileHelper;
17 use FluentCommunity\Framework\Http\Request\Request;
18 use FluentCommunity\Framework\Support\Arr;
19
20 class ProfileController extends Controller
21 {
22 public function getProfile(Request $request, $userName)
23 {
24 $xprofile = XProfile::where('username', $userName)->firstOrFail();
25
26 $user = get_user_by('ID', $xprofile->user_id);
27
28 $profile = [
29 'user_id' => $xprofile->user_id,
30 'is_verified' => $xprofile->is_verified,
31 'display_name' => $xprofile->display_name,
32 'username' => $xprofile->username,
33 'avatar' => $xprofile->avatar,
34 'created_at' => $xprofile->created_at->format('Y-m-d H:i:s'),
35 'last_activity' => $xprofile->last_activity,
36 'short_description_rendered' => FeedsHelper::mdToHtml($xprofile->short_description),
37 'cover_photo' => Arr::get($xprofile->meta, 'cover_photo'),
38 'website' => Arr::get($xprofile->meta, 'website'),
39 'social_links' => (object)Arr::get($xprofile->meta, 'social_links', []),
40 'status' => $xprofile->status,
41 'badge_slug' => Arr::get($xprofile->meta, 'badge_slug'),
42 'compilation_score' => $xprofile->getCompletionScore(),
43 'total_points' => $xprofile->total_points,
44 'canViewUserSpaces' => ProfileHelper::canViewUserSpaces($xprofile->user_id, $this->getUser())
45 ];
46
47 $isAdmin = Helper::isSiteAdmin();
48 if ($xprofile->user_id == get_current_user_id() || $isAdmin) {
49 $profile['email'] = $user->user_email;
50 $profile['first_name'] = $user->first_name;
51 $profile['last_name'] = $user->last_name;
52 $profile['short_description'] = $xprofile->short_description;
53 $profile['can_change_username'] = $isAdmin || Utility::getPrivacySetting('can_customize_username') === 'yes';
54 }
55
56 return [
57 'profile' => $profile
58 ];
59 }
60
61 public function patchProfile(Request $request, $userName)
62 {
63 $xprofile = $this->verfifyAndGetProfile($userName);
64
65 $updateData = $request->get('data');
66
67 $mediaTypes = ['cover_photo', 'avatar'];
68
69 foreach ($mediaTypes as $type) {
70 if (!empty($updateData[$type])) {
71 $media = Helper::getMediaFromUrl($updateData[$type]);
72 if (!$media || $media->is_active) {
73 return $this->sendError([
74 'message' => 'Invalid media image. Please upload a new one.'
75 ]);
76 }
77
78 $updateData[$type] = $media->public_url;
79
80 $media->update([
81 'is_active' => true,
82 'user_id' => $xprofile->user_id,
83 'object_source' => 'user_' . $type
84 ]);
85 }
86 }
87
88 $deletedMedias = [];
89
90 if (!empty($updateData['avatar'])) {
91
92 $deletedMedias[] = $xprofile->avatar;
93
94 $xprofile->avatar = $updateData['avatar'];
95
96 if (defined('FLUENTCRM')) {
97 $contact = $xprofile->contact;
98
99 if ($contact) {
100 $contact->update([
101 'avatar' => $updateData['avatar']
102 ]);
103 }
104 }
105
106 }
107
108 if (isset($updateData['cover_photo'])) {
109 $deletedMedias[] = Arr::get($xprofile->meta, 'cover_photo');
110 $xprofile->meta = wp_parse_args(['cover_photo' => $updateData['cover_photo']], $xprofile->meta);
111 }
112
113 $xprofile->save();
114
115 if ($deletedMedias = array_filter($deletedMedias)) {
116 do_action('fluent_community/remove_medias_by_url', $deletedMedias, [
117 'user_id' => $xprofile->user_id,
118 'object_sources' => ['user_avatar', 'user_cover_photo']
119 ]);
120 }
121
122 return [
123 'message' => __('Profile updated', 'fluent-community')
124 ];
125 }
126
127 public function updateProfile(Request $request, $userName)
128 {
129 $currentUser = $this->getUser(true);
130 $data = $request->get('data', []);
131
132 if ($currentUser->isCommunityModerator()) {
133 $xProfile = XProfile::where('user_id', $data['user_id'])->firstOrFail();
134 } else {
135 $xProfile = XProfile::where('username', $userName)->firstOrFail();
136 if ($xProfile->user_id != get_current_user_id()) {
137 return $this->sendError([
138 'message' => 'You are not allowed to update this profile'
139 ]);
140 }
141 }
142
143 $this->validate($data, [
144 'first_name' => 'required',
145 ], [
146 'first_name.required' => __('First name is required', 'fluent-community')
147 ]);
148
149 $updateData = Arr::only($data, ['first_name', 'last_name', 'short_description', 'website']);
150
151 $currentUser = User::findOrFail(get_current_user_id());
152 $meta = $xProfile->meta;
153
154 $userNameChanged = false;
155
156 if ($currentUser->isCommunityModerator()) {
157 $updateData['is_verified'] = Arr::get($data, 'is_verified') ? 1 : 0;
158 $updateData['status'] = Arr::get($data, 'status', 'active');
159 $userName = Arr::get($data, 'username');
160
161 if (user_can($xProfile->user_id, 'list_users')) {
162 $updateData['status'] = 'active';
163 }
164
165 if ($userName) {
166 // Check if username is exit or not
167 $userName = CustomSanitizer::sanitizeUserName($userName);
168
169 if (!$userName) {
170 return $this->sendError([
171 'message' => __('Invalid username. Only Latin characters with _ & - are allowed.', 'fluent-community')
172 ]);
173 }
174
175 if (XProfile::where('username', $userName)->where('user_id', '!=', $xProfile->user_id)->exists()) {
176 return $this->sendError([
177 'message' => __('Community Username already taken by someone else', 'fluent-community')
178 ]);
179 }
180
181 $userExist = get_user_by('user_login', $userName);
182
183 if ($userExist && $userExist->ID != $xProfile->user_id) {
184 return $this->sendError([
185 'message' => __('Username already taken by someone else. Please use a different username.', 'fluent-community')
186 ]);
187 }
188
189 $updateData['username'] = $userName;
190 $userNameChanged = $userName != $xProfile->username;
191 }
192
193 if (Helper::isFeatureEnabled('user_badge')) {
194 $badgeSlug = Arr::get($data, 'badge_slug');
195 $meta['badge_slug'] = $badgeSlug;
196 }
197 } else if (Utility::getPrivacySetting('can_customize_username')) {
198 $userName = Arr::get($data, 'username');
199
200 if ($xProfile->username != $userName) {
201 $userName = strtolower(CustomSanitizer::sanitizeUserName($userName));
202 if (!$userName) {
203 return $this->sendError([
204 'message' => __('Invalid username. Only Latin characters with _ & - are allowed.', 'fluent-community')
205 ]);
206 }
207
208 if (XProfile::where('username', $userName)->where('user_id', '!=', $xProfile->user_id)->exists()) {
209 return $this->sendError([
210 'message' => __('Community Username already taken by someone else', 'fluent-community')
211 ]);
212 }
213
214 if(strlen($userName) < 3) {
215 return $this->sendError([
216 'message' => __('Username should be at least 3 characters long.', 'fluent-community')
217 ]);
218 }
219
220 $reservedUserNames = ProfileHelper::getReservedUserNames();
221 if (in_array($userName, $reservedUserNames)) {
222 return $this->sendError([
223 'message' => __('Please use another username. This username is reserved', 'fluent-community')
224 ]);
225 }
226
227 $updateData['username'] = $userName;
228 $userNameChanged = true;
229 }
230
231 }
232
233 $updateData['display_name'] = trim(sanitize_text_field(Arr::get($data, 'first_name') . ' ' . Arr::get($data, 'last_name')));
234 $updateData['short_description'] = CustomSanitizer::unslashMarkdown(sanitize_textarea_field(trim(Arr::get($data, 'short_description'))));
235 $meta['website'] = sanitize_url(Arr::get($data, 'website'));
236 $socialLinks = Arr::get($data, 'social_links', []);
237
238 $maxDescriptionLength = apply_filters('fluent_community/max_profile_description_length', 5000);
239 if ($updateData['short_description'] && strlen($updateData['short_description']) > $maxDescriptionLength) {
240 return $this->sendError([
241 'message' => sprintf(__('Profile bio should not exceed %d characters.', 'fluent-community'), $maxDescriptionLength)
242 ]);
243 }
244
245 if ($socialLinks) {
246 $socialLinks = array_filter($socialLinks);
247 $formattedSocialLinkes = [];
248 $socialLinkProviders = ProfileHelper::socialLinkProviders();
249 foreach ($socialLinks as $linkName => $socialLink) {
250 if (isset($socialLinkProviders[$linkName])) {
251 $formattedSocialLinkes[$linkName] = sanitize_text_field(trim($socialLink));
252 }
253 }
254 $meta['social_links'] = $formattedSocialLinkes;
255 }
256
257 $updateData['meta'] = $meta;
258
259 $xProfile->fill($updateData);
260 $xProfile->save();
261
262
263 // Let's update the user's details
264 $xProfile->user->updateCustomData($updateData);
265 $xProfile->compilation_score = $xProfile->getCompletionScore();
266
267 if ($userNameChanged) {
268 return [
269 'message' => __('Profile has been updated', 'fluent-community'),
270 'profile' => $xProfile,
271 'redirect_url' => Helper::baseUrl('u/' . $xProfile->username . '/update')
272 ];
273 }
274
275 return [
276 'message' => __('Profile has been updated', 'fluent-community'),
277 'profile' => $xProfile
278 ];
279 }
280
281 public function getSpaces(Request $request, $userName)
282 {
283 $xProfile = XProfile::where('username', $userName)->firstOrFail();
284 $currentUser = $this->getUser();
285
286 if (!ProfileHelper::canViewUserSpaces($xProfile->user_id, $currentUser)) {
287 return $this->sendError([
288 'message' => __('You are not allowed to view this profile\'s spaces.', 'fluent-community'),
289 'permission_failed' => true
290 ]);
291 }
292
293 if ($xProfile->user_id == get_current_user_id() || ($currentUser && $currentUser->isCommunityModerator())) {
294 $spaces = $xProfile->spaces()
295 ->wherePivot('status', 'active')
296 ->get();
297 } else {
298 $spaces = $xProfile->spaces()
299 ->whereIn('privacy', ['public', 'private'])
300 ->wherePivot('status', 'active')
301 ->get();
302 }
303
304 foreach ($spaces as $space) {
305 $space->members_count = $space->members()->count();
306 }
307
308 return [
309 'spaces' => $spaces
310 ];
311 }
312
313 public function getComments(Request $request, $userName)
314 {
315 $xProfile = XProfile::where('username', $userName)->first();
316
317 if (!$xProfile) {
318 return $this->sendError([
319 'message' => 'Profile not found'
320 ]);
321 }
322
323 $currentUser = $this->getUser();
324 $hasAllAccess = $xProfile->user_id == get_current_user_id() || ($currentUser && $currentUser->isCommunityModerator());
325
326 $comments = Comment::where('user_id', $xProfile->user_id)
327 ->with([
328 'post' => function ($q) {
329 $q->select(['id', 'title', 'message', 'type', 'space_id', 'slug', 'created_at'])
330 ->with([
331 'space' => function ($q) {
332 $q->select(['id', 'title', 'slug', 'type']);
333 }
334 ]);
335 }
336 ])
337 ->when(!$hasAllAccess, function ($q) use ($xProfile) {
338 $q->whereHas('post', function ($query) use ($xProfile) {
339 $query->byUserAccess(get_current_user_id());
340 $query->where('type', 'text');
341 });
342 })
343 ->orderBy('id', 'desc')
344 ->paginate();
345
346 return [
347 'comments' => $comments,
348 'xprofile' => $xProfile
349 ];
350 }
351
352 public function getNotificationPreferance(Request $request, $userName)
353 {
354 $emailPref = Utility::getEmailNotificationSettings();
355
356 $xProfile = $this->verfifyAndGetProfile($userName);
357
358 $globalPreferances = NotificationPref::getGlobalPrefs();
359 $userPrefs = NotificationSubscription::where('user_id', $xProfile->user_id)
360 ->select(['notification_type', 'is_read', 'object_id'])
361 ->get();
362
363 $userGlobalPrefs = [];
364 $spaceWisePrefs = [];
365 foreach ($userPrefs as $pref) {
366 if (!$pref->object_id) {
367 $userGlobalPrefs[$pref->notification_type] = $pref->is_read ? 'yes' : 'no';
368 } else {
369 if (empty($spaceWisePrefs[$pref->object_id])) {
370 $spaceWisePrefs[$pref->object_id] = [];
371 }
372 $spaceWisePrefs[$pref->object_id][$pref->notification_type] = $pref->is_read;
373 }
374 }
375
376 $userGlobalPrefsDefaults = [
377 'digest_mail' => Arr::get($globalPreferances, 'digest_email_status') ? 'yes' : 'no',
378 'mention_mail' => Arr::get($globalPreferances, 'mention_mail') ? 'yes' : 'no',
379 'reply_my_com_mail' => Arr::get($globalPreferances, 'reply_my_com_mail') ? 'yes' : 'no',
380 'com_my_post_mail' => Arr::get($globalPreferances, 'com_my_post_mail') ? 'yes' : 'no',
381 ];
382 $userGlobalPrefs = wp_parse_args($userGlobalPrefs, $userGlobalPrefsDefaults);
383
384 $spaceGroups = SpaceGroup::with(['spaces' => function ($query) {
385 $query->whereHas('members', function ($q) {
386 $q->where('user_id', get_current_user_id());
387 })
388 ->where('type', 'community');
389 }])
390 ->orderBy('serial', 'ASC')
391 ->get();
392
393 $formattedSpaceGroups = [];
394 foreach ($spaceGroups as $group) {
395 if ($group->spaces->isEmpty()) {
396 continue;
397 }
398
399 $formattedSpaces = [];
400 foreach ($group->spaces as $space) {
401
402 $pref = '';
403 if (isset($spaceWisePrefs[$space->id])) {
404 $perfs = (array)$spaceWisePrefs[$space->id];
405 if (!empty($perfs['np_by_member_mail'])) {
406 $pref = 'all_member_posts';
407 } else if (!empty($perfs['np_by_admin_mail'])) {
408 $pref = 'admin_only_posts';
409 }
410 }
411
412 $formattedSpaces[] = [
413 'id' => $space->id,
414 'title' => $space->title,
415 'icon' => $space->getIconMark(),
416 'pref' => $pref
417 ];
418 }
419
420 if ($formattedSpaces) {
421 $formattedSpaceGroups[] = [
422 'id' => $group->id,
423 'title' => $group->title,
424 'spaces' => $formattedSpaces
425 ];
426 }
427 }
428
429 $digestDay = (string)Arr::get($emailPref, 'digest_mail_day', 'tue');
430 if ($digestDay) {
431 $maps = [
432 'mon' => __('Monday', 'fluent-community'),
433 'tue' => __('Tuesday', 'fluent-community'),
434 'wed' => __('Wednesday', 'fluent-community'),
435 'thu' => __('Thursday', 'fluent-community'),
436 'fri' => __('Friday', 'fluent-community'),
437 'sat' => __('Saturday', 'fluent-community'),
438 'sun' => __('Sunday', 'fluent-community'),
439 ];
440 if (isset($maps[$digestDay])) {
441 $digestDay = $maps[$digestDay];
442 }
443 }
444
445 return [
446 'user_globals' => (object)$userGlobalPrefs,
447 'spaceGroups' => $formattedSpaceGroups,
448 'space_prefs' => $spaceWisePrefs,
449 'digestEmailDay' => $digestDay
450 ];
451 }
452
453 public function saveNotificationPreferance(Request $request, $userName)
454 {
455 $xProfile = $this->verfifyAndGetProfile($userName);
456
457 $userPrefs = $request->get('user_globals', []);
458 $sapcePrefs = $request->get('space_prefs', []);
459
460 $userPrefs = array_map(function ($item) {
461 return $item == 'yes' ? 1 : 0;
462 }, $userPrefs);
463
464 foreach ($sapcePrefs as $spaceId => $pref) {
465 $spaceId = (int)$spaceId;
466 if (!$pref || !$spaceId) {
467 continue;
468 }
469
470 if ($pref == 'all_member_posts') {
471 $userPrefs['np_by_member_mail_' . $spaceId] = 1;
472 $userPrefs['np_by_admin_mail_' . $spaceId] = 1;
473 } else if ($pref == 'admin_only_posts') {
474 $userPrefs['np_by_admin_mail_' . $spaceId] = 1;
475 }
476 }
477
478
479 NotificationPref::updateUserPrefs($xProfile->user_id, $userPrefs);
480
481 return [
482 'prefs' => $userPrefs,
483 'message' => __('Email Notification preferences have been updated', 'fluent-community')
484 ];
485 }
486
487 private function verfifyAndGetProfile($userName)
488 {
489 $xProfile = XProfile::where('username', $userName)->firstOrFail();
490
491 $currentUser = $this->getUser();
492 if ($xProfile->user_id != get_current_user_id() && (!$currentUser || !$currentUser->isCommunityModerator())) {
493 throw new \Exception('You are not allowed to update this profile');
494 }
495
496 return $xProfile;
497 }
498 }
499