Compare commits
14 commits
Author | SHA1 | Date | |
---|---|---|---|
c6e5002ebd | |||
0a310e8a34 | |||
9e72bba7ca | |||
003abbbf98 | |||
48b45ef2ff | |||
85a336a265 | |||
f8fc96c1bb | |||
408c9f9e19 | |||
a87653d50d | |||
17af718f84 | |||
3c36b7a66d | |||
9273c597ca | |||
db4b1193cf | |||
368c8767f0 |
43 changed files with 233 additions and 4090 deletions
2
.gitignore
vendored
2
.gitignore
vendored
|
@ -18,3 +18,5 @@
|
||||||
|
|
||||||
/.vscode
|
/.vscode
|
||||||
/src/config/config.php
|
/src/config/config.php
|
||||||
|
|
||||||
|
/composer.phar
|
|
@ -3,6 +3,7 @@
|
||||||
### Added
|
### Added
|
||||||
|
|
||||||
- Support for PHP 8.3
|
- Support for PHP 8.3
|
||||||
|
- Support for custom MJML API URLs (Private.coffee fork only)
|
||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
|
|
||||||
|
|
|
@ -1,12 +1,18 @@
|
||||||
{
|
{
|
||||||
|
"repositories": [
|
||||||
|
{
|
||||||
|
"type": "vcs",
|
||||||
|
"url": "https://git.private.coffee/kumi/mjml-php.git"
|
||||||
|
}
|
||||||
|
],
|
||||||
"require": {
|
"require": {
|
||||||
"embed/embed": "^4.4",
|
"embed/embed": "^4.4",
|
||||||
"qferr/mjml-php": "^2.0",
|
|
||||||
"gettext/gettext": "^5.6",
|
"gettext/gettext": "^5.6",
|
||||||
"gettext/translator": "^1.1",
|
"gettext/translator": "^1.1",
|
||||||
"jaybizzle/crawler-detect": "^1.2",
|
"jaybizzle/crawler-detect": "^1.2",
|
||||||
"slim/psr7": "^1.6",
|
"slim/psr7": "^1.6",
|
||||||
"erusev/parsedown": "^1.7"
|
"erusev/parsedown": "^1.7",
|
||||||
|
"kumi/mjml-php": "dev-main"
|
||||||
},
|
},
|
||||||
"require-dev": {
|
"require-dev": {
|
||||||
"dealerdirect/phpcodesniffer-composer-installer": "^1.0",
|
"dealerdirect/phpcodesniffer-composer-installer": "^1.0",
|
||||||
|
|
104
composer.lock
generated
104
composer.lock
generated
|
@ -4,7 +4,7 @@
|
||||||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||||
"This file is @generated automatically"
|
"This file is @generated automatically"
|
||||||
],
|
],
|
||||||
"content-hash": "d2667894e4108f2ea9ece2a5b6a85243",
|
"content-hash": "939c1896caf454544982bfefec1310cc",
|
||||||
"packages": [
|
"packages": [
|
||||||
{
|
{
|
||||||
"name": "composer/ca-bundle",
|
"name": "composer/ca-bundle",
|
||||||
|
@ -551,6 +551,55 @@
|
||||||
},
|
},
|
||||||
"time": "2024-06-07T07:58:43+00:00"
|
"time": "2024-06-07T07:58:43+00:00"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "kumi/mjml-php",
|
||||||
|
"version": "dev-main",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://git.private.coffee/kumi/mjml-php.git",
|
||||||
|
"reference": "b8ce0c35cc3376b5fc5ecd913a6ea701d2de762d"
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"ext-curl": "*",
|
||||||
|
"ext-json": "*",
|
||||||
|
"php": ">=7.2"
|
||||||
|
},
|
||||||
|
"require-dev": {
|
||||||
|
"phpunit/phpunit": "^8.5"
|
||||||
|
},
|
||||||
|
"default-branch": true,
|
||||||
|
"type": "library",
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"Qferrer\\Mjml\\": "src/"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"autoload-dev": {
|
||||||
|
"psr-4": {
|
||||||
|
"Qferrer\\Tests\\Mjml\\": "tests/"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"scripts": {
|
||||||
|
"test": [
|
||||||
|
"phpunit tests/"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"license": [
|
||||||
|
"MIT"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Quentin",
|
||||||
|
"email": "qferrer@outook.com"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Kumi",
|
||||||
|
"email": "mjml-php@kumi.email"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "A simple PHP library to render MJML to HTML.",
|
||||||
|
"time": "2025-03-10T15:03:58+00:00"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "ml/iri",
|
"name": "ml/iri",
|
||||||
"version": "1.1.4",
|
"version": "1.1.4",
|
||||||
|
@ -868,51 +917,6 @@
|
||||||
},
|
},
|
||||||
"time": "2023-04-04T09:54:51+00:00"
|
"time": "2023-04-04T09:54:51+00:00"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"name": "qferr/mjml-php",
|
|
||||||
"version": "2.0.0",
|
|
||||||
"source": {
|
|
||||||
"type": "git",
|
|
||||||
"url": "https://github.com/qferr/mjml-php.git",
|
|
||||||
"reference": "c7185024d8b561bd3b532b29f46cba0f4b789b70"
|
|
||||||
},
|
|
||||||
"dist": {
|
|
||||||
"type": "zip",
|
|
||||||
"url": "https://api.github.com/repos/qferr/mjml-php/zipball/c7185024d8b561bd3b532b29f46cba0f4b789b70",
|
|
||||||
"reference": "c7185024d8b561bd3b532b29f46cba0f4b789b70",
|
|
||||||
"shasum": ""
|
|
||||||
},
|
|
||||||
"require": {
|
|
||||||
"ext-curl": "*",
|
|
||||||
"ext-json": "*",
|
|
||||||
"php": ">=7.2"
|
|
||||||
},
|
|
||||||
"require-dev": {
|
|
||||||
"phpunit/phpunit": "^8.5"
|
|
||||||
},
|
|
||||||
"type": "library",
|
|
||||||
"autoload": {
|
|
||||||
"psr-4": {
|
|
||||||
"Qferrer\\Mjml\\": "src/"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"notification-url": "https://packagist.org/downloads/",
|
|
||||||
"license": [
|
|
||||||
"MIT"
|
|
||||||
],
|
|
||||||
"authors": [
|
|
||||||
{
|
|
||||||
"name": "Quentin",
|
|
||||||
"email": "qferrer@outook.com"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"description": "A simple PHP library to render MJML to HTML.",
|
|
||||||
"support": {
|
|
||||||
"issues": "https://github.com/qferr/mjml-php/issues",
|
|
||||||
"source": "https://github.com/qferr/mjml-php/tree/2.0.0"
|
|
||||||
},
|
|
||||||
"time": "2022-04-09T21:34:38+00:00"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"name": "ralouphie/getallheaders",
|
"name": "ralouphie/getallheaders",
|
||||||
"version": "3.0.3",
|
"version": "3.0.3",
|
||||||
|
@ -3917,10 +3921,12 @@
|
||||||
],
|
],
|
||||||
"aliases": [],
|
"aliases": [],
|
||||||
"minimum-stability": "stable",
|
"minimum-stability": "stable",
|
||||||
"stability-flags": [],
|
"stability-flags": {
|
||||||
|
"kumi/mjml-php": 20
|
||||||
|
},
|
||||||
"prefer-stable": false,
|
"prefer-stable": false,
|
||||||
"prefer-lowest": false,
|
"prefer-lowest": false,
|
||||||
"platform": [],
|
"platform": {},
|
||||||
"platform-dev": [],
|
"platform-dev": {},
|
||||||
"plugin-api-version": "2.6.0"
|
"plugin-api-version": "2.6.0"
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,6 +29,10 @@ class Email
|
||||||
|
|
||||||
$this->mjml = str_replace('<mj-include path="MJML_PART" />', $this->contentsPart, $this->contentsTemplate);
|
$this->mjml = str_replace('<mj-include path="MJML_PART" />', $this->contentsPart, $this->contentsTemplate);
|
||||||
|
|
||||||
|
/** Replace references to wishthis.online with instance-specific information */
|
||||||
|
$baseurl = $_SERVER['REQUEST_SCHEME'] . '://' . $_SERVER['HTTP_HOST'];
|
||||||
|
$this->mjml = str_replace('https://wishthis.online', $baseurl, $this->mjml);
|
||||||
|
|
||||||
/** Set Locale */
|
/** Set Locale */
|
||||||
global $locale;
|
global $locale;
|
||||||
|
|
||||||
|
@ -44,9 +48,16 @@ class Email
|
||||||
{
|
{
|
||||||
global $options;
|
global $options;
|
||||||
|
|
||||||
|
// Break if MJML API is not configured
|
||||||
|
if (!$options->getOption('mjml_api_application_id') && !$options->getOption('mjml_api_url')) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
$api = new \Qferrer\Mjml\Http\CurlApi(
|
$api = new \Qferrer\Mjml\Http\CurlApi(
|
||||||
$options->getOption('mjml_api_application_id'),
|
$options->getOption('mjml_api_application_id'),
|
||||||
$options->getOption('mjml_api_secret_key')
|
$options->getOption('mjml_api_secret_key'),
|
||||||
|
null,
|
||||||
|
$options->getOption('mjml_api_url')
|
||||||
);
|
);
|
||||||
$renderer = new \Qferrer\Mjml\Renderer\ApiRenderer($api);
|
$renderer = new \Qferrer\Mjml\Renderer\ApiRenderer($api);
|
||||||
|
|
||||||
|
|
|
@ -74,43 +74,13 @@ class Wish
|
||||||
|
|
||||||
public static function getAffiliateLink(string $url): string
|
public static function getAffiliateLink(string $url): string
|
||||||
{
|
{
|
||||||
$urlParts = parse_url($url);
|
// Bypass the link generation entirely for Private.coffee fork
|
||||||
|
|
||||||
if (isset($urlParts['query'])) {
|
|
||||||
\parse_str($urlParts['query'], $urlParameters);
|
|
||||||
} else {
|
|
||||||
$urlParameters = [];
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach (self::$affiliates as $host => $tagId) {
|
|
||||||
if (\str_contains($urlParts['host'], $host)) {
|
|
||||||
$urlParameters['tag'] = $tagId;
|
|
||||||
$urlParts['query'] = \http_build_query($urlParameters);
|
|
||||||
$url = $urlParts['scheme'] . '://' . $urlParts['host'] . $urlParts['path'] . '?' . $urlParts['query'];
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return $url;
|
return $url;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function hasAffiliateLink(string $url): bool
|
public static function hasAffiliateLink(string $url): bool
|
||||||
{
|
{
|
||||||
$urlParts = parse_url($url);
|
// Just bypass the check entirely for Private.coffee fork
|
||||||
|
|
||||||
if (isset($urlParts['query'])) {
|
|
||||||
\parse_str($urlParts['query'], $urlParameters);
|
|
||||||
} else {
|
|
||||||
$urlParameters = [];
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach (self::$affiliates as $host => $tagId) {
|
|
||||||
if (\str_contains($urlParts['host'], $host) && isset($urlParameters['tag'])) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
/>
|
/>
|
||||||
</mj-attributes>
|
</mj-attributes>
|
||||||
|
|
||||||
<mj-font name="Raleway" href="https://fonts.googleapis.com/css?family=Raleway" />
|
<mj-font name="Raleway" href="https://googledonts.private.coffee/css?family=Raleway" />
|
||||||
|
|
||||||
<mj-style>
|
<mj-style>
|
||||||
a {
|
a {
|
||||||
|
|
|
@ -348,13 +348,23 @@ $page->navigation();
|
||||||
<label><?= __('Advertisements') ?></label>
|
<label><?= __('Advertisements') ?></label>
|
||||||
|
|
||||||
<div class="ui toggle checkbox advertisements">
|
<div class="ui toggle checkbox advertisements">
|
||||||
<?php if (true === $user->getAdvertisements()) { ?>
|
<?php
|
||||||
<input type="checkbox" name="enable-advertisements" checked="checked" />
|
$wishthis_hosts = [
|
||||||
<?php } else { ?>
|
'wishthis.localhost',
|
||||||
<input type="checkbox" name="enable-advertisements" />
|
'wishthis.online',
|
||||||
<?php } ?>
|
'rc.wishthis.online',
|
||||||
|
'dev.wishthis.online',
|
||||||
|
];
|
||||||
|
|
||||||
<label><?= __('Enable advertisements') ?></label>
|
if (!in_array($_SERVER['HTTP_HOST'], $wishthis_hosts, true)) { ?>
|
||||||
|
<input type="checkbox" name="enable-advertisements" disabled="disabled" />
|
||||||
|
<?php } elseif (true === $user->getAdvertisements()) { ?>
|
||||||
|
<input type="checkbox" name="enable-advertisements" checked="checked" />
|
||||||
|
<?php } else { ?>
|
||||||
|
<input type="checkbox" name="enable-advertisements" />
|
||||||
|
<?php } ?>
|
||||||
|
|
||||||
|
<label><?= __('Enable advertisements') ?></label>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
|
@ -18,11 +18,11 @@ $page = new Page(__FILE__, $pageTitle);
|
||||||
|
|
||||||
if (isset($_POST['email'], $_POST['password']) && !empty($_POST['planet']) && !$registrationDisabled) {
|
if (isset($_POST['email'], $_POST['password']) && !empty($_POST['planet']) && !$registrationDisabled) {
|
||||||
$users = $database
|
$users = $database
|
||||||
->query(
|
->query(
|
||||||
'SELECT *
|
'SELECT *
|
||||||
FROM `users`;'
|
FROM `users`;'
|
||||||
)
|
)
|
||||||
->fetchAll();
|
->fetchAll();
|
||||||
$emails = array_map(
|
$emails = array_map(
|
||||||
function ($user) {
|
function ($user) {
|
||||||
return $user['email'];
|
return $user['email'];
|
||||||
|
@ -71,16 +71,16 @@ if (isset($_POST['email'], $_POST['password']) && !empty($_POST['planet']) && !$
|
||||||
* Password reset
|
* Password reset
|
||||||
*/
|
*/
|
||||||
$userQuery = $database
|
$userQuery = $database
|
||||||
->query(
|
->query(
|
||||||
'SELECT *
|
'SELECT *
|
||||||
FROM `users`
|
FROM `users`
|
||||||
WHERE `email` = :user_email
|
WHERE `email` = :user_email
|
||||||
AND `password_reset_token` = :user_password_reset_token',
|
AND `password_reset_token` = :user_password_reset_token',
|
||||||
[
|
[
|
||||||
'user_email' => $user_email,
|
'user_email' => $user_email,
|
||||||
'user_password_reset_token' => $user_token,
|
'user_password_reset_token' => $user_token,
|
||||||
]
|
]
|
||||||
);
|
);
|
||||||
|
|
||||||
if (false !== $userQuery) {
|
if (false !== $userQuery) {
|
||||||
$user = new User($userQuery->fetch());
|
$user = new User($userQuery->fetch());
|
||||||
|
@ -88,15 +88,15 @@ if (isset($_POST['email'], $_POST['password']) && !empty($_POST['planet']) && !$
|
||||||
echo \date('d.m.Y H:i') . ' <= ' . \date('d.m.Y H:i', $user->getPasswordResetValidUntil()) . '.';
|
echo \date('d.m.Y H:i') . ' <= ' . \date('d.m.Y H:i', $user->getPasswordResetValidUntil()) . '.';
|
||||||
if (time() <= $user->getPasswordResetValidUntil()) {
|
if (time() <= $user->getPasswordResetValidUntil()) {
|
||||||
$database
|
$database
|
||||||
->query(
|
->query(
|
||||||
'UPDATE `users`
|
'UPDATE `users`
|
||||||
SET `password` = :user_password
|
SET `password` = :user_password
|
||||||
WHERE `id` = :user_id;',
|
WHERE `id` = :user_id;',
|
||||||
[
|
[
|
||||||
'user_password' => User::passwordToHash($_POST['password']),
|
'user_password' => User::passwordToHash($_POST['password']),
|
||||||
'user_id' => $user->getId(),
|
'user_id' => $user->getId(),
|
||||||
]
|
]
|
||||||
);
|
);
|
||||||
|
|
||||||
$page->messages[] = Page::success(
|
$page->messages[] = Page::success(
|
||||||
'Password has been successfully reset for <strong>' . $user_email . '</strong>.',
|
'Password has been successfully reset for <strong>' . $user_email . '</strong>.',
|
||||||
|
@ -179,8 +179,8 @@ if (isset($_POST['email'], $_POST['password']) && !empty($_POST['planet']) && !$
|
||||||
$wishlist_hash = sha1(time() . $user_id . $wishlist_name);
|
$wishlist_hash = sha1(time() . $user_id . $wishlist_name);
|
||||||
|
|
||||||
$database
|
$database
|
||||||
->query(
|
->query(
|
||||||
'INSERT INTO `wishlists` (
|
'INSERT INTO `wishlists` (
|
||||||
`user`,
|
`user`,
|
||||||
`name`,
|
`name`,
|
||||||
`hash`
|
`hash`
|
||||||
|
@ -189,12 +189,12 @@ if (isset($_POST['email'], $_POST['password']) && !empty($_POST['planet']) && !$
|
||||||
:wishlist_name,
|
:wishlist_name,
|
||||||
:wishlist_hash
|
:wishlist_hash
|
||||||
);',
|
);',
|
||||||
[
|
[
|
||||||
'wishlist_user_id' => $user_id,
|
'wishlist_user_id' => $user_id,
|
||||||
'wishlist_name' => $wishlist_name,
|
'wishlist_name' => $wishlist_name,
|
||||||
'wishlist_hash' => $wishlist_hash,
|
'wishlist_hash' => $wishlist_hash,
|
||||||
]
|
]
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
$page->messages[] = Page::error(
|
$page->messages[] = Page::error(
|
||||||
|
@ -236,8 +236,7 @@ $page->navigation();
|
||||||
name="email"
|
name="email"
|
||||||
placeholder="john.doe@domain.tld"
|
placeholder="john.doe@domain.tld"
|
||||||
value="<?= $_GET['password-reset'] ?>"
|
value="<?= $_GET['password-reset'] ?>"
|
||||||
readonly
|
readonly />
|
||||||
/>
|
|
||||||
<?php } else { ?>
|
<?php } else { ?>
|
||||||
<input type="email" name="email" placeholder="john.doe@domain.tld" />
|
<input type="email" name="email" placeholder="john.doe@domain.tld" />
|
||||||
<?php } ?>
|
<?php } ?>
|
||||||
|
@ -278,12 +277,10 @@ $page->navigation();
|
||||||
<input class="ui primary button"
|
<input class="ui primary button"
|
||||||
type="submit"
|
type="submit"
|
||||||
value="<?= $buttonSubmit ?>"
|
value="<?= $buttonSubmit ?>"
|
||||||
title="<?= $buttonSubmit ?>"
|
title="<?= $buttonSubmit ?>" />
|
||||||
/>
|
|
||||||
<a class="ui tertiary button"
|
<a class="ui tertiary button"
|
||||||
href="<?= Page::PAGE_LOGIN ?>"
|
href="<?= Page::PAGE_LOGIN ?>"
|
||||||
title="<?= __('Login') ?>"
|
title="<?= __('Login') ?>">
|
||||||
>
|
|
||||||
<?= __('Login') ?>
|
<?= __('Login') ?>
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -17,6 +17,11 @@ if (isset($_POST['mjml_api'], $_POST['api_application_id'], $_POST['mjml_api_sec
|
||||||
$options->setOption('mjml_api_application_id', $_POST['api_application_id']);
|
$options->setOption('mjml_api_application_id', $_POST['api_application_id']);
|
||||||
$options->setOption('mjml_api_secret_key', $_POST['mjml_api_secret_key']);
|
$options->setOption('mjml_api_secret_key', $_POST['mjml_api_secret_key']);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (isset($_POST['mjml_api'])) {
|
||||||
|
// In contrast to the two before, this one may reasonably be set to an empty string.
|
||||||
|
$options->setOption('mjml_api_url', $_POST['api_url']);
|
||||||
|
}
|
||||||
?>
|
?>
|
||||||
|
|
||||||
<main>
|
<main>
|
||||||
|
@ -29,6 +34,15 @@ if (isset($_POST['mjml_api'], $_POST['api_application_id'], $_POST['mjml_api_sec
|
||||||
|
|
||||||
<h3 class="ui header"><?= __('API') ?></h3>
|
<h3 class="ui header"><?= __('API') ?></h3>
|
||||||
<form class="ui form" method="POST">
|
<form class="ui form" method="POST">
|
||||||
|
<div class="field">
|
||||||
|
<label><?=__('API URL') ?></label>
|
||||||
|
<input type="text"
|
||||||
|
name="api_url"
|
||||||
|
placeholder="https://api.mjml.io/v1/"
|
||||||
|
value="<?= $options->getOption('mjml_api_url'); ?>"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="field">
|
<div class="field">
|
||||||
<label><?= __('Application ID') ?></label>
|
<label><?= __('Application ID') ?></label>
|
||||||
<input type="text"
|
<input type="text"
|
||||||
|
|
27
vendor/composer/InstalledVersions.php
vendored
27
vendor/composer/InstalledVersions.php
vendored
|
@ -32,6 +32,11 @@ class InstalledVersions
|
||||||
*/
|
*/
|
||||||
private static $installed;
|
private static $installed;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var bool
|
||||||
|
*/
|
||||||
|
private static $installedIsLocalDir;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var bool|null
|
* @var bool|null
|
||||||
*/
|
*/
|
||||||
|
@ -309,6 +314,12 @@ class InstalledVersions
|
||||||
{
|
{
|
||||||
self::$installed = $data;
|
self::$installed = $data;
|
||||||
self::$installedByVendor = array();
|
self::$installedByVendor = array();
|
||||||
|
|
||||||
|
// when using reload, we disable the duplicate protection to ensure that self::$installed data is
|
||||||
|
// always returned, but we cannot know whether it comes from the installed.php in __DIR__ or not,
|
||||||
|
// so we have to assume it does not, and that may result in duplicate data being returned when listing
|
||||||
|
// all installed packages for example
|
||||||
|
self::$installedIsLocalDir = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -322,19 +333,27 @@ class InstalledVersions
|
||||||
}
|
}
|
||||||
|
|
||||||
$installed = array();
|
$installed = array();
|
||||||
|
$copiedLocalDir = false;
|
||||||
|
|
||||||
if (self::$canGetVendors) {
|
if (self::$canGetVendors) {
|
||||||
|
$selfDir = strtr(__DIR__, '\\', '/');
|
||||||
foreach (ClassLoader::getRegisteredLoaders() as $vendorDir => $loader) {
|
foreach (ClassLoader::getRegisteredLoaders() as $vendorDir => $loader) {
|
||||||
|
$vendorDir = strtr($vendorDir, '\\', '/');
|
||||||
if (isset(self::$installedByVendor[$vendorDir])) {
|
if (isset(self::$installedByVendor[$vendorDir])) {
|
||||||
$installed[] = self::$installedByVendor[$vendorDir];
|
$installed[] = self::$installedByVendor[$vendorDir];
|
||||||
} elseif (is_file($vendorDir.'/composer/installed.php')) {
|
} elseif (is_file($vendorDir.'/composer/installed.php')) {
|
||||||
/** @var array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>} $required */
|
/** @var array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>} $required */
|
||||||
$required = require $vendorDir.'/composer/installed.php';
|
$required = require $vendorDir.'/composer/installed.php';
|
||||||
$installed[] = self::$installedByVendor[$vendorDir] = $required;
|
self::$installedByVendor[$vendorDir] = $required;
|
||||||
if (null === self::$installed && strtr($vendorDir.'/composer', '\\', '/') === strtr(__DIR__, '\\', '/')) {
|
$installed[] = $required;
|
||||||
self::$installed = $installed[count($installed) - 1];
|
if (self::$installed === null && $vendorDir.'/composer' === $selfDir) {
|
||||||
|
self::$installed = $required;
|
||||||
|
self::$installedIsLocalDir = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (self::$installedIsLocalDir && $vendorDir.'/composer' === $selfDir) {
|
||||||
|
$copiedLocalDir = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -350,7 +369,7 @@ class InstalledVersions
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (self::$installed !== array()) {
|
if (self::$installed !== array() && !$copiedLocalDir) {
|
||||||
$installed[] = self::$installed;
|
$installed[] = self::$installed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
4
vendor/composer/autoload_psr4.php
vendored
4
vendor/composer/autoload_psr4.php
vendored
|
@ -15,8 +15,8 @@ return array(
|
||||||
'Symfony\\Component\\String\\' => array($vendorDir . '/symfony/string'),
|
'Symfony\\Component\\String\\' => array($vendorDir . '/symfony/string'),
|
||||||
'Symfony\\Component\\Console\\' => array($vendorDir . '/symfony/console'),
|
'Symfony\\Component\\Console\\' => array($vendorDir . '/symfony/console'),
|
||||||
'Slim\\Psr7\\' => array($vendorDir . '/slim/psr7/src'),
|
'Slim\\Psr7\\' => array($vendorDir . '/slim/psr7/src'),
|
||||||
'Qferrer\\Mjml\\' => array($vendorDir . '/qferr/mjml-php/src'),
|
'Qferrer\\Mjml\\' => array($vendorDir . '/kumi/mjml-php/src'),
|
||||||
'Psr\\Http\\Message\\' => array($vendorDir . '/psr/http-message/src', $vendorDir . '/psr/http-factory/src'),
|
'Psr\\Http\\Message\\' => array($vendorDir . '/psr/http-factory/src', $vendorDir . '/psr/http-message/src'),
|
||||||
'Psr\\Http\\Client\\' => array($vendorDir . '/psr/http-client/src'),
|
'Psr\\Http\\Client\\' => array($vendorDir . '/psr/http-client/src'),
|
||||||
'Psr\\Container\\' => array($vendorDir . '/psr/container/src'),
|
'Psr\\Container\\' => array($vendorDir . '/psr/container/src'),
|
||||||
'PhpParser\\' => array($vendorDir . '/nikic/php-parser/lib/PhpParser'),
|
'PhpParser\\' => array($vendorDir . '/nikic/php-parser/lib/PhpParser'),
|
||||||
|
|
6
vendor/composer/autoload_static.php
vendored
6
vendor/composer/autoload_static.php
vendored
|
@ -120,12 +120,12 @@ class ComposerStaticInit5f3db9fc1d0cf1dd6a77a1d84501b4b1
|
||||||
),
|
),
|
||||||
'Qferrer\\Mjml\\' =>
|
'Qferrer\\Mjml\\' =>
|
||||||
array (
|
array (
|
||||||
0 => __DIR__ . '/..' . '/qferr/mjml-php/src',
|
0 => __DIR__ . '/..' . '/kumi/mjml-php/src',
|
||||||
),
|
),
|
||||||
'Psr\\Http\\Message\\' =>
|
'Psr\\Http\\Message\\' =>
|
||||||
array (
|
array (
|
||||||
0 => __DIR__ . '/..' . '/psr/http-message/src',
|
0 => __DIR__ . '/..' . '/psr/http-factory/src',
|
||||||
1 => __DIR__ . '/..' . '/psr/http-factory/src',
|
1 => __DIR__ . '/..' . '/psr/http-message/src',
|
||||||
),
|
),
|
||||||
'Psr\\Http\\Client\\' =>
|
'Psr\\Http\\Client\\' =>
|
||||||
array (
|
array (
|
||||||
|
|
100
vendor/composer/installed.json
vendored
100
vendor/composer/installed.json
vendored
|
@ -650,6 +650,58 @@
|
||||||
},
|
},
|
||||||
"install-path": "../jaybizzle/crawler-detect"
|
"install-path": "../jaybizzle/crawler-detect"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "kumi/mjml-php",
|
||||||
|
"version": "dev-main",
|
||||||
|
"version_normalized": "dev-main",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://git.private.coffee/kumi/mjml-php.git",
|
||||||
|
"reference": "b8ce0c35cc3376b5fc5ecd913a6ea701d2de762d"
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"ext-curl": "*",
|
||||||
|
"ext-json": "*",
|
||||||
|
"php": ">=7.2"
|
||||||
|
},
|
||||||
|
"require-dev": {
|
||||||
|
"phpunit/phpunit": "^8.5"
|
||||||
|
},
|
||||||
|
"time": "2025-03-10T15:03:58+00:00",
|
||||||
|
"default-branch": true,
|
||||||
|
"type": "library",
|
||||||
|
"installation-source": "source",
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"Qferrer\\Mjml\\": "src/"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"autoload-dev": {
|
||||||
|
"psr-4": {
|
||||||
|
"Qferrer\\Tests\\Mjml\\": "tests/"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"scripts": {
|
||||||
|
"test": [
|
||||||
|
"phpunit tests/"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"license": [
|
||||||
|
"MIT"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Quentin",
|
||||||
|
"email": "qferrer@outook.com"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Kumi",
|
||||||
|
"email": "mjml-php@kumi.email"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "A simple PHP library to render MJML to HTML.",
|
||||||
|
"install-path": "../kumi/mjml-php"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "marcocesarato/php-conventional-changelog",
|
"name": "marcocesarato/php-conventional-changelog",
|
||||||
"version": "1.17.2",
|
"version": "1.17.2",
|
||||||
|
@ -1982,54 +2034,6 @@
|
||||||
},
|
},
|
||||||
"install-path": "../psr/http-message"
|
"install-path": "../psr/http-message"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"name": "qferr/mjml-php",
|
|
||||||
"version": "2.0.0",
|
|
||||||
"version_normalized": "2.0.0.0",
|
|
||||||
"source": {
|
|
||||||
"type": "git",
|
|
||||||
"url": "https://github.com/qferr/mjml-php.git",
|
|
||||||
"reference": "c7185024d8b561bd3b532b29f46cba0f4b789b70"
|
|
||||||
},
|
|
||||||
"dist": {
|
|
||||||
"type": "zip",
|
|
||||||
"url": "https://api.github.com/repos/qferr/mjml-php/zipball/c7185024d8b561bd3b532b29f46cba0f4b789b70",
|
|
||||||
"reference": "c7185024d8b561bd3b532b29f46cba0f4b789b70",
|
|
||||||
"shasum": ""
|
|
||||||
},
|
|
||||||
"require": {
|
|
||||||
"ext-curl": "*",
|
|
||||||
"ext-json": "*",
|
|
||||||
"php": ">=7.2"
|
|
||||||
},
|
|
||||||
"require-dev": {
|
|
||||||
"phpunit/phpunit": "^8.5"
|
|
||||||
},
|
|
||||||
"time": "2022-04-09T21:34:38+00:00",
|
|
||||||
"type": "library",
|
|
||||||
"installation-source": "dist",
|
|
||||||
"autoload": {
|
|
||||||
"psr-4": {
|
|
||||||
"Qferrer\\Mjml\\": "src/"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"notification-url": "https://packagist.org/downloads/",
|
|
||||||
"license": [
|
|
||||||
"MIT"
|
|
||||||
],
|
|
||||||
"authors": [
|
|
||||||
{
|
|
||||||
"name": "Quentin",
|
|
||||||
"email": "qferrer@outook.com"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"description": "A simple PHP library to render MJML to HTML.",
|
|
||||||
"support": {
|
|
||||||
"issues": "https://github.com/qferr/mjml-php/issues",
|
|
||||||
"source": "https://github.com/qferr/mjml-php/tree/2.0.0"
|
|
||||||
},
|
|
||||||
"install-path": "../qferr/mjml-php"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"name": "ralouphie/getallheaders",
|
"name": "ralouphie/getallheaders",
|
||||||
"version": "3.0.3",
|
"version": "3.0.3",
|
||||||
|
|
20
vendor/composer/installed.php
vendored
20
vendor/composer/installed.php
vendored
|
@ -100,6 +100,17 @@
|
||||||
'aliases' => array(),
|
'aliases' => array(),
|
||||||
'dev_requirement' => false,
|
'dev_requirement' => false,
|
||||||
),
|
),
|
||||||
|
'kumi/mjml-php' => array(
|
||||||
|
'pretty_version' => 'dev-main',
|
||||||
|
'version' => 'dev-main',
|
||||||
|
'reference' => 'b8ce0c35cc3376b5fc5ecd913a6ea701d2de762d',
|
||||||
|
'type' => 'library',
|
||||||
|
'install_path' => __DIR__ . '/../kumi/mjml-php',
|
||||||
|
'aliases' => array(
|
||||||
|
0 => '9999999-dev',
|
||||||
|
),
|
||||||
|
'dev_requirement' => false,
|
||||||
|
),
|
||||||
'marcocesarato/php-conventional-changelog' => array(
|
'marcocesarato/php-conventional-changelog' => array(
|
||||||
'pretty_version' => '1.17.2',
|
'pretty_version' => '1.17.2',
|
||||||
'version' => '1.17.2.0',
|
'version' => '1.17.2.0',
|
||||||
|
@ -298,15 +309,6 @@
|
||||||
0 => '1.0|2.0|3.0',
|
0 => '1.0|2.0|3.0',
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
'qferr/mjml-php' => array(
|
|
||||||
'pretty_version' => '2.0.0',
|
|
||||||
'version' => '2.0.0.0',
|
|
||||||
'reference' => 'c7185024d8b561bd3b532b29f46cba0f4b789b70',
|
|
||||||
'type' => 'library',
|
|
||||||
'install_path' => __DIR__ . '/../qferr/mjml-php',
|
|
||||||
'aliases' => array(),
|
|
||||||
'dev_requirement' => false,
|
|
||||||
),
|
|
||||||
'ralouphie/getallheaders' => array(
|
'ralouphie/getallheaders' => array(
|
||||||
'pretty_version' => '3.0.3',
|
'pretty_version' => '3.0.3',
|
||||||
'version' => '3.0.3.0',
|
'version' => '3.0.3.0',
|
||||||
|
|
1
vendor/kumi/mjml-php
vendored
Submodule
1
vendor/kumi/mjml-php
vendored
Submodule
|
@ -0,0 +1 @@
|
||||||
|
Subproject commit b8ce0c35cc3376b5fc5ecd913a6ea701d2de762d
|
53
vendor/qferr/mjml-php/.github/workflows/php.yml
vendored
53
vendor/qferr/mjml-php/.github/workflows/php.yml
vendored
|
@ -1,53 +0,0 @@
|
||||||
name: PHPUnit
|
|
||||||
|
|
||||||
on: ['push']
|
|
||||||
|
|
||||||
permissions:
|
|
||||||
contents: read
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
build:
|
|
||||||
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
|
|
||||||
strategy:
|
|
||||||
fail-fast: true
|
|
||||||
matrix:
|
|
||||||
php-versions: ['7.2', '7.3', '7.4', '8.0', '8.1']
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v3
|
|
||||||
|
|
||||||
# https://github.com/shivammathur/setup-php (community)
|
|
||||||
- name: Setup PHP, extensions and composer with shivammathur/setup-php
|
|
||||||
uses: shivammathur/setup-php@v2
|
|
||||||
with:
|
|
||||||
php-version: ${{ matrix.php-versions }}
|
|
||||||
extensions: json, curl
|
|
||||||
|
|
||||||
- uses: actions/setup-node@v3
|
|
||||||
with:
|
|
||||||
node-version: '14'
|
|
||||||
|
|
||||||
- name: Install JS dependencies
|
|
||||||
run: npm ci
|
|
||||||
|
|
||||||
- name: Validate composer.json and composer.lock
|
|
||||||
run: composer validate --strict
|
|
||||||
|
|
||||||
- name: Cache Composer packages
|
|
||||||
id: composer-cache
|
|
||||||
uses: actions/cache@v3
|
|
||||||
with:
|
|
||||||
path: vendor
|
|
||||||
key: ${{ runner.os }}-php-${{ hashFiles('**/composer.lock') }}
|
|
||||||
restore-keys: |
|
|
||||||
${{ runner.os }}-php-
|
|
||||||
|
|
||||||
- name: Install dependencies
|
|
||||||
run: composer update --no-interaction --no-scripts --no-progress
|
|
||||||
|
|
||||||
- name: Run test suite
|
|
||||||
run: composer run-script test
|
|
||||||
|
|
||||||
|
|
6
vendor/qferr/mjml-php/.gitignore
vendored
6
vendor/qferr/mjml-php/.gitignore
vendored
|
@ -1,6 +0,0 @@
|
||||||
.idea/
|
|
||||||
vendor/
|
|
||||||
node_modules/
|
|
||||||
phpunit.xml
|
|
||||||
.phpunit.result.cache
|
|
||||||
.php-cs-fixer.cache
|
|
78
vendor/qferr/mjml-php/README.md
vendored
78
vendor/qferr/mjml-php/README.md
vendored
|
@ -1,78 +0,0 @@
|
||||||
MJML in PHP
|
|
||||||
===========
|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
A simple PHP library to render MJML to HTML.
|
|
||||||
|
|
||||||
There are two ways for integrating MJML in PHP:
|
|
||||||
* using the MJML API
|
|
||||||
* using the MJML library
|
|
||||||
|
|
||||||
### Installation
|
|
||||||
|
|
||||||
```shell script
|
|
||||||
composer require qferr/mjml-php
|
|
||||||
```
|
|
||||||
|
|
||||||
### Using MJML library
|
|
||||||
|
|
||||||
Install the MJML library:
|
|
||||||
|
|
||||||
```shell script
|
|
||||||
npm install mjml --save
|
|
||||||
```
|
|
||||||
|
|
||||||
If you want a specific version, use the following syntax: `npm install mjml@4.7.1 --save`
|
|
||||||
|
|
||||||
```php
|
|
||||||
<?php
|
|
||||||
require_once 'vendor/autoload.php';
|
|
||||||
|
|
||||||
$renderer = new \Qferrer\Mjml\Renderer\BinaryRenderer(__DIR__ . '/node_modules/.bin/mjml');
|
|
||||||
|
|
||||||
$html = $renderer->render('
|
|
||||||
<mjml>
|
|
||||||
<mj-body>
|
|
||||||
<mj-section>
|
|
||||||
<mj-column>
|
|
||||||
<mj-text>Hello world</mj-text>
|
|
||||||
</mj-column>
|
|
||||||
</mj-section>
|
|
||||||
</mj-body>
|
|
||||||
</mjml>
|
|
||||||
');
|
|
||||||
```
|
|
||||||
|
|
||||||
### Using MJML API
|
|
||||||
|
|
||||||
```php
|
|
||||||
<?php
|
|
||||||
require_once 'vendor/autoload.php';
|
|
||||||
|
|
||||||
$apiId = 'abcdef-1234-5678-ghijkl';
|
|
||||||
$secretKey = 'ghijkl-5678-1234-abcdef';
|
|
||||||
|
|
||||||
$api = new \Qferrer\Mjml\Http\CurlApi($apiId, $secretKey);
|
|
||||||
$renderer = new \Qferrer\Mjml\Renderer\ApiRenderer($api);
|
|
||||||
|
|
||||||
$html = $renderer->render('
|
|
||||||
<mjml>
|
|
||||||
<mj-body>
|
|
||||||
<mj-section>
|
|
||||||
<mj-column>
|
|
||||||
<mj-text>Hello world</mj-text>
|
|
||||||
</mj-column>
|
|
||||||
</mj-section>
|
|
||||||
</mj-body>
|
|
||||||
</mjml>
|
|
||||||
');
|
|
||||||
```
|
|
||||||
|
|
||||||
You can get the version of MJML used by the API to transpile:
|
|
||||||
|
|
||||||
```php
|
|
||||||
$api->getMjmlVersion();
|
|
||||||
```
|
|
||||||
|
|
||||||
More details in the API documentation: [https://mjml.io/api/documentation](https://mjml.io/api/documentation)
|
|
38
vendor/qferr/mjml-php/composer.json
vendored
38
vendor/qferr/mjml-php/composer.json
vendored
|
@ -1,38 +0,0 @@
|
||||||
{
|
|
||||||
"name": "qferr/mjml-php",
|
|
||||||
"description": "A simple PHP library to render MJML to HTML.",
|
|
||||||
"type": "library",
|
|
||||||
"license": "MIT",
|
|
||||||
"authors": [
|
|
||||||
{
|
|
||||||
"name": "Quentin",
|
|
||||||
"email": "qferrer@outook.com"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"require": {
|
|
||||||
"php": ">=7.2",
|
|
||||||
"ext-curl": "*",
|
|
||||||
"ext-json": "*"
|
|
||||||
},
|
|
||||||
"require-dev": {
|
|
||||||
"phpunit/phpunit": "^8.5"
|
|
||||||
},
|
|
||||||
"autoload": {
|
|
||||||
"psr-4": {
|
|
||||||
"Qferrer\\Mjml\\" : "src/"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"autoload-dev": {
|
|
||||||
"psr-4": {
|
|
||||||
"Qferrer\\Tests\\Mjml\\" : "tests/"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"scripts": {
|
|
||||||
"test": "phpunit tests/"
|
|
||||||
},
|
|
||||||
"config": {
|
|
||||||
"platform": {
|
|
||||||
"php": "7.2.30"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
1806
vendor/qferr/mjml-php/composer.lock
generated
vendored
1806
vendor/qferr/mjml-php/composer.lock
generated
vendored
File diff suppressed because it is too large
Load diff
1248
vendor/qferr/mjml-php/package-lock.json
generated
vendored
1248
vendor/qferr/mjml-php/package-lock.json
generated
vendored
File diff suppressed because it is too large
Load diff
12
vendor/qferr/mjml-php/package.json
vendored
12
vendor/qferr/mjml-php/package.json
vendored
|
@ -1,12 +0,0 @@
|
||||||
{
|
|
||||||
"name": "mjml-php",
|
|
||||||
"description": "MJML in PHP",
|
|
||||||
"author": "Quentin Ferrer",
|
|
||||||
"bugs": {
|
|
||||||
"url": "https://github.com/qferr/mjml-php/issues"
|
|
||||||
},
|
|
||||||
"homepage": "https://github.com/qferr/mjml-php#readme",
|
|
||||||
"devDependencies": {
|
|
||||||
"mjml": "^4.12.0"
|
|
||||||
}
|
|
||||||
}
|
|
18
vendor/qferr/mjml-php/phpunit.xml.dist
vendored
18
vendor/qferr/mjml-php/phpunit.xml.dist
vendored
|
@ -1,18 +0,0 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
|
|
||||||
<!-- https://phpunit.readthedocs.io/en/latest/configuration.html -->
|
|
||||||
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
|
||||||
xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/6.3/phpunit.xsd"
|
|
||||||
backupGlobals="false"
|
|
||||||
colors="true"
|
|
||||||
>
|
|
||||||
<php>
|
|
||||||
<ini name="error_reporting" value="-1" />
|
|
||||||
</php>
|
|
||||||
|
|
||||||
<testsuites>
|
|
||||||
<testsuite name="Project Test Suite">
|
|
||||||
<directory>tests</directory>
|
|
||||||
</testsuite>
|
|
||||||
</testsuites>
|
|
||||||
</phpunit>
|
|
26
vendor/qferr/mjml-php/src/ApiInterface.php
vendored
26
vendor/qferr/mjml-php/src/ApiInterface.php
vendored
|
@ -1,26 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
namespace Qferrer\Mjml;
|
|
||||||
|
|
||||||
use Qferrer\Mjml\Exception\ApiException;
|
|
||||||
|
|
||||||
interface ApiInterface
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* Renders a MJML to HTML content.
|
|
||||||
*
|
|
||||||
* @param string $mjml The MJML content
|
|
||||||
*
|
|
||||||
* @return string The generated HTML
|
|
||||||
*
|
|
||||||
* @throws ApiException
|
|
||||||
*/
|
|
||||||
public function getHtml(string $mjml): string;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the version of MJML used by the API to transpile.
|
|
||||||
*
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
public function getMjmlVersion(): string;
|
|
||||||
}
|
|
|
@ -1,7 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
namespace Qferrer\Mjml\Exception;
|
|
||||||
|
|
||||||
class ApiException extends \RuntimeException
|
|
||||||
{
|
|
||||||
}
|
|
|
@ -1,7 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
namespace Qferrer\Mjml\Exception;
|
|
||||||
|
|
||||||
class CurlException extends \RuntimeException
|
|
||||||
{
|
|
||||||
}
|
|
|
@ -1,7 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
namespace Qferrer\Mjml\Exception;
|
|
||||||
|
|
||||||
class ProcessException extends \RuntimeException
|
|
||||||
{
|
|
||||||
}
|
|
31
vendor/qferr/mjml-php/src/Http/Curl.php
vendored
31
vendor/qferr/mjml-php/src/Http/Curl.php
vendored
|
@ -1,31 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
namespace Qferrer\Mjml\Http;
|
|
||||||
|
|
||||||
use Qferrer\Mjml\Exception\CurlException;
|
|
||||||
|
|
||||||
class Curl implements CurlInterface
|
|
||||||
{
|
|
||||||
public function request(string $url, array $options = []): CurlResponseInterface
|
|
||||||
{
|
|
||||||
$request = @curl_init($url);
|
|
||||||
|
|
||||||
if (false === $request) {
|
|
||||||
throw new CurlException('Unable to initialize Curl.');
|
|
||||||
}
|
|
||||||
|
|
||||||
curl_setopt_array($request, $options);
|
|
||||||
|
|
||||||
$data = curl_exec($request);
|
|
||||||
|
|
||||||
if (false === $data) {
|
|
||||||
throw new CurlException(sprintf('Curl Error: "%s"', curl_error($request)));
|
|
||||||
}
|
|
||||||
|
|
||||||
$response = new CurlResponse($data, curl_getinfo($request, CURLINFO_HTTP_CODE));
|
|
||||||
|
|
||||||
curl_close($request);
|
|
||||||
|
|
||||||
return $response;
|
|
||||||
}
|
|
||||||
}
|
|
88
vendor/qferr/mjml-php/src/Http/CurlApi.php
vendored
88
vendor/qferr/mjml-php/src/Http/CurlApi.php
vendored
|
@ -1,88 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
declare(strict_types=1);
|
|
||||||
|
|
||||||
namespace Qferrer\Mjml\Http;
|
|
||||||
|
|
||||||
use Qferrer\Mjml\ApiInterface;
|
|
||||||
use Qferrer\Mjml\Exception\ApiException;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @see https://mjml.io/api/documentation/
|
|
||||||
*/
|
|
||||||
final class CurlApi implements ApiInterface
|
|
||||||
{
|
|
||||||
protected $apiEndpoint = "https://api.mjml.io/v1";
|
|
||||||
protected $appId;
|
|
||||||
protected $secretKey;
|
|
||||||
protected $credentials;
|
|
||||||
protected $curl;
|
|
||||||
|
|
||||||
public function __construct(string $appId, string $secretKey, ?CurlInterface $curl = null)
|
|
||||||
{
|
|
||||||
if (!\extension_loaded('curl')) {
|
|
||||||
throw new \LogicException(sprintf(
|
|
||||||
'You cannot use the "%s" as the "curl" extension is not installed.',
|
|
||||||
CurlApi::class
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->appId = $appId;
|
|
||||||
$this->secretKey = $secretKey;
|
|
||||||
$this->credentials = base64_encode("$appId:$secretKey");
|
|
||||||
$this->curl = $curl ?? new Curl();
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getHtml(string $mjml): string
|
|
||||||
{
|
|
||||||
$data = $this->getResult($mjml);
|
|
||||||
|
|
||||||
return $data['html'] ?? '';
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getMjmlVersion(): string
|
|
||||||
{
|
|
||||||
$data = $this->getResult('<mjml></mjml>');
|
|
||||||
|
|
||||||
return $data['mjml_version'] ?? 'unknown';
|
|
||||||
}
|
|
||||||
|
|
||||||
private function getResult(string $mjml): array
|
|
||||||
{
|
|
||||||
$response = $this->curl->request($this->apiEndpoint . '/render', [
|
|
||||||
CURLOPT_RETURNTRANSFER => true,
|
|
||||||
CURLOPT_ENCODING => "UTF-8",
|
|
||||||
CURLOPT_MAXREDIRS => 10,
|
|
||||||
CURLOPT_TIMEOUT => 0,
|
|
||||||
CURLOPT_FOLLOWLOCATION => true,
|
|
||||||
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
|
|
||||||
CURLOPT_POST => true,
|
|
||||||
CURLOPT_POSTFIELDS => json_encode(['mjml' => $mjml]),
|
|
||||||
CURLOPT_HTTPHEADER => [
|
|
||||||
"Content-Type: application/json",
|
|
||||||
"Authorization: Basic {$this->credentials}"
|
|
||||||
]
|
|
||||||
]);
|
|
||||||
|
|
||||||
$data = @json_decode($response->getContent(), true);
|
|
||||||
|
|
||||||
if (false === $data || null === $data) {
|
|
||||||
throw new ApiException(sprintf(
|
|
||||||
'Unable to decode the JSON response: "%s".',
|
|
||||||
json_last_error_msg()
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
$httpCode = $response->getStatusCode();
|
|
||||||
|
|
||||||
if ($httpCode !== 200) {
|
|
||||||
throw new ApiException(sprintf(
|
|
||||||
'Unexpected HTTP code: %s. Api Error Message: "%s".',
|
|
||||||
$httpCode,
|
|
||||||
$data['message'] ?? 'Unknown Error'
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
return $data;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,8 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
namespace Qferrer\Mjml\Http;
|
|
||||||
|
|
||||||
interface CurlInterface
|
|
||||||
{
|
|
||||||
public function request(string $url, array $options = []): CurlResponseInterface;
|
|
||||||
}
|
|
25
vendor/qferr/mjml-php/src/Http/CurlResponse.php
vendored
25
vendor/qferr/mjml-php/src/Http/CurlResponse.php
vendored
|
@ -1,25 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
namespace Qferrer\Mjml\Http;
|
|
||||||
|
|
||||||
class CurlResponse implements CurlResponseInterface
|
|
||||||
{
|
|
||||||
private $data;
|
|
||||||
private $statusCode;
|
|
||||||
|
|
||||||
public function __construct($data, int $statusCode)
|
|
||||||
{
|
|
||||||
$this->data = $data;
|
|
||||||
$this->statusCode = $statusCode;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getContent()
|
|
||||||
{
|
|
||||||
return $this->data;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getStatusCode(): int
|
|
||||||
{
|
|
||||||
return $this->statusCode;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,13 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
namespace Qferrer\Mjml\Http;
|
|
||||||
|
|
||||||
interface CurlResponseInterface
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* @return mixed
|
|
||||||
*/
|
|
||||||
public function getContent();
|
|
||||||
|
|
||||||
public function getStatusCode(): int;
|
|
||||||
}
|
|
91
vendor/qferr/mjml-php/src/Process/Process.php
vendored
91
vendor/qferr/mjml-php/src/Process/Process.php
vendored
|
@ -1,91 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
namespace Qferrer\Mjml\Process;
|
|
||||||
|
|
||||||
use Qferrer\Mjml\Exception\ProcessException;
|
|
||||||
|
|
||||||
class Process
|
|
||||||
{
|
|
||||||
private $command;
|
|
||||||
private $input;
|
|
||||||
private $output;
|
|
||||||
private $errorMessage = '';
|
|
||||||
|
|
||||||
public const STDIN = 0;
|
|
||||||
public const STDOUT = 1;
|
|
||||||
public const STDERR = 2;
|
|
||||||
|
|
||||||
private static $descriptors = [
|
|
||||||
self::STDIN => ['pipe', 'r'],
|
|
||||||
self::STDOUT => ['pipe', 'w'],
|
|
||||||
self::STDERR => ['pipe', 'w']
|
|
||||||
];
|
|
||||||
|
|
||||||
public function __construct(string $command, string $input)
|
|
||||||
{
|
|
||||||
$this->command = $command;
|
|
||||||
$this->input = $input;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function run(): void
|
|
||||||
{
|
|
||||||
$this->initialize();
|
|
||||||
|
|
||||||
$pipes = [];
|
|
||||||
$process = $this->createProcess($pipes);
|
|
||||||
|
|
||||||
$this->setInput($pipes);
|
|
||||||
$this->setOutput($pipes);
|
|
||||||
$this->setErrorMessage($pipes);
|
|
||||||
|
|
||||||
if (0 !== proc_close($process)) {
|
|
||||||
throw new ProcessException($this->errorMessage);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getOutput()
|
|
||||||
{
|
|
||||||
return $this->output;
|
|
||||||
}
|
|
||||||
|
|
||||||
private function initialize(): void
|
|
||||||
{
|
|
||||||
$this->output = null;
|
|
||||||
$this->errorMessage = '';
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return resource
|
|
||||||
*/
|
|
||||||
private function createProcess(array &$pipes)
|
|
||||||
{
|
|
||||||
$process = proc_open($this->command, self::$descriptors, $pipes);
|
|
||||||
|
|
||||||
if (!is_resource($process)) {
|
|
||||||
throw new ProcessException('Unable to create a process.');
|
|
||||||
}
|
|
||||||
|
|
||||||
return $process;
|
|
||||||
}
|
|
||||||
|
|
||||||
private function setInput(array $pipes): void
|
|
||||||
{
|
|
||||||
$stdin = $pipes[self::STDIN];
|
|
||||||
fwrite($stdin, $this->input);
|
|
||||||
fclose($stdin);
|
|
||||||
}
|
|
||||||
|
|
||||||
private function setOutput(array $pipes): void
|
|
||||||
{
|
|
||||||
$stdout = $pipes[self::STDOUT];
|
|
||||||
$this->output = stream_get_contents($stdout);
|
|
||||||
fclose($stdout);
|
|
||||||
}
|
|
||||||
|
|
||||||
private function setErrorMessage(array $pipes): void
|
|
||||||
{
|
|
||||||
$stderr = $pipes[self::STDERR];
|
|
||||||
$this->errorMessage = stream_get_contents($stderr);
|
|
||||||
fclose($stderr);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,37 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
namespace Qferrer\Mjml\Renderer;
|
|
||||||
|
|
||||||
use Qferrer\Mjml\ApiInterface;
|
|
||||||
use Qferrer\Mjml\RendererInterface;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Class ApiRenderer
|
|
||||||
*/
|
|
||||||
class ApiRenderer implements RendererInterface
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* The HTTP client.
|
|
||||||
*
|
|
||||||
* @var ApiInterface
|
|
||||||
*/
|
|
||||||
private $client;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* ApiRenderer constructor.
|
|
||||||
*
|
|
||||||
* @param ApiInterface $httpClient
|
|
||||||
*/
|
|
||||||
public function __construct(ApiInterface $httpClient)
|
|
||||||
{
|
|
||||||
$this->client = $httpClient;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @inheritDoc
|
|
||||||
*/
|
|
||||||
public function render(string $content): string
|
|
||||||
{
|
|
||||||
return $this->client->getHtml($content);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,46 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
namespace Qferrer\Mjml\Renderer;
|
|
||||||
|
|
||||||
use Qferrer\Mjml\Process\Process;
|
|
||||||
use Qferrer\Mjml\RendererInterface;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Class BinaryRenderer
|
|
||||||
*/
|
|
||||||
class BinaryRenderer implements RendererInterface
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* The MJML CLI path.
|
|
||||||
*
|
|
||||||
* @var string
|
|
||||||
*/
|
|
||||||
private $bin;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @var string
|
|
||||||
*/
|
|
||||||
private $command;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* BinaryRenderer constructor.
|
|
||||||
*
|
|
||||||
* @param string $bin
|
|
||||||
*/
|
|
||||||
public function __construct(string $bin)
|
|
||||||
{
|
|
||||||
$this->bin = $bin;
|
|
||||||
$this->command = "{$this->bin} -i -s --config.validationLevel --config.minify";
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @inheritDoc
|
|
||||||
*/
|
|
||||||
public function render(string $content): string
|
|
||||||
{
|
|
||||||
$process = new Process($this->command, $content);
|
|
||||||
$process->run();
|
|
||||||
|
|
||||||
return $process->getOutput();
|
|
||||||
}
|
|
||||||
}
|
|
18
vendor/qferr/mjml-php/src/RendererInterface.php
vendored
18
vendor/qferr/mjml-php/src/RendererInterface.php
vendored
|
@ -1,18 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
namespace Qferrer\Mjml;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Interface RendererInterface
|
|
||||||
*/
|
|
||||||
interface RendererInterface
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* Renders MJML to HTML content.
|
|
||||||
*
|
|
||||||
* @param string $content The MJML content
|
|
||||||
*
|
|
||||||
* @return string The generated HTML
|
|
||||||
*/
|
|
||||||
public function render(string $content): string;
|
|
||||||
}
|
|
94
vendor/qferr/mjml-php/tests/Http/CurlApiTest.php
vendored
94
vendor/qferr/mjml-php/tests/Http/CurlApiTest.php
vendored
|
@ -1,94 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
namespace Qferrer\Tests\Mjml\Http;
|
|
||||||
|
|
||||||
use PHPUnit\Framework\TestCase;
|
|
||||||
use Qferrer\Mjml\Http\CurlApi;
|
|
||||||
use Qferrer\Mjml\Exception\ApiException;
|
|
||||||
use Qferrer\Mjml\Http\CurlInterface;
|
|
||||||
use Qferrer\Mjml\Http\CurlResponseInterface;
|
|
||||||
|
|
||||||
class CurlApiTest extends TestCase
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* @var \PHPUnit\Framework\MockObject\MockObject|CurlInterface
|
|
||||||
*/
|
|
||||||
private $curl;
|
|
||||||
private $api;
|
|
||||||
private $response;
|
|
||||||
|
|
||||||
protected function setUp(): void
|
|
||||||
{
|
|
||||||
$this->response = $this->createMock(CurlResponseInterface::class);
|
|
||||||
$this->curl = $this->createMock(CurlInterface::class);
|
|
||||||
$this->curl->method('request')->willReturn($this->response);
|
|
||||||
$this->api = new CurlApi('test', 'mysecret', $this->curl);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function testGetHtml()
|
|
||||||
{
|
|
||||||
$html = '<p>Hello World</p>';
|
|
||||||
|
|
||||||
$this->configureResponseMock(['html' => $html], 200);
|
|
||||||
$this->curl->method('request')->with('https://api.mjml.io/v1/render', [
|
|
||||||
CURLOPT_RETURNTRANSFER => true,
|
|
||||||
CURLOPT_ENCODING => "UTF-8",
|
|
||||||
CURLOPT_MAXREDIRS => 10,
|
|
||||||
CURLOPT_TIMEOUT => 0,
|
|
||||||
CURLOPT_FOLLOWLOCATION => true,
|
|
||||||
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
|
|
||||||
CURLOPT_POST => true,
|
|
||||||
CURLOPT_POSTFIELDS => json_encode(['mjml' => 'test']),
|
|
||||||
CURLOPT_HTTPHEADER => [
|
|
||||||
"Content-Type: application/json",
|
|
||||||
"Authorization: Basic " . base64_encode("test:mysecret")
|
|
||||||
]
|
|
||||||
]);
|
|
||||||
|
|
||||||
$this->assertEquals($html, $this->api->getHtml('test'));
|
|
||||||
}
|
|
||||||
|
|
||||||
public function testGetHtmlWithInvalidStatusCode()
|
|
||||||
{
|
|
||||||
$this->configureResponseMock([], 400);
|
|
||||||
$this->expectException(ApiException::class);
|
|
||||||
$this->expectExceptionMessage('Unexpected HTTP code: 400. Api Error Message: "Unknown Error"');
|
|
||||||
|
|
||||||
$this->api->getHtml('test');
|
|
||||||
}
|
|
||||||
|
|
||||||
public function testGetHtmlWithInvalidStatusCodeAndErrorMessage()
|
|
||||||
{
|
|
||||||
$this->configureResponseMock(['message' => 'Invalid JSON'], 400);
|
|
||||||
$this->expectException(ApiException::class);
|
|
||||||
$this->expectExceptionMessage('Unexpected HTTP code: 400. Api Error Message: "Invalid JSON"');
|
|
||||||
|
|
||||||
$this->api->getHtml('test');
|
|
||||||
}
|
|
||||||
|
|
||||||
public function testGetHtmlWithInvalidContent()
|
|
||||||
{
|
|
||||||
$this->configureResponseMock('{invalid json}', 200);
|
|
||||||
$this->expectException(ApiException::class);
|
|
||||||
$this->expectExceptionMessage('Unable to decode the JSON response: "Syntax error".');
|
|
||||||
|
|
||||||
$this->api->getHtml('test');
|
|
||||||
}
|
|
||||||
|
|
||||||
public function testGetMjmlVersion()
|
|
||||||
{
|
|
||||||
$this->configureResponseMock(['mjml_version' => '4.4.0'], 200);
|
|
||||||
|
|
||||||
$this->assertEquals('4.4.0', $this->api->getMjmlVersion());
|
|
||||||
}
|
|
||||||
|
|
||||||
private function configureResponseMock($data, int $statusCode)
|
|
||||||
{
|
|
||||||
if (is_array($data)) {
|
|
||||||
$data = json_encode($data);
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->response->method('getContent')->willReturn($data);
|
|
||||||
$this->response->method('getStatusCode')->willReturn($statusCode);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,30 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
namespace Qferrer\Tests\Mjml\Renderer;
|
|
||||||
|
|
||||||
use PHPUnit\Framework\TestCase;
|
|
||||||
use Qferrer\Mjml\ApiInterface;
|
|
||||||
use Qferrer\Mjml\Http\CurlApi;
|
|
||||||
use Qferrer\Mjml\Renderer\ApiRenderer;
|
|
||||||
|
|
||||||
class ApiRendererTests extends TestCase
|
|
||||||
{
|
|
||||||
private $httpClient;
|
|
||||||
private $apiRenderer;
|
|
||||||
|
|
||||||
protected function setUp(): void
|
|
||||||
{
|
|
||||||
$this->httpClient = $this->createMock(ApiInterface::class);
|
|
||||||
$this->apiRenderer = new ApiRenderer($this->httpClient);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function testRender()
|
|
||||||
{
|
|
||||||
$expectedHtml = '<p>Test</p>';
|
|
||||||
$this->httpClient->expects($this->once())->method('getHtml')->willReturn($expectedHtml);
|
|
||||||
|
|
||||||
$html = $this->apiRenderer->render('<mjml>Test</mjml>');
|
|
||||||
|
|
||||||
$this->assertEquals($expectedHtml, $html);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,40 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
namespace Qferrer\Tests\Mjml\Renderer;
|
|
||||||
|
|
||||||
use PHPUnit\Framework\TestCase;
|
|
||||||
use Qferrer\Mjml\Exception\ProcessException;
|
|
||||||
use Qferrer\Mjml\Renderer\BinaryRenderer;
|
|
||||||
use Qferrer\Tests\Mjml\ResourcesTrait;
|
|
||||||
|
|
||||||
class BinaryRendererTest extends TestCase
|
|
||||||
{
|
|
||||||
use ResourcesTrait;
|
|
||||||
|
|
||||||
public function testRender()
|
|
||||||
{
|
|
||||||
$renderer = new BinaryRenderer(__DIR__ . '/../../node_modules/.bin/mjml');
|
|
||||||
|
|
||||||
$html = $renderer->render($this->loadResource('hello_world.mjml'));
|
|
||||||
|
|
||||||
$this->assertEquals($this->loadResource('hello_world.min.html.text'), $html);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function testRenderWithInvalidBinaryThrowException()
|
|
||||||
{
|
|
||||||
$this->expectException(ProcessException::class);
|
|
||||||
$this->expectExceptionMessage('unknown');
|
|
||||||
|
|
||||||
$renderer = new BinaryRenderer('unknown');
|
|
||||||
$renderer->render($this->loadResource('hello_world.mjml'));
|
|
||||||
}
|
|
||||||
|
|
||||||
public function testRenderWithMalformedMjml()
|
|
||||||
{
|
|
||||||
$this->expectException(ProcessException::class);
|
|
||||||
$this->expectExceptionMessage('Malformed MJML. Check that your structure is correct and enclosed in <mjml> tags.');
|
|
||||||
|
|
||||||
$renderer = new BinaryRenderer(__DIR__ . '/../../node_modules/.bin/mjml');
|
|
||||||
$renderer->render('<mljm></mljm>');
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,53 +0,0 @@
|
||||||
<!-- FILE: undefined -->
|
|
||||||
<!doctype html><html xmlns="http://www.w3.org/1999/xhtml" xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office"><head><title></title><!--[if !mso]><!--><meta http-equiv="X-UA-Compatible" content="IE=edge"><!--<![endif]--><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><meta name="viewport" content="width=device-width,initial-scale=1"><style type="text/css">#outlook a {
|
|
||||||
padding: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
body {
|
|
||||||
margin: 0;
|
|
||||||
padding: 0;
|
|
||||||
-webkit-text-size-adjust: 100%;
|
|
||||||
-ms-text-size-adjust: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
table,
|
|
||||||
td {
|
|
||||||
border-collapse: collapse;
|
|
||||||
mso-table-lspace: 0pt;
|
|
||||||
mso-table-rspace: 0pt;
|
|
||||||
}
|
|
||||||
|
|
||||||
img {
|
|
||||||
border: 0;
|
|
||||||
height: auto;
|
|
||||||
line-height: 100%;
|
|
||||||
outline: none;
|
|
||||||
text-decoration: none;
|
|
||||||
-ms-interpolation-mode: bicubic;
|
|
||||||
}
|
|
||||||
|
|
||||||
p {
|
|
||||||
display: block;
|
|
||||||
margin: 13px 0;
|
|
||||||
}</style><!--[if mso]>
|
|
||||||
<noscript>
|
|
||||||
<xml>
|
|
||||||
<o:OfficeDocumentSettings>
|
|
||||||
<o:AllowPNG/>
|
|
||||||
<o:PixelsPerInch>96</o:PixelsPerInch>
|
|
||||||
</o:OfficeDocumentSettings>
|
|
||||||
</xml>
|
|
||||||
</noscript>
|
|
||||||
<![endif]--><!--[if lte mso 11]>
|
|
||||||
<style type="text/css">
|
|
||||||
.mj-outlook-group-fix { width:100% !important; }
|
|
||||||
</style>
|
|
||||||
<![endif]--><!--[if !mso]><!--><link href="https://fonts.googleapis.com/css?family=Ubuntu:300,400,500,700" rel="stylesheet" type="text/css"><style type="text/css">@import url(https://fonts.googleapis.com/css?family=Ubuntu:300,400,500,700);</style><!--<![endif]--><style type="text/css">@media only screen and (min-width:480px) {
|
|
||||||
.mj-column-per-100 {
|
|
||||||
width: 100% !important;
|
|
||||||
max-width: 100%;
|
|
||||||
}
|
|
||||||
}</style><style media="screen and (min-width:480px)">.moz-text-html .mj-column-per-100 {
|
|
||||||
width: 100% !important;
|
|
||||||
max-width: 100%;
|
|
||||||
}</style><style type="text/css"></style><style type="text/css"></style></head><body style="word-spacing:normal;"><div><!--[if mso | IE]><table align="center" border="0" cellpadding="0" cellspacing="0" class="" role="presentation" style="width:600px;" width="600" ><tr><td style="line-height:0px;font-size:0px;mso-line-height-rule:exactly;"><![endif]--><div style="margin:0px auto;max-width:600px;"><table align="center" border="0" cellpadding="0" cellspacing="0" role="presentation" style="width:100%;"><tbody><tr><td style="direction:ltr;font-size:0px;padding:20px 0;text-align:center;"><!--[if mso | IE]><table role="presentation" border="0" cellpadding="0" cellspacing="0"><tr><td class="" style="vertical-align:top;width:600px;" ><![endif]--><div class="mj-column-per-100 mj-outlook-group-fix" style="font-size:0px;text-align:left;direction:ltr;display:inline-block;vertical-align:top;width:100%;"><table border="0" cellpadding="0" cellspacing="0" role="presentation" style="vertical-align:top;" width="100%"><tbody><tr><td align="left" style="font-size:0px;padding:10px 25px;word-break:break-word;"><div style="font-family:Ubuntu, Helvetica, Arial, sans-serif;font-size:13px;line-height:1;text-align:left;color:#000000;">Hello world</div></td></tr></tbody></table></div><!--[if mso | IE]></td></tr></table><![endif]--></td></tr></tbody></table></div><!--[if mso | IE]></td></tr></table><![endif]--></div></body></html>
|
|
|
@ -1,9 +0,0 @@
|
||||||
<mjml>
|
|
||||||
<mj-body>
|
|
||||||
<mj-section>
|
|
||||||
<mj-column>
|
|
||||||
<mj-text>Hello world</mj-text>
|
|
||||||
</mj-column>
|
|
||||||
</mj-section>
|
|
||||||
</mj-body>
|
|
||||||
</mjml>
|
|
11
vendor/qferr/mjml-php/tests/ResourcesTrait.php
vendored
11
vendor/qferr/mjml-php/tests/ResourcesTrait.php
vendored
|
@ -1,11 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
namespace Qferrer\Tests\Mjml;
|
|
||||||
|
|
||||||
trait ResourcesTrait
|
|
||||||
{
|
|
||||||
private function loadResource($filename)
|
|
||||||
{
|
|
||||||
return file_get_contents(__DIR__ . '/Resources/' . $filename);
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
Add table
Add a link
Reference in a new issue