PluginProbe
FluentCommunity – Ultra-Fast High-Performance Social Network, Community, LMS & Online Courses / 2.7.0
FluentCommunity – Ultra-Fast High-Performance Social Network, Community, LMS & Online Courses v2.7.0
2.11.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 All 78 releases
fluent-community / app / Http / Controllers / ProfileController.php

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

828 lines 32.7 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\SpaceUserPivot;
11 use FluentCommunity\App\Models\User;
12 use FluentCommunity\App\Models\XProfile;
13 use FluentCommunity\App\Services\CustomSanitizer;
14 use FluentCommunity\App\Services\FeedsHelper;
15 use FluentCommunity\App\Services\Helper;
16 use FluentCommunity\App\Services\NotificationPref;
17 use FluentCommunity\App\Services\ProfileHelper;
18 use FluentCommunity\Framework\Http\Request\Request;
19 use FluentCommunity\Framework\Support\Arr;
20 use FluentCommunity\Modules\Course\Model\CourseLesson;
21 use FluentCommunity\Modules\Course\Model\CourseTopic;
22 use FluentCommunity\Modules\Course\Services\CourseHelper;
23
24 class ProfileController extends Controller
25 {
26 public function getProfile(Request $request, $userName)
27 {
28 $xprofile = XProfile::where('username', $userName)
29 ->firstOrFail();
30
31 if ($xprofile->status != 'active' && !Helper::isModerator()) {
32 return $this->sendError([
33 'message' => __('This profile is not active', 'fluent-community'),
34 'status' => 403
35 ]);
36 }
37
38 $canViewProfile = Utility::canViewUserProfile($xprofile->user_id);
39
40 $user = get_user_by('ID', $xprofile->user_id);
41
42 $profile = [
43 'user_id' => $xprofile->user_id,
44 'is_verified' => $xprofile->is_verified,
45 'display_name' => $xprofile->display_name,
46 'username' => $xprofile->username,
47 'avatar' => $xprofile->avatar,
48 'has_custom_avatar' => $xprofile->hasCustomAvatar(),
49 'cover_photo' => Arr::get($xprofile->meta, 'cover_photo'),
50 'headline' => Arr::get($xprofile->meta, 'headline', ''),
51 'total_points' => $xprofile->total_points,
52 'badge_slugs' => (array)Arr::get($xprofile->meta, 'badge_slug', []),
53 'status' => $xprofile->status,
54 'is_restricted' => !$canViewProfile,
55 'canViewUserSpaces' => ProfileHelper::canViewUserSpaces($xprofile->user_id, $this->getUser())
56 ];
57
58 if (Utility::showLastActivity()) {
59 $profile['last_activity'] = $xprofile->last_activity;
60 }
61
62 if ($canViewProfile) {
63 $profile['website'] = Arr::get($xprofile->meta, 'website');
64 $profile['created_at'] = $xprofile->created_at->format('Y-m-d H:i:s');
65 $profile['social_links'] = (object) Arr::get($xprofile->meta, 'social_links', []);
66 $profile['compilation_score'] = $xprofile->getCompletionScore();
67 $profile['short_description_rendered'] = wp_kses_post(FeedsHelper::mdToHtml($xprofile->short_description));
68 }
69
70 $currentUserId = get_current_user_id();
71
72 $isOwn = $xprofile->user_id == $currentUserId;
73
74 $isAdmin = Helper::isSiteAdmin($currentUserId);
75
76 if ($isOwn || $isAdmin) {
77 $enableUserSync = Utility::getPrivacySetting('enable_user_sync') === 'yes';
78 $nameArray = explode(' ', trim($xprofile->display_name));
79 $xprofileFirstName = array_shift($nameArray);
80 $xprofileLastName = implode(' ', $nameArray);
81
82 $profile['email'] = $user->user_email;
83 $profile['first_name'] = $enableUserSync ? $user->first_name : $xprofileFirstName;
84 $profile['last_name'] = $enableUserSync ? $user->last_name : $xprofileLastName;
85 $profile['short_description'] = $xprofile->short_description;
86 $profile['can_change_username'] = $isAdmin || Utility::getPrivacySetting('can_customize_username') === 'yes';
87 $profile['can_change_email'] = current_user_can('edit_users') || (Utility::getPrivacySetting('can_change_email') === 'yes' && $isOwn);
88 }
89
90 $profileBaseUrl = Helper::baseUrl('u/' . $xprofile->username . '/');
91
92 $profile['profile_navs'] = [
93 [
94 'slug' => 'user_profile',
95 'title' => __('About', 'fluent-community'),
96 'url' => $profileBaseUrl,
97 'wrapper_class' => 'fcom_profile_about',
98 'route' => [
99 'name' => 'user_profile'
100 ]
101 ],
102 [
103 'slug' => 'user_profile_feeds',
104 'title' => __('Posts', 'fluent-community'),
105 'wrapper_class' => 'fcom_profile_posts',
106 'url' => $profileBaseUrl . 'posts',
107 'route' => [
108 'name' => 'user_profile_feeds'
109 ]
110 ]
111 ];
112
113 if ($profile['canViewUserSpaces']) {
114 $profile['profile_navs'][] = [
115 'slug' => 'user_spaces',
116 'wrapper_class' => 'fcom_profile_spaces',
117 'title' => __('Spaces', 'fluent-community'),
118 'url' => $profileBaseUrl . 'spaces',
119 'route' => [
120 'name' => 'user_spaces'
121 ]
122 ];
123
124 if (Helper::isFeatureEnabled('course_module')) {
125 $profile['profile_navs'][] = [
126 'slug' => 'user_courses',
127 'wrapper_class' => 'fcom_profile_courses',
128 'title' => __('Courses', 'fluent-community'),
129 'url' => $profileBaseUrl . 'courses',
130 'route' => [
131 'name' => 'user_courses'
132 ]
133 ];
134 }
135 }
136
137 $profile['profile_navs'][] = [
138 'slug' => 'user_comments',
139 'wrapper_class' => 'fcom_profile_comments',
140 'title' => __('Comments', 'fluent-community'),
141 'url' => $profileBaseUrl . 'comments',
142 'route' => [
143 'name' => 'user_comments'
144 ]
145 ];
146
147 $profile['profile_nav_actions'] = [];
148
149 $profile = apply_filters('fluent_community/profile_view_data', $profile, $xprofile, $isAdmin);
150
151 return [
152 'profile' => $profile
153 ];
154 }
155
156 public function patchProfile(Request $request, $userName)
157 {
158 $xprofile = $this->verfifyAndGetProfile($userName);
159
160 $updateData = $request->get('data', []);
161
162 if (!empty($updateData['status']) && $updateData['status'] === 'deactivated' && $xprofile->status === 'active') {
163 // handle deactivation
164 $canDeactivate = Utility::getPrivacySetting('can_deactive_account') === 'yes' || Helper::isSiteAdmin();
165 if (!$canDeactivate) {
166 return $this->sendError([
167 'message' => __('You are not allowed to deactivate this account.', 'fluent-community')
168 ]);
169 }
170
171 $xprofile->status = '';
172 $xprofile->save();
173 update_user_meta($xprofile->user_id, '_fcom_deactivated_at', current_time('mysql'));
174 do_action('fluent_community/profile_deactivated', $xprofile);
175
176 return [
177 'message' => __('Your profile has been deactivated successfully.', 'fluent-community')
178 ];
179 }
180
181 $mediaTypes = ['cover_photo', 'avatar'];
182
183 foreach ($mediaTypes as $type) {
184 if (!empty($updateData[$type])) {
185 $media = Helper::getMediaFromUrl($updateData[$type]);
186 if (!$media || $media->is_active) {
187 return $this->sendError([
188 'message' => __('Invalid media image. Please upload a new one.', 'fluent-community')
189 ]);
190 }
191
192 $updateData[$type] = $media->public_url;
193
194 $media->update([
195 'is_active' => true,
196 'user_id' => $xprofile->user_id,
197 'object_source' => 'user_' . $type
198 ]);
199 }
200 }
201
202 $deletedMedias = [];
203
204 if (isset($updateData['avatar'])) {
205
206 if ($xprofile->hasCustomAvatar()) {
207 $deletedMedias[] = $xprofile->attributes['avatar'];
208 }
209
210 $xprofile->avatar = $updateData['avatar'];
211
212 if (defined('FLUENTCRM')) {
213 $contact = $xprofile->contact;
214
215 if ($contact) {
216 $contact->update([
217 'avatar' => $updateData['avatar'] ?: null
218 ]);
219 }
220 }
221
222 if (empty($updateData['avatar'])) {
223 Utility::forgetCache('user_avatar_' . $xprofile->user_id);
224 }
225 }
226
227 if (isset($updateData['cover_photo'])) {
228 $deletedMedias[] = Arr::get($xprofile->meta, 'cover_photo');
229 $xprofile->meta = wp_parse_args(['cover_photo' => $updateData['cover_photo']], $xprofile->meta);
230 }
231
232 $xprofile->save();
233
234 if ($deletedMedias = array_filter($deletedMedias)) {
235 do_action('fluent_community/remove_medias_by_url', $deletedMedias, [
236 'user_id' => $xprofile->user_id,
237 'object_sources' => ['user_avatar', 'user_cover_photo']
238 ]);
239 }
240
241 return [
242 'message' => __('Profile updated', 'fluent-community')
243 ];
244 }
245
246 public function updateProfile(Request $request, $userName)
247 {
248 $currentUser = $this->getUser(true);
249 $data = $request->get('data', []);
250
251 $xProfile = XProfile::where('username', $userName)->firstOrFail();
252
253 if ($xProfile->user_id != get_current_user_id()) {
254 if(!$currentUser->isCommunityModerator()) {
255 return $this->sendError([
256 'message' => __('You are not allowed to update this profile', 'fluent-community')
257 ]);
258 }
259 }
260
261 $this->validate($data, [
262 'first_name' => 'required',
263 ], [
264 'first_name.required' => __('First name is required', 'fluent-community')
265 ]);
266
267 $updateData = Arr::only($data, ['first_name', 'last_name', 'short_description', 'website']);
268
269 $updateData = apply_filters('fluent_community/update_profile_data', $updateData, $data, $xProfile, $currentUser);
270
271 $meta = $xProfile->meta;
272
273 $userNameChanged = false;
274
275 if ($currentUser->isCommunityModerator()) {
276 $updateData['is_verified'] = Arr::get($data, 'is_verified') ? 1 : 0;
277 $updateData['status'] = Arr::get($data, 'status', 'active');
278 $userName = Arr::get($data, 'username');
279
280 if (user_can($xProfile->user_id, 'list_users')) {
281 $updateData['status'] = 'active';
282 }
283
284 if ($userName) {
285 // Check if username is exit or not
286 $userName = CustomSanitizer::sanitizeUserName($userName);
287
288 if (!$userName) {
289 return $this->sendError([
290 'message' => __('Invalid username. Only Latin characters with _ & - are allowed.', 'fluent-community')
291 ]);
292 }
293
294 if (XProfile::where('username', $userName)->where('user_id', '!=', $xProfile->user_id)->exists()) {
295 return $this->sendError([
296 'message' => __('Community Username already taken by someone else', 'fluent-community')
297 ]);
298 }
299
300 $userExist = get_user_by('user_login', $userName);
301
302 if ($userExist && $userExist->ID != $xProfile->user_id) {
303 return $this->sendError([
304 'message' => __('Username already taken by someone else. Please use a different username.', 'fluent-community')
305 ]);
306 }
307
308 $updateData['username'] = $userName;
309 $userNameChanged = $userName != $xProfile->username;
310 }
311
312 if (Helper::isFeatureEnabled('user_badge')) {
313 $badgeSlug = (array)Arr::get($data, 'badge_slugs', []);
314 $meta['badge_slug'] = $badgeSlug;
315 }
316 } else if (Utility::getPrivacySetting('can_customize_username')) {
317 $userName = Arr::get($data, 'username');
318
319 if ($xProfile->username != $userName) {
320 $userName = strtolower(CustomSanitizer::sanitizeUserName($userName));
321 if (!$userName) {
322 return $this->sendError([
323 'message' => __('Invalid username. Only Latin characters with _ & - are allowed.', 'fluent-community')
324 ]);
325 }
326
327 if (XProfile::where('username', $userName)->where('user_id', '!=', $xProfile->user_id)->exists()) {
328 return $this->sendError([
329 'message' => __('Community Username already taken by someone else', 'fluent-community')
330 ]);
331 }
332
333 if (strlen($userName) < 3) {
334 return $this->sendError([
335 'message' => __('Username should be at least 3 characters long.', 'fluent-community')
336 ]);
337 }
338
339 $reservedUserNames = ProfileHelper::getReservedUserNames();
340 if (in_array($userName, $reservedUserNames)) {
341 return $this->sendError([
342 'message' => __('Please use another username. This username is reserved', 'fluent-community')
343 ]);
344 }
345
346 $updateData['username'] = $userName;
347 $userNameChanged = true;
348 }
349 }
350
351 $updateData['display_name'] = trim(sanitize_text_field(Arr::get($data, 'first_name') . ' ' . Arr::get($data, 'last_name')));
352
353 $updateData['short_description'] = CustomSanitizer::unslashMarkdown(sanitize_textarea_field(trim(Arr::get($data, 'short_description'))));
354 $meta['website'] = sanitize_url(Arr::get($data, 'website'));
355 $meta['headline'] = sanitize_text_field(trim(Arr::get($data, 'headline', '')));
356 $socialLinks = Arr::get($data, 'social_links', []);
357
358 $maxDescriptionLength = apply_filters('fluent_community/max_profile_description_length', 5000);
359 if ($updateData['short_description'] && strlen($updateData['short_description']) > $maxDescriptionLength) {
360 return $this->sendError([
361 'message' => sprintf(
362 /* translators: %d: Maximum number of characters allowed in the profile bio. */
363 __('Profile bio should not exceed %d characters.', 'fluent-community'),
364 $maxDescriptionLength
365 )
366 ]);
367 }
368
369 $maxHeadlineLength = apply_filters('fluent_community/max_profile_headline_length', 60);
370 if ($meta['headline'] && mb_strlen($meta['headline']) > $maxHeadlineLength) {
371 return $this->sendError([
372 'message' => sprintf(
373 /* translators: %d: Maximum number of characters allowed in the profile headline. */
374 __('Headline should not exceed %d characters.', 'fluent-community'),
375 $maxHeadlineLength
376 )
377 ]);
378 }
379
380 if ($socialLinks) {
381 $socialLinks = array_filter($socialLinks);
382 $formattedSocialLinkes = [];
383 $socialLinkProviders = ProfileHelper::socialLinkProviders(true);
384 foreach ($socialLinks as $linkName => $socialLink) {
385 if (isset($socialLinkProviders[$linkName])) {
386 $formattedSocialLinkes[$linkName] = sanitize_text_field(trim($socialLink));
387 }
388 }
389 $meta['social_links'] = $formattedSocialLinkes;
390 }
391
392 $meta['short_description_rendered'] = wp_kses_post(FeedsHelper::mdToHtml($updateData['short_description']));
393
394 $updateData['meta'] = $meta;
395
396 $xProfile->fill($updateData);
397 $xProfile->save();
398
399 // Let's update the user's details
400 $xProfile->user->updateCustomData($updateData);
401 $xProfile->compilation_score = $xProfile->getCompletionScore();
402
403 if ($userNameChanged) {
404 return [
405 'message' => __('Profile has been updated', 'fluent-community'),
406 'profile' => $xProfile,
407 'redirect_url' => Helper::baseUrl('u/' . $xProfile->username . '/update')
408 ];
409 }
410
411 $isOwn = $xProfile->user_id == get_current_user_id();
412 $canEditUsers = current_user_can('edit_users');
413 if ($canEditUsers || (Utility::getPrivacySetting('can_change_email') === 'yes' && $isOwn)) {
414 $emailAddress = Arr::get($data, 'email');
415
416 if ($emailAddress && is_email($emailAddress) && $emailAddress != $xProfile->user->user_email) {
417 $owner_id = email_exists($emailAddress);
418 if ($owner_id && $owner_id != $xProfile->user_id) {
419 return $this->sendError([
420 'message' => __('Email address already taken by someone else. Please use a different email address.', 'fluent-community')
421 ]);
422 }
423
424 // Let's check if it's their own
425 $requireVerification = $isOwn && !$canEditUsers;
426 if ($requireVerification) {
427 $currentUser = get_user_by('ID', $xProfile->user_id);
428 ProfileHelper::sendConfirmationOnProfileEmailChange($currentUser, $emailAddress);
429 return [
430 'message' => __('Email address change is pending. Please check your inbox to verify the new email address.', 'fluent-community'),
431 'profile' => $xProfile
432 ];
433 }
434
435 wp_update_user([
436 'user_email' => $emailAddress,
437 'ID' => $xProfile->user_id
438 ]);
439 }
440 }
441
442 return [
443 'message' => __('Profile has been updated', 'fluent-community'),
444 'profile' => $xProfile
445 ];
446 }
447
448 public function getAllMemberships(Request $request, $userName)
449 {
450 $xProfile = XProfile::where('username', $userName)->firstOrFail();
451
452 $currentUser = $this->getUser();
453
454 if (!ProfileHelper::canViewUserSpaces($xProfile->user_id, $currentUser)) {
455 return $this->sendError([
456 'message' => __('You are not allowed to view this profile\'s membership.', 'fluent-community'),
457 'permission_failed' => true
458 ]);
459 }
460
461 $memberships = $xProfile->space_pivot()
462 ->where('status', 'active')
463 ->pluck('space_id');
464
465 return apply_filters('fluent_community/profile_all_memberships_api_response', [
466 'memberships' => $memberships
467 ], $request->all());
468 }
469
470 public function getSpaces(Request $request, $userName)
471 {
472 $xProfile = XProfile::where('username', $userName)->firstOrFail();
473 $currentUser = $this->getUser();
474
475 if (!ProfileHelper::canViewUserSpaces($xProfile->user_id, $currentUser)) {
476 return $this->sendError([
477 'message' => __('You are not allowed to view this profile\'s spaces.', 'fluent-community'),
478 'permission_failed' => true
479 ]);
480 }
481
482 if ($xProfile->user_id == get_current_user_id() || ($currentUser && $currentUser->isCommunityModerator())) {
483 $spaces = $xProfile->spaces()
484 ->wherePivot('status', 'active')
485 ->get();
486 } else {
487 $spaces = $xProfile->spaces()
488 ->whereIn('privacy', ['public', 'private'])
489 ->wherePivot('status', 'active')
490 ->get();
491 }
492
493 foreach ($spaces as $space) {
494 $shouldHideMembersCount = Arr::get($space->settings, 'hide_members_count') == 'yes';
495 $canViewMembers = $currentUser && $space->verifyUserPermisson($currentUser, 'can_view_members', false);
496 if ($shouldHideMembersCount && !$canViewMembers) {
497 $space->members_count = 0;
498 continue;
499 }
500 $space->members_count = $space->members()->count();
501 }
502
503 $data = [
504 'spaces' => $spaces
505 ];
506
507 return apply_filters('fluent_community/profile_spaces_api_response', $data, $request->all());
508 }
509
510 public function getCourses(Request $request, $userName)
511 {
512 if (!Helper::isFeatureEnabled('course_module')) {
513 return $this->sendError([
514 'message' => __('Course module is disabled.', 'fluent-community')
515 ]);
516 }
517
518 $xProfile = XProfile::where('username', $userName)->firstOrFail();
519 $currentUser = $this->getUser();
520
521 if (!ProfileHelper::canViewUserSpaces($xProfile->user_id, $currentUser)) {
522 return $this->sendError([
523 'message' => __('You are not allowed to view this profile\'s courses.', 'fluent-community'),
524 'permission_failed' => true
525 ]);
526 }
527
528 $hasAllAccess = $xProfile->user_id == get_current_user_id() || ($currentUser && $currentUser->isCommunityModerator());
529
530 $courses = $xProfile->courses()
531 ->wherePivot('status', 'active')
532 ->where('fcom_spaces.status', 'published')
533 ->when(!$hasAllAccess, function ($q) {
534 $q->whereIn('fcom_spaces.privacy', ['public', 'private']);
535 })
536 ->get();
537
538 foreach ($courses as $course) {
539 $course->isEnrolled = CourseHelper::isEnrolled($course->id, $xProfile->user_id);
540 if ($course->isEnrolled) {
541 $course->progress = CourseHelper::getCourseProgress($course->id, $xProfile->user_id);
542 }
543
544 if (!$course->cover_photo) {
545 $course->cover_photo = FLUENT_COMMUNITY_PLUGIN_URL . 'assets/images/course-placeholder.jpg';
546 }
547
548 $course->sectionsCount = CourseTopic::where('space_id', $course->id)->count();
549 $course->lessonsCount = CourseLesson::where('space_id', $course->id)->count();
550 if (Arr::get($course->settings, 'hide_members_count') != 'yes') {
551 $course->studentsCount = SpaceUserPivot::where('space_id', $course->id)->count();
552 } else {
553 $course->studentsCount = 0;
554 }
555
556 do_action_ref_array('fluent_community/course', [&$course]);
557 }
558
559 $data = [
560 'courses' => $courses
561 ];
562
563 return apply_filters('fluent_community/profile_courses_api_response', $data, $request->all());
564 }
565
566 public function getComments(Request $request, $userName)
567 {
568 $xProfile = XProfile::where('username', $userName)->first();
569
570 if (!$xProfile) {
571 return $this->sendError([
572 'message' => __('Profile not found', 'fluent-community')
573 ]);
574 }
575
576 $currentUser = $this->getUser();
577 $hasAllAccess = $xProfile->user_id == get_current_user_id() || ($currentUser && $currentUser->isCommunityModerator());
578
579 $comments = Comment::where('user_id', $xProfile->user_id)
580 ->where('status', 'published')
581 ->with([
582 'post' => function ($q) {
583 $q->select(['id', 'title', 'message', 'type', 'space_id', 'slug', 'created_at'])
584 ->with([
585 'space' => function ($q) {
586 $q->select(['id', 'title', 'slug', 'type']);
587 }
588 ]);
589 }
590 ])
591 ->when(!$hasAllAccess, function ($q) {
592 $q->whereHas('post', function ($query) {
593 $query->byUserAccess(get_current_user_id());
594 $query->where('type', 'text');
595 });
596 })
597 ->orderBy('id', 'desc')
598 ->paginate();
599
600 $data = [
601 'comments' => $comments,
602 'xprofile' => $xProfile
603 ];
604
605 return apply_filters('fluent_community/profile_comments_api_response', $data, $request->all());
606 }
607
608 public function getNotificationPreferance(Request $request, $userName)
609 {
610 $emailPref = Utility::getEmailNotificationSettings();
611
612 $xProfile = $this->verfifyAndGetProfile($userName);
613
614 $globalPreferances = NotificationPref::getGlobalPrefs();
615
616 $userPrefs = NotificationSubscription::where('user_id', $xProfile->user_id)
617 ->select(['notification_type', 'is_read', 'object_id'])
618 ->get();
619
620 $userGlobalPrefs = [];
621 $spaceWisePrefs = [];
622 foreach ($userPrefs as $pref) {
623 if (!$pref->object_id) {
624 if ($pref->notification_type === 'message_email_frequency') {
625 $maps = [
626 0 => 'disabled',
627 1 => 'hourly',
628 2 => 'daily',
629 3 => 'weekly'
630 ];
631
632 if ($maps[$pref->is_read]) {
633 $userGlobalPrefs[$pref->notification_type] = $maps[$pref->is_read];
634 } else {
635 $userGlobalPrefs[$pref->notification_type] = 'default';
636 }
637 continue;
638 }
639 $userGlobalPrefs[$pref->notification_type] = $pref->is_read ? 'yes' : 'no';
640 } else {
641 if (empty($spaceWisePrefs[$pref->object_id])) {
642 $spaceWisePrefs[$pref->object_id] = [];
643 }
644 $spaceWisePrefs[$pref->object_id][$pref->notification_type] = $pref->is_read;
645 }
646 }
647
648 $messagingConfig = Utility::getOption('_messaging_settings', []);
649 $isGlobalPerUser = Arr::get($messagingConfig, 'messaging_email_frequency') == 'disabled';
650
651 $userGlobalPrefsDefaults = [
652 'digest_mail' => Arr::get($globalPreferances, 'digest_email_status') ? 'yes' : 'no',
653 'mention_mail' => Arr::get($globalPreferances, 'mention_mail') ? 'yes' : 'no',
654 'reply_my_com_mail' => Arr::get($globalPreferances, 'reply_my_com_mail') ? 'yes' : 'no',
655 'com_my_post_mail' => Arr::get($globalPreferances, 'com_my_post_mail') ? 'yes' : 'no',
656 'message_email_frequency' => $isGlobalPerUser ? 'disabled' : 'default'
657 ];
658
659 $userGlobalPrefs = wp_parse_args($userGlobalPrefs, $userGlobalPrefsDefaults);
660
661 $profileUserId = $xProfile->user_id;
662 $spaceGroups = SpaceGroup::with(['spaces' => function ($query) use ($profileUserId) {
663 $query->whereHas('members', function ($q) use ($profileUserId) {
664 $q->where('user_id', $profileUserId)
665 ->where('status', 'active');
666 })
667 ->where('type', 'community');
668 }])
669 ->orderBy('serial', 'ASC')
670 ->get();
671
672 $formattedSpaceGroups = [];
673 foreach ($spaceGroups as $group) {
674 if ($group->spaces->isEmpty()) {
675 continue;
676 }
677 $formattedSpaces = [];
678 foreach ($group->spaces as $space) {
679
680 $pref = '';
681 if (isset($spaceWisePrefs[$space->id])) {
682 $perfs = (array)$spaceWisePrefs[$space->id];
683 if (!empty($perfs['np_by_member_mail'])) {
684 $pref = 'all_member_posts';
685 } else if (!empty($perfs['np_by_admin_mail'])) {
686 $pref = 'admin_only_posts';
687 }
688 }
689
690 $formattedSpaces[] = [
691 'id' => $space->id,
692 'title' => $space->title,
693 'icon' => $space->getIconMark(),
694 'pref' => $pref
695 ];
696 }
697 if ($formattedSpaces) {
698 $formattedSpaceGroups[] = [
699 'id' => $group->id,
700 'title' => $group->title,
701 'spaces' => $formattedSpaces
702 ];
703 }
704 }
705
706 // let's find the other spaces
707 $otherSpaces = Space::whereHas('members', function ($q) use ($xProfile) {
708 $q->where('user_id', $xProfile->user_id);
709 })
710 ->whereNull('parent_id')
711 ->orderBy('title', 'ASC')
712 ->get();
713
714 if (!$otherSpaces->isEmpty()) {
715 $formattedSpaces = [];
716 foreach ($otherSpaces as $space) {
717 $pref = '';
718 if (isset($spaceWisePrefs[$space->id])) {
719 $perfs = (array)$spaceWisePrefs[$space->id];
720 if (!empty($perfs['np_by_member_mail'])) {
721 $pref = 'all_member_posts';
722 } else if (!empty($perfs['np_by_admin_mail'])) {
723 $pref = 'admin_only_posts';
724 }
725 }
726
727 $formattedSpaces[] = [
728 'id' => $space->id,
729 'title' => $space->title,
730 'icon' => $space->getIconMark(),
731 'pref' => $pref
732 ];
733 }
734
735 $formattedSpaceGroups[] = [
736 'id' => 'other_space_group',
737 'title' => __('Other Spaces', 'fluent-community'),
738 'spaces' => $formattedSpaces
739 ];
740 }
741
742 $digestDay = (string)Arr::get($emailPref, 'digest_mail_day', 'tue');
743 if ($digestDay) {
744 $maps = [
745 'mon' => __('Monday', 'fluent-community'),
746 'tue' => __('Tuesday', 'fluent-community'),
747 'wed' => __('Wednesday', 'fluent-community'),
748 'thu' => __('Thursday', 'fluent-community'),
749 'fri' => __('Friday', 'fluent-community'),
750 'sat' => __('Saturday', 'fluent-community'),
751 'sun' => __('Sunday', 'fluent-community'),
752 ];
753 if (isset($maps[$digestDay])) {
754 $digestDay = $maps[$digestDay];
755 }
756 }
757
758 $data = [
759 'user_globals' => (object)$userGlobalPrefs,
760 'spaceGroups' => $formattedSpaceGroups,
761 'space_prefs' => $spaceWisePrefs,
762 'digestEmailDay' => $digestDay,
763 'default_messaging_email_frequency' => Arr::get($messagingConfig, 'messaging_email_status') !== 'yes' ? 'no' : Arr::get($messagingConfig, 'messaging_email_frequency'),
764 ];
765
766 return apply_filters('fluent_community/profile_notification_pref_api_response', $data, $request->all());
767 }
768
769 public function saveNotificationPreferance(Request $request, $userName)
770 {
771 $xProfile = $this->verfifyAndGetProfile($userName);
772
773 $userPrefs = $request->get('user_globals', []);
774 $sapcePrefs = $request->get('space_prefs', []);
775
776 $messagingPref = Arr::get($userPrefs, 'message_email_frequency');
777
778 $userPrefs = array_map(function ($item) {
779 return $item == 'yes' ? 1 : 0;
780 }, $userPrefs);
781
782 if ($messagingPref == 'hourly') {
783 $userPrefs['message_email_frequency'] = 1;
784 } else if ($messagingPref == 'daily') {
785 $userPrefs['message_email_frequency'] = 2;
786 } else if ($messagingPref == 'disabled') {
787 $userPrefs['message_email_frequency'] = 0;
788 } else if ($messagingPref == 'weekly') {
789 $userPrefs['message_email_frequency'] = 3;
790 } else {
791 unset($userPrefs['message_email_frequency']);
792 }
793
794 foreach ($sapcePrefs as $spaceId => $pref) {
795 $spaceId = (int)$spaceId;
796 if (!$pref || !$spaceId) {
797 continue;
798 }
799
800 if ($pref == 'all_member_posts') {
801 $userPrefs['np_by_member_mail_' . $spaceId] = 1;
802 $userPrefs['np_by_admin_mail_' . $spaceId] = 1;
803 } else if ($pref == 'admin_only_posts') {
804 $userPrefs['np_by_admin_mail_' . $spaceId] = 1;
805 }
806 }
807
808 NotificationPref::updateUserPrefs($xProfile->user_id, $userPrefs);
809
810 return [
811 'prefs' => $userPrefs,
812 'message' => __('Email Notification preferences have been updated', 'fluent-community')
813 ];
814 }
815
816 private function verfifyAndGetProfile($userName)
817 {
818 $xProfile = XProfile::where('username', $userName)->firstOrFail();
819
820 $currentUser = $this->getUser();
821 if ($xProfile->user_id != get_current_user_id() && (!$currentUser || !$currentUser->isCommunityModerator())) {
822 throw new \Exception('You are not allowed to update this profile');
823 }
824
825 return $xProfile;
826 }
827 }
828