HTML formatting: TWO fixes in one! Fixed a bug introduced in 2.3.0-beta: the stylesheet cannot be defined within the email templates (aka ActionEmail) anymore. Instead, a default (ready for use) stylesheet is provided into /css/email.css and it can be overriden by the configuration parameter email_css. The fix consists in transforming the stylesheet into inline style... which fixes a limitation of gmail and Outlook that support only the inline styles. The implementation relies on a new library: emogrifier. This library has been changed (home-made utility) to be compatible with PHP 5.3 (declaration of arrays).

SVN:trunk[4277]
This commit is contained in:
Romain Quetiez
2016-07-04 15:06:28 +00:00
parent 8582f6da70
commit 396c4564b4
15 changed files with 2922 additions and 3 deletions

View File

@@ -324,6 +324,8 @@ class ActionEmail extends ActionNotification
if (isset($sSubject)) $oLog->Set('subject', $sSubject);
if (isset($sBody)) $oLog->Set('body', $sBody);
}
$sStyles = file_get_contents(APPROOT.'css/email.css');
$sStyles .= MetaModel::GetConfig()->Get('email_css');
$oEmail = new EMail();
@@ -344,7 +346,7 @@ class ActionEmail extends ActionNotification
$sTestBody .= "</ul>\n";
$sTestBody .= "</p>\n";
$sTestBody .= "</div>\n";
$oEmail->SetBody($sTestBody);
$oEmail->SetBody($sTestBody, 'text/html', $sStyles);
$oEmail->SetRecipientTO($this->Get('test_recipient'));
$oEmail->SetRecipientFrom($this->Get('test_recipient'));
$oEmail->SetReferences($sReference);
@@ -353,7 +355,7 @@ class ActionEmail extends ActionNotification
else
{
$oEmail->SetSubject($sSubject);
$oEmail->SetBody($sBody);
$oEmail->SetBody($sBody, 'text/html', $sStyles);
$oEmail->SetRecipientTO($sTo);
$oEmail->SetRecipientCC($sCC);
$oEmail->SetRecipientBCC($sBCC);

View File

@@ -404,6 +404,14 @@ class Config
'source_of_value' => '',
'show_in_conf_sample' => false,
),
'email_css' => array(
'type' => 'string',
'description' => 'CSS that will override the standard stylesheet used for the notifications',
'default' => "",
'value' => "",
'source_of_value' => '',
'show_in_conf_sample' => false,
),
'apc_cache.enabled' => array(
'type' => 'bool',
'description' => 'If set, the APC cache is allowed (the PHP extension must also be active)',

View File

@@ -305,8 +305,14 @@ IssueLog::Info(__METHOD__.' '.$this->m_oMessage->toString());
$this->AddToHeader('References', $sReferences);
}
public function SetBody($sBody, $sMimeType = 'text/html')
public function SetBody($sBody, $sMimeType = 'text/html', $sCustomStyles = null)
{
if (($sMimeType === 'text/html') && ($sCustomStyles !== null))
{
require_once(APPROOT.'lib/emogrifier/classes/emogrifier.php');
$emogrifier = new \Pelago\Emogrifier($sBody, $sCustomStyles);
$sBody = $emogrifier->emogrify(); // Adds html/body tags if not already present
}
$this->m_aData['body'] = array('body' => $sBody, 'mimeType' => $sMimeType);
$this->m_oMessage->setBody($sBody, $sMimeType);
}

12
css/email.css Normal file
View File

@@ -0,0 +1,12 @@
/* Note: only CSS1 is supported here (see the limitations of emogrifier: https://github.com/jjriv/emogrifier/) */
.caselog_header {
padding: 3px;
border-top: 1px solid #fff;
background-color: #ddd;
padding-left: 16px;
width: 100%;
}
.caselog_header_date {
}
.caselog_header_user {
}

24
lib/emogrifier/.gitignore vendored Normal file
View File

@@ -0,0 +1,24 @@
#########################
# global ignore file
########################
# ignoring temporary files (left by e.g. vim)
# ignoring by common IDE's used directories/files
# dont ignore .rej and .orig as we want to see/clean files after conflict resolution
#
# for local exclude patterns please edit .git/info/exclude
#
*~
*.bak
*.idea
*.project
*.swp
.buildpath
.cache
.project
.session
.settings
.TemporaryItems
.webprj
nbproject
/vendor/
composer.lock

View File

@@ -0,0 +1,31 @@
sudo: false
language: php
cache:
directories:
- vendor
env:
global:
secure: nOIIWvxRsDlkg+5H21dmVeqvFbweOAk3l3ZiyZO1m5XuGuuZR9yj10oOudee8m0hzJ7e9eoZ+dfB3t8lmK0fTRTB6w0G7RuGiQb89ief3Zhs1vOveYOgS5yfTMRym57iluxsLeCe7AxWmy7+0fWAvx1qL7bKp+THGK9yv/aj9eM=
php:
- 5.4
- 5.5
- 5.6
- 7.0
- hhvm
before_script:
- composer install
- vendor/bin/phpcs --config-set encoding utf-8
- if [ "$GITHUB_COMPOSER_AUTH" ]; then composer config -g github-oauth.github.com $GITHUB_COMPOSER_AUTH; fi
script:
# Run PHP lint on all PHP files.
- find Classes/ Tests/ -name '*.php' -print0 | xargs -0 -n 1 -P 4 php -l
# Check the coding style.
- vendor/bin/phpcs --standard=Configuration/PhpCodeSniffer/Standards/Emogrifier/ Classes/ Tests/
# Run the unit tests.
- vendor/bin/phpunit Tests/

View File

@@ -0,0 +1,92 @@
# Emogrifier Change Log
All notable changes to this project will be documented in this file.
This project adheres to [Semantic Versioning](http://semver.org/).
Emogrifier is in a pre-1.0 state. This means that its APIs and behavior are
subject to breaking changes without deprecation notices.
## [1.0.0][] (2015-10-15)
### Added
- Add branch alias ([#231](https://github.com/jjriv/emogrifier/pull/231))
- Remove media queries which do not impact the document
([#217](https://github.com/jjriv/emogrifier/pull/217))
- Allow elements to be excluded from emogrification
([#215](https://github.com/jjriv/emogrifier/pull/215))
- Handle !important ([#214](https://github.com/jjriv/emogrifier/pull/214))
- emogrifyBodyContent() method
([#206](https://github.com/jjriv/emogrifier/pull/206))
- Cache combinedStyles ([#211](https://github.com/jjriv/emogrifier/pull/211))
- Allow user to define media types to keep
([#200](https://github.com/jjriv/emogrifier/pull/200))
- Ignore invalid CSS selectors
([#194](https://github.com/jjriv/emogrifier/pull/194))
- isRemoveDisplayNoneEnabled option
([#162](https://github.com/jjriv/emogrifier/pull/162))
- Allow disabling of "inline style" and "style block" parsing
([#156](https://github.com/jjriv/emogrifier/pull/156))
- Preserve @media if necessary
([#62](https://github.com/jjriv/emogrifier/pull/62))
- Add extraction of style blocks within the HTML
- Add several new pseudo-selectors (first-child, last-child, nth-child,
and nth-of-type)
### Changed
- Make HTML5 the default document type
([#245](https://github.com/jjriv/emogrifier/pull/245))
- Make copyCssWithMediaToStyleNode private
([#218](https://github.com/jjriv/emogrifier/pull/218))
- Stop encoding umlauts and dollar signs
([#170](https://github.com/jjriv/emogrifier/pull/170))
- Convert the classes to namespaces
([#41](https://github.com/jjriv/emogrifier/pull/41))
### Deprecated
- Support for PHP 5.4 will be removed in Emogrifier 2.0.
### Removed
- Drop support for PHP 5.3
([#114](https://github.com/jjriv/emogrifier/pull/114))
- Support for character sets other than UTF-8 was removed.
### Fixed
- Fix failing tests on Windows due to line endings
([#263](https://github.com/jjriv/emogrifier/pull/263))
- Parsing CSS declaration blocks
([#261](https://github.com/jjriv/emogrifier/pull/261))
- Fix first-child and last-child selectors
([#257](https://github.com/jjriv/emogrifier/pull/257))
- Fix parsing of CSS for data URIs
([#243](https://github.com/jjriv/emogrifier/pull/243))
- Fix multi-line media queries
([#241](https://github.com/jjriv/emogrifier/pull/241))
- Keep CSS media queries even if followed by CSS comments
([#201](https://github.com/jjriv/emogrifier/pull/201))
- Fix CSS selectors with exact attribute only
([#197](https://github.com/jjriv/emogrifier/pull/197))
- Properly handle UTF-8 characters and entities
([#189](https://github.com/jjriv/emogrifier/pull/189))
- Add mbstring extension to composer.json
([#93](https://github.com/jjriv/emogrifier/pull/93))
- Prevent incorrectly capitalized CSS selectors from being stripped
([#85](https://github.com/jjriv/emogrifier/pull/85))
- Fix CSS selectors with exact attribute only
([#197](https://github.com/jjriv/emogrifier/pull/197))
- Wrong selector extraction from minified CSS
([#69](https://github.com/jjriv/emogrifier/pull/69))
- Restore libxml error handler state after clearing
([#65](https://github.com/jjriv/emogrifier/pull/65))
- Ignore all warnings produced by DOMDocument::loadHTML()
([#63](https://github.com/jjriv/emogrifier/pull/63))
- Style tags in HTML cause an Xpath invalid query error
([#60](https://github.com/jjriv/emogrifier/pull/60))
- Fix PHP warnings with PHP 5.5
([#26](https://github.com/jjriv/emogrifier/pull/26))
- Make removal of invisible nodes operate in a case-insensitive manner
- Fix a bug that was overwriting existing inline styles from the original HTML

View File

@@ -0,0 +1,78 @@
# Contributing to Emogrifier
Those that wish to contribute bug fixes, new features, refactorings and
clean-up to Emogrifier are more than welcome.
When you contribute, please take the following things into account:
## General workflow
After you have submitted a pull request, the Emogrifier team will review your
changes. This will probably result in quite a few comments on ways to improve
your pull request. The Emogrifier project receives contributions from
developers around the world, so we need the code to be the most consistent,
readable, and maintainable that it can be.
Please do not feel frustrated by this - instead please view this both as our
contribution to your pull request as well as a way to learn more about
improving code quality.
If you would like to know whether an idea would fit in the general strategy of
the Emogrifier project or would like to get feedback on the best architecture
for your ideas, we propose you open a ticket first and discuss your ideas there
first before investing a lot of time in writing code.
## Install the development dependencies
To install the development dependencies (PHPUnit and PHP_CodeSniffer), please
run the following command:
composer install
## Unit-test your changes
Please cover all changes with unit tests and make sure that your code does not
break any existing tests. We will only merge pull request that include full
code coverage of the fixed bugs and the new features.
To run the existing PHPUnit tests, run this command:
vendor/bin/phpunit Tests/
## Coding Style
Please use the same coding style (PSR-2) as the rest of the code. Indentation
is four spaces.
We will only merge pull requests that follow the project's coding style.
Please check your code with the provided PHP_CodeSniffer standard:
vendor/bin/phpcs --standard=Configuration/PhpCodeSniffer/Standards/Emogrifier/ Classes/ Tests/
Please make your code clean, well-readable and easy to understand.
If you add new methods or fields, please add proper PHPDoc for the new
methods/fields. Please use grammatically correct, complete sentences in the
code documentation.
## Git commits
Git commits should have a <= 50 character summary, optionally followed by a
blank line and a more in depth description of 79 characters per line.
[Please squash related commits together](http://gitready.com/advanced/2009/02/10/squashing-commits-with-rebase.html).
If you already have a commit and work on it, you can also
[amend the first commit](https://nathanhoad.net/git-amend-your-last-commit).
Please use grammatically correct, complete sentences in the commit messages.
Also, please prefix the subject line of the commit message with either
[FEATURE], [TASK], [BUGFIX] OR [CLEANUP]. This makes it faster to see what
a commit is about.

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,136 @@
<?xml version="1.0" encoding="UTF-8"?>
<ruleset name="PPW Coding Standard">
<description>This is the coding standard used for the Emogrifier code.
This standard has been tested with to work with PHP_CodeSniffer >= 2.3.0.
</description>
<!--The complete PSR-2 ruleset-->
<rule ref="PSR2"/>
<!-- Arrays -->
<rule ref="Generic.Arrays.DisallowLongArraySyntax"/>
<rule ref="Squiz.Arrays.ArrayBracketSpacing"/>
<!-- Classes -->
<rule ref="Generic.Classes.DuplicateClassName"/>
<rule ref="Squiz.Classes.ClassFileName"/>
<rule ref="Squiz.Classes.DuplicateProperty"/>
<rule ref="Squiz.Classes.LowercaseClassKeywords"/>
<rule ref="Squiz.Classes.SelfMemberReference"/>
<!-- Code analysis -->
<rule ref="Generic.CodeAnalysis.EmptyStatement"/>
<rule ref="Generic.CodeAnalysis.ForLoopShouldBeWhileLoop"/>
<rule ref="Generic.CodeAnalysis.ForLoopWithTestFunctionCall"/>
<rule ref="Generic.CodeAnalysis.JumbledIncrementer"/>
<rule ref="Generic.CodeAnalysis.UnconditionalIfStatement"/>
<rule ref="Generic.CodeAnalysis.UnnecessaryFinalModifier"/>
<rule ref="Generic.CodeAnalysis.UnusedFunctionParameter"/>
<rule ref="Generic.CodeAnalysis.UselessOverridingMethod"/>
<!-- Commenting -->
<rule ref="Generic.Commenting.Fixme"/>
<rule ref="Generic.Commenting.Todo"/>
<rule ref="PEAR.Commenting.InlineComment"/>
<rule ref="Squiz.Commenting.DocCommentAlignment"/>
<rule ref="Squiz.Commenting.EmptyCatchComment"/>
<rule ref="Squiz.Commenting.FunctionCommentThrowTag"/>
<rule ref="Squiz.Commenting.PostStatementComment"/>
<rule ref="TYPO3SniffPool.Commenting.ClassComment"/>
<rule ref="TYPO3SniffPool.Commenting.DoubleSlashCommentsInNewLine"/>
<rule ref="TYPO3SniffPool.Commenting.SpaceAfterDoubleSlash"/>
<!-- Control structures -->
<rule ref="PEAR.ControlStructures.ControlSignature"/>
<rule ref="TYPO3SniffPool.ControlStructures.DisallowEachInLoopCondition"/>
<rule ref="TYPO3SniffPool.ControlStructures.DisallowElseIfConstruct"/>
<rule ref="TYPO3SniffPool.ControlStructures.ExtraBracesByAssignmentInLoop"/>
<rule ref="TYPO3SniffPool.ControlStructures.SwitchDeclaration"/>
<rule ref="TYPO3SniffPool.ControlStructures.TernaryConditionalOperator"/>
<rule ref="TYPO3SniffPool.ControlStructures.UnusedVariableInForEachLoop"/>
<!-- Debug -->
<rule ref="Generic.Debug.ClosureLinter"/>
<rule ref="TYPO3SniffPool.Debug.DebugCode"/>
<!-- Files -->
<rule ref="Generic.Files.OneClassPerFile"/>
<rule ref="Generic.Files.OneInterfacePerFile"/>
<rule ref="TYPO3SniffPool.Files.FileExtension"/>
<rule ref="TYPO3SniffPool.Files.Filename"/>
<rule ref="TYPO3SniffPool.Files.IncludingFile"/>
<rule ref="Zend.Files.ClosingTag"/>
<!-- Formatting -->
<rule ref="Generic.Formatting.SpaceAfterCast"/>
<rule ref="PEAR.Formatting.MultiLineAssignment"/>
<!-- Functions -->
<rule ref="Generic.Functions.CallTimePassByReference"/>
<rule ref="Squiz.Functions.FunctionDuplicateArgument"/>
<rule ref="Squiz.Functions.GlobalFunction"/>
<!-- Metrics -->
<!-- Enable this rule when the cyclomatic complexity of all methods is sufficiently low. -->
<!--<rule ref="Generic.Metrics.CyclomaticComplexity"/>-->
<rule ref="Generic.Metrics.NestingLevel"/>
<!-- Naming conventions -->
<rule ref="Generic.NamingConventions.ConstructorName"/>
<rule ref="PEAR.NamingConventions.ValidClassName"/>
<rule ref="TYPO3SniffPool.NamingConventions.ValidFunctionName"/>
<rule ref="TYPO3SniffPool.NamingConventions.ValidVariableName"/>
<!-- Objects -->
<rule ref="Squiz.Objects.ObjectMemberComma"/>
<!-- Operators -->
<rule ref="Squiz.Operators.IncrementDecrementUsage"/>
<rule ref="Squiz.Operators.ValidLogicalOperators"/>
<!-- PHP -->
<rule ref="Generic.PHP.CharacterBeforePHPOpeningTag"/>
<rule ref="Generic.PHP.DeprecatedFunctions"/>
<rule ref="Generic.PHP.DisallowShortOpenTag"/>
<rule ref="Generic.PHP.ForbiddenFunctions"/>
<rule ref="Generic.PHP.NoSilencedErrors"/>
<rule ref="Squiz.PHP.CommentedOutCode">
<properties>
<property name="maxPercentage" value="70"/>
</properties>
</rule>
<rule ref="Squiz.PHP.DisallowMultipleAssignments"/>
<rule ref="Squiz.PHP.DisallowSizeFunctionsInLoops"/>
<rule ref="Squiz.PHP.DiscouragedFunctions"/>
<rule ref="Squiz.PHP.Eval"/>
<rule ref="Squiz.PHP.ForbiddenFunctions"/>
<rule ref="Squiz.PHP.GlobalKeyword"/>
<rule ref="Squiz.PHP.Heredoc"/>
<rule ref="Squiz.PHP.InnerFunctions"/>
<rule ref="Squiz.PHP.LowercasePHPFunctions"/>
<rule ref="Squiz.PHP.NonExecutableCode"/>
<!-- Scope -->
<rule ref="Squiz.Scope.MemberVarScope"/>
<rule ref="Squiz.Scope.StaticThisUsage"/>
<rule ref="TYPO3SniffPool.Scope.AlwaysReturn">
<exclude-pattern>*/Tests/*</exclude-pattern>
</rule>
<!--Strings-->
<rule ref="Squiz.Strings.DoubleQuoteUsage"/>
<rule ref="TYPO3SniffPool.Strings.ConcatenationSpacing"/>
<rule ref="TYPO3SniffPool.Strings.UnnecessaryStringConcat"/>
<!-- Whitespace -->
<rule ref="PEAR.WhiteSpace.ObjectOperatorIndent"/>
<rule ref="PEAR.WhiteSpace.ScopeClosingBrace"/>
<rule ref="Squiz.WhiteSpace.CastSpacing"/>
<rule ref="Squiz.WhiteSpace.LogicalOperatorSpacing"/>
<rule ref="Squiz.WhiteSpace.OperatorSpacing"/>
<rule ref="Squiz.WhiteSpace.PropertyLabelSpacing"/>
<rule ref="Squiz.WhiteSpace.SemicolonSpacing"/>
<rule ref="TYPO3SniffPool.WhiteSpace.NoWhitespaceAtInDecrement"/>
<rule ref="TYPO3SniffPool.WhiteSpace.ScopeClosingBrace"/>
<rule ref="TYPO3SniffPool.WhiteSpace.WhitespaceAfterCommentSigns"/>
</ruleset>

21
lib/emogrifier/LICENSE Normal file
View File

@@ -0,0 +1,21 @@
Emogrifier is copyright (c) 2008-2014 Pelago and licensed under the MIT license.
The MIT License (MIT)
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

198
lib/emogrifier/README.md Normal file
View File

@@ -0,0 +1,198 @@
# Emogrifier
[![Build Status](https://travis-ci.org/jjriv/emogrifier.svg?branch=master)](https://travis-ci.org/jjriv/emogrifier)
[![Latest Stable Version](https://poser.pugx.org/pelago/emogrifier/v/stable.svg)](https://packagist.org/packages/pelago/emogrifier)
[![Total Downloads](https://poser.pugx.org/pelago/emogrifier/downloads.svg)](https://packagist.org/packages/pelago/emogrifier)
[![Latest Unstable Version](https://poser.pugx.org/pelago/emogrifier/v/unstable.svg)](https://packagist.org/packages/pelago/emogrifier)
[![License](https://poser.pugx.org/pelago/emogrifier/license.svg)](https://packagist.org/packages/pelago/emogrifier)
_n. e•mog•ri•fi•er [\ē-'mä-grƏ-,fī-Ər\] - a utility for changing completely the
nature or appearance of HTML email, esp. in a particularly fantastic or bizarre
manner_
Emogrifier converts CSS styles into inline style attributes in your HTML code.
This ensures proper display on email and mobile device readers that lack
stylesheet support.
This utility was developed as part of [Intervals](http://www.myintervals.com/)
to deal with the problems posed by certain email clients (namely Outlook 2007
and GoogleMail) when it comes to the way they handle styling contained in HTML
emails. As many web developers and designers already know, certain email
clients are notorious for their lack of CSS support. While attempts are being
made to develop common [email standards](http://www.email-standards.org/),
implementation is still a ways off.
The primary problem with uncooperative email clients is that most tend to only
regard inline CSS, discarding all `<style>` elements and links to stylesheets
in `<link>` elements. Emogrifier solves this problem by converting CSS styles
into inline style attributes in your HTML code.
- [How it works](#how-it-works)
- [Usage](#usage)
- [Installing with Composer](#installing-with-composer)
- [Usage](#usage)
- [Supported CSS selectors](#supported-css-selectors)
- [Caveats](#caveats)
- [Maintainer](#maintainer)
- [Contributing](#contributing)
## How it Works
Emogrifier automagically transmogrifies your HTML by parsing your CSS and
inserting your CSS definitions into tags within your HTML based on your CSS
selectors.
## Usage
First, you provide Emogrifier with the HTML and CSS you would like to merge.
This can happen directly during instantiation:
$html = '<html><h1>Hello world!</h1></html>';
$css = 'h1 {font-size: 32px;}';
$emogrifier = new \Pelago\Emogrifier($html, $css);
You could also use the setters for providing this data after instantiation:
$emogrifier = new \Pelago\Emogrifier();
$html = '<html><h1>Hello world!</h1></html>';
$css = 'h1 {font-size: 32px;}';
$emogrifier->setHtml($html);
$emogrifier->setCss($css);
After you have set the HTML and CSS, you can call the `emogrify` method to
merge both:
$mergedHtml = $emogrifier->emogrify();
Emogrifier automatically adds a Content-Type meta tag to set the charset for
the document (if it is not provided).
If you would like to get back only the content of the BODY element instead of
the complete HTML document, you can use the `emogrifyBodyContent` instead:
$bodyContent = $emogrifier->emogrifyBodyContent();
## Options
There are several options that you can set on the Emogrifier object before
calling the `emogrify` method:
* `$emogrifier->disableStyleBlocksParsing()` - By default, Emogrifier will grab
all `<style>` blocks in the HTML and will apply the CSS styles as inline
"style" attributes to the HTML. The `<style>` blocks will then be removed
from the HTML. If you want to disable this functionality so that Emogrifier
leaves these `<style>` blocks in the HTML and does not parse them, you should
use this option.
* `$emogrifier->disableInlineStylesParsing()` - By default, Emogrifier
preserves all of the "style" attributes on tags in the HTML you pass to it.
However if you want to discard all existing inline styles in the HTML before
the CSS is applied, you should use this option.
* `$emogrifier->disableInvisibleNodeRemoval()` - By default, Emogrifier removes
elements from the DOM that have the style attribute `display: none;`. If
you would like to keep invisible elements in the DOM, use this option.
* `$emogrifier->addAllowedMediaType(string $mediaName)` - By default, Emogrifier
will keep only media types `all`, `screen` and `print`. If you want to keep
some others, you can use this method to define them.
* `$emogrifier->removeAllowedMediaType(string $mediaName)` - You can use this
method to remove media types that Emogrifier keeps.
* `$emogrifier->addExcludedSelector(string $selector)` - Keeps elements from
being affected by emogrification.
## Requirements
* PHP from 5.4 to 7.0 (with the mbstring extension)
* or HHVM
## Installing with Composer
Download the [`composer.phar`](https://getcomposer.org/composer.phar) locally
or install [Composer](https://getcomposer.org/) globally:
curl -s https://getcomposer.org/installer | php
Run the following command for a local installation:
php composer.phar require pelago/emogrifier:@dev
Or for a global installation, run the following command:
composer require pelago/emogrifier:@dev
You can also add follow lines to your `composer.json` and run the
`composer update` command:
"require": {
"pelago/emogrifier": "@dev"
}
See https://getcomposer.org/ for more information and documentation.
## Supported CSS selectors
Emogrifier currently support the following
[CSS selectors](http://www.w3.org/TR/CSS2/selector.html):
* ID
* class
* type
* descendant
* child
* adjacent
* attribute presence
* attribute value
* attribute only
* first-child
* last-child
The following selectors are not implemented yet:
* universal
## Caveats
* Emogrifier requires the HTML and the CSS to be UTF-8. Encodings like
ISO8859-1 or ISO8859-15 are not supported.
* Emogrifier now preserves all valuable @media queries. Media queries
can be very useful in responsive email design. See
[media query support](https://litmus.com/help/email-clients/media-query-support/).
* Emogrifier will grab existing inline style attributes _and_ will
grab `<style>` blocks from your HTML, but it will not grab CSS files
referenced in <link> elements. (The problem email clients are going to ignore
these tags anyway, so why leave them in your HTML?)
* Even with styles inline, certain CSS properties are ignored by certain email
clients. For more information, refer to these resources:
* [http://www.email-standards.org/](http://www.email-standards.org/)
* [https://www.campaignmonitor.com/css/](https://www.campaignmonitor.com/css/)
* [http://templates.mailchimp.com/resources/email-client-css-support/](http://templates.mailchimp.com/resources/email-client-css-support/)
* All CSS attributes that apply to a node will be applied, even if they are
redundant. For example, if you define a font attribute _and_ a font-size
attribute, both attributes will be applied to that node (in other words, the
more specific attribute will not be combined into the more general
attribute).
* There's a good chance you might encounter problems if your HTML is not
well-formed and valid (DOMDocument might complain). If you get problems like
this, consider running your HTML through
[Tidy](http://php.net/manual/en/book.tidy.php) before you pass it to
Emogrifier.
* Emogrifier automatically converts the provided (X)HTML into HTML5, i.e.,
self-closing tags will lose their slash. To keep your HTML valid, it is
recommended to use HTML5 instead of one of the XHTML variants.
* Emogrifier only supports CSS1 level selectors and a few CSS2 level selectors
(but not all of them). It does not support pseudo selectors. (Emogrifier
works by converting CSS selectors to XPath selectors, and pseudo selectors
cannot be converted accurately).
## Maintainer
Emogrifier is maintained by the good people at
[Pelago](http://www.pelagodesign.com/), info AT pelagodesign DOT com.

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,46 @@
{
"name": "pelago/emogrifier",
"description": "Converts CSS styles into inline style attributes in your HTML code",
"tags": ["email", "css", "pre-processing"],
"license": "MIT",
"homepage": "http://www.pelagodesign.com/sidecar/emogrifier/",
"authors": [
{
"name": "John Reeve",
"email": "jreeve@pelagodesign.com"
},
{
"name": "Cameron Brooks"
},
{
"name": "Jaime Prado"
},
{
"name": "Oliver Klee",
"email": "typo3-coding@oliverklee.de"
},
{
"name": "Roman Ožana",
"email": "ozana@omdesign.cz"
}
],
"require": {
"php": ">=5.4.0",
"ext-mbstring": "*"
},
"require-dev": {
"squizlabs/php_codesniffer": "2.3.4",
"typo3-ci/typo3sniffpool": "2.1.1",
"phpunit/phpunit": "4.8.11"
},
"autoload": {
"psr-4": {
"Pelago\\": "Classes/"
}
},
"extra": {
"branch-alias": {
"dev-master": "1.1.x-dev"
}
}
}

View File

@@ -2378,4 +2378,28 @@ IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
</pre>]]></text>
</license>
<license>
<product>Emogrifier</product>
<author>Pelago</author>
<license_type>MIT</license_type>
<text><![CDATA[<pre>Copyright (c) 2008-2014 Pelago, https://github.com/jjriv/emogrifier
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
</pre>]]></text>
</license>
</licenses>