firstOrFail(); $user = get_user_by('ID', $xprofile->user_id); $profile = [ 'user_id' => $xprofile->user_id, 'is_verified' => $xprofile->is_verified, 'display_name' => $xprofile->display_name, 'username' => $xprofile->username, 'avatar' => $xprofile->avatar, 'created_at' => $xprofile->created_at->format('Y-m-d H:i:s'), 'last_activity' => $xprofile->last_activity, 'short_description_rendered' => FeedsHelper::mdToHtml($xprofile->short_description), 'cover_photo' => Arr::get($xprofile->meta, 'cover_photo'), 'website' => Arr::get($xprofile->meta, 'website'), 'social_links' => (object)Arr::get($xprofile->meta, 'social_links', []), 'status' => $xprofile->status, 'badge_slug' => Arr::get($xprofile->meta, 'badge_slug'), 'compilation_score' => $xprofile->getCompletionScore(), 'total_points' => $xprofile->total_points, 'canViewUserSpaces' => ProfileHelper::canViewUserSpaces($xprofile->user_id, $this->getUser()) ]; $isAdmin = Helper::isSiteAdmin(); if ($xprofile->user_id == get_current_user_id() || $isAdmin) { $profile['email'] = $user->user_email; $profile['first_name'] = $user->first_name; $profile['last_name'] = $user->last_name; $profile['short_description'] = $xprofile->short_description; $profile['can_change_username'] = $isAdmin || Utility::getPrivacySetting('can_customize_username') === 'yes'; } return [ 'profile' => $profile ]; } public function patchProfile(Request $request, $userName) { $xprofile = $this->verfifyAndGetProfile($userName); $updateData = $request->get('data'); $mediaTypes = ['cover_photo', 'avatar']; foreach ($mediaTypes as $type) { if (!empty($updateData[$type])) { $media = Helper::getMediaFromUrl($updateData[$type]); if (!$media || $media->is_active) { return $this->sendError([ 'message' => 'Invalid media image. Please upload a new one.' ]); } $updateData[$type] = $media->public_url; $media->update([ 'is_active' => true, 'user_id' => $xprofile->user_id, 'object_source' => 'user_' . $type ]); } } $deletedMedias = []; if (!empty($updateData['avatar'])) { $deletedMedias[] = $xprofile->avatar; $xprofile->avatar = $updateData['avatar']; if (defined('FLUENTCRM')) { $contact = $xprofile->contact; if ($contact) { $contact->update([ 'avatar' => $updateData['avatar'] ]); } } } if (isset($updateData['cover_photo'])) { $deletedMedias[] = Arr::get($xprofile->meta, 'cover_photo'); $xprofile->meta = wp_parse_args(['cover_photo' => $updateData['cover_photo']], $xprofile->meta); } $xprofile->save(); if ($deletedMedias = array_filter($deletedMedias)) { do_action('fluent_community/remove_medias_by_url', $deletedMedias, [ 'user_id' => $xprofile->user_id, 'object_sources' => ['user_avatar', 'user_cover_photo'] ]); } return [ 'message' => __('Profile updated', 'fluent-community') ]; } public function updateProfile(Request $request, $userName) { $currentUser = $this->getUser(true); $data = $request->get('data', []); if ($currentUser->isCommunityModerator()) { $xProfile = XProfile::where('user_id', $data['user_id'])->firstOrFail(); } else { $xProfile = XProfile::where('username', $userName)->firstOrFail(); if ($xProfile->user_id != get_current_user_id()) { return $this->sendError([ 'message' => 'You are not allowed to update this profile' ]); } } $this->validate($data, [ 'first_name' => 'required', ], [ 'first_name.required' => __('First name is required', 'fluent-community') ]); $updateData = Arr::only($data, ['first_name', 'last_name', 'short_description', 'website']); $currentUser = User::findOrFail(get_current_user_id()); $meta = $xProfile->meta; $userNameChanged = false; if ($currentUser->isCommunityModerator()) { $updateData['is_verified'] = Arr::get($data, 'is_verified') ? 1 : 0; $updateData['status'] = Arr::get($data, 'status', 'active'); $userName = Arr::get($data, 'username'); if (user_can($xProfile->user_id, 'list_users')) { $updateData['status'] = 'active'; } if ($userName) { // Check if username is exit or not $userName = CustomSanitizer::sanitizeUserName($userName); if (!$userName) { return $this->sendError([ 'message' => __('Invalid username. Only Latin characters with _ & - are allowed.', 'fluent-community') ]); } if (XProfile::where('username', $userName)->where('user_id', '!=', $xProfile->user_id)->exists()) { return $this->sendError([ 'message' => __('Community Username already taken by someone else', 'fluent-community') ]); } $userExist = get_user_by('user_login', $userName); if ($userExist && $userExist->ID != $xProfile->user_id) { return $this->sendError([ 'message' => __('Username already taken by someone else. Please use a different username.', 'fluent-community') ]); } $updateData['username'] = $userName; $userNameChanged = $userName != $xProfile->username; } if (Helper::isFeatureEnabled('user_badge')) { $badgeSlug = Arr::get($data, 'badge_slug'); $meta['badge_slug'] = $badgeSlug; } } else if (Utility::getPrivacySetting('can_customize_username')) { $userName = Arr::get($data, 'username'); if ($xProfile->username != $userName) { $userName = strtolower(CustomSanitizer::sanitizeUserName($userName)); if (!$userName) { return $this->sendError([ 'message' => __('Invalid username. Only Latin characters with _ & - are allowed.', 'fluent-community') ]); } if (XProfile::where('username', $userName)->where('user_id', '!=', $xProfile->user_id)->exists()) { return $this->sendError([ 'message' => __('Community Username already taken by someone else', 'fluent-community') ]); } if(strlen($userName) < 3) { return $this->sendError([ 'message' => __('Username should be at least 3 characters long.', 'fluent-community') ]); } $reservedUserNames = ProfileHelper::getReservedUserNames(); if (in_array($userName, $reservedUserNames)) { return $this->sendError([ 'message' => __('Please use another username. This username is reserved', 'fluent-community') ]); } $updateData['username'] = $userName; $userNameChanged = true; } } $updateData['display_name'] = trim(sanitize_text_field(Arr::get($data, 'first_name') . ' ' . Arr::get($data, 'last_name'))); $updateData['short_description'] = CustomSanitizer::unslashMarkdown(sanitize_textarea_field(trim(Arr::get($data, 'short_description')))); $meta['website'] = sanitize_url(Arr::get($data, 'website')); $socialLinks = Arr::get($data, 'social_links', []); $maxDescriptionLength = apply_filters('fluent_community/max_profile_description_length', 5000); if ($updateData['short_description'] && strlen($updateData['short_description']) > $maxDescriptionLength) { return $this->sendError([ 'message' => sprintf(__('Profile bio should not exceed %d characters.', 'fluent-community'), $maxDescriptionLength) ]); } if ($socialLinks) { $socialLinks = array_filter($socialLinks); $formattedSocialLinkes = []; $socialLinkProviders = ProfileHelper::socialLinkProviders(); foreach ($socialLinks as $linkName => $socialLink) { if (isset($socialLinkProviders[$linkName])) { $formattedSocialLinkes[$linkName] = sanitize_text_field(trim($socialLink)); } } $meta['social_links'] = $formattedSocialLinkes; } $updateData['meta'] = $meta; $xProfile->fill($updateData); $xProfile->save(); // Let's update the user's details $xProfile->user->updateCustomData($updateData); $xProfile->compilation_score = $xProfile->getCompletionScore(); if ($userNameChanged) { return [ 'message' => __('Profile has been updated', 'fluent-community'), 'profile' => $xProfile, 'redirect_url' => Helper::baseUrl('u/' . $xProfile->username . '/update') ]; } return [ 'message' => __('Profile has been updated', 'fluent-community'), 'profile' => $xProfile ]; } public function getSpaces(Request $request, $userName) { $xProfile = XProfile::where('username', $userName)->firstOrFail(); $currentUser = $this->getUser(); if (!ProfileHelper::canViewUserSpaces($xProfile->user_id, $currentUser)) { return $this->sendError([ 'message' => __('You are not allowed to view this profile\'s spaces.', 'fluent-community'), 'permission_failed' => true ]); } if ($xProfile->user_id == get_current_user_id() || ($currentUser && $currentUser->isCommunityModerator())) { $spaces = $xProfile->spaces() ->wherePivot('status', 'active') ->get(); } else { $spaces = $xProfile->spaces() ->whereIn('privacy', ['public', 'private']) ->wherePivot('status', 'active') ->get(); } foreach ($spaces as $space) { $space->members_count = $space->members()->count(); } return [ 'spaces' => $spaces ]; } public function getComments(Request $request, $userName) { $xProfile = XProfile::where('username', $userName)->first(); if (!$xProfile) { return $this->sendError([ 'message' => 'Profile not found' ]); } $currentUser = $this->getUser(); $hasAllAccess = $xProfile->user_id == get_current_user_id() || ($currentUser && $currentUser->isCommunityModerator()); $comments = Comment::where('user_id', $xProfile->user_id) ->with([ 'post' => function ($q) { $q->select(['id', 'title', 'message', 'type', 'space_id', 'slug', 'created_at']) ->with([ 'space' => function ($q) { $q->select(['id', 'title', 'slug', 'type']); } ]); } ]) ->when(!$hasAllAccess, function ($q) use ($xProfile) { $q->whereHas('post', function ($query) use ($xProfile) { $query->byUserAccess(get_current_user_id()); $query->where('type', 'text'); }); }) ->orderBy('id', 'desc') ->paginate(); return [ 'comments' => $comments, 'xprofile' => $xProfile ]; } public function getNotificationPreferance(Request $request, $userName) { $emailPref = Utility::getEmailNotificationSettings(); $xProfile = $this->verfifyAndGetProfile($userName); $globalPreferances = NotificationPref::getGlobalPrefs(); $userPrefs = NotificationSubscription::where('user_id', $xProfile->user_id) ->select(['notification_type', 'is_read', 'object_id']) ->get(); $userGlobalPrefs = []; $spaceWisePrefs = []; foreach ($userPrefs as $pref) { if (!$pref->object_id) { $userGlobalPrefs[$pref->notification_type] = $pref->is_read ? 'yes' : 'no'; } else { if (empty($spaceWisePrefs[$pref->object_id])) { $spaceWisePrefs[$pref->object_id] = []; } $spaceWisePrefs[$pref->object_id][$pref->notification_type] = $pref->is_read; } } $userGlobalPrefsDefaults = [ 'digest_mail' => Arr::get($globalPreferances, 'digest_email_status') ? 'yes' : 'no', 'mention_mail' => Arr::get($globalPreferances, 'mention_mail') ? 'yes' : 'no', 'reply_my_com_mail' => Arr::get($globalPreferances, 'reply_my_com_mail') ? 'yes' : 'no', 'com_my_post_mail' => Arr::get($globalPreferances, 'com_my_post_mail') ? 'yes' : 'no', ]; $userGlobalPrefs = wp_parse_args($userGlobalPrefs, $userGlobalPrefsDefaults); $spaceGroups = SpaceGroup::with(['spaces' => function ($query) { $query->whereHas('members', function ($q) { $q->where('user_id', get_current_user_id()); }) ->where('type', 'community'); }]) ->orderBy('serial', 'ASC') ->get(); $formattedSpaceGroups = []; foreach ($spaceGroups as $group) { if ($group->spaces->isEmpty()) { continue; } $formattedSpaces = []; foreach ($group->spaces as $space) { $pref = ''; if (isset($spaceWisePrefs[$space->id])) { $perfs = (array)$spaceWisePrefs[$space->id]; if (!empty($perfs['np_by_member_mail'])) { $pref = 'all_member_posts'; } else if (!empty($perfs['np_by_admin_mail'])) { $pref = 'admin_only_posts'; } } $formattedSpaces[] = [ 'id' => $space->id, 'title' => $space->title, 'icon' => $space->getIconMark(), 'pref' => $pref ]; } if ($formattedSpaces) { $formattedSpaceGroups[] = [ 'id' => $group->id, 'title' => $group->title, 'spaces' => $formattedSpaces ]; } } $digestDay = (string)Arr::get($emailPref, 'digest_mail_day', 'tue'); if ($digestDay) { $maps = [ 'mon' => __('Monday', 'fluent-community'), 'tue' => __('Tuesday', 'fluent-community'), 'wed' => __('Wednesday', 'fluent-community'), 'thu' => __('Thursday', 'fluent-community'), 'fri' => __('Friday', 'fluent-community'), 'sat' => __('Saturday', 'fluent-community'), 'sun' => __('Sunday', 'fluent-community'), ]; if (isset($maps[$digestDay])) { $digestDay = $maps[$digestDay]; } } return [ 'user_globals' => (object)$userGlobalPrefs, 'spaceGroups' => $formattedSpaceGroups, 'space_prefs' => $spaceWisePrefs, 'digestEmailDay' => $digestDay ]; } public function saveNotificationPreferance(Request $request, $userName) { $xProfile = $this->verfifyAndGetProfile($userName); $userPrefs = $request->get('user_globals', []); $sapcePrefs = $request->get('space_prefs', []); $userPrefs = array_map(function ($item) { return $item == 'yes' ? 1 : 0; }, $userPrefs); foreach ($sapcePrefs as $spaceId => $pref) { $spaceId = (int)$spaceId; if (!$pref || !$spaceId) { continue; } if ($pref == 'all_member_posts') { $userPrefs['np_by_member_mail_' . $spaceId] = 1; $userPrefs['np_by_admin_mail_' . $spaceId] = 1; } else if ($pref == 'admin_only_posts') { $userPrefs['np_by_admin_mail_' . $spaceId] = 1; } } NotificationPref::updateUserPrefs($xProfile->user_id, $userPrefs); return [ 'prefs' => $userPrefs, 'message' => __('Email Notification preferences have been updated', 'fluent-community') ]; } private function verfifyAndGetProfile($userName) { $xProfile = XProfile::where('username', $userName)->firstOrFail(); $currentUser = $this->getUser(); if ($xProfile->user_id != get_current_user_id() && (!$currentUser || !$currentUser->isCommunityModerator())) { throw new \Exception('You are not allowed to update this profile'); } return $xProfile; } }