Problem/Motivation

Right after the Drupal installation, if a user tries to contact the site owner via the provided contact form that is linked in the footer, he gets an error message that the mail could not be delivered. This happens, because the contact module creates the site contact form without pre filling any recipient. The admin has to set the recipient at /admin/structure/contact/manage/feedback, but this is not obvious.

Proposed resolution

A resolution would be for the site to send the contact form email to the site's email address, if the recipients field is not set. This can happen only for the default contact form that comes with installation, as the recipients field is mandatory and no other form may be created without this field properly filled in.

I have created a patch that does just that. Checks if the recipients are set. if not, sends the mail to the site's email address.

Also, another approach is to set the contact form email recipient during installation time. The patch at #6 works like this.

Remaining tasks

- Add tests.
- Rewrite patch.
- Review patch.

User interface changes

None

API changes

Could be API change if we inject the config.factory service into the MailHandler class. This is the "right" way to do this.

Comments

yannisc’s picture

Status: Active » Needs review
StatusFileSize
new839 bytes

I attach the patch.

mradcliffe’s picture

Issue summary: View changes
Status: Needs review » Needs work
Issue tags: +Needs tests
  1. +++ b/core/modules/contact/src/MailHandler.php
    @@ -103,6 +103,12 @@ public function sendMailMessages(MessageInterface $message, AccountInterface $se
    +        // If email is not set from the contact form configuration (only possible
    +        // in the default site form that comes with the installation), send to the site's email.
    

    The comment line should end at 80 characters or less. If a word exceeds this, then you should start a new line.

  2. +++ b/core/modules/contact/src/MailHandler.php
    @@ -103,6 +103,12 @@ public function sendMailMessages(MessageInterface $message, AccountInterface $se
    +        $to = \Drupal::config('system.site')->get('mail');
    

    Would it be possible to inject the configuration class into MailHandler?

    This would be an API change, but would be better code.

We probably need a test for this as our current tests haven't caught the issue. A test would assert that the recepient of the mail is system.site.mail via assertMail... methods.

mradcliffe’s picture

To inject the service you would need to modify contact.services.yml and add @config.factory service (iirc on the service name in core.services.yml).

Then __construct needs to be modified to set $this->config = ConfigFactory.... there are some examples around core.

yannisc’s picture

Matthew, thank you for your comments!

I will fix the comments length issue, but could you please elaborate on the configuration class issue?

What do you mean by "inject the configuration class"? What do we want to achieve?

Thanks again for your help and mentorship,
Yannis

larowlan’s picture

Does the default form live in standard profile? If so the fix should be to load the form config entity in standard_install() and set using the value in config

yannisc’s picture

StatusFileSize
new890 bytes

@larowlan, yes, the default form lives in the standard profile.

I agree that it would be better if the form got populated with the site's email during installation time. I think it cannot be done via standard_install though, as this runs before the user inputs the site email, but can be done through SiteConfigureForm.php.

I attach a patch with this approach.

yannisc’s picture

Issue summary: View changes
Status: Needs work » Needs review
d.pagkratis’s picture

The patch attached from yannisc works properly!

penyaskito’s picture

Status: Needs review » Needs work
Issue tags: +Novice
--- a/core/lib/Drupal/Core/Installer/Form/SiteConfigureForm.php
+++ b/core/lib/Drupal/Core/Installer/Form/SiteConfigureForm.php

@@ -274,6 +274,13 @@ public function submitForm(array &$form, FormStateInterface $form_state) {
+    if (\Drupal::moduleHandler()->moduleExists('contact')) {

We should use $this->moduleHandler, which is already injected. Otherwise, I think is RTBC.

yannisc’s picture

StatusFileSize
new888 bytes

I attach with penyaskito's fix.

yannisc’s picture

Status: Needs work » Needs review

Status: Needs review » Needs work

The last submitted patch, 10: Contact-form-email-not-sent-2349651-3.patch, failed testing.

penyaskito’s picture

Oh! And we need tests too!

yannisc’s picture

Status: Needs work » Needs review
StatusFileSize
new886 bytes

Sorry, this is the right one.

yannisc’s picture

I don't see an Installer folder in the Tests folder. Mradcliffe added the needs tests tag before switching to the installer approach. Can you point me to the right direction?

penyaskito’s picture

Status: Needs review » Needs work

Installer tests are in Drupal\system\Tests\Installer. You should extend InstallerTestBase. Look at Drupal\system\Tests\Installer\SiteNameTest as an example.

larowlan’s picture

This is wrong. You said earlier that contact.form.feedback lives in standard profile. In which case globally changing the installer for all profiles is wrong. Please add a hook form alter to standard profile that adds a new submit handler which in turn updates the config.

yannisc’s picture

larowlan, I've added an if that checks if the contact module is enabled and only then it adds the site email to the recipient field. That way, it will work with any profile. I've tested it with both the standard and the minimal profiles and works ok.

larowlan’s picture

But what about a contrib profile that includes contact module but not the feedback form?

yannisc’s picture

Should I add an extra condition that checks for the feedback form and that the recipient field is empty, then?

larowlan’s picture

Status: Needs work » Needs review
Issue tags: -Needs tests, -Novice
StatusFileSize
new2.8 KB
new1.02 KB
new1.94 KB

No, as said in #5 this is an issue with standard profile, nothing to do with contact.

Here's how I think it should be done, as well as a test to verify it works.
Test only patch is the .fail one - should come back red.
Pass patch should come back green.

The last submitted patch, 21: contact-email-standard-2349651.fail_.patch, failed testing.

yannisc’s picture

It worked for me as well.

penyaskito’s picture

Status: Needs review » Reviewed & tested by the community

#21 is RTBC, test coverage++.

alexpott’s picture

Status: Reviewed & tested by the community » Fixed

Nice find, nice fix and nice test.

Committed 62f8b46 and pushed to 8.0.x. Thanks!

  • alexpott committed 62f8b46 on 8.0.x
    Issue #2349651 by yannisc, larowlan: Fixed Default contact form does not...

  • alexpott committed ad302e3 on 8.0.x
    Revert "Issue #2349651 by yannisc, larowlan: Fixed Default contact form...
alexpott’s picture

Status: Fixed » Needs work

hmmm... actually contact.form.feedback is provided by the contact module. Reverted the change for now.

I think we should consider moving the feedback form to the standard profile.

Status: Needs work » Needs review
larowlan’s picture

Status: Needs review » Needs work
larowlan’s picture

Issue tags: +Needs reroll

Lets move it to standard

larowlan’s picture

Assigned: Unassigned » larowlan
StatusFileSize
new430.29 KB

larowlan’s picture

Status: Needs work » Needs review
StatusFileSize
new2.76 KB
new4.69 KB
larowlan’s picture

Issue tags: -Needs reroll

Status: Needs review » Needs work

The last submitted patch, 33: contact-email-standard-2349651.33.patch, failed testing.

larowlan’s picture

Status: Needs work » Needs review
StatusFileSize
new1.3 KB
new5.99 KB
penyaskito’s picture

Status: Needs review » Needs work

Feedback form is in standard profile instead of the contact module as alexpott suggested.

--- /dev/null
+++ b/core/modules/contact/tests/modules/contact_test/contact_test.info.yml

Missing hidden: true?

Otherwise, RTBC.

penyaskito’s picture

Status: Needs work » Reviewed & tested by the community

Talked with larowlan on IRC.
After checking #2188661: Extension System, Part II: ExtensionDiscovery (item 1.4 on proposed resolution) and looking at the existing test modules, if we grep'ed correctly there are only 3 which define hidden:true. So not a requirement then.

alexpott’s picture

Status: Reviewed & tested by the community » Fixed

Nice - only if all core modules did the same as contact - yep I'm looking at you forum, book, node and views. Moving all "feature-like" config entities into standard will be awesome - roll on 9.x :)

Committed 9a19c4e and pushed to 8.0.x. Thanks!

  • alexpott committed 9a19c4e on 8.0.x
    Issue #2349651 by larowlan, yannisc: Fixed Default contact form does not...
berdir’s picture

contact_install() still has this:

  $config = \Drupal::config('contact.form.feedback');
  // Update the recipients if the default configuration entity has been created.
  // We should never rely on default config entities as during enabling a module
  // during config sync they will not exist.
  if (!$config->isNew()) {
    \Drupal::config('contact.form.feedback')->set('recipients', array($site_mail))->save();
  }

That's dead code now?

alexpott’s picture

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.