webservco / mail
A PHP component/library. Saves outgoing emails in a database table and sends them later from a scheduled job using PHPMailer.
Requires
- php: ^8.4
- phpmailer/phpmailer: ^6
- psr/log: ^3
- webservco/command: ^2
- webservco/configuration: ^2
- webservco/data: ^2
- webservco/database: ^2
Requires (Dev)
- pds/skeleton: ^1
- phan/phan: ^6
- php-parallel-lint/php-console-highlighter: ^1
- php-parallel-lint/php-parallel-lint: ^1
- phpmd/phpmd: ^3
- phpstan/phpstan: ^2
- phpstan/phpstan-deprecation-rules: ^2
- phpstan/phpstan-phpunit: ^2
- phpstan/phpstan-strict-rules: ^2
- phpunit/phpunit: ^13
- slevomat/coding-standard: ^8
- squizlabs/php_codesniffer: ^4
- vimeo/psalm: ^6
- webservco/coding-standards: ^2
- webservco/component-common: ^2
Suggests
None
Provides
None
Conflicts
None
Replaces
None
README
A PHP component/library. Please see webservco/sandbox for an example project using these types of components.
Saves outgoing emails in a database table and sends them later from a scheduled job using PHPMailer.
- Requires: the
mailingtable (structure), a PDO container fromwebservco/database - Related:
webservco/command(the sending job runs as a command and reports what it processed)
Installation
composer require webservco/mail
Usage
Add an email to the queue
use WebServCo\Mail\DataTransfer\MailItem; use WebServCo\Mail\Service\MailingTableNameServiceFromConfig; use WebServCo\Mail\Service\Storage\MailItemStorage; // \WebServCo\Mail\Contract\Service\MailingTableNameServiceInterface $tableNameService = new MailingTableNameServiceFromConfig($configurationGetter); // \WebServCo\Mail\Contract\Service\Storage\MailItemStorageInterface $mailItemStorage = new MailItemStorage($tableNameService, $pdoContainer); $mailItemId = $mailItemStorage->storeMailItem( // subject, HTML message, to, cc, bcc new MailItem('Your order', '<p>Thank you.</p>', 'client@example.com', null, 'shop@example.com'), );
Send the queue
Run this from a command on a schedule (cron).
// \WebServCo\Mail\Contract\Factory\MailingProcessorFactoryInterface (your factory) $mailingProcessor = $mailingProcessorFactory->createMailingProcessor($tableNameService); $mailingProcessor->process(); // \WebServCo\Command\Contract\ItemsProcessingReportInterface $report = $mailingProcessor->getItemsProcessingReport(); $output->write(sprintf('Sent %d of %d.', $report->getTotalProcessed(), $report->getTotalItems()));
Your factory creates Service\Processor\MailingProcessor with a report, a logger, MailItemEntityStorage, MailItemStorage, a pause in seconds between emails, and a configured PHPMailer (SMTP settings and sender).
Contracts
| Interface | Implementation | Purpose |
|---|---|---|
Contract\Service\Storage\MailItemStorageInterface |
Service\Storage\MailItemStorage |
Adds emails and marks them as sent or failed. |
Contract\Service\Storage\MailItemEntityStorageInterface |
Service\Storage\MailItemEntityStorage |
Iterates emails that haven't been sent. |
Contract\Processor\MailingProcessorInterface |
Service\Processor\MailingProcessor |
Sends each unsent email and counts the results. |
Contract\Service\MailingTableNameServiceInterface |
Service\MailingTableNameServiceFromConfig |
Table name, from the configuration. |
Contract\Factory\MailingProcessorFactoryInterface |
your factory | Creates the processor. |
Contract\Factory\PHPMailerFactoryInterface |
your factory | Creates a configured PHPMailer. |
Namespaces are relative to WebServCo\Mail\.
Configuration
The table can have any name.
[Mail] MAILING_TABLE_NAME = mailing
Notes
Messages are sent as HTML. to takes exactly one address, while cc and bcc take several, separated by commas.
When sending fails, the error goes into error_message and the email stays unsent. The next run tries it again, and the one after that, with no limit. Check the error column now and then for addresses that will never work.
The processor clears PHPMailer's recipients after each email.
Development
# Start project. ddev start # Install dependencies. ddev c u # Run all validations. ddev c c # Run unit tests. ddev c test:dox