0

I am trying to use hook_mail_alter to create a custom contact mail.

I want to get the display setting of the contact form.

(example path: http://mysite/admin/structure/contact/manage/my_contact_form/display/mail)

The things I want to know are:

  • Field Label
  • If its disabled or not
  • Field order
  • Field ID

How can I get this information in the PHP script?

EDIT:

I was able to get most of the information I wanted. but I couldn't get the field weight to display in the right order. I have a display mode called 'mail' and I want to get the weight of each field in this mode.

for now the code looks like this:

/**
 * Implements hook_mail_alter().
 */
function contact_plus_mail_alter(&$message) {
    if (isset($message['id']) && $message['id'] == 'contact_page_mail') {

        $siteName = \Drupal::config('system.site')->get('name');
        $siteMail = \Drupal::config('system.site')->get('mail');
        /** @var \Drupal\contact\Entity\Message $contactMessage */
        $contactMessage = $message['params']['contact_message'];
        $entityType = $contactMessage->getEntityType()->id();
        $bundle = $contactMessage->bundle();

        $contactForm = $contactMessage->getContactForm();
        $form_title = $contactForm->label();
        $recipients = implode(',', $contactForm->getRecipients());
        /** @var \Drupal\Core\Field\FieldItemListInterface[] $fields */
        $fields = $contactMessage->getFields();
        $data = [
            'title' => $form_title,
            'fields' => [],
        ];
        foreach ($fields as $key => $field) {
            $fieldDefinition = $field->getFieldDefinition();
            $data['fields'][] = [
                'label' => $fieldDefinition->getLabel(),
                'info' => $field->getValue(),
                'display_options' => $fieldDefinition->getDisplayOptions(),
                'weight' => '', // I want to get the field weight for the 'mail' display mode.
            ];
        }
        // TODO: order the data by weight

        // ... send the email
    }
}
  • What you want to achieve is composing your email body using the fields values, labels and display options from your form mode for a given entity, in this case 'contact_message' entity. Am I right? If that is the case I would use a view mode with the exact same layout as the form and use a theme suggestion (like contact-message--mail.html.twig assuming the view mode is mail) to customize the resulting HTML. – d70rr3s Jul 24 '18 at 22:00
  • Thanks for the hint. but I cant see how I would get the fields with it's settings in the twig. I solved my problem with the getComponents() function. Here is how: answer – Ravi Jul 25 '18 at 2:34
0

I was able to retrieve the order of the 'mail' display. The secret was in the ->getComponets() function in this part:

$display = \Drupal::entityTypeManager()
    ->getStorage('entity_view_display')
    ->load($entityType . '.' . $bundle . '.' . $displayMode);
$displayFields = $display->getComponents();

the final code looks like this:

/**
 * Implements hook_mail_alter().
 */
function contact_plus_mail_alter(&$message) {
    if (isset($message['id']) && $message['id'] == 'contact_page_mail') {
        $message['send'] = false;

        $siteName = \Drupal::config('system.site')->get('name');
        $siteMail = \Drupal::config('system.site')->get('mail');

        /** @var \Drupal\contact\Entity\Message $contactMessage */
        $contactMessage = $message['params']['contact_message'];
        $entityType = $contactMessage->getEntityType()->id();
        $bundle = $contactMessage->bundle();
        $contactForm = $contactMessage->getContactForm();
        $form_title = $contactForm->label();
        $recipients = implode(',', $contactForm->getRecipients());
        // Data for the email
        $data = [
            'title' => $form_title,
            'today' => (new \DateTime('now', new \DateTimeZone('UTC')))->format('m/d/Y'),
            'fields' => [],
        ];
        // get the 'mail' display mode if defined
        $viewModes = \Drupal::service('entity_display.repository')
            ->getViewModeOptionsByBundle(
                $entityType, $bundle
            );
        $displayMode = array_key_exists('mail', $viewModes) ? 'mail' : 'default';

        // get display field settings (weight, id, etc...)
        /** @var \Drupal\Core\Entity\Entity\EntityViewDisplay $display */
        $display = \Drupal::entityTypeManager()
            ->getStorage('entity_view_display')
            ->load($entityType . '.' . $bundle . '.' . $displayMode);
        $displayFields = $display->getComponents();

        // put the fields info in the email data
        foreach ($displayFields as $key => $fieldConfig) {
            $field = $contactMessage->get($key);
            $fieldDefinition = $field->getFieldDefinition();
            $data['fields'][$key] = [
                'label' => $fieldDefinition->getLabel(),
                'info' => $field->getValue(),
                'display_options' => $fieldDefinition->getDisplayOptions(),
                'weight' => $fieldConfig['weight'],
            ];
        }

        // order by weight
        function compare_weight($a, $b) {
            return strnatcmp($a['weight'], $b['weight']);
        }
        uasort($data['fields'], 'compare_weight');

        // send the email for the responsible
        $emailSender = new EmailSender($siteName . '<' . $siteMail . '>', $recipients, $form_title, 'my_theme', $data);
        $emailSender->createAndSendEmail();

        // send a copy to the person who filed the form
        if (isset($data['fields']['field_email'])) {
            $email = $data['fields']['field_email']['info'][0]['value'];
            $emailSender->to = $email;
        }
        $emailSender->createAndSendEmail();
    }
}

Hope it helps someone.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.