social_profile.module in Open Social 10.3.x
Same filename and directory in other branches
- 8.9 modules/social_features/social_profile/social_profile.module
- 8 modules/social_features/social_profile/social_profile.module
- 8.2 modules/social_features/social_profile/social_profile.module
- 8.3 modules/social_features/social_profile/social_profile.module
- 8.4 modules/social_features/social_profile/social_profile.module
- 8.5 modules/social_features/social_profile/social_profile.module
- 8.6 modules/social_features/social_profile/social_profile.module
- 8.7 modules/social_features/social_profile/social_profile.module
- 8.8 modules/social_features/social_profile/social_profile.module
- 10.0.x modules/social_features/social_profile/social_profile.module
- 10.1.x modules/social_features/social_profile/social_profile.module
- 10.2.x modules/social_features/social_profile/social_profile.module
The Social profile module.
File
modules/social_features/social_profile/social_profile.moduleView source
<?php
/**
* @file
* The Social profile module.
*/
use Drupal\Core\Access\AccessResult;
use Drupal\Core\Cache\Cache;
use Drupal\Core\Entity\Display\EntityFormDisplayInterface;
use Drupal\Core\Entity\Display\EntityViewDisplayInterface;
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Entity\EntityTypeInterface;
use Drupal\Core\Field\BaseFieldDefinition;
use Drupal\Core\Field\FieldStorageDefinitionInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Link;
use Drupal\Core\Render\Element;
use Drupal\Core\Session\AccountInterface;
use Drupal\Core\Session\AccountProxyInterface;
use Drupal\Core\StringTranslation\TranslatableMarkup;
use Drupal\Core\Url;
use Drupal\file\Entity\File;
use Drupal\image\Entity\ImageStyle;
use Drupal\node\Entity\Node;
use Drupal\profile\Entity\Profile;
use Drupal\profile\Entity\ProfileInterface;
use Drupal\profile\Entity\ProfileType;
use Drupal\social_profile\Plugin\views\filter\SocialSearchApiSplitProfileTerms;
use Drupal\user\Entity\User;
use Drupal\user\UserInterface;
use Drupal\social_profile\SocialProfileUserFormAlter;
use Drupal\block\Entity\Block;
define('SOCIAL_PROFILE_SUGGESTIONS_USERNAME', 'username');
define('SOCIAL_PROFILE_SUGGESTIONS_FULL_NAME', 'full_name');
define('SOCIAL_PROFILE_SUGGESTIONS_ALL', 'all');
/**
* Implements hook_field_widget_form_alter().
*/
function social_profile_field_widget_form_alter(&$element, FormStateInterface $form_state, $context) {
/** @var \Drupal\Core\Field\FieldDefinitionInterface $field_definition */
$field_definition = $context['items']
->getFieldDefinition();
switch ($field_definition
->getName()) {
case 'field_profile_phone_number':
// @todo Remove this when rule for .form-tel elements will be added.
$element['value']['#attributes']['class'][] = 'form-text';
break;
case 'field_profile_address':
// @todo Remove this when script for custom selects will be added.
$element['country_code']['#attributes']['class'][] = 'browser-default';
break;
}
// This replaces all user entity references with our EntityReferenceSelection.
if ($field_definition
->getType() === 'entity_reference') {
if (isset($element['target_id']['#target_type']) && $element['target_id']['#target_type'] === 'user' && $element['target_id']['#type'] !== 'social_private_message_entity_autocomplete') {
$element['target_id']['#selection_handler'] = 'social';
}
}
}
/**
* Implements hook_form_FORM_ID_alter().
*/
function social_profile_form_profile_profile_add_form_alter(array &$form, FormStateInterface $form_state, $form_id) {
$user = \Drupal::currentUser();
$profile_settings = \Drupal::config('social_profile.settings');
// Check for permission on custom edit profile tags, it's only for CM+ who can
// actually edit a users profile and add profile tags there.
$form['field_profile_profile_tag']['#access'] = FALSE;
if ($profile_settings
->get('allow_tagging_for_lu') || $user
->hasPermission('edit profile tags')) {
$form['field_profile_profile_tag']['#access'] = TRUE;
}
// Remove the save and set default submit button on profile creation.
if (isset($form['actions']['set_default'])) {
unset($form['actions']['set_default']);
}
if (isset($form['field_profile_expertise']['widget']['target_id'])) {
$form['field_profile_expertise']['widget']['target_id']['#selection_settings']['hide_id'] = TRUE;
}
if (isset($form['field_profile_interests']['widget']['target_id'])) {
$form['field_profile_interests']['widget']['target_id']['#selection_settings']['hide_id'] = TRUE;
}
// Add custom submit handler just for redirect purposes. We don't want to
// override the form::save in profile.
$form['actions']['submit']['#submit'][] = '_social_profile_profile_edit_form_submit';
}
/**
* Implements hook_form_FORM_ID_alter().
*/
function social_profile_form_profile_profile_edit_form_alter(array &$form, FormStateInterface $form_state, $form_id) {
$viewing_user = \Drupal::currentUser();
$profile_settings = \Drupal::config('social_profile.settings');
/** @var \Drupal\profile\Entity\Profile $profile */
$profile = $form_state
->getFormObject()
->getEntity();
// Check for permission on custom edit profile tags, it's only for CM+ who can
// actually edit a users profile and add profile tags there.
$form['field_profile_profile_tag']['#access'] = FALSE;
if ($profile_settings
->get('allow_tagging_for_lu') || $viewing_user
->hasPermission('edit profile tags')) {
$form['field_profile_profile_tag']['#access'] = TRUE;
}
// Remove the save and set default submit button on profile edit.
if (isset($form['actions']['set_default'])) {
unset($form['actions']['set_default']);
}
if (isset($form['field_profile_expertise']['widget']['target_id'])) {
$form['field_profile_expertise']['widget']['target_id']['#selection_settings']['hide_id'] = TRUE;
}
if (isset($form['field_profile_interests']['widget']['target_id'])) {
$form['field_profile_interests']['widget']['target_id']['#selection_settings']['hide_id'] = TRUE;
}
// Check if the Social Profile Fields module is on.
if (\Drupal::moduleHandler()
->moduleExists('social_profile_fields')) {
// Load the profile fields and check if at least one of them can be changed.
// Load the profile fields and check if at least one of them can be changed.
$profile_fields = \Drupal::entityTypeManager()
->getStorage('field_config')
->loadByProperties([
'entity_type' => 'profile',
'bundle' => 'profile',
]);
if ($profile_fields) {
$empty_profile = TRUE;
foreach ($profile_fields as $field) {
if (isset($form[$field
->get('field_name')]) && $form[$field
->get('field_name')]['#access'] === TRUE) {
$empty_profile = FALSE;
}
}
// There are no fields the user can edit here. Set an explanatory message
// and disable the Save button.
if ($empty_profile === TRUE) {
$form['empty_profile'] = [
'#type' => 'fieldset',
];
// If a user is viewing their own profile, suggest they change settings.
if ($viewing_user
->id() === $profile
->getOwnerId()) {
$settings_link = Link::createFromRoute(t('account settings here'), 'entity.user.edit_form', [
'user' => $profile
->getOwnerId(),
])
->toString();
$form['empty_profile']['notice'] = [
'#type' => 'html_tag',
'#tag' => 'p',
'#value' => t('There is no profile information you can change here. Change your @settings.', [
'@settings' => $settings_link,
]),
];
}
else {
$form['empty_profile']['notice'] = [
'#type' => 'html_tag',
'#tag' => 'p',
'#value' => t('There is no profile information you can change here.'),
];
}
$form['actions']['submit']['#disabled'] = TRUE;
}
}
}
// Add custom submit handler just for redirect purposes. We don't want to
// override the form::save in profile.
$form['actions']['submit']['#submit'][] = '_social_profile_profile_edit_form_submit';
// Add cancel button, so user can easily navigate form edit form to profile.
$form['actions']['cancel'] = [
'#type' => 'link',
'#title' => t('Cancel'),
'#url' => Url::fromRoute('view.user_information.user_information', [
'user' => $profile
->getOwnerId(),
]),
];
}
/**
* Form submit for profile_profile_edit_form and profile_profile_add_form.
*
* @param array $form
* The profile edit form.
* @param \Drupal\Core\Form\FormStateInterface $form_state
* The form state interface.
*/
function _social_profile_profile_edit_form_submit(array $form, FormStateInterface $form_state) {
/** @var \Drupal\profile\Entity\Profile $profile */
$profile = $form_state
->getFormObject()
->getEntity();
// Let's be on the safe side.
if ($profile instanceof Profile) {
// Get the uid of the profile.
$uid = $profile
->getOwnerId();
// Invalidate cache tag.
Cache::invalidateTags([
'user:breadcrumb:' . $uid,
]);
// Set redirect to the profile page when a user saves their profile.
$form_state
->setRedirect('view.user_information.user_information', [
'user' => $uid,
]);
}
}
/**
* Implements hook_local_tasks_alter().
*/
function social_profile_local_tasks_alter(&$local_tasks) {
// Remove the profile main "Profile information" from the local tabs.
if (!empty($local_tasks['entity.profile.user_profile_form:profile.type.main'])) {
unset($local_tasks['entity.profile.user_profile_form:profile.type.main']);
}
if (!empty($local_tasks['entity.profile.user_profile_form:profile.type.profile'])) {
unset($local_tasks['entity.profile.user_profile_form:profile.type.profile']);
}
}
/**
* Implements hook_menu_local_tasks_alter().
*/
function social_profile_menu_local_tasks_alter(&$data, $route_name) {
if (isset($data['tabs'][0]['profile.user_page:profile'])) {
unset($data['tabs'][0]['profile.user_page:profile']);
}
}
/**
* Implements hook_preprocess_fieldset().
*/
function social_profile_preprocess_fieldset(&$variables) {
// Style our checkboxes as nested checkboxes.
if (isset($variables['element']['#name']) && $variables['element']['#name'] === 'profile_tag') {
$variables['attributes']['class'][] = 'checkboxes--nested';
}
}
/**
* Implements hook_preprocess_input().
*/
function social_profile_preprocess_input(&$variables) {
// Edit the profile tag displays to show the hierarchy to users.
// Only do this if it starts with a - to indicate it's a child.
if (!empty($variables['element']['#parents']) && $variables['element']['#parents'][0] === 'profile_tag' && substr($variables['element']['#title'], 0, 1) === '-') {
$variables['element']['#attributes']['class'][] = 'checkboxes--nested__child';
}
}
/**
* Implements hook_preprocess_form_element_label().
*/
function social_profile_preprocess_form_element_label(&$variables) {
// Edit the profile tag displays to show the hierarchy to users.
// Only do this if it starts with a - to indicate it's a child.
if (isset($variables['element']['#id']) && substr($variables['element']['#id'], 0, 17) === 'edit-profile-tag-' && substr($variables['element']['#title'], 0, 1) === '-') {
$variables['title']['#markup'] = substr($variables['title']['#markup'], 1);
}
}
/**
* Implements hook_theme_suggestions_HOOK_alter().
*/
function social_profile_theme_suggestions_profile_alter(array &$suggestions, array $variables) {
// @todo remove this when it lands in the profile module, make sure it will have the same hooks though.
$original = $variables['theme_hook_original'];
$entity = $variables['elements']['#profile'];
$sanitized_view_mode = strtr($variables['elements']['#view_mode'], '.', '_');
$suggestions = [];
$suggestions[] = $original;
$suggestions[] = $original . '__' . $sanitized_view_mode;
$suggestions[] = $original . '__' . $entity
->bundle();
$suggestions[] = $original . '__' . $entity
->bundle() . '__' . $sanitized_view_mode;
$suggestions[] = $original . '__' . $entity
->id();
$suggestions[] = $original . '__' . $entity
->id() . '__' . $sanitized_view_mode;
return $suggestions;
}
/**
* Prepares variables for profile templates.
*
* Default template: profile.html.twig.
*
* @param array $variables
* An associative array containing:
* - elements: An array of elements to display in view mode.
* - profile: The profile object.
* - view_mode: View mode; e.g., 'full', 'teaser', etc.
*/
function social_profile_preprocess_profile(array &$variables) {
/** @var \Drupal\profile\Entity\Profile $profile */
$profile = $variables['profile'];
$user = User::load($profile
->getOwnerId());
$current_user = \Drupal::currentUser();
// See social_user_user_format_name_alter(), DisplayName is either first name
// + last name, or username if both first and last name aren't filled out.
$variables['profile_name'] = $user
->getDisplayName();
$variables['profile_contact_url'] = _social_profile_get_contact_url($user);
$variables['profile_stream_url'] = Url::fromUserInput('/user/' . $profile
->getOwnerId() . '/stream');
$variables['profile_home'] = Url::fromRoute('entity.user.canonical', [
'user' => $user
->id(),
]);
// Set a condition for the label to show in the teaser
// The actual label text should be changeable in the template.
// Disable for the LU's own profile.
$variables['profile_contact_label'] = 'profile_info';
if (\Drupal::moduleHandler()
->moduleExists('social_private_message') && $current_user
->id() != $profile
->getOwnerId() && $current_user
->hasPermission('use private messaging system') && User::load($profile
->getOwnerId())
->hasPermission('use private messaging system')) {
$variables['profile_contact_label'] = 'private_message';
$variables['#cache']['contexts'][] = 'user';
}
if (_social_profile_check_property_access($profile, $current_user, 'email')) {
// Derived from MailToFormatter.php.
$variables['user_mail'] = Link::fromTextAndUrl($user
->getEmail(), Url::fromUri('mailto:' . $user
->getEmail()));
}
// Language field.
$language_manager = \Drupal::languageManager();
if ($language_manager
->isMultilingual() && _social_profile_check_property_access($profile, $current_user, 'language')) {
// Add the user language.
$variables['user_lang'] = $language_manager
->getLanguageName($user
->getPreferredLangcode());
}
// Edit profile URL.
// Get the current route name to check if the user is on the edit or delete
// page.
$route = \Drupal::routeMatch()
->getRouteName();
if ($route !== 'profile.user_page.single' && $profile
->access('update', $current_user)) {
$variables['profile_edit_url'] = Url::fromUserInput('/user/' . $profile
->getOwnerId() . '/profile');
$variables['#cache']['contexts'][] = 'route.name';
}
// Add the hero styled image if we have access to it.
if (!empty($profile->field_profile_banner_image->entity) && $profile->field_profile_banner_image
->access('view')) {
$variables['profile_hero_styled_image_url'] = ImageStyle::load('social_xx_large')
->buildUrl($profile->field_profile_banner_image->entity
->getFileUri());
}
// Add the profile image.
if (!empty($profile->field_profile_image->entity)) {
$variables['profile_image_url'] = ImageStyle::load('social_medium')
->buildUrl($profile->field_profile_image->entity
->getFileUri());
}
// Profile information URL.
$variables['profile_info_url'] = Url::fromRoute('view.user_information.user_information', [
'user' => $profile
->getOwnerId(),
]);
// Prepare variables for statistic block.
if ($variables['elements']['#view_mode'] === 'statistic') {
/** @var \Drupal\social_profile\UserStatistics $user_statistics */
$user_statistics = \Drupal::service('social_profile.user_statistics');
$variables['profile_topics'] = $user_statistics
->nodeCount($user
->id(), 'topic');
$variables['profile_events'] = $user_statistics
->nodeCount($user
->id(), 'event');
$variables['profile_groups'] = \Drupal::service('social_group.helper_service')
->countGroupMembershipsForUser($user
->id());
}
/** @var \Drupal\social_profile\SocialProfileTagServiceInterface $tag_service */
$tag_service = \Drupal::service('social_profile.tag_service');
$variables['profile_tagging_active'] = $tag_service
->isActive();
$variables['profile_tagging_allow_split'] = $tag_service
->allowSplit();
if (!$profile
->get('field_profile_profile_tag')
->isEmpty()) {
$tags = $profile
->get('field_profile_profile_tag')
->getValue();
$variables['profile_tagging_hierarchy'] = $tag_service
->buildHierarchy($tags);
}
}
/**
* Helps determine if current user has access to view the property of user.
*
* @param \Drupal\profile\Entity\Profile $profile
* The profile the current user is viewing.
* @param \Drupal\Core\Session\AccountProxyInterface $current_user
* The current user.
* @param string $property
* The property against we need to check the access.
*
* @return bool
* Return TRUE if current user is allowed to see the property else FALSE.
*/
function _social_profile_check_property_access(Profile $profile, AccountProxyInterface $current_user, string $property) {
// Flag to set.
$flag = FALSE;
switch ($property) {
case 'email':
// If the current user has this permission, return true straight away.
if ($current_user
->hasPermission('social profile privacy view hidden fields') || $current_user
->hasPermission('view profile email')) {
$flag = TRUE;
}
// Prepare some variables for checking on the email field.
$global_show_email = \Drupal::config('social_profile.settings')
->get('social_profile_show_email');
$profile_show_email = isset($profile->field_profile_show_email) ? $profile->field_profile_show_email->value : NULL;
// If the current user doesn't have the above permission, perform
// additional checks to see if the current user is still able to view
// this email field.
if ($global_show_email || !$global_show_email && !empty($profile_show_email)) {
$flag = TRUE;
}
break;
case 'language':
// If the current user has this permission, return true straight away.
if ($current_user
->hasPermission('view profile language')) {
$flag = TRUE;
}
// Prepare some variables for checking on the language access.
$global_show_lang = \Drupal::config('social_profile.settings')
->get('social_profile_show_language');
$profile_show_lang = \Drupal::service('user.data')
->get('social_profile_privacy', $profile
->get('uid')->target_id, 'lang_info') ?? NULL;
// If the current user doesn't have the above permission, perform
// additional checks to see if the current user is still able to view
// this preferred language.
if ($global_show_lang || !$global_show_lang && !empty($profile_show_lang)) {
$flag = TRUE;
}
break;
}
return $flag;
}
/**
* Get the contact URL. This can be private message or other means of contact.
*
* @param \Drupal\user\Entity\User $account
* The user object.
*
* @return \Drupal\Core\Url
* The URL to contact the user.
*/
function _social_profile_get_contact_url(User $account) {
if (\Drupal::moduleHandler()
->moduleExists('social_private_message')) {
$current_user = \Drupal::currentUser();
if ($current_user
->hasPermission('use private messaging system') && $account
->hasPermission('use private messaging system') && $current_user
->id() != $account
->id()) {
$members = [
$current_user,
$account,
];
$thread_id = \Drupal::service('private_message.mapper')
->getThreadIdForMembers($members);
if ($thread_id) {
$url = Url::fromRoute('entity.private_message_thread.canonical', [
'private_message_thread' => $thread_id,
], [
'attributes' => [
'class' => [
'private_message_link',
],
],
]);
if ($url
->access($current_user)) {
return $url;
}
}
return Url::fromRoute('private_message.private_message_create', [], [
'query' => [
'recipient' => $account
->id(),
],
]);
}
}
return Url::fromUserInput('/user/' . $account
->id() . '/information');
}
/**
* Implements hook_ENTITY_TYPE_insert().
*
* In order to save a new default profile on user creation.
*/
function social_profile_user_insert(UserInterface $account) {
// If the new account has a UID, we can create a default profile.
// Default image is added through the field settings.
if (!empty($account
->id())) {
/** @var \Drupal\profile\Entity\ProfileType $profile_type */
$profile_type = ProfileType::load('profile');
// Sometimes profile fields are already requested during registration.
// In those cases, the profile will already be created from that.
if ($profile_type !== NULL && $profile_type
->getRegistration() === FALSE) {
$default_values = [
'type' => $profile_type
->id(),
'uid' => $account
->id(),
];
// Get all field instances for the profile entity and check if the address
// field exists.
$instances = \Drupal::service('entity_field.manager')
->getFieldDefinitions('profile', $profile_type
->id());
if (array_key_exists('field_profile_address', $instances)) {
// Set the users default country to the site default country.
$default_values['field_profile_address'][0]['country_code'] = \Drupal::config('system.date')
->get('country.default');
}
// Create a profile.
$profile = Profile::create($default_values);
$profile
->save();
}
}
}
/**
* Implements hook_form_FORM_ID_alter() for user_form().
*/
function social_profile_form_user_form_alter(&$form, FormStateInterface $form_state) {
$profile = _social_profile_get_profile_from_route();
if ($profile instanceof Profile) {
// @todo Move privacy settings to a separate entity.
// Check what the global value is.
$social_profile_settings_config = \Drupal::config('social_profile.settings');
$global_values = [
'social_profile_show_email' => $social_profile_settings_config
->get('social_profile_show_email'),
];
// Account values.
$show_email = $profile->field_profile_show_email->value;
$form['profile_privacy'] = [
'#type' => 'fieldset',
'#title' => t('Privacy settings'),
'#tree' => TRUE,
];
$form['profile_privacy']['social_profile_show_email'] = [
'#type' => 'checkbox',
'#title' => t('Show my email on my profile'),
'#default_value' => $show_email,
'#attributes' => [
'data-switch' => TRUE,
],
];
$is_multilingual = \Drupal::languageManager()
->isMultilingual();
if ($is_multilingual) {
$user_data = \Drupal::service('user.data');
$lang_info = $user_data
->get('social_profile_privacy', $profile
->get('uid')->target_id, 'lang_info');
$global_values['social_profile_show_language'] = $social_profile_settings_config
->get('social_profile_show_language');
$form['profile_privacy']['social_profile_show_language'] = [
'#type' => 'checkbox',
'#title' => t('Show my language on my profile'),
'#default_value' => $lang_info,
'#attributes' => [
'data-switch' => TRUE,
],
];
}
// If global setting is set, disable the setting and give a reason why.
foreach ($global_values as $key => $value) {
if ($value && ($key == 'social_profile_show_language' && $is_multilingual || $key == 'social_profile_show_email')) {
$form['profile_privacy']["{$key}"]['#disabled'] = TRUE;
$form['profile_privacy']["{$key}"]['#value'] = TRUE;
$form['profile_privacy']["{$key}"]['#description'] = t('This setting is currently being controlled by a platform wide setting and cannot be changed. Please contact a sitemanager if you have questions.');
}
}
// Add Submit function only when the data is actually editable.
if (empty($global_value['social_profile_show_email']) || empty($global_value['social_profile_show_language'])) {
$form['actions']['submit']['#submit'][] = '_social_profile_form_user_form_submit';
}
}
$form['#pre_render'][] = [
SocialProfileUserFormAlter::class,
'preRender',
];
}
/**
* Form submit for user_form.
*
* @param array $form
* Commnent on a post form.
* @param \Drupal\Core\Form\FormStateInterface $form_state
* Form state interface.
*/
function _social_profile_form_user_form_submit(array $form, FormStateInterface $form_state) {
$profile = _social_profile_get_profile_from_route();
$profile_privacy = $form_state
->getValue('profile_privacy');
if ($profile instanceof Profile) {
if (isset($profile->field_profile_show_email)) {
$profile->field_profile_show_email->value = $profile_privacy['social_profile_show_email'];
$profile
->save();
}
$uid = $profile
->getOwnerId();
if (isset($profile_privacy['social_profile_show_language'])) {
// Save language info in the user data.
// @todo Move privacy settings to a separate entity.
\Drupal::service('user.data')
->set('social_profile_privacy', $uid, 'lang_info', $profile_privacy['social_profile_show_language']);
}
// Invalidate profile cache tags.
Cache::invalidateTags([
'profile:' . $uid,
]);
}
}
/**
* Gets the users profile by route.
*
* @return mixed
* The profile or NULL if nothing could be found.
*/
function _social_profile_get_profile_from_route() {
$profile = NULL;
$entity_type_manager = \Drupal::entityTypeManager();
$account = \Drupal::routeMatch()
->getParameter('user');
if (!is_object($account) && !is_null($account)) {
$account = $entity_type_manager
->getStorage('user')
->load($account);
}
if (!empty($account)) {
$storage = $entity_type_manager
->getStorage('profile');
if (!empty($storage)) {
$profile = $storage
->loadByUser($account, 'profile');
}
}
return $profile;
}
/**
* Implements hook_form_FORM_ID_alter().
*/
function social_profile_form_user_register_form_alter(&$form, FormStateInterface $form_state, $form_id) {
// Set User Register form Email field as required.
$form['account']['mail']['#required'] = TRUE;
}
/**
* Implements hook_ENTITY_TYPE_view_alter().
*/
function social_profile_profile_view_alter(array &$build, EntityInterface $entity, EntityViewDisplayInterface $display) {
/** @var \Drupal\Core\Session\AccountProxy $current_user */
$current_user = \Drupal::currentUser();
// If the current user has no access to viewing user profiles, it might not
// have access to the users profile.
if (!$current_user
->hasPermission('view any profile profile') && isset($display
->get('content')['field_profile_image'])) {
// Try to load the profile picture.
$fid = $entity
->get('field_profile_image')->target_id;
// Must have a value and not be NULL.
if (!is_null($fid)) {
// Load the file.
$file = File::load($fid);
// Check if it's a real file.
if ($file instanceof File) {
// Potentially the file is in the private file system. In that case,
// anonymous user don't have access to it.
if (!$file
->access('view', $current_user)) {
// Load default data.
$replacement_data = social_profile_get_default_image();
/** @var \Drupal\image\Plugin\Field\FieldType\ImageItem $imgitem */
$imgitem = $build['field_profile_image'][0]['#item'];
// Time to override the data that going to be rendered.
$imgitem
->set('target_id', $replacement_data['id']);
$imgitem
->set('width', $replacement_data['width']);
$imgitem
->set('height', $replacement_data['height']);
// Put replacement data back in the object that's about to be built.
$build['field_profile_image'][0]['#item'] = $imgitem;
}
}
}
}
}
/**
* Function to fetch the default profile image.
*/
function social_profile_get_default_image() {
// Load default image.
$config_factory = \Drupal::configFactory();
$field_image_config = $config_factory
->getEditable('field.field.profile.profile.field_profile_image');
$default_image = $field_image_config
->get('settings.default_image');
// Load by uuid.
$files = \Drupal::entityTypeManager()
->getStorage('file')
->loadByProperties([
'uuid' => $default_image['uuid'],
]);
// Pop it.
$file = array_pop($files);
// Set in an array.
$data = [
"id" => $file
->id(),
"width" => $default_image['width'],
"height" => $default_image['height'],
];
// Retun the array.
return $data;
}
/**
* Implements hook_social_user_name_display_suggestions().
*
* @throws \Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException
* @throws \Drupal\Component\Plugin\Exception\PluginNotFoundException
*/
function social_profile_social_user_name_display_suggestions(AccountInterface $account) : array {
$suggestions = [];
$entityTypeManager = \Drupal::entityTypeManager();
/** @var \Drupal\profile\ProfileStorageInterface $storage */
$storage = $entityTypeManager
->getStorage('profile');
if ($user_profile = $storage
->loadByUser($account, 'profile')) {
/** @var \Drupal\profile\ProfileAccessControlHandler $accessControlHandler */
$accessControlHandler = $entityTypeManager
->getAccessControlHandler('profile');
$first_name_field = $user_profile
->get('field_profile_first_name');
$last_name_field = $user_profile
->get('field_profile_last_name');
$first_name = $accessControlHandler
->fieldAccess('view', $first_name_field
->getFieldDefinition(), NULL, $first_name_field, FALSE) ? $first_name_field
->getString() : "";
$last_name = $accessControlHandler
->fieldAccess('view', $last_name_field
->getFieldDefinition(), NULL, $last_name_field, FALSE) ? $last_name_field
->getString() : "";
$account_name = trim($first_name . " " . $last_name);
if ($account_name !== '') {
// Add the full name with a default weight.
$suggestions['full_name'] = [
'name' => $account_name,
];
}
}
return $suggestions;
}
/**
* Hide timezone fields group label.
*/
function _social_profile_form_pre_render($element) {
$element['group_locale_settings']['timezone']['#title'] = NULL;
return $element;
}
/**
* Implements hook_entity_operation_alter().
*/
function social_profile_entity_operation_alter(array &$operations, EntityInterface $entity) {
if ($entity
->getEntityTypeId() === 'user') {
if (isset($operations['edit'])) {
$operations['edit']['title'] = t('Edit account');
$operations['edit_profile'] = [
'title' => t('Edit profile'),
'weight' => isset($operations['edit']['weight']) ? $operations['edit']['weight']-- : 0,
'url' => Url::fromUserInput('/user/' . $entity
->id() . '/profile'),
];
}
}
}
/**
* Implements hook_social_user_account_header_account_links().
*
* Adds the "View my profile" and "Edit profile" link to the user menu.
*/
function social_profile_social_user_account_header_account_links(array $context) {
// We require a user for these links.
if (empty($context['user']) || !$context['user'] instanceof AccountInterface) {
return [];
}
return [
'my_profile' => [
'#type' => 'link',
'#attributes' => [
'title' => new TranslatableMarkup('View my profile'),
],
'#title' => new TranslatableMarkup('My profile'),
'#weight' => 500,
] + Url::fromRoute('user.page')
->toRenderArray(),
'edit_profile' => [
'#type' => 'link',
'#attributes' => [
'title' => new TranslatableMarkup("Edit profile"),
],
'#title' => new TranslatableMarkup("Edit profile"),
'#weight' => 1300,
] + Url::fromRoute('profile.user_page.single', [
'user' => $context['user']
->id(),
'profile_type' => 'profile',
])
->toRenderArray(),
];
}
/**
* Implements hook_social_user_account_header_items_alter().
*
* Replaces the default user icon with the user's profile image if available.
*/
function social_profile_social_user_account_header_items_alter(array &$menu_items, array $context) {
// If we don't have an account_box there's nothing to do.
if (empty($menu_items['account_box'])) {
return;
}
// A user is required to find the profile image.
if (empty($context['user']) || !$context['user'] instanceof AccountInterface) {
return;
}
$storage = \Drupal::entityTypeManager()
->getStorage('profile');
$profile = $storage
->loadByUser($context['user'], 'profile');
// If the user does not have a profile then there's no profile image.
if (empty($profile)) {
return;
}
// Provide a render array as image which will overrule the user icon.
$menu_items['account_box']['#image'] = \Drupal::entityTypeManager()
->getViewBuilder('profile')
->view($profile, 'small');
}
/**
* Implements hook_ENTITY_TYPE_access().
*/
function social_profile_profile_access(EntityInterface $entity, $operation, AccountInterface $account) {
$display_profile_teaser = FALSE;
$route_match = \Drupal::service('current_route_match');
$allowed_node_types = [
'landing_page',
'dashboard',
];
if ($route_match
->getRouteName() === 'entity.node.canonical') {
$node = $route_match
->getParameter('node');
if (!is_null($node) && !$node instanceof Node) {
$node = Node::load($node);
}
if ($node instanceof Node && in_array($node
->getType(), $allowed_node_types)) {
$display_profile_teaser = TRUE;
}
}
// Provides access only to viewing user profile info, like referenced data in
// featured items for landing & dashboard pages, if the current user has no
// permissions.
if ($operation === 'view' && $display_profile_teaser && !$account
->hasPermission('view any profile profile')) {
return AccessResult::allowed();
}
}
/**
* Show exposed filters block only when tagging filters are enabled for profile.
*
* Implements hook_block_access().
*/
function social_profile_block_access(Block $block, $operation, AccountInterface $account) {
if ($operation === 'view' && $block
->getPluginId() === 'views_exposed_filter_block:newest_users-page_newest_users') {
$access = AccessResult::forbidden();
if (\Drupal::moduleHandler()
->moduleExists('social_tagging')) {
/** @var \Drupal\social_tagging\SocialTaggingService $tag_service */
$tag_service = \Drupal::service('social_tagging.tag_service');
if ($tag_service
->profileActive()) {
$access = AccessResult::allowed();
}
}
return $access;
}
// No opinion.
return AccessResult::neutral();
}
/**
* Implements hook_entity_form_display_alter().
*/
function social_profile_entity_form_display_alter(EntityFormDisplayInterface $form_display, array $context) {
if ($form_display
->id() === 'profile.profile.default') {
$content = $form_display
->get('content');
if (isset($content['field_profile_profile_tag'])) {
$content['field_profile_profile_tag']['type'] = 'social_profile_tag_split';
$form_display
->set('content', $content);
}
}
}
/**
* Implements hook_form_FORM_ID_alter().
*/
function social_profile_form_taxonomy_overview_terms_alter(&$form, FormStateInterface $form_state, $form_id) {
if (\Drupal::service('social_profile.tag_service')
->allowSplit()) {
$storage = $form_state
->getStorage();
/** @var \Drupal\taxonomy\Entity\Vocabulary $vocabulary */
$vocabulary = $storage['taxonomy']['vocabulary'];
if ($vocabulary
->id() === 'profile_tag') {
// Remove edit/delete links.
foreach (Element::children($form['terms']) as $name) {
unset($form['terms'][$name]['weight']);
}
// Hide Save button.
$form['actions']['submit']['#access'] = FALSE;
// Remove tableDrag.
unset($form['terms']['#tabledrag']);
// Remove Weight column.
unset($form['terms']['#header'][1]);
}
}
}
/**
* Implements hook_views_plugins_filter_alter().
*/
function social_profile_views_plugins_filter_alter(array &$plugins) {
$plugins['search_api_term']['class'] = SocialSearchApiSplitProfileTerms::class;
}
/**
* Implements hook_entity_base_field_info().
*/
function social_profile_entity_base_field_info(EntityTypeInterface $entity_type) {
$fields = [];
// Check if we're dealing with the profile entity.
if ($entity_type
->id() === 'profile') {
$fields['profile_name'] = BaseFieldDefinition::create('string')
->setLabel(t('Profile name'))
->setCardinality(FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED)
->setReadOnly(TRUE);
}
return $fields;
}
/**
* Implements hook_ENTITY_TYPE_presave().
*
* Set the correct profile name.
*/
function social_profile_profile_presave(EntityInterface $profile) {
if ($profile instanceof ProfileInterface) {
/** @var \Drupal\social_profile\SocialProfileNameService $profile_name_service */
$profile_name_service = \Drupal::service('social_profile.name_service');
// Check if we need update Profile name.
if (!$profile_name_service
->needToUpdateProfileName($profile)) {
return;
}
// Get generated profile name.
$profile_name = $profile_name_service
->getProfileName($profile);
// Update profile name.
$profile
->set('profile_name', $profile_name);
}
}