Skip to content

Commit 6f5d751

Browse files
Resolve stripping media tags (#14)
* Maintenance notice * Correct issue where @media files are being removed. * Upgrade depends * Upgrade depends --------- Co-authored-by: Pete Cooper <pete@petecoop.co.uk>
1 parent a2a967a commit 6f5d751

13 files changed

Lines changed: 168 additions & 68 deletions

.github/dependabot.yml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
version: 2
2+
updates:
3+
- package-ecosystem: composer
4+
directory: /
5+
schedule:
6+
interval: weekly
7+
- package-ecosystem: github-actions
8+
directory: /
9+
schedule:
10+
interval: weekly

.github/workflows/laravel-package.yml

Lines changed: 23 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,29 +6,44 @@ on:
66

77
jobs:
88
laravel:
9-
name: Laravel Package (PHP ${{ matrix.php-versions }} on ${{ matrix.operating-system }})
9+
name: Laravel ${{ matrix.laravel }} (PHP ${{ matrix.php-version }} on ${{ matrix.operating-system }})
1010

1111
runs-on: ${{ matrix.operating-system }}
1212

1313
strategy:
14+
fail-fast: false
1415
matrix:
15-
operating-system: [ubuntu-latest]
16-
php-versions: ['8.4']
16+
include:
17+
- operating-system: ubuntu-latest
18+
php-version: '8.4'
19+
laravel: '12'
20+
illuminate-version: '^12.55'
21+
testbench-version: '^10.11'
22+
- operating-system: ubuntu-latest
23+
php-version: '8.4'
24+
laravel: '13'
25+
illuminate-version: '^13.10'
26+
testbench-version: '^11.1'
1727

1828
steps:
1929
- name: Checkout
20-
uses: actions/checkout@v1
30+
uses: actions/checkout@v4
2131

2232
- name: Setup PHP, with composer and extensions
2333
uses: shivammathur/setup-php@v2
2434
with:
25-
php-version: ${{ matrix.php-versions }}
35+
php-version: ${{ matrix.php-version }}
36+
37+
- name: Configure Laravel dependencies
38+
run: |
39+
composer require --no-interaction --no-progress --no-update "illuminate/support:${{ matrix.illuminate-version }}" "illuminate/view:${{ matrix.illuminate-version }}"
40+
composer require --dev --no-interaction --no-progress --no-update "orchestra/testbench:${{ matrix.testbench-version }}"
2641
2742
- name: Install Composer dependencies
28-
run: composer install --no-progress --no-suggest --prefer-dist --optimize-autoloader
43+
run: composer update --no-interaction --no-progress --prefer-dist --optimize-autoloader
2944

3045
- name: Check styling with PHP CS Fixer
31-
uses: StephaneBour/actions-php-cs-fixer@1.0
46+
run: vendor/bin/php-cs-fixer fix --dry-run --diff --config=.php-cs-fixer.dist.php
3247

3348
- name: Test with phpunit
34-
run: vendor/bin/phpunit --coverage-text
49+
run: vendor/bin/phpunit

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ composer.lock
44
/.vscode
55
npm-debug.log
66
.php_cs.cache
7+
.php-cs-fixer.cache
78
.phpunit.result.cache
89
.DS_Store
910
/.phpunit.cache/

.php-cs-fixer.dist.php

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
use PhpCsFixer\Config;
6+
use PhpCsFixer\Finder;
7+
8+
return (new Config())
9+
->setRiskyAllowed(false)
10+
->setRules([
11+
'@PSR12' => true,
12+
'new_with_parentheses' => false,
13+
])
14+
->setFinder(
15+
Finder::create()
16+
->in([
17+
__DIR__ . '/src',
18+
__DIR__ . '/tests',
19+
])
20+
);

composer.json

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,15 @@
1616
"require": {
1717
"php": "^8.4",
1818
"incentfit/inky": "1.3.6.5",
19-
"illuminate/support": "^11.0|^12.0|^13.0",
20-
"illuminate/view": "^11.0|^12.0|^13.0",
21-
"symfony/dom-crawler": "^2.7|^3.0|^4.0|^5.0|^7.0",
22-
"tijsverkoyen/css-to-inline-styles": "^2.2"
19+
"illuminate/support": "^12.55|^13.10",
20+
"illuminate/view": "^12.55|^13.10",
21+
"symfony/dom-crawler": "^7.4.12|^8.0.12",
22+
"tijsverkoyen/css-to-inline-styles": "^2.4"
2323
},
2424
"require-dev": {
25-
"phpunit/phpunit": "^8.0|^9.0|^10.5|^11.0",
26-
"graham-campbell/testbench": "^5.3|^6.1"
25+
"phpunit/phpunit": ">=13.1 <13.2",
26+
"orchestra/testbench": "^10.11|^11.1",
27+
"friendsofphp/php-cs-fixer": "^3.95"
2728
},
2829
"autoload": {
2930
"psr-4": {

phpunit.xml.dist

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<?xml version="1.0" encoding="UTF-8"?>
2-
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" backupGlobals="false" bootstrap="vendor/autoload.php" colors="true" processIsolation="false" stopOnError="false" stopOnFailure="false" xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/10.5/phpunit.xsd" cacheDirectory=".phpunit.cache" backupStaticProperties="false">
2+
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" backupGlobals="false" bootstrap="vendor/autoload.php" colors="true" processIsolation="false" stopOnError="false" stopOnFailure="false" xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/13.1/phpunit.xsd" cacheDirectory=".phpunit.cache" backupStaticProperties="false">
33
<testsuites>
44
<testsuite name="Laravel Inky Test Suite">
55
<directory suffix="Test.php">./tests</directory>

readme.md

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,10 @@
1-
[![Actions Status](https://github.com/rsvpify/laravel-inky/workflows/Testing%20Laravel%20Package/badge.svg)](https://github.com/rsvpify/laravel-inky/actions)
2-
3-
Allows you to use Foundation's [Inky](http://foundation.zurb.com/emails/docs/inky.html) email templates nicely in Laravel 6-11.
1+
Allows you to use Foundation's [Inky](http://foundation.zurb.com/emails/docs/inky.html) email templates nicely in Laravel 12-13. Requires PHP 8.4+.
42

53
Any views with a `.inky.php` extension will be compiled with both Inky and Blade, allowing you to use both templating engines seamlessly together. CSS is automatically inlined so styles work in email clients that don't support external stylesheets.
64

75
## Installation
86

9-
Require with composer
7+
Require with composer.
108
```
119
composer require rsvpify/laravel-inky
1210
```

src/InkyCompiler.php

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -5,25 +5,23 @@
55
use IncentFit\Inky\Inky;
66
use Illuminate\Filesystem\Filesystem;
77
use Illuminate\View\Compilers\Compiler;
8+
use Illuminate\View\Compilers\BladeCompiler;
89
use Illuminate\View\Compilers\CompilerInterface;
910

1011
class InkyCompiler extends Compiler implements CompilerInterface
1112
{
12-
protected $inky;
13+
protected Inky $inky;
1314

14-
protected $blade;
15+
protected ?string $path = null;
1516

16-
protected $path;
17-
18-
public function __construct(Compiler $blade, Filesystem $files, $cachePath)
17+
public function __construct(protected BladeCompiler $blade, Filesystem $files, string $cachePath)
1918
{
2019
parent::__construct($files, $cachePath);
2120

22-
$this->blade = $blade;
2321
$this->inky = new Inky;
2422
}
2523

26-
public function compile($path = null)
24+
public function compile($path = null): void
2725
{
2826
if ($path) {
2927
$this->setPath($path);
@@ -36,29 +34,29 @@ public function compile($path = null)
3634
}
3735
}
3836

39-
public function getPath()
37+
public function getPath(): ?string
4038
{
4139
return $this->path;
4240
}
4341

44-
public function setPath($path)
42+
public function setPath(string $path): static
4543
{
4644
$this->path = $path;
4745

4846
return $this;
4947
}
5048

51-
public function compileString($value)
49+
public function compileString(string $value): string
5250
{
5351
return $this->blade->compileString($this->inky->releaseTheKraken($value));
5452
}
5553

56-
public function getFiles()
54+
public function getFiles(): Filesystem
5755
{
5856
return $this->files;
5957
}
6058

61-
public function getBlade()
59+
public function getBlade(): BladeCompiler
6260
{
6361
return $this->blade;
6462
}

src/InkyCompilerEngine.php

Lines changed: 35 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
namespace Rsvpify\LaravelInky;
44

5+
use Illuminate\Support\Str;
56
use Illuminate\Filesystem\Filesystem;
67
use Symfony\Component\DomCrawler\Crawler;
78
use Illuminate\View\Engines\CompilerEngine;
@@ -10,21 +11,15 @@
1011

1112
class InkyCompilerEngine extends CompilerEngine
1213
{
13-
protected $filesystem;
14-
15-
public function __construct(CompilerInterface $compiler, Filesystem $filesystem)
14+
public function __construct(CompilerInterface $compiler, protected Filesystem $filesystem)
1615
{
1716
parent::__construct($compiler);
18-
19-
$this->filesystem = $filesystem;
2017
}
2118

22-
public function get($inkyFilePath, array $data = [])
19+
public function get($inkyFilePath, array $data = []): string
2320
{
24-
// Compiles the inky template as if it were a regular blade file
2521
$html = parent::get($inkyFilePath, $data);
2622

27-
// remove css stylesheet links from email's HTML
2823
$crawler = new Crawler;
2924
$crawler->addHtmlContent($html);
3025
$cssLinks = $crawler->filter('link[rel=stylesheet]');
@@ -37,18 +32,44 @@ public function get($inkyFilePath, array $data = [])
3732

3833
$htmlWithoutLinks = $crawler->html();
3934

40-
// Combine all stylesheets into 1 string of CSS
41-
$combinedStyles = collect(config('inky.stylesheets'))->map(function ($path) {
42-
return $this->filesystem->get(base_path($path));
43-
})->implode("\n\n");
35+
$combinedStyles = collect(config('inky.stylesheets'))
36+
->map(fn ($path) => $this->filesystem->get(base_path($path)))
37+
->implode("\n\n");
4438

4539
$inliner = new CssToInlineStyles;
4640

47-
return $inliner->convert($htmlWithoutLinks, $combinedStyles);
41+
return $inliner->convert(
42+
$this->appendExternalMediaQueries($htmlWithoutLinks, $combinedStyles),
43+
$combinedStyles
44+
);
4845
}
4946

50-
public function getFiles()
47+
public function getFiles(): Filesystem
5148
{
5249
return $this->filesystem;
5350
}
51+
52+
protected function appendExternalMediaQueries(string $html, string $css): string
53+
{
54+
if (($mediaQueries = $this->extractMediaQueries($css)) === '') {
55+
return $html;
56+
}
57+
58+
$styleTag = "<style>\n{$mediaQueries}\n</style>";
59+
60+
if (Str::contains($html, '</head>')) {
61+
return Str::replaceFirst('</head>', "{$styleTag}\n</head>", $html);
62+
}
63+
64+
return "{$styleTag}\n{$html}";
65+
}
66+
67+
protected function extractMediaQueries(string $css): string
68+
{
69+
return Str::of($css)
70+
->matchAll('/@media[^{]*+{(?:[^{}]++|{[^{}]*+})*+}/i')
71+
->map(fn ($query) => trim($query))
72+
->filter()
73+
->implode("\n\n");
74+
}
5475
}

src/InkyServiceProvider.php

Lines changed: 4 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,7 @@
66

77
class InkyServiceProvider extends ServiceProvider
88
{
9-
/**
10-
* Bootstrap the application services.
11-
*
12-
* @return void
13-
*/
14-
public function boot()
9+
public function boot(): void
1510
{
1611
$this->registerExtension();
1712

@@ -20,12 +15,7 @@ public function boot()
2015
]);
2116
}
2217

23-
/**
24-
* Register the application services.
25-
*
26-
* @return void
27-
*/
28-
public function register()
18+
public function register(): void
2919
{
3020
$app = $this->app;
3121
$resolver = $app['view.engine.resolver'];
@@ -36,12 +26,10 @@ public function register()
3626
return new InkyCompiler($app['blade.compiler'], $app['files'], $cache);
3727
});
3828

39-
$resolver->register('inky', function () use ($app) {
40-
return new InkyCompilerEngine($app['inky.compiler'], $app['files']);
41-
});
29+
$resolver->register('inky', fn () => new InkyCompilerEngine($app['inky.compiler'], $app['files']));
4230
}
4331

44-
protected function registerExtension()
32+
protected function registerExtension(): void
4533
{
4634
$this->app['view']->addExtension('inky.php', 'inky');
4735
}

0 commit comments

Comments
 (0)