Newer
Older
* Enables the use of personal and site-wide contact forms.
use Drupal\Core\Url;
Dries Buytaert
committed
use Drupal\Core\Form\FormStateInterface;
Angie Byron
committed
use Drupal\Core\Routing\RouteMatchInterface;
use Drupal\contact\Plugin\rest\resource\ContactMessageResource;
Alex Pott
committed
use Drupal\user\Entity\User;
Angie Byron
committed
Dries Buytaert
committed
* Implements hook_help().
Angie Byron
committed
function contact_help($route_name, RouteMatchInterface $route_match) {
Alex Pott
committed
switch ($route_name) {
case 'help.page.contact':
$menu_page = \Drupal::moduleHandler()->moduleExists('menu_ui') ? Url::fromRoute('entity.menu.collection')->toString() : '#';
$block_page = \Drupal::moduleHandler()->moduleExists('block') ? Url::fromRoute('block.admin_display')->toString() : '#';
$contact_page = Url::fromRoute('entity.contact_form.collection')->toString();
Angie Byron
committed
$output = '';
$output .= '<h2>' . t('About') . '</h2>';
$output .= '<p>' . t('The Contact module allows visitors to contact registered users on your site, using the personal contact form, and also allows you to set up site-wide contact forms. For more information, see the <a href=":contact">online documentation for the Contact module</a>.', [':contact' => 'https://www.drupal.org/documentation/modules/contact']) . '</p>';
$output .= '<h2>' . t('Uses') . '</h2>';
Angie Byron
committed
$output .= '<dl>';
Alex Pott
committed
$output .= '<dt>' . t('Using the personal contact form') . '</dt>';
$output .= '<dd>' . t("Site visitors can email registered users on your site by using the personal contact form, without knowing or learning the email address of the recipient. When a site visitor is viewing a user profile, the viewer will see a <em>Contact</em> tab or link, which leads to the personal contact form. The personal contact link is not shown when you are viewing your own profile, and users must have both <em>View user information</em> (to see user profiles) and <em>Use users' personal contact forms</em> permission to see the link. The user whose profile is being viewed must also have their personal contact form enabled (this is a user account setting); viewers with <em>Administer users</em> permission can bypass this setting.") . '</dd>';
$output .= '<dt>' . t('Configuring contact forms') . '</dt>';
$output .= '<dd>' . t('On the <a href=":contact_admin">Contact forms page</a>, you can configure the fields and display of the personal contact form, and you can set up one or more site-wide contact forms. Each site-wide contact form has a machine name, a label, and one or more defined recipients; when a site visitor submits the form, the field values are sent to those recipients.', [':contact_admin' => $contact_page]) . '</dd>';
Alex Pott
committed
$output .= '<dt>' . t('Linking to contact forms') . '</dt>';
$output .= '<dd>' . t('One site-wide contact form can be designated as the default contact form. If you choose to designate a default form, the <em>Contact</em> menu link in the <em>Footer</em> menu will link to it. You can modify this link from the <a href=":menu-settings">Menus page</a> if you have the Menu UI module installed. You can also create links to other contact forms; the URL for each form you have set up has format <em>contact/machine_name_of_form</em>.', [':menu-settings' => $menu_page]) . '</p>';
Alex Pott
committed
$output .= '<dt>' . t('Adding content to contact forms') . '</dt>';
$output .= '<dd>' . t('From the <a href=":contact_admin">Contact forms page</a>, you can configure the fields to be shown on contact forms, including their labels and help text. If you would like other content (such as text or images) to appear on a contact form, use a block. You can create and edit blocks on the <a href=":blocks">Block layout page</a>, if the Block module is installed.', [':blocks' => $block_page, ':contact_admin' => $contact_page]) . '</dd>';
Angie Byron
committed
$output .= '</dl>';
Dries Buytaert
committed
return $output;
Alex Pott
committed
/**
* Implements hook_entity_type_alter().
Alex Pott
committed
*/
function contact_entity_type_alter(array &$entity_types) {
/** @var \Drupal\Core\Entity\EntityTypeInterface[] $entity_types */
$entity_types['user']->setLinkTemplate('contact-form', '/user/{user}/contact');
Alex Pott
committed
}
Dries Buytaert
committed
/**
* Implements hook_entity_extra_field_info().
Dries Buytaert
committed
*/
function contact_entity_extra_field_info() {
$fields = [];
foreach (array_keys(\Drupal::service('entity_type.bundle.info')->getBundleInfo('contact_message')) as $bundle) {
$fields['contact_message'][$bundle]['form']['name'] = [
Dries Buytaert
committed
'label' => t('Sender name'),
'description' => t('Text'),
'weight' => -50,
];
$fields['contact_message'][$bundle]['form']['mail'] = [
'label' => t('Sender email'),
'description' => t('Email'),
Dries Buytaert
committed
'weight' => -40,
];
if ($bundle == 'personal') {
$fields['contact_message'][$bundle]['form']['recipient'] = [
Angie Byron
committed
'label' => t('Recipient username'),
'description' => t('User'),
'weight' => -30,
];
}
$fields['contact_message'][$bundle]['form']['preview'] = [
'label' => t('Preview sender message'),
'description' => t('Preview'),
'weight' => 40,
];
$fields['contact_message'][$bundle]['form']['copy'] = [
Dries Buytaert
committed
'label' => t('Send copy to sender'),
'description' => t('Option'),
'weight' => 50,
];
Dries Buytaert
committed
}
Dries Buytaert
committed
$fields['user']['user']['form']['contact'] = [
Dries Buytaert
committed
'label' => t('Contact settings'),
'description' => t('Contact module form element.'),
'weight' => 5,
];
Dries Buytaert
committed
return $fields;
}
Alex Pott
committed
/**
* Implements hook_menu_local_tasks_alter().
*
* Hides the 'Contact' tab on the user profile if the user does not have an
* email address configured.
*/
function contact_menu_local_tasks_alter(&$data, $route_name) {
if ($route_name == 'entity.user.canonical') {
foreach ($data['tabs'][0] as $href => $tab_data) {
if ($href == 'entity.user.contact_form') {
$link_params = $tab_data['#link']['url']->getRouteParameters();
$account = User::load($link_params['user']);
if (!$account->getEmail()) {
unset($data['tabs'][0]['entity.user.contact_form']);
}
}
}
}
}
Gábor Hojtsy
committed
/**
Dries Buytaert
committed
* Implements hook_mail().
Gábor Hojtsy
committed
*/
function contact_mail($key, &$message, $params) {
Dries Buytaert
committed
$contact_message = $params['contact_message'];
/** @var \Drupal\user\UserInterface $sender */
Dries Buytaert
committed
$sender = $params['sender'];
$language = \Drupal::languageManager()->getLanguage($message['langcode']);
Dries Buytaert
committed
$variables = [
catch
committed
'@site-name' => \Drupal::config('system.site')->get('name'),
'@subject' => $contact_message->getSubject(),
'@form' => !empty($params['contact_form']) ? $params['contact_form']->label() : '',
'@form-url' => Url::fromRoute('<current>', [], ['absolute' => TRUE, 'language' => $language])->toString(),
catch
committed
'@sender-name' => $sender->getDisplayName(),
];
Dries Buytaert
committed
if ($sender->isAuthenticated()) {
$variables['@sender-url'] = $sender->toUrl('canonical', ['absolute' => TRUE, 'language' => $language])->toString();
Dries Buytaert
committed
}
else {
$variables['@sender-url'] = $params['sender']->getEmail() ?? '';
Dries Buytaert
committed
}
$options = ['langcode' => $language->getId()];
Gábor Hojtsy
committed
switch ($key) {
case 'page_mail':
case 'page_copy':
catch
committed
$message['subject'] .= t('[@form] @subject', $variables, $options);
$message['body'][] = t("@sender-name (@sender-url) sent a message using the contact form at @form-url.", $variables, $options);
$build = \Drupal::entityTypeManager()
->getViewBuilder('contact_message')
->view($contact_message, 'mail');
$message['body'][] = \Drupal::service('renderer')->renderInIsolation($build);
Gábor Hojtsy
committed
break;
Gábor Hojtsy
committed
case 'page_autoreply':
catch
committed
$message['subject'] .= t('[@form] @subject', $variables, $options);
$message['body'][] = $params['contact_form']->getReply();
Gábor Hojtsy
committed
break;
Gábor Hojtsy
committed
case 'user_mail':
case 'user_copy':
$variables += [
catch
committed
'@recipient-name' => $params['recipient']->getDisplayName(),
'@recipient-edit-url' => $params['recipient']->toUrl('edit-form', ['absolute' => TRUE, 'language' => $language])->toString(),
];
catch
committed
$message['subject'] .= t('[@site-name] @subject', $variables, $options);
$message['body'][] = t('Hello @recipient-name,', $variables, $options);
$message['body'][] = t("@sender-name (@sender-url) has sent you a message via your contact form at @site-name.", $variables, $options);
// Only include the opt-out line in the original email and not in the
// copy to the sender. Also exclude this if the email was sent from a
// user administrator because they can always send emails even if the
// contacted user has disabled their contact form.
if ($key === 'user_mail' && !$params['sender']->hasPermission('administer users')) {
$message['body'][] = t("If you don't want to receive such messages, you can change your settings at @recipient-edit-url.", $variables, $options);
}
$build = \Drupal::entityTypeManager()
->getViewBuilder('contact_message')
->view($contact_message, 'mail');
$message['body'][] = \Drupal::service('renderer')->renderInIsolation($build);
Gábor Hojtsy
committed
break;
}
Dries Buytaert
committed
}
Dries Buytaert
committed
Dries Buytaert
committed
* Implements hook_form_FORM_ID_alter().
*
* Add the enable personal contact form to an individual user's account page.
*
Alex Pott
committed
* @see \Drupal\user\ProfileForm::form()
Dries Buytaert
committed
function contact_form_user_form_alter(&$form, FormStateInterface $form_state) {
$form['contact'] = [
'#type' => 'details',
catch
committed
'#title' => t('Contact settings'),
Angie Byron
committed
'#open' => TRUE,
catch
committed
'#weight' => 5,
];
$account = $form_state->getFormObject()->getEntity();
if (!\Drupal::currentUser()->isAnonymous() && $account->id()) {
$account_data = \Drupal::service('user.data')->get('contact', $account->id(), 'enabled');
}
$form['contact']['contact'] = [
catch
committed
'#type' => 'checkbox',
'#title' => t('Personal contact form'),
'#default_value' => $account_data ?? \Drupal::config('contact.settings')->get('user_default_enabled'),
'#description' => t('Allow other users to contact you via a personal contact form which keeps your email address hidden. Note that some privileged users such as site administrators are still able to contact you even if you choose to disable this feature.'),
];
Alex Pott
committed
$form['actions']['submit']['#submit'][] = 'contact_user_profile_form_submit';
Dries Buytaert
committed
/**
Alex Pott
committed
* Submit callback for the user profile form to save the contact page setting.
Dries Buytaert
committed
*/
Dries Buytaert
committed
function contact_user_profile_form_submit($form, FormStateInterface $form_state) {
$account = $form_state->getFormObject()->getEntity();
Alex Pott
committed
if ($account->id() && $form_state->hasValue('contact')) {
\Drupal::service('user.data')->set('contact', $account->id(), 'enabled', (int) $form_state->getValue('contact'));
}
Dries Buytaert
committed
}
Dries Buytaert
committed
/**
Dries Buytaert
committed
* Implements hook_form_FORM_ID_alter().
*
* Add the default personal contact setting on the user settings page.
*
* @see \Drupal\user\AccountSettingsForm
Dries Buytaert
committed
*/
Dries Buytaert
committed
function contact_form_user_admin_settings_alter(&$form, FormStateInterface $form_state) {
$form['contact'] = [
'#type' => 'details',
'#title' => t('Contact settings'),
Angie Byron
committed
'#open' => TRUE,
Dries Buytaert
committed
'#weight' => 0,
];
$form['contact']['contact_default_status'] = [
Dries Buytaert
committed
'#type' => 'checkbox',
Alex Pott
committed
'#title' => t('Enable the personal contact form by default for new users'),
'#description' => t('Changing this setting will not affect existing users.'),
'#default_value' => \Drupal::configFactory()->getEditable('contact.settings')->get('user_default_enabled'),
];
Dries Buytaert
committed
// Add submit handler to save contact configuration.
$form['#submit'][] = 'contact_form_user_admin_settings_submit';
}
/**
* Form submission handler for user_admin_settings().
*
* @see contact_form_user_admin_settings_alter()
*/
Dries Buytaert
committed
function contact_form_user_admin_settings_submit($form, FormStateInterface $form_state) {
\Drupal::configFactory()->getEditable('contact.settings')
Alex Pott
committed
->set('user_default_enabled', $form_state->getValue('contact_default_status'))
Dries Buytaert
committed
->save();
Dries Buytaert
committed
}
/**
* Implements hook_rest_resource_alter().
*/
function contact_rest_resource_alter(&$definitions) {
$definitions['entity:contact_message']['class'] = ContactMessageResource::class;
}