beecubu/php-foundation-emailer
最新稳定版本:v2.4.0
Composer 安装命令:
composer require beecubu/php-foundation-emailer
包简介
PHP Object Foundation Framework Emailer library for SMTP, EWS and Microsoft Graph
README 文档
README
PHP Object Foundation Emailer with SMTP, Microsoft Exchange Web Services (EWS) and Microsoft Graph API support. It includes:
- A unified
Emailsender for SMTP, EWS or Microsoft Graph. - A database-agnostic email queue system.
- Helpers for attachments and queued processing.
This package is database-agnostic: it defines the queue interface but does not include any persistence implementation. Use a persistence plugin to provide a concrete queue backend:
beecubu/php-foundation-emailer-mongodb— MongoDB backend.beecubu/php-foundation-emailer-sqlite— SQLite backend.
Requirements
- PHP 7.1+
ext-json,ext-curlbeecubu/php-foundation-coresymfony/mailer5.4php-ews/php-ews(via the configured VCS repo)
Installation
composer require beecubu/php-foundation-emailer
# Plus a persistence plugin (choose one):
composer require beecubu/php-foundation-emailer-mongodb
# or
composer require beecubu/php-foundation-emailer-sqlite
Basic SMTP Example
<?php
use Beecubu\Foundation\Emailer\Entities\Email\Email;
use Beecubu\Foundation\Emailer\Entities\EmailConfig\EmailConfig;
use Beecubu\Foundation\Emailer\Entities\EmailConfig\EmailConfigService;
$config = new EmailConfig();
$config->service = EmailConfigService::SMTP;
$config->from = 'no-reply@example.com';
$config->fromName = 'Example App';
$config->server = 'smtp.example.com';
$config->port = 587;
$config->userName = 'smtp-user';
$config->password = 'smtp-pass';
$config->verifyPeer = true;
$mailer = Email::emailWithEmailConfig($config);
$mailer->send(
'owner-1',
'user@example.com',
'User Name',
'Welcome',
'<p>Hello!</p>',
false
);
EWS Example
<?php
use Beecubu\Foundation\Emailer\Entities\Email\Email;
use Beecubu\Foundation\Emailer\Entities\EmailConfig\EmailConfig;
use Beecubu\Foundation\Emailer\Entities\EmailConfig\EmailConfigService;
use Beecubu\Foundation\Emailer\Entities\EmailConfig\EmailEWSVersion;
$config = new EmailConfig();
$config->service = EmailConfigService::EWS;
// You can use either the bare host or the full Exchange endpoint URL.
$config->server = 'https://exchange.example.com/EWS/Exchange.asmx';
$config->userName = 'user@example.com';
$config->password = 'password';
$config->version = EmailEWSVersion::VERSION_2010;
$config->verifyPeer = false;
$mailer = Email::emailWithEmailConfig($config);
$mailer->send(
'owner-1',
'user@example.com',
'User Name',
'EWS Test',
'<p>Sent via EWS</p>',
false
);
The server field accepts any of these formats — all are normalized internally:
exchange.example.comexchange.example.com/EWS/Exchange.asmxhttps://exchange.example.com/EWS/Exchange.asmx
SMTP Options
SMTP supports explicit overrides, but the recommended configuration is to let Symfony resolve them automatically.
<?php
use Beecubu\Foundation\Emailer\Entities\EmailConfig\EmailConfigAuth;
use Beecubu\Foundation\Emailer\Entities\EmailConfig\EmailConfigEncryption;
$config->authMode = EmailConfigAuth::AUTO;
$config->encryption = EmailConfigEncryption::Encryption_Auto;
$config->verifyPeer = true;
Available options:
EmailConfigAuth::AUTO: recommended, delegates authentication negotiation to Symfony.EmailConfigAuth::NONE("None"): disables SMTP credentials. When using this mode,userNameandpasswordare not required.EmailConfigAuth::PLAIN,LOGIN,CRAM_MD5: accepted for configuration compatibility, but the framework now prioritizes Symfony's automatic negotiation for forward compatibility.EmailConfigEncryption::Encryption_Auto: recommended, delegates TLS behavior to Symfony.EmailConfigEncryption::Encryption_TLS: forces SMTP with STARTTLS-style negotiation.EmailConfigEncryption::Encryption_SSL: forces implicit SMTPS.EmailConfigEncryption::Encryption_None: disables TLS at transport construction time.
Microsoft Graph Example
Microsoft Graph is the modern Microsoft API for Office 365 / Exchange Online. Authentication uses OAuth 2.0 client credentials (app-only), which means no user interaction is required — the application authenticates directly with Azure AD using a tenantId, clientId and clientSecret.
1) Register an Azure AD application
- Go to Azure Portal → Azure Active Directory → App registrations → New registration.
- Give it a name (e.g.
MyApp Emailer) and register it. - Go to API permissions → Add a permission → Microsoft Graph → Application permissions.
- Add
Mail.Send. - Click Grant admin consent (required for application permissions).
- Go to Certificates & secrets → New client secret. Copy the secret value immediately.
- Note the Application (client) ID and the Directory (tenant) ID from the Overview page.
2) Configure and send
<?php
use Beecubu\Foundation\Emailer\Entities\Email\Email;
use Beecubu\Foundation\Emailer\Entities\EmailConfig\EmailConfig;
use Beecubu\Foundation\Emailer\Entities\EmailConfig\EmailConfigService;
$config = new EmailConfig();
$config->service = EmailConfigService::GRAPH;
$config->from = 'no-reply@yourdomain.com'; // must be a mailbox in your tenant
$config->fromName = 'Example App';
$config->tenantId = 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx';
$config->clientId = 'yyyyyyyy-yyyy-yyyy-yyyy-yyyyyyyyyyyy';
$config->clientSecret = 'your-client-secret';
$config->verifyPeer = true;
$mailer = Email::emailWithEmailConfig($config);
$mailer->send(
'owner-1',
'user@example.com',
'User Name',
'Graph Test',
'<p>Sent via Microsoft Graph</p>',
false
);
How it works internally
- On the first send,
Graphrequests an access token fromhttps://login.microsoftonline.com/{tenantId}/oauth2/v2.0/tokenusing the client credentials grant. - The token is cached in memory until 60 seconds before its expiry (typically 1 hour), so subsequent sends within the same process reuse it.
- The email is sent via
POST https://graph.microsoft.com/v1.0/users/{from}/sendMail. - On failure, an
EmailGraphSendingErrorexception is thrown with the error message returned by the API.
Note: The
fromaddress must be a valid mailbox within your Azure AD tenant. The registered application needs theMail.Sendapplication permission (not delegated) for this flow to work without a signed-in user.
Verification Model
EmailConfig now separates two different concerns:
sendingVerified: confirms that the technical delivery configuration has passed a functional send test.ownershipVerified: confirms that the mailbox infromhas been validated by a verification token.
Related internal fields:
sendingVerification: hash used to detect delivery-related configuration changes.ownershipVerification: token tied to thefrommailbox ownership.
Behavior:
- Changing SMTP / EWS / Graph technical settings invalidates
sendingVerified. - Changing
frominvalidatesownershipVerified. verifySending()marks the config as delivery-verified.verifyOwnershipToken($token)validates mailbox ownership.
Attachments
use Beecubu\Foundation\Emailer\Entities\Email\EmailAttachment;
$attachments = [
EmailAttachment::create('report.pdf', $pdfBinary, 'application/pdf'),
];
$mailer->send(
'owner-1',
'user@example.com',
'User Name',
'Report',
'<p>Attached.</p>',
false,
$attachments
);
Attachments work the same way across all three transports (SMTP, EWS, Graph).
Queueing Emails
When $queue = true, emails are stored in the configured persistence backend and can be sent later.
1) Initialize persistence
Before queuing any emails, register a persistence backend using the plugin's bootstrap:
// MongoDB
use Beecubu\Foundation\Emailer\MongoDB\RepositoryBootstrap;
RepositoryBootstrap::register();
// or SQLite
use Beecubu\Foundation\Emailer\SQLite\RepositoryBootstrap;
RepositoryBootstrap::register();
2) Queue an email
$mailer->send(
'owner-1',
'user@example.com',
'User Name',
'Queued Email',
'<p>This will be queued.</p>',
true
);
3) Processing the Queue
Extend EmailQueueSender to provide a config for each queued item:
<?php
use Beecubu\Foundation\Emailer\Entities\EmailQueueItem\EmailQueueSender;
use Beecubu\Foundation\Emailer\Entities\EmailQueueItem\EmailQueueItem;
use Beecubu\Foundation\Emailer\Entities\EmailConfig\EmailConfig;
class MyQueueSender extends EmailQueueSender
{
protected static function getEmailConfigByItem(EmailQueueItem $item): ?EmailConfig
{
// Resolve the EmailConfig for this ownerId.
// Return null if it does not exist.
return MyEmailConfigRepo::findByOwnerId($item->ownerId);
}
}
// Silent (default is verbose)
MyQueueSender::execute();
// With console logs
MyQueueSender::execute(verbose: true);
When $verbose is enabled, each email processed prints:
- Before sending: recipient, subject and owner ID.
- On success: confirmation line.
- On error: the error message.
The queue will:
- Fetch the next email in
waitingstate. - Mark it as
sendingto avoid duplicates across concurrent workers. - Send it via the configured transport (SMTP, EWS or Graph).
- Remove it from the queue on success.
- Mark it as
erroron failure and store: error: a short error message.errorDebug: a technical debug log with transport-specific details when available.
Architecture
php-foundation-emailer (core, DB-agnostic)
↑ implemented by
php-foundation-emailer-mongodb (MongoDB plugin)
php-foundation-emailer-sqlite (SQLite plugin)
The core package defines IEmailQueueRepository and EmailQueueProvider. Plugins provide concrete implementations and register them via RepositoryBootstrap::register().
Notes
- For SMTP, this package uses Symfony Mailer.
- For EWS, it uses
php-ews/php-ews(on-premise Exchange). - For Microsoft Graph, it uses the Graph REST API directly via
ext-curl(no extra SDK required). This is the recommended approach for Office 365 / Exchange Online. - On queued failures, SMTP stores Symfony transport debug output, Graph stores endpoint/HTTP/API diagnostic context, and EWS stores request/response metadata in
errorDebug.
统计信息
- 总下载量: 55
- 月度下载量: 0
- 日度下载量: 0
- 收藏数: 0
- 点击次数: 1
- 依赖项目数: 2
- 推荐数: 0
其他信息
- 授权协议: MIT
- 更新时间: 2023-11-16