Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
66 commits
Select commit Hold shift + click to select a range
4e48ff6
Fix PHPUnit compatibility issues across Symfony/Twig upgrades
azine May 25, 2026
afa552f
Fix remaining PHPUnit failures and legacy compatibility
azine May 26, 2026
980ebae
Fix remaining Symfony 7.4 PHPUnit regressions
azine May 26, 2026
3f074df
Add Symfony Mailer template service contract
azine Aug 11, 2026
5a60328
Keep deprecated Swiftmailer interface as compatibility alias
azine Aug 11, 2026
3941d15
Migrate template email delivery to Symfony Mailer
azine Aug 11, 2026
09e8485
Keep deprecated Swiftmailer class as Symfony Mailer alias
azine Aug 11, 2026
915d832
Use Symfony Mime messages in template provider contract
azine Aug 11, 2026
58cc616
Separate legacy and Symfony Mailer header extension points
azine Aug 11, 2026
96168ca
Add Symfony Mailer header extension point
azine Aug 11, 2026
d3ca69f
Provide default Symfony Mailer headers
azine Aug 11, 2026
1f425ac
Bridge legacy and Symfony Mailer header hooks
azine Aug 11, 2026
9997b3b
Make legacy mailer contract compatible with Symfony Mime
azine Aug 11, 2026
6aab4e8
Expose canonical Symfony Mailer contract
azine Aug 11, 2026
50e18d2
Modernize EmailBundle configuration for Symfony Mailer
azine Aug 11, 2026
d0f8b3e
Wire canonical Symfony Mailer services and aliases
azine Aug 11, 2026
ff5b9d6
Wire Symfony Mailer services and compatibility aliases
azine Aug 11, 2026
0a048af
Declare Symfony 7.4, PHP 8.5 and runtime extensions
azine Aug 11, 2026
97ac535
Test PHP 8.5 against stable and lowest dependencies
azine Aug 11, 2026
1dd3ec7
Test Symfony Mailer while preserving legacy service API
azine Aug 11, 2026
351c06f
Remove obsolete Swiftmailer spool command
azine Aug 11, 2026
5422cf6
Remove obsolete Swiftmailer spool command tests
azine Aug 11, 2026
3c41328
Remove obsolete Swiftmailer spool command service
azine Aug 11, 2026
7e65daa
Modernize web-view retention command for Symfony 7
azine Aug 11, 2026
6e137b9
Inject retention command dependencies
azine Aug 11, 2026
c540575
Modernize web-view retention command tests
azine Aug 11, 2026
e7ca2f9
Type the notifier service contract
azine Aug 11, 2026
03268cb
Preserve notifier extension compatibility during Symfony upgrade
azine Aug 11, 2026
d226e8e
Modernize newsletter command dependencies and locking
azine Aug 11, 2026
54fc050
Modernize notification command dependencies and locking
azine Aug 11, 2026
7a76d5a
Wire notifier commands with filesystem locks
azine Aug 11, 2026
d20d385
Modernize newsletter command tests
azine Aug 11, 2026
af92aa8
Modernize notification command tests
azine Aug 11, 2026
63e630b
Remove obsolete command test helper
azine Aug 11, 2026
be3d525
Type the recipient provider contract
azine Aug 11, 2026
04cceb9
Modernize Doctrine recipient queries
azine Aug 11, 2026
86e263e
Modernize recipient provider tests for Doctrine ORM 3
azine Aug 11, 2026
85d35fe
Modernize web-view service tests
azine Aug 11, 2026
6390678
Add narrow Twig 3 compatibility aliases
azine Aug 11, 2026
2117303
Autoload narrow legacy Twig compatibility aliases
azine Aug 11, 2026
20db1d7
Make the query test double compatible with Doctrine ORM 3
azine Aug 11, 2026
0a7719e
Use Doctrine ORM 3 Query mocks in retention tests
azine Aug 11, 2026
9d5b472
Use Doctrine ORM 3 repository and query mocks
azine Aug 11, 2026
2c5ef52
Avoid notifier expectations in command metadata tests
azine Aug 11, 2026
76a813f
Avoid notifier expectations in command metadata tests
azine Aug 11, 2026
1e2019a
Modernize template provider tests for PHPUnit 12 and Symfony Mime
azine Aug 11, 2026
737eb59
Modernize EmailBundle dependency injection tests
azine Aug 11, 2026
b01446c
Correct EmailBundle DI parameter expectations
azine Aug 11, 2026
d5e1b5c
Extract HTTPS Postmark spam-score client
azine Aug 11, 2026
3539f3d
Expose configurable HTTPS spam-check endpoint
azine Aug 11, 2026
653ac3c
Configure the HTTPS spam-check service endpoint
azine Aug 11, 2026
7ddf25b
Add Symfony HttpClient for spam-score checks
azine Aug 11, 2026
99ec3ad
Align web-view service contract with existing override support
azine Aug 11, 2026
164d4d7
Migrate email preview controller to Symfony 7 and Symfony Mime
azine Aug 11, 2026
aed020f
Wire Symfony 7 email preview and spam-check services
azine Aug 11, 2026
edb40b4
Modernize EmailBundle route controller notation
azine Aug 11, 2026
b8c9e07
Test Symfony 7 email preview controller behavior
azine Aug 11, 2026
e0a85a7
Declare mailparse extension used by test-email address parsing
azine Aug 11, 2026
8201383
Install mailparse in PHP 8.5 CI
azine Aug 11, 2026
0030e93
Test HTTPS spam-score client behavior
azine Aug 11, 2026
bce2c88
Handle malformed spam-check responses deterministically
azine Aug 11, 2026
656d605
Modernize notifier service for Symfony 7 and Doctrine ORM 3
azine Aug 11, 2026
e0cd765
Replace legacy notifier tests with Symfony 7 and ORM 3 coverage
azine Aug 11, 2026
d6e0037
Fix Symfony user and recipient assertions in preview controller tests
azine Aug 11, 2026
8cbd53b
Test image embedding and web-view persistence with Symfony Mailer
azine Aug 11, 2026
2bc7cc2
Document Symfony Mailer and Symfony 7.4 migration
azine Aug 11, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 24 additions & 7 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,38 +4,55 @@ on:
push:
pull_request:

permissions:
contents: read

jobs:
tests:
name: PHP 8.5 / Symfony 7.4
name: "PHPUnit (PHP 8.5, deps: ${{ matrix.dependency-mode }})"
runs-on: ubuntu-latest
timeout-minutes: 20

strategy:
fail-fast: false
matrix:
dependency-mode: ['stable', 'lowest']

env:
MAILER_DSN: 'null://null'

steps:
- name: Checkout
uses: actions/checkout@v4
uses: actions/checkout@v6

- name: Setup PHP
uses: shivammathur/setup-php@v2
with:
php-version: '8.5'
coverage: none
extensions: mbstring, xml, ctype, iconv, intl, dom, json, pdo, pdo_sqlite
extensions: ctype, dom, fileinfo, filter, gd, iconv, intl, json, mailparse, mbstring, pdo, pdo_sqlite, simplexml, tokenizer, xml, xmlwriter
tools: composer:v2

- name: Cache Composer
uses: actions/cache@v4
uses: actions/cache@v5
with:
path: |
~/.composer/cache/files
~/.cache/composer/files
key: composer-${{ runner.os }}-${{ hashFiles('**/composer.json') }}
restore-keys: composer-${{ runner.os }}-
key: composer-${{ runner.os }}-php85-${{ matrix.dependency-mode }}-${{ hashFiles('composer.json') }}
restore-keys: |
composer-${{ runner.os }}-php85-${{ matrix.dependency-mode }}-

- name: Validate composer.json
run: composer validate --strict --no-check-publish

- name: Install dependencies
- name: Install dependencies (stable)
if: matrix.dependency-mode == 'stable'
run: composer update --prefer-dist --no-interaction

- name: Install dependencies (lowest)
if: matrix.dependency-mode == 'lowest'
run: composer update --prefer-lowest --prefer-stable --prefer-dist --no-interaction

- name: Run test suite
run: vendor/bin/phpunit -c phpunit.xml.dist
137 changes: 0 additions & 137 deletions Command/ClearAndLogFailedMailsCommand.php

This file was deleted.

108 changes: 46 additions & 62 deletions Command/RemoveOldWebViewEmailsCommand.php
Original file line number Diff line number Diff line change
@@ -1,91 +1,75 @@
<?php

declare(strict_types=1);

namespace Azine\EmailBundle\Command;

use Azine\EmailBundle\Entity\SentEmail;
use Doctrine\Persistence\ManagerRegistry;
use Symfony\Component\Console\Attribute\AsCommand;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;

/**
* Remove emails stored for web-view that are older than the configured time.
*
* @author dominik
*/
#[AsCommand(
name: 'emails:remove-old-web-view-emails',
description: 'Remove stored email web views older than the configured retention period.',
)]
class RemoveOldWebViewEmailsCommand extends Command
{
/** @var ContainerInterface|null */
private $container;

public function setContainer(?ContainerInterface $container = null): ?ContainerInterface
{
$previous = $this->container;
$this->container = $container;

return $previous;
public function __construct(
private readonly ManagerRegistry $managerRegistry,
private readonly int $retentionDays,
) {
parent::__construct();
}

protected function getContainer(): ContainerInterface
{
if (null === $this->container) {
throw new \LogicException('Container has not been set.');
}

return $this->container;
}

/**
* (non-PHPdoc).
*
* @see Symfony\Component\Console\Command.Command::configure()
*/
protected function configure(): void
{
$this->setName('emails:remove-old-web-view-emails')
->setDescription('Remove all "SentEmail" from the database that are older than the configured time.')
->setDefinition(array(new InputArgument('keep', InputArgument::OPTIONAL, 'Remove all SentEmails older than "keep" days => also see azine_email_web_view_retention_time ')))
->setHelp(<<<EOF
The <info>emails:remove-old-web-view-emails</info> command deletes all SentEmail entities from the database
that are older than the number of days specified in the command-line parameter "keep" or configured in the
parameter "azine_email_web_view_retention" in your config.yml.
EOF
)
;
$this
->addArgument(
'keep',
InputArgument::OPTIONAL,
'Remove stored emails older than this number of days.',
)
->setHelp(<<<'HELP'
The <info>emails:remove-old-web-view-emails</info> command deletes SentEmail entities older than
"keep" days. When the argument is omitted, azine_email.web_view_retention is used.
HELP
);
}

/**
* (non-PHPdoc).
*
* @see Symfony\Component\Console\Command.Command::execute()
*/
protected function execute(InputInterface $input, OutputInterface $output): int
{
// get the number of days from the command-line-input
$days = $input->getArgument('keep');
$argument = $input->getArgument('keep');
$days = is_numeric($argument) ? (int) $argument : $this->retentionDays;

// or if it is not given, from the config.yml
if (!is_numeric($days)) {
$days = $this->getContainer()->getParameter('azine_email_web_view_retention');
$output->writeln("using the parameter from the configuration => '$days' days.");
}
if ($days < 1) {
$output->writeln('<error>The web-view retention period must be at least one day.</error>');

if (null === $days) {
$output->writeln('either the commandline parameter "keep" or the "azine_email_web_view_retention" in your config.yml or the default-config has to be defined.');
return Command::INVALID;
}

return Command::SUCCESS;
if (!is_numeric($argument)) {
$output->writeln(sprintf('Using the configured retention period: %d days.', $days));
}

// delete all SentEmails older than $date from the database
$date = new \DateTime("$days days ago");
$sentEmails = $this->getContainer()->get('doctrine')->getManager()->createQueryBuilder()
->delete('AzineEmailBundle:SentEmail', 's')
$cutoff = new \DateTimeImmutable(sprintf('-%d days', $days));
$deleted = $this->managerRegistry
->getManager()
->createQueryBuilder()
->delete(SentEmail::class, 's')
->where('s.sent < :sent')
->setParameter('sent', $date);
$q = $sentEmails->getQuery();
$result = $q->execute();
->setParameter('sent', $cutoff)
->getQuery()
->execute();

$output->writeln($result.' SentEmails have been deleted that were older than '.$date->format('Y-m-d H:i:s'));
$output->writeln(sprintf(
'%d SentEmails older than %s were deleted.',
(int) $deleted,
$cutoff->format('Y-m-d H:i:s'),
));

return Command::SUCCESS;
}
Expand Down
Loading
Loading