diff --git a/config/optional/field.field.user.user.field_user_social_links.yml b/config/optional/field.field.user.user.field_user_social_links.yml new file mode 100644 index 0000000..f4c9b53 --- /dev/null +++ b/config/optional/field.field.user.user.field_user_social_links.yml @@ -0,0 +1,20 @@ +langcode: en +status: true +dependencies: + config: + - field.storage.user.field_user_social_links + module: + - site_users + - user +id: user.user.field_user_social_links +field_name: field_user_social_links +entity_type: user +bundle: user +label: 'Social Links' +description: 'Social network profile links.' +required: false +translatable: false +default_value: {} +default_value_callback: '' +settings: {} +field_type: social_link diff --git a/config/optional/field.storage.user.field_user_social_links.yml b/config/optional/field.storage.user.field_user_social_links.yml new file mode 100644 index 0000000..1bf50a5 --- /dev/null +++ b/config/optional/field.storage.user.field_user_social_links.yml @@ -0,0 +1,18 @@ +langcode: en +status: true +dependencies: + module: + - site_users + - user +id: user.field_user_social_links +field_name: field_user_social_links +entity_type: user +type: social_link +settings: {} +module: site_users +locked: false +cardinality: -1 +translatable: false +indexes: {} +persist_with_no_fields: false +custom_storage: false diff --git a/config/translations/pt-br/field.field.user.user.field_user_social_links.yml b/config/translations/pt-br/field.field.user.user.field_user_social_links.yml new file mode 100644 index 0000000..191ff0a --- /dev/null +++ b/config/translations/pt-br/field.field.user.user.field_user_social_links.yml @@ -0,0 +1,2 @@ +label: 'Redes Sociais' +description: 'Links de perfil em redes sociais.' diff --git a/site_users.install b/site_users.install index 2ea8dad..95ae700 100644 --- a/site_users.install +++ b/site_users.install @@ -67,6 +67,16 @@ function site_users_install() { ]); } + // Campo Redes Sociais. + if (!$form_display->getComponent('field_user_social_links')) { + $form_display->setComponent('field_user_social_links', [ + 'type' => 'social_link_widget', + 'weight' => 16, + 'settings' => [], + 'region' => 'content', + ]); + } + // Campo Foto Padrão - oculto no form (será gerenciado via hook_form_alter). $form_display->removeComponent('field_user_default_photo'); @@ -127,6 +137,17 @@ function site_users_install() { ]); } + // Campo Redes Sociais. + if (!$view_display->getComponent('field_user_social_links')) { + $view_display->setComponent('field_user_social_links', [ + 'type' => 'social_link_formatter', + 'weight' => 16, + 'label' => 'above', + 'settings' => [], + 'region' => 'content', + ]); + } + // Campo Foto Padrão. if (!$view_display->getComponent('field_user_default_photo')) { $view_display->setComponent('field_user_default_photo', [ @@ -212,3 +233,57 @@ function site_users_update_10001() { return t('Default photo field created successfully.'); } + +/** + * Adds the field_user_social_links field for social network profile links. + */ +function site_users_update_10002() { + // Create field storage if it does not exist. + if (!FieldStorageConfig::loadByName('user', 'field_user_social_links')) { + FieldStorageConfig::create([ + 'field_name' => 'field_user_social_links', + 'entity_type' => 'user', + 'type' => 'social_link', + 'module' => 'site_users', + 'cardinality' => -1, + 'translatable' => FALSE, + ])->save(); + } + + // Create field instance if it does not exist. + if (!FieldConfig::loadByName('user', 'user', 'field_user_social_links')) { + FieldConfig::create([ + 'field_name' => 'field_user_social_links', + 'entity_type' => 'user', + 'bundle' => 'user', + 'label' => 'Social Links', + 'description' => 'Social network profile links.', + 'required' => FALSE, + ])->save(); + } + + // Add to form display. + $form_display = EntityFormDisplay::load('user.user.default'); + if ($form_display && !$form_display->getComponent('field_user_social_links')) { + $form_display->setComponent('field_user_social_links', [ + 'type' => 'social_link_widget', + 'weight' => 16, + 'settings' => [], + 'region' => 'content', + ])->save(); + } + + // Add to view display. + $view_display = EntityViewDisplay::load('user.user.default'); + if ($view_display && !$view_display->getComponent('field_user_social_links')) { + $view_display->setComponent('field_user_social_links', [ + 'type' => 'social_link_formatter', + 'weight' => 16, + 'label' => 'above', + 'settings' => [], + 'region' => 'content', + ])->save(); + } + + return t('Social links field created successfully.'); +} diff --git a/site_users.module b/site_users.module index aab9848..3b07ab2 100644 --- a/site_users.module +++ b/site_users.module @@ -55,8 +55,7 @@ function site_users_entity_field_access($operation, FieldDefinitionInterface $fi $profile_fields = [ 'field_user_name', 'field_user_phone', - - + 'field_user_social_links', 'field_user_bio', ]; diff --git a/src/Plugin/Block/UserInfoBlock.php b/src/Plugin/Block/UserInfoBlock.php index ae03a27..3832a8f 100644 --- a/src/Plugin/Block/UserInfoBlock.php +++ b/src/Plugin/Block/UserInfoBlock.php @@ -109,9 +109,8 @@ class UserInfoBlock extends BlockBase implements ContainerFactoryPluginInterface 'username' => $user->getDisplayName(), 'name' => $this->getFieldValue($user, 'field_user_name'), 'phone' => $this->getFieldValue($user, 'field_user_phone'), - - 'bio' => $this->getFieldValue($user, 'field_user_bio'), + 'social_links' => $this->getSocialLinks($user), 'photo_url' => $default_photo_url, 'photo_alt' => $default_photo ? $default_photo->label() : '', ]; @@ -150,6 +149,34 @@ class UserInfoBlock extends BlockBase implements ContainerFactoryPluginInterface return NULL; } + /** + * Returns the social network links of a user. + * + * @param \Drupal\user\UserInterface $user + * The user entity. + * + * @return array + * Array of items with 'network' and 'url' keys. + */ + protected function getSocialLinks(UserInterface $user): array { + $links = []; + + if (!$user->hasField('field_user_social_links') || $user->get('field_user_social_links')->isEmpty()) { + return $links; + } + + foreach ($user->get('field_user_social_links') as $item) { + if (!$item->isEmpty()) { + $links[] = [ + 'network' => $item->network, + 'url' => $item->url, + ]; + } + } + + return $links; + } + /** * Obtém o valor de um campo do usuário. * diff --git a/src/Plugin/Field/FieldFormatter/SocialLinkFormatter.php b/src/Plugin/Field/FieldFormatter/SocialLinkFormatter.php new file mode 100644 index 0000000..0798764 --- /dev/null +++ b/src/Plugin/Field/FieldFormatter/SocialLinkFormatter.php @@ -0,0 +1,52 @@ + $item) { + if ($item->isEmpty()) { + continue; + } + + $network_label = $networks[$item->network] ?? $item->network; + + $elements[$delta] = [ + '#type' => 'link', + '#title' => $network_label, + '#url' => Url::fromUri($item->url), + '#attributes' => [ + 'class' => ['social-link', 'social-link--' . $item->network], + 'target' => '_blank', + 'rel' => 'noopener noreferrer', + ], + ]; + } + + return $elements; + } + +} diff --git a/src/Plugin/Field/FieldType/SocialLinkItem.php b/src/Plugin/Field/FieldType/SocialLinkItem.php new file mode 100644 index 0000000..d9b794c --- /dev/null +++ b/src/Plugin/Field/FieldType/SocialLinkItem.php @@ -0,0 +1,84 @@ + 'Facebook', + 'instagram' => 'Instagram', + 'linkedin' => 'LinkedIn', + 'twitter' => 'X (Twitter)', + 'youtube' => 'YouTube', + 'github' => 'GitHub', + 'tiktok' => 'TikTok', + 'telegram' => 'Telegram', + 'whatsapp' => 'WhatsApp', + 'pinterest' => 'Pinterest', + ]; + } + + /** + * {@inheritdoc} + */ + public static function propertyDefinitions(FieldStorageDefinitionInterface $field_definition): array { + $properties['network'] = DataDefinition::create('string') + ->setLabel(t('Network')) + ->setRequired(TRUE); + + $properties['url'] = DataDefinition::create('uri') + ->setLabel(t('URL')) + ->setRequired(TRUE); + + return $properties; + } + + /** + * {@inheritdoc} + */ + public static function schema(FieldStorageDefinitionInterface $field_definition): array { + return [ + 'columns' => [ + 'network' => [ + 'type' => 'varchar', + 'length' => 64, + ], + 'url' => [ + 'type' => 'varchar', + 'length' => 2048, + ], + ], + ]; + } + + /** + * {@inheritdoc} + */ + public function isEmpty(): bool { + return empty($this->get('network')->getValue()) + || empty($this->get('url')->getValue()); + } + +} diff --git a/src/Plugin/Field/FieldWidget/SocialLinkWidget.php b/src/Plugin/Field/FieldWidget/SocialLinkWidget.php new file mode 100644 index 0000000..b6578e0 --- /dev/null +++ b/src/Plugin/Field/FieldWidget/SocialLinkWidget.php @@ -0,0 +1,47 @@ + 'select', + '#title' => $this->t('Network'), + '#options' => ['' => $this->t('- Select -')] + SocialLinkItem::getNetworks(), + '#default_value' => $item->network ?? '', + ]; + + $element['url'] = [ + '#type' => 'url', + '#title' => $this->t('Profile URL'), + '#default_value' => $item->url ?? '', + '#maxlength' => 2048, + '#placeholder' => 'https://', + ]; + + return $element; + } + +} diff --git a/templates/site-user-info-block.html.twig b/templates/site-user-info-block.html.twig index d32aad4..7e20d4a 100644 --- a/templates/site-user-info-block.html.twig +++ b/templates/site-user-info-block.html.twig @@ -1,20 +1,19 @@ {# /** * @file - * Template para o bloco de informações do usuário. + * Template for the user information block. * - * Variáveis disponíveis: - * - user_info: Array com informações do usuário: - * - uid: ID do usuário - * - username: Nome de usuário (display name) - * - name: Nome completo - * - phone: Telefone - * - category: Categoria - * - dept_code: Código do departamento - * - bio: Biografia - * - photo_url: URL da foto padrão - * - photo_alt: Texto alternativo da foto - * - user: Entidade do usuário. + * Available variables: + * - user_info: Array with user information: + * - uid: User ID + * - username: Display name + * - name: Full name + * - phone: Phone number + * - bio: Biography + * - social_links: Array of social links, each with 'network' and 'url' keys + * - photo_url: Default photo URL + * - photo_alt: Photo alternative text + * - user: User entity. */ #}
@@ -35,22 +34,9 @@ {{ user_info.name ?: user_info.username }} - {% if user_info.category %} -
- {{ user_info.category }} -
- {% endif %} - - {% if user_info.dept_code %} -
- - {{ user_info.dept_code }} -
- {% endif %} - {% if user_info.phone %}
- + {{ user_info.phone }}
{% endif %} @@ -60,5 +46,18 @@ {{ user_info.bio }}
{% endif %} + + {% if user_info.social_links %} + + {% endif %} diff --git a/translations/site_users.pt-br.po b/translations/site_users.pt-br.po index 6ca3664..4557eef 100644 --- a/translations/site_users.pt-br.po +++ b/translations/site_users.pt-br.po @@ -102,3 +102,32 @@ msgstr "Você pode adicionar no máximo @max fotos. Atualmente há @count fotos # Install/update msgid "Default photo field created successfully." msgstr "Campo de foto padrão criado com sucesso." + +msgid "Social links field created successfully." +msgstr "Campo de redes sociais criado com sucesso." + +# Social link field type +msgid "Social link" +msgstr "Link social" + +msgid "Stores a social network type and profile URL." +msgstr "Armazena um tipo de rede social e URL de perfil." + +msgid "Network" +msgstr "Rede" + +msgid "- Select -" +msgstr "- Selecione -" + +msgid "Profile URL" +msgstr "URL do perfil" + +msgid "Social Links" +msgstr "Redes Sociais" + +msgid "Social network profile links." +msgstr "Links de perfil em redes sociais." + +# Template +msgid "Phone:" +msgstr "Telefone:"