Download the PHP package hampel/sparkpost-transport without Composer

On this page you can find all versions of the php package hampel/sparkpost-transport. It is possible to download/install these versions without Composer. Possible dependencies are resolved automatically.

FAQ

After the download, you have to make one include require_once('vendor/autoload.php');. After that you have to import the classes with use statements.

Example:
If you use only one package a project is not needed. But if you use more then one package, without a project it is not possible to import the classes with use statements.

In general, it is recommended to use always a project to download your libraries. In an application normally there is more than one library needed.
Some PHP packages are not free to download and because of that hosted in private repositories. In this case some credentials are needed to access such packages. Please use the auth.json textarea to insert credentials, if a package is coming from a private repository. You can look here for more information.

  • Some hosting areas are not accessible by a terminal or SSH. Then it is not possible to use Composer.
  • To use Composer is sometimes complicated. Especially for beginners.
  • Composer needs much resources. Sometimes they are not available on a simple webspace.
  • If you are using private repositories you don't need to share your credentials. You can set up everything on our site and then you provide a simple download link to your team member.
  • Simplify your Composer build process. Use our own command line tool to download the vendor folder as binary. This makes your build process faster and you don't need to expose your credentials for private repositories.
Please rate this library. Is it a good library?

Informations about the package sparkpost-transport

SparkPost transport for Symfony Mailer

Tests Latest Version on Packagist Total Downloads Open Issues License

Sends Symfony Mailer messages through the SparkPost transmissions API, using hampel/sparkpost to do the talking.

By Simon Hampel

Installation

You also need a PSR-18 HTTP client and a PSR-17 factory, because the API client takes whatever your application already has. Guzzle 7 provides both:

Usage

HTTP 200 is not a successful send

SparkPost answers 200 having accepted zero recipients — a suppressed address, an invalid one. A transport that reads only the status code reports that as a successful send. Here it is a failure:

Everything that leaves the transport implements Symfony's TransportExceptionInterface, including API errors and connection failures, so the one catch a Symfony consumer already writes is enough.

The original exception is kept as previous, not flattened into a message. SparkPost returns a structured errors array and hampel/sparkpost carries it decoded, so an application that wants to show what the API objected to — an admin screen, a diagnostics page — reads the fields rather than parsing them back out of a string:

This is a supported contract and will not be removed in a 1.x release.

The container is promised; the contents are not, and the line between them is hampel/sparkpost's rather than this package's. $errors is public readonly on every ApiException subclass and is always a list of arrays — empty when the response carried no errors, and empty when the body was not JSON at all, which happens when a proxy answers on that URL with HTML. It is never null, so no guard is needed beyond the instanceof. The keys inside each error are SparkPost's payload, passed through unreshaped: if SparkPost renames a field, neither package will notice and neither will issue a major for it. Hence ?? above rather than a bare index.

ApiException is abstract; the concrete throw is ClientException, RateLimitException or ServerException, so the one instanceof covers all three and keeps working if a fourth appears.

The SparkPost transmission id is recorded as the message id. Mailer::send() returns void, so the SentMessage carrying it comes from the transport:

The transport dispatches the same events the mailer does. It returns null only when a listener rejected the message before it was sent.

SparkPost-specific fields

Campaigns, metadata and substitution data are transmission-level concepts with no MIME equivalent, so there is nowhere in a plain Email to put them. Use SparkPostEmail:

It is a plain Email in every other respect, and it survives serialisation — so a message queued through Symfony Messenger arrives at the worker with all of the above intact.

Stored templates and A/B tests replace the message body entirely. The message still needs a From and a To, because the envelope is built from them:

Options for every message

Campaigns and metadata are per-message, but tracking and transactional are usually a decision an application makes once. EmailConverter takes defaults for them, applied to every message the transport sends — including a plain Email, which matters when the messages are built by a framework that has never heard of SparkPostEmail:

Anything the message itself carries wins, so a single SparkPostEmail can still turn tracking back on without disturbing the default.

The bounce address

SparkPost's return_path is the envelope sender: where a bounce is delivered, and the domain a receiver runs SPF against. It is a different thing from the From: a reader sees, and the difference is what DMARC alignment is about.

Set it the ordinary Symfony way and it is used:

Nothing is sent when you set nothing: the transport only populates return_path when the envelope sender actually differs from the From:, so a message nobody configured a bounce address for is left to SparkPost's own defaults.

SparkPostEmail::setSparkPostReturnPath() sets the same field and wins over the envelope, for when a single message needs a different bounce address.

What SparkPost then does with it

None of this is visible from inside this package — it is SparkPost's behaviour, and it depends on how the account is configured, so it can only be established by operating one. The following was measured against a live account rather than read from documentation:

Setting one is worth doing, and it has to be chosen with the From:

A custom bounce domain is usually presented as being about where bounces are collected. The larger reason is authentication. SPF authenticates the Return-Path domain, and DMARC passes on the strength of SPF only when that domain aligns with the From: — so every fallback above authenticates correctly, aligns with nothing, and leaves DMARC resting on DKIM alone.

That is one failure away from rejection rather than two. An aligned bounce domain is not belt-and-braces: it is the second of two independent routes to a DMARC pass. Without one the message rests entirely on DKIM alignment, so a DKIM problem becomes an outage rather than a degradation — and a receiver enforcing DMARC refuses a message SparkPost sent perfectly well, with nothing on the sending side to show that it did.

Alignment is a relationship between the two domains, not a property of either. Relaxed alignment needs the same organisational domain, strict needs the identical one:

Return-Path From: aligns
<id>@example.com [email protected] strict, and relaxed
<id>@bounce.example.com [email protected] relaxed
<id>@bounce.example.net [email protected] neither

The last row is configured, valid, delivered — and has bought nothing. So the bounce domain and the From: are chosen together: change either alone and everything keeps working, mail keeps arriving, and the second DMARC path disappears with nothing to show for it.

Unset is a working configuration rather than a recommended one. An application with a bounce domain available on the account should set it, and should pick one that aligns.

Cc, Bcc, and what the recipient sees

SparkPost sends one message per recipient, so a naive transport gives every recipient a To: line containing only themselves, and loses Cc entirely. This one does what ordinary mail does: every recipient gets the same To: line, Cc is made visible with a CC header, and Bcc gets no header at all — which is what makes it blind.

Testing against the sink

SparkPost accepts, counts and discards anything at <address>.sink.sparkpostmail.com, so a staging site can exercise real sending, including bounce and delivery events, without mail reaching anyone:

The dispatcher has to reach the transport, which is what invokes the listener. A listener added to a dispatcher the transport never received does nothing, and the mail is delivered normally.

It rewrites the envelope and leaves the headers alone, so the delivered message still reads as though it were addressed normally.

Symfony versions

^5.4|^6.4|^7.0, and the suite runs against all three. 5.4 is included deliberately: this package is used inside host applications that bundle Symfony themselves at 5.4 and load their own copy first, so a consumer there cannot substitute a newer one.

Licence

MIT. See LICENSE.md.


All versions of sparkpost-transport with dependencies

PHP Build Version
Package Version
Requires php Version >=8.3
hampel/sparkpost Version ^1.0
psr/event-dispatcher Version ^1
psr/log Version ^1|^2|^3
symfony/event-dispatcher Version ^5.4|^6.4|^7.0
symfony/mailer Version ^5.4|^6.4|^7.0
symfony/mime Version ^5.4|^6.4|^7.0
Composer command for our command line client (download client) This client runs in each environment. You don't need a specific PHP version etc. The first 20 API calls are free. Standard composer command

The package hampel/sparkpost-transport contains the following files

Loading the files please wait ...