Download the PHP package rlnks/php-mail-audit without Composer

On this page you can find all versions of the php package rlnks/php-mail-audit. 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 php-mail-audit

php-mail-audit

Email HTML quality analysis engine for PHP.

Analyze email templates before sending — detect compatibility issues, score your HTML against major email clients, and get actionable insights to fix problems before they reach your users' inboxes.

"Grammarly for HTML emails"

PHP


Table of Contents


Requirements


Installation


Quick Start

Example output:


Configuration

All configuration is optional. The package works out of the box with the bundled rule set.

Config reference

Key Type Default Description
auto_update bool false Enable remote KB fetch
ttl_days int 7 Days before cache is considered stale
endpoint string\|null null Remote URL to fetch rules from
api_key string\|null null Bearer token sent in Authorization header
cache_path string\|null null Absolute path to the local cache file

Config file pattern


Analyzing HTML

Pass the raw HTML string of the email template. The HTML does not need to be a complete document — partials and fragments are accepted.


Result Format

analyze() returns an array with four keys:

score

An integer between 0 and 100. Higher is better. See Score Calculation.

insights

Each triggered rule produces one insight:

Each location entry points to one occurrence of the issue in the source HTML:

Field Type Description
line int Line number (1-based)
column int Column within that line (1-based)
offset_start int Byte offset of the match start in the HTML string
offset_end int Byte offset of the match end (exclusive)

This is designed for editor integration — use offset_start/offset_end with CodeMirror or Monaco Range objects to highlight the exact positions, and line/column to scroll and place the cursor.

When multiple locales are requested, message and fix are associative arrays keyed by locale instead of strings:

passed

Rules that did not trigger and carry a success_message appear here — useful for showing positive feedback alongside issues (similar to htmlemailcheck.com):

Not every rule generates a passed item — only rules that define a success_message in their JSON (those where the absence of an issue is meaningfully good news).

summary


Bundled Rules

56 rules ship with the package. The philosophy: flag bad usage, not feature presence. Media queries, hover states, and class selectors used correctly (with inline fallbacks) score well. The engine penalizes the absence of fallbacks, not the features themselves.

Errors — break rendering in major clients

Rule ID Description Weight
no-flexbox CSS display: flex not supported in Outlook 15
no-grid CSS display: grid not supported anywhere 15
no-form-elements <form>, <input>, <button> stripped by all clients 15
no-script <script> stripped by all clients for security reasons 15
no-iframe <iframe> blocked by all clients 15
no-svg SVG not rendered in Outlook or Gmail 12
no-video <video> not supported in Outlook or Gmail 12
no-audio <audio> not supported in any major client 10
no-css-gap CSS gap / row-gap / column-gap not supported anywhere 9
no-object-fit object-fit not supported in any major client 8
no-css-filter CSS filter not supported in Outlook or Gmail 8
no-clip-path clip-path not supported in any major client 8
no-css-variables CSS var() used without a fallback value — Outlook and Gmail silently ignore the property entirely 7

Warnings — real problems when fallbacks are missing

Rule ID Description Weight
style-no-inline-fallback <style> block present but zero inline styles — layout breaks entirely when Gmail/Outlook strip the style block 12
html-too-large HTML exceeds 102 KB — Gmail clips the message and shows a "Message clipped" link 10
media-no-inline-base @media queries present but no inline style baseline — responsive layout has no fallback for Gmail/Outlook 10
img-dimensions <img> without width/height — layout breaks when images are blocked 8
no-float float breaks column layouts in Outlook 2007–2019 8
font-no-fallback External font loaded but no inline font-family fallback stack — text falls back to client default when font is stripped 8
no-picture <picture> / srcset not supported in Outlook or Gmail 8
missing-alt-img <img> without alt shows broken icons when images blocked 7
no-css-calc calc() not supported in Outlook 2007–2019 or Gmail 7
missing-https HTTP (non-HTTPS) src/href detected — email clients block mixed content, breaking images and links 6
no-div-layout <div> with layout CSS (width, float, margin, etc.) — box model ignored by Outlook 6
no-animation CSS animation / @keyframes ignored by Outlook and Gmail 6
url-unencoded Unencoded space in a URL (href or src) — breaks the link in all clients 5
css-at-import @import in <style> silently ignored by Gmail/Outlook 5
no-transform CSS transform not supported in Outlook or Gmail 5
css-at-import-no-link @import in <style> with no <link> fallback — font will not load in clients that strip <style> blocks 5
link-no-text <a> with no accessible text or descriptive image alt — screen readers announce it as an unlabeled link 5
text-image-ratio Email is mostly images with very little readable text — high spam filter risk, renders blank when images are blocked 6
email-max-width Fixed-width <table> over 600 px — overflows the Outlook rendering pane and narrow viewports 5

Info — usage noted, minimal score impact

Rules in this category flag the presence of a feature that is often used correctly as progressive enhancement. They fire when the feature is detected, regardless of fallback quality — the corresponding warning-level rules handle the bad cases.

Rule ID Description Weight
no-position-absolute position: absolute/fixed ignored in most clients 5
no-border-radius border-radius ignored by Outlook desktop 4
no-box-shadow box-shadow not supported in Outlook 3
no-transition CSS transition not supported in Outlook or Gmail 3
table-role-presentation Layout tables without role="presentation" confuse screen readers 3
preheader-missing No preheader div found — inbox preview will show unrelated body text 3
inline-css <style> block present — acceptable when inline fallback styles are defined 2
css-class-selectors Class-based CSS in <style> — Gmail strips class attributes 2
css-media-queries @media queries detected — great when paired with inline styles 2
no-external-fonts External font loaded — supported in Apple Mail, not Gmail/Outlook 2
missing-lang <html> without lang attribute — screen readers and translation tools rely on it 2
missing-viewport No <meta name="viewport"> — mobile clients may render at desktop width 2
preheader-too-long Preheader text exceeds 150 characters (filler excluded) — most clients truncate at 85–150 chars 2
css-pseudo-selectors :hover, :focus etc. detected — ignored in Outlook/Gmail, use as enhancement only 1
div-content <div> used as content wrapper — acceptable, but <td> preferred for compatibility 1
empty-alt-img <img alt=""> detected — verify image is truly decorative and carries no information 1
nbsp-missing Regular space between a number and a currency/unit symbol — may break across lines on narrow screens 1
heading-order Heading levels skipped (e.g. <h1> directly followed by <h3>) — hurts accessibility and screen reader navigation 2
tracking-pixel 1×1 tracking pixel detected — note that Apple Mail Privacy Protection may trigger false open events 0
font-family-unquoted Multi-word font name used without quotes in font-family — may be misinterpreted by some CSS parsers 2
missing-charset No character encoding declaration in <head> — some clients may misrender special characters 2
missing-doctype No <!DOCTYPE html> declaration — some clients fall back to quirks mode rendering 2
table-cellspacing <table> without cellpadding="0" cellspacing="0" — default cell spacing varies across clients 2
missing-body-bgcolor No background color on <body> — some clients display a grey or off-white default background 1

Detection Types

Every rule declares a detection object that specifies how the engine finds the issue. All detectors return exact character positions (line, column, byte offsets) for every match — see locations in the result format.

css_property

Matches CSS patterns anywhere in the document — inline style="" attributes and <style> blocks.

Supports optional "regex": true for patterns that require precision (e.g. to avoid false positives with similar property names):

html_tag

Fires when the specified HTML tag is present at least once. Uses DOMDocument for accurate parsing.

Patterns are tag names (no angle brackets).

html_attribute_missing

Fires when at least one instance of tag is missing a required attribute, or has an attribute with the wrong value.

With value check:

With "only_empty": true — fires when the attribute is present but empty (alt=""). Useful for distinguishing missing alt text from intentionally empty alt text:

html_content

Matches arbitrary string patterns anywhere in the raw HTML string.

Supports "regex": true for patterns requiring precision. The ~ character is used as the regex delimiter internally — escape it as \\~ if needed in a pattern:

html_tag_with_style

Fires when a tag is present and its inline style attribute contains one of the given CSS patterns. Useful for distinguishing structural divs from decorative ones.

Supports "regex": true for precise matching (e.g. to avoid matching max-width: when looking for width:):

correlation

Fires when a trigger pattern is present but an expected fallback pattern is absent. Use this to flag bad usage of a feature rather than its mere presence.

The rule above fires only when an external font is loaded and no inline font-family fallback stack is found — correctly scoring emails that use custom fonts with proper fallbacks.

style_block

Searches exclusively inside <style> block content. Supports plain strings or regular expressions.

With regex:

preheader

Detects the standard email preheader pattern — a <div> with both display:none and overflow:hidden in its inline style. Two modes:

html_metric

Measures a numeric property of the HTML and fires when it exceeds a threshold. Currently supported metrics:

Metric Description
size Total byte length of the HTML string (strlen)

heading_order

Detects heading levels that are skipped in document order (e.g. <h1> directly followed by <h3>). No configuration options.

html_link_no_text

Fires when an <a> element has no accessible text — no text node content and no child <img> with a non-empty alt. No configuration options.

html_tracking_pixel

Detects <img> elements with width="1" and height="1", the classic open-tracking pattern. No configuration options.

css_font_family

Detects multi-word font names used without quotes in font-family declarations (e.g. font-family: Open Sans instead of font-family: 'Open Sans'). No configuration options.

html_table_width

Fires when a <table> element carries an inline width in pixels that exceeds max_width (default: 600).


Localization

Five locales are bundled: en (English), fr (French), es (Spanish), de (German), pt (Portuguese).

Single locale

If a locale is missing for a rule, it falls back to en automatically.

Multiple locales

Pass an array to receive all translations in a single pass:

This is useful when building multi-language UIs without running analyze() twice.

Adding a locale

Add the locale key to message, fix, and optionally success_message in each rule JSON:


Remote KB Sync

By default the package uses the bundled rule set. You can point it at a remote endpoint to receive updated rules without a Composer update.

How it works

Enabling sync

Tier behavior

Condition Rules returned
No api_key Free rules only
Valid api_key Free + Pro rules
Expired / invalid api_key 401 response → silent fallback to bundled rules

Cache behavior

Situation Behavior
First install, no cache Bundled rules
Cache exists, not stale Cache used
Cache stale or missing Fetch from endpoint, write cache
Fetch fails (network error) Bundled rules (silent fallback)
auto_update = false Always bundled rules

CLI

A command-line tool is available at vendor/bin/mailaudit after installation.

sync — refresh the local cache

Using environment variables:

Using a config file:

Dry run (fetch but do not write cache):

Available options

Option Description
--config=<path> PHP file returning a config array
--dry-run Fetch without writing the cache

Environment variables

Variable Description
MAILAUDIT_ENDPOINT Remote KB endpoint URL
MAILAUDIT_API_KEY API key for pro tier
MAILAUDIT_CACHE_PATH Absolute path to the local cache file

audit — analyze an email file

Example output (text):

With --format=json, the full analyze() result array is printed as pretty-printed JSON — same structure as documented in Result Format.

audit options

Option Description
--locale=<code> Locale for messages: en (default), fr, es, de, pt
--format=json Output the full result as JSON instead of the formatted summary

Custom Rules

You can add your own rules without modifying the package.

1. Create a rule JSON file

2. Load it alongside the bundled rules

Or subclass MailAudit to make this reusable in your project.

Rule JSON reference

Field Type Required Description
id string Yes Unique identifier
version string Yes Semver string, bumped on changes
updated_at string Yes ISO date YYYY-MM-DD
source string No Reference URL (e.g. caniemail.com)
tier string Yes free or pro
severity string Yes error, warning, or info
weight int Yes Points deducted from score (0–100)
tags string[] No Categorization tags
detection object Yes See Detection Types
affected_clients object No Per-client support data
message object Yes Locale-keyed problem description
fix object Yes Locale-keyed fix suggestion
success_message object No Locale-keyed message shown when the rule passes. When present, the rule appears in the passed array of the result.

Custom Detectors

You can register new detection types to support custom rule patterns.

1. Implement DetectorInterface

2. Register it with the factory

3. Use it in a rule JSON

Registration is global and static — register once at application bootstrap before calling analyze().


Score Calculation

The score starts at 100. Each triggered rule deducts a weighted amount based on its severity:

Example:

Rule triggered Severity Weight Multiplier Deduction
no-svg error 12 × 1.0 12.0
style-no-inline-fallback warning 12 × 0.6 7.2
no-css-calc warning 7 × 0.6 4.2
css-media-queries info 2 × 0.3 0.6
Total deduction 24.0
Final score 76 / 100

The score cannot go below 0.

Severity vs weight

Severity (error, warning, info) is a qualitative label indicating the nature of the problem. Weight is the nominal importance of the rule. The multiplier ensures that warnings and info items have a proportionally smaller impact on the score than blocking errors, so a well-crafted email with minor compatibility caveats scores realistically (75–90) rather than being penalized alongside fundamentally broken emails.


Integration Examples

Vanilla PHP

Symfony

Laravel

In a CI/CD pipeline (GitHub Actions)


Running Tests

Run static analysis:


License

MIT — © 2026 rlnks


All versions of php-mail-audit with dependencies

PHP Build Version
Package Version
Requires php Version ^8.1
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 rlnks/php-mail-audit contains the following files

Loading the files please wait ...