定制 beecubu/php-foundation-emailer 二次开发

按需修改功能、优化性能、对接业务系统,提供一站式技术支持

邮箱:yvsm@zunyunkeji.com | QQ:316430983 | 微信:yvsm316

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 Email sender 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:

Requirements

  • PHP 7.1+
  • ext-json, ext-curl
  • beecubu/php-foundation-core
  • symfony/mailer 5.4
  • php-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.com
  • exchange.example.com/EWS/Exchange.asmx
  • https://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, userName and password are 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

  1. Go to Azure PortalAzure Active DirectoryApp registrationsNew registration.
  2. Give it a name (e.g. MyApp Emailer) and register it.
  3. Go to API permissionsAdd a permissionMicrosoft GraphApplication permissions.
  4. Add Mail.Send.
  5. Click Grant admin consent (required for application permissions).
  6. Go to Certificates & secretsNew client secret. Copy the secret value immediately.
  7. 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

  1. On the first send, Graph requests an access token from https://login.microsoftonline.com/{tenantId}/oauth2/v2.0/token using the client credentials grant.
  2. The token is cached in memory until 60 seconds before its expiry (typically 1 hour), so subsequent sends within the same process reuse it.
  3. The email is sent via POST https://graph.microsoft.com/v1.0/users/{from}/sendMail.
  4. On failure, an EmailGraphSendingError exception is thrown with the error message returned by the API.

Note: The from address must be a valid mailbox within your Azure AD tenant. The registered application needs the Mail.Send application 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 in from has been validated by a verification token.

Related internal fields:

  • sendingVerification: hash used to detect delivery-related configuration changes.
  • ownershipVerification: token tied to the from mailbox ownership.

Behavior:

  • Changing SMTP / EWS / Graph technical settings invalidates sendingVerified.
  • Changing from invalidates ownershipVerified.
  • 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 waiting state.
  • Mark it as sending to 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 error on 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

GitHub 信息

  • Stars: 0
  • Watchers: 0
  • Forks: 0
  • 开发语言: PHP

其他信息

  • 授权协议: MIT
  • 更新时间: 2023-11-16

承接程序开发

PHP开发

VUE

Vue开发

前端开发

小程序开发

公众号开发

系统定制

数据库设计

云部署

网站建设

安全加固