I have been poking around this module for days and one thing that strikes me as very odd: this doesn't work out of the box.

If I install the module and then install composer dependencies to get the swiftmailer library and HTML2text it doesn't work. I keep getting an error saying

Fatal error: Class 'Swift_Message' not found in /wwwroot/gollum/public_html/modules/swiftmailer/src/Plugin/Mail/SwiftMailer.php on line 176

In the end I did not know about how to solve dependencies using composer drupal-update or drupal require. So the error above was non-existing. But it would be nice to show a message to users like me to give them a nudge in the right direction.

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

DragonEye created an issue. See original summary.

matthias_bauw’s picture

Status: Active » Needs review
FileSize
426 bytes

I added a require_once statement to SiwftMailer.php file that includes the composer-generated autoloader. That way the classes become available.

matthias_bauw’s picture

Been trying to find a more elegant way to do this so I implemented a static function in the swiftmailer class that first detects if the autoloader is present. If it is then the require_once statement is called.

If it is not FALSE is returned so the initiating function can decide what to do with that. This way you don't get fatal errors any more. An error message is displayed in drupal and the error message is logged. The message in the logs looks like this:

An attempt to send an e-mail message failed, and the following error message was returned : The Swiftmailer library could not be found. You can easily install this using composer.

The e-mail carried the following headers:

No headers were found.

Again, I'm very much a beginner and maybe I'm missing the point. If I'm bothering anyone with this, just tell me :)

Matt.

matthias_bauw’s picture

ok,

This will probrably be the last one. Since the loadLibraries function is now a public static of the Swiftmailer class it can now replace the validate_library function. So I changed the code in the settingsform to use that function to check if the library is present because I think that's the better way to do it. I removed the validate_library function.

When I did that I found a new error: when the settings page is loaded and the library is not present an error occurs:

The website encountered an unexpected error. Please try again later.
Recoverable fatal error: Argument 2 passed to Drupal::l() must be an instance of Drupal\Core\Url, string given, called in /wwwroot/gollum/public_html/modules/swiftmailer/src/Form/SettingsForm.php on line 241 and defined in Drupal::l() (line 574 of core/lib/Drupal.php).

Drupal::l(Object, 'admin/config/people/swiftmailer')
Drupal\swiftmailer\Form\SettingsForm->buildForm(Array, Object)
call_user_func_array(Array, Array)
Drupal\Core\Form\FormBuilder->retrieveForm('swiftmailer_settings_form', Object)
Drupal\Core\Form\FormBuilder->buildForm(Object, Object)
Drupal\Core\Controller\FormController->getContentResult(Object, Object)
call_user_func_array(Array, Array)
Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->Drupal\Core\EventSubscriber\{closure}()
Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object)
Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->wrapControllerExecutionInRenderContext(Array, Array)
Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->Drupal\Core\EventSubscriber\{closure}()
call_user_func_array(Object, Array)
Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1)
Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1)
Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1)
Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1)
Drupal\page_cache\StackMiddleware\PageCache->pass(Object, 1, 1)
Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1)
Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1)
Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1)
Stack\StackedHttpKernel->handle(Object, 1, 1)
Drupal\Core\DrupalKernel->handle(Object)

Probably some old D7 code that was still there. I have changed the code to show a simple error message. In the original code there was a link there to admin/config/people/swiftmailer but that location does not exist, I checked. So I have not replaced it with a new link since composer is the solution.

The message that is shown is: The Swiftmailer library could not be found. You can install this by using composer. Just go to the module directory and execute "composer install"

And I think that completed my work on this. I hope that somebody can do something with it. But even if it was useless I had fun :)

Matt.

Status: Needs review » Needs work

The last submitted patch, 4: composerautoload-2622366-4.patch, failed testing.

matthias_bauw’s picture

I was surprised this failed but I have taken a look at the test code and it's quite absurd actually.

It tests for the settings page to be present but of course it's not present because the test to see if the library is installed is now working correctly.

But this means that this code fails:

// Login..
    $user = $this->createUser(['administer swiftmailer']);
    $this->drupalLogin($user);
    $this->drupalGet(t('admin/config/swiftmailer/transport'));
    $this->assertText(t('Transport types'));

So there are only two options if you ask me
- We change the test but since most of the rest of the test depends on the settingspage being loaded this would almost mean cancelling the whole test
- We remove the library check when loading the settings page. A possible solution could be to load the settings page entirely but to show a warning message that the library was not detected. That would make the test functional again and still give the user some information as to why it won't work and how to solve it

I'll try and fix it tomorrow

Matt.

matthias_bauw’s picture

I have implemented the warning message on the settings page. This means that the options on the settings page are now shown at all times.

The error message tells the user that the module will probably not work and tells them to use composer to solve dependencies.

matthias_bauw’s picture

Status: Needs work » Needs review

The last submitted patch, 4: composerautoload-2622366-4.patch, failed testing.

Status: Needs review » Needs work

The last submitted patch, 7: composerautoload-2622366-7.patch, failed testing.

matthias_bauw’s picture

ok,

Of course there are two tabs and the same controls are active in the messages tab. So I implemented the same validation mechanism as in patch 7. Same warning message is displayed now.

I hope this one passes testing.

Matt.

matthias_bauw’s picture

matthias_bauw’s picture

matthias_bauw’s picture

ok,

That seems to be it! The module is now usable out of the box. Just copy the code in the modules directory and run composer install. If you forget a message is shown and everytime an e-mail is sent a log message is recorded and an error is displayed

Matt.

matthias_bauw’s picture

I have been doing some reading up and I discovered the composer mechanism that is included in core. Didn't know the composer drupal-update command. That is why it didn't work out of the box.

So I'm going to keep working on this because if some helpful error messages had been there I would have had no trouble finding out how to do this. I'm gonna change some things and make sure that this becomes more user-friendly for people just starting out with drupal like me.

The docs are also very wrong about the installation of the library

Matt.

sbrattla’s picture

Hi,

Just a quick comment. The docs are written for the D7 module. Many things have changed, and I'm sure a D8 documentation would look different. You are very welcome to look into D8 issues for this module. The more eyes we can get on this, the merrier :-)

matthias_bauw’s picture

Status: Needs review » Needs work
Berdir’s picture

The correct way to load the composer dependencies is to either use composer require to get the module if you use that approach or https://www.drupal.org/project/composer_manager.

Do *not* run composer install inside the module, instead follow the instructions from composer manager and it should just work.

matthias_bauw’s picture

Yeah Berdir,

now I figured that out :) But it's just not clear in docs and in D7 this was not possible right? I don't have too much experience with external libraries and Drupal. But I'm learning :)

Matt.

Berdir’s picture

Yeah, this is different and D8 and definitely needs better docs.

I haven't seen #15 and that you already discovered this yourself, sorry :)

matthias_bauw’s picture

Title: Swiftmailer library does not load » module installs even when composer dependencies aren't met
Priority: Normal » Minor

heh, no problem. I am wondering though if it would be advisable to implement hook_requirements. That way beginning users like me would never get to this wrong assumption. We could display an error message that tells the user to use composer to solve dependencies before installing the module

Changed the title of the issue too.

matthias_bauw’s picture

This is a patch that implements hook-requirements. The module won't install before dependencies are met. A message is displayed.

Because of this the library validation is no longer necessary so i removed validate_library and the if/else statements that had to show error messages after installing the module.

Maybe, however small, something useful came out of this in the end.

Matt

matthias_bauw’s picture

Status: Needs work » Needs review
matthias_bauw’s picture

Issue summary: View changes
matthias_bauw’s picture

Issue summary: View changes
webflo’s picture

Issue summary: View changes
FileSize
4.53 KB
873 bytes

Thanks for cleaning the up. I added a link to the composer manager project page.

webflo’s picture

Status: Needs review » Fixed

Thanks!

  • webflo committed 73f6c9c on 8.x-1.x
    Issue #2622366 by DragonEye, webflo: Prevent module installation when...
matthias_bauw’s picture

Wohoo! That was officially my first contribution!

Thanks

Matt

webflo’s picture

You are welcome! :)

Status: Fixed » Closed (fixed)

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