Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add an adapter to support the Symfony Mailer component and deprecate the Swiftmailer integration #102

Merged
merged 1 commit into from
Jun 9, 2022

Conversation

mbabker
Copy link
Contributor

@mbabker mbabker commented Dec 4, 2021

Replaces #18

@mbabker mbabker force-pushed the feature/symfony-mailer branch 3 times, most recently from d99600f to 628ca55 Compare December 4, 2021 02:15
Copy link
Member

@Zales0123 Zales0123 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hello @mbabker, we can finally move forward with this one 🎉 I've left some comments, please, take a look at them. Do you think you would have some time to work on this PR in the nearest future, or should I take it over and finish the work? Thank you for your contribution! 🖖 🏅

@mbabker mbabker requested a review from a team as a code owner May 10, 2022 00:11
composer.json Outdated
@@ -45,6 +45,8 @@
"phpunit/phpunit": "^9.4",
"sylius-labs/coding-standard": "^4.0",
"symfony/console": "^4.4 || ^5.4",
"symfony/event-dispatcher": "^4.4 || ^5.4",
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The event dispatcher is used in a few classes, but even for development, it was only installed through transient dependencies.

@@ -40,7 +40,7 @@

<service id="sylius.email_renderer.adapter.abstract" class="Sylius\Component\Mailer\Renderer\Adapter\AbstractAdapter" abstract="true">
<call method="setEventDispatcher">
<argument type="service" id="event_dispatcher" />
<argument type="service" id="event_dispatcher" on-invalid="ignore" />
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This (and the change immediately below) ends up being a bug fix. The event dispatcher is an optional dependency in the classes that support it, yet compiling the container would fail hard if the dispatcher service isn't there. This ensures that the dispatcher stays optional.

Copy link
Member

@loic425 loic425 May 12, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

isn't on-invalid="null"? is this different?

I don't find any documentation about this value.
https://symfony.com/doc/current/service_container/optional_dependencies.html

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It’s the “ignoring missing dependencies” section on that page.

The null behavior is valid if you’re working with a nullable argument. The $dispatcher argument on the abstract adapter’s setEventDispatcher() method is not nullable, so the invalid behavior is the right behavior for this case (which means it just won’t be called).

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oh yes, I just had not seen it was with a call method, excuxe me.

@mbabker mbabker force-pushed the feature/symfony-mailer branch 3 times, most recently from 6b7a3cb to 22a6c57 Compare May 10, 2022 01:34
Copy link
Member

@Zales0123 Zales0123 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you rebase with #128 it would be easier to tell whether the container is building properly or not 🖖 I also believe we should run the lint:container with the symfony/mailer enabled or disabled to see if everything works 💃 Thank you, one more time, for your work @mbabker 🎉

@mbabker mbabker force-pushed the feature/symfony-mailer branch 2 times, most recently from 0594f68 to ad5eaf1 Compare May 10, 2022 23:00
@Zales0123
Copy link
Member

Zales0123 commented May 11, 2022

I believe it still has some problems :D Let's take a look at this build (this PR enhanced with additional steps in the build): https://github.com/Zales0123/SyliusMailerBundle/runs/6384899456?check_suite_focus=true

As I said, we need a few different cases covered with the test application:

  1. no adapter configured
  2. swiftmailer adapter configured (with or without symfony/mailer in composer.json)
  3. symfony mailer adapter configured (with or without symfony/swiftmailer-bundle in composer.json)
    Maybe even something more :D

The alternative is to require symfony/mailer and symfony/swiftmailer-bundle not in dev but in normal requirements - it would lower the number of test cases. But we definitely need to cover some test cases to be sure it works 🖖

cc @loic425 @lchrusciel I need you opinions :)

@mbabker mbabker force-pushed the feature/symfony-mailer branch 7 times, most recently from d2c5925 to 26d2ccc Compare May 11, 2022 23:55
@mbabker
Copy link
Contributor Author

mbabker commented May 12, 2022

The build setup you used won't work. The sylius.email_sender.adapter.swiftmailer and sylius.email_sender.adapter.symfony_mailer services were not created until the compiler pass runs, and only if a service is not explicitly set in the configuration (neither of those services were defined in the services.xml file previously).

To simplify testing, I've reworked things again to use feature detection though ContainerBuilder::willBeAvailable() inside the container extension (yes, it's static; no, wrapping it into something that can be mocked is not practical, see Sylius/SyliusGridBundle#227 (comment) for more on that).

On a side note, trying to do the entire CI in one build is rather limiting. By my count, there should be at least four separate workflows (Psalm and PHPStan as separate jobs in one workflow, code style checks in another workflow, PHPSpec in a 3rd workflow, and PHPUnit in a 4th). This would ensure that the entirety of the CI suite runs on every build instead of half of it not even running because of a code style issue somewhere in the package. You also wouldn't need things like the four separate lint:container calls after running a bunch of Composer commands to get everything in the desired state, you'd do the Composer setup one time and account for the optional things being removed in the test code (at least that's how I'm smoke testing the PagerfantaBundle with Twig fully removed).

@Zales0123
Copy link
Member

Thank you for the clarification, I agree 👍 I've checked a few cases with the current state of PR on Sylius (I assumed swiftmailer is always installed via composer, as it's provided by Sylius itself):

  1. Symfony/mailer not installed, no adapter configured - works, swiftmailer used ✅
  2. Symfony/mailer not installed, symfony adapter configured - fails and it should ✅
  3. Symfony/mailer not installed, swiftmailer adapter configured - fails, but it shouldn’t 🚫
  4. Symfony/mailer installed, no adapter configured - works, swiftmailer used ✅
  5. Symfony/mailer installed, symfony adapter configured - works, symfony mailer used ✅
  6. Symfony/mailer installed, swiftmailer adapter configured - works, swiftmailer used ✅

Can you please check out scenario 3? it can happen when one has a Sylius application with swiftmailer adapter configured (even though it's the default one), updates the mailer bundle and sees the exception (as there is a service created that has a dependency to Symfony Mailer probably).

cc @loic425 @lchrusciel I still need your eye on it as well 😄

Regarding the test suite - I totally agree, that we should refactor it to multiple builds 👍 The proposed suite was just for now 🖖

rm -rf src/Bundle/test/var/cache
mv src/Bundle/test/config/packages/mailer.yaml mailer.yaml
composer remove symfony/mailer --dev
(cd src/Bundle/test && bin/console lint:container)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if we keep this test suite this way for a moment, I think we have to add composer require --dev symfony/mailer at the end

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I’m not following what it is you’re suggesting to do. The order of operations for all the Composer commands is fine as is, there is no point in doing a full reset to the starting state at the end of each lint step (everything a step is doing is building off the state the previous step left things in).

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think depending on a previous one is a little bit risky. On resource bundle, we do that : https://github.com/Sylius/SyliusResourceBundle/blob/1.10/.github/workflows/build.yml#L106

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

By that same logic, you can’t rely on the previous steps to have set up the environment correctly either 😉 (if these were parallel or separately running jobs it’d be another story, but it’s a single threaded build).

The only difference in workflows is where certain commands are run, and running less Composer commands overall since each step builds on the previous.

.github/workflows/build.yml Show resolved Hide resolved
.github/workflows/build.yml Show resolved Hide resolved
…the Swiftmailer integration

Co-authored-by: Michael Babker <[email protected]>
@mbabker
Copy link
Contributor Author

mbabker commented May 13, 2022

I've taken the feature detection around the services as far as I can sanely take it.

Copy link
Member

@Zales0123 Zales0123 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've also checked all scenarios described here with this implementation and it seems to work like a charm ✨ 🎉

->shouldBeCalled()
;

$mailer->send(Argument::type(Email::class))->shouldBeCalled();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We could work a little bit at this prophecy to check the Email content as well 🖖

@Zales0123 Zales0123 merged commit bfeab0b into Sylius:master Jun 9, 2022
@Zales0123
Copy link
Member

What an adventure! 🎉 Thank you, @mbabker, for this amazing work 🥇

@mbabker mbabker deleted the feature/symfony-mailer branch June 9, 2022 13:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Feature New feature proposals.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants