[TASK] Init

This commit is contained in:
Daniel Huf 2017-12-14 14:00:53 +01:00
parent 91027442a7
commit a7c019d658
9 changed files with 310 additions and 2 deletions

14
.gitignore vendored Normal file
View file

@ -0,0 +1,14 @@
# ide
/.project
/.buildpath
/.settings
/.nbproject
/.idea
# git
/.auth.json
# node / grunt / sass / bower
.sass-cache
node_modules
bower_components

View file

@ -0,0 +1,130 @@
<?php
declare(strict_types=1);
namespace Saccas\Mjml\Domain\Finishers;
/*
* This file is part of the TYPO3 CMS project.
*
* It is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License, either version 2
* of the License, or any later version.
*
* For the full copyright and license information, please read the
* LICENSE.txt file that was distributed with this source code.
*
* The TYPO3 project - inspiring people to share!
*/
use TYPO3\CMS\Core\Mail\MailMessage;
use TYPO3\CMS\Extbase\Domain\Model\FileReference;
use TYPO3\CMS\Fluid\View\StandaloneView;
use TYPO3\CMS\Form\Domain\Finishers\Exception\FinisherException;
use TYPO3\CMS\Form\Domain\Model\FormElements\FileUpload;
use TYPO3\CMS\Form\Domain\Runtime\FormRuntime;
use TYPO3\CMS\Form\Service\TranslationService;
use TYPO3\CMS\Form\ViewHelpers\RenderRenderableViewHelper;
use Saccas\Mjml\View\MjmlBasedView;
/**
* This finisher sends an email to one recipient
*
* Options:
*
* - templatePathAndFilename (mandatory): Template path and filename for the mail body
* - layoutRootPath: root path for the layouts
* - partialRootPath: root path for the partials
* - variables: associative array of variables which are available inside the Fluid template
*
* The following options control the mail sending. In all of them, placeholders in the form
* of {...} are replaced with the corresponding form value; i.e. {email} as recipientAddress
* makes the recipient address configurable.
*
* - subject (mandatory): Subject of the email
* - recipientAddress (mandatory): Email address of the recipient
* - recipientName: Human-readable name of the recipient
* - senderAddress (mandatory): Email address of the sender
* - senderName: Human-readable name of the sender
* - replyToAddress: Email address of to be used as reply-to email (use multiple addresses with an array)
* - carbonCopyAddress: Email address of the copy recipient (use multiple addresses with an array)
* - blindCarbonCopyAddress: Email address of the blind copy recipient (use multiple addresses with an array)
* - format: format of the email (one of the FORMAT_* constants). By default mails are sent as HTML
*
* Scope: frontend
*/
class MjmlEmailFinisher extends \TYPO3\CMS\Form\Domain\Finishers\EmailFinisher
{
const FORMAT_PLAINTEXT = 'plaintext';
const FORMAT_HTML = 'html';
/**
* @var array
*/
protected $defaultOptions = [
'recipientName' => '',
'senderName' => '',
'format' => self::FORMAT_HTML,
'attachUploads' => true
];
/**
* Executes this finisher
* @see AbstractFinisher::execute()
*
* @throws FinisherException
*/
protected function executeInternal()
{
parent::executeInternal();
}
/**
* @param FormRuntime $formRuntime
* @return StandaloneView
* @throws FinisherException
*/
protected function initializeStandaloneView(FormRuntime $formRuntime): StandaloneView
{
$format = ucfirst($this->parseOption('format'));
$standaloneView = $this->objectManager->get(MjmlBasedView::class);
if (isset($this->options['templatePathAndFilename'])) {
$this->options['templatePathAndFilename'] = strtr($this->options['templatePathAndFilename'], [
'{@format}' => $format
]);
$standaloneView->setTemplatePathAndFilename($this->options['templatePathAndFilename']);
} else {
if (!isset($this->options['templateName'])) {
throw new FinisherException('The option "templateName" must be set for the EmailFinisher.', 1327058829);
}
$this->options['templateName'] = strtr($this->options['templateName'], [
'{@format}' => $format
]);
$standaloneView->setTemplate($this->options['templateName']);
}
$standaloneView->assign('finisherVariableProvider', $this->finisherContext->getFinisherVariableProvider());
if (isset($this->options['templateRootPaths']) && is_array($this->options['templateRootPaths'])) {
$standaloneView->setTemplateRootPaths($this->options['templateRootPaths']);
}
if (isset($this->options['partialRootPaths']) && is_array($this->options['partialRootPaths'])) {
$standaloneView->setPartialRootPaths($this->options['partialRootPaths']);
}
if (isset($this->options['layoutRootPaths']) && is_array($this->options['layoutRootPaths'])) {
$standaloneView->setLayoutRootPaths($this->options['layoutRootPaths']);
}
if (isset($this->options['variables'])) {
$standaloneView->assignMultiple($this->options['variables']);
}
$standaloneView->assign('form', $formRuntime);
$standaloneView->getRenderingContext()
->getViewHelperVariableContainer()
->addOrUpdate(RenderRenderableViewHelper::class, 'formRuntime', $formRuntime);
return $standaloneView;
}
}

View file

@ -0,0 +1,34 @@
<?php
namespace Saccas\Mjml\View;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Fluid\View\StandaloneView;
use TYPO3\CMS\Core\Utility\CommandUtility;
class MjmlBasedView extends StandaloneView
{
function render()
{
return $this->getHtmlFromMjml(parent::render());
}
protected function getHtmlFromMjml($mjml)
{
$configuration = unserialize($GLOBALS['TYPO3_CONF_VARS']['EXT']['extConf']['mjml']);
$temporaryMjmlFileWithPath = GeneralUtility::tempnam('mjml_', '.mjml');
$mjmlFile = fopen($temporaryMjmlFileWithPath, 'w');
fwrite($mjmlFile, $mjml);
fclose($mjmlFile);
// see https://mjml.io/download and https://www.npmjs.com/package/mjml-cli
$cmd = $configuration['nodeBinaryPath'] . ' ' . $configuration['mjmlBinaryPath'] . $configuration['mjmlBinary'] .' ' . $configuration['mjmlParams'] . ' ' . $temporaryMjmlFileWithPath;
$result = [];
$returnValue = '';
CommandUtility::exec($cmd, $result, $returnValue);
return implode('',$result);
}
}

View file

@ -1,2 +1,33 @@
# mjml
TYPO3 Mjml.io integration for EXT:Form
# MJML
https://mjml.io integration for **TYPO3 EXT:Form**
MJML is a markup language designed to reduce the pain of coding a responsive email. Its semantic syntax makes it easy and straightforward and its rich standard components library speeds up your development time and lightens your email codebase. MJMLs open-source engine generates high quality responsive HTML compliant with best practices. https://mjml.io/getting-started-onboard
## Installation
### Over composer:
`composer require saccas/mjml`
### NPM
Npm is needed for the conversion of the MJML file to HTML
## Usage in EXT:Form
You can overwrite the default _finishersEmailMixin_ so that he uses the _MjmlEmailFinisher_
or create your own.
```
TYPO3:
CMS:
Form:
mixins:
finishersEmailMixin:
implementationClassName: 'Saccas\Mjml\Domain\Finishers\MjmlEmailFinisher'
```
## MJML Documentation
https://mjml.io/documentation/

22
composer.json Normal file
View file

@ -0,0 +1,22 @@
{
"name": "saccas/mjml",
"description": "Mjml view using mjml over npm",
"type": "typo3-cms-extension",
"version": "1.0.0",
"homepage": "https://mjml.io",
"license": ["GPL-2.0+"],
"autoload": {
"psr-4": {
"Saccas\\Mjml\\": "Classes/"
}
},
"require": {
"php": ">=7.0.0 <=7.2.99",
"typo3/cms-core": ">=8.7.0,<8.9.99"
},
"scripts": {
"post-install-cmd": [
"npm install"
]
}
}

11
ext_conf_template.txt Normal file
View file

@ -0,0 +1,11 @@
# cat=node/Binary/1000; type=string; label=Path to node binary
nodeBinaryPath = /usr/local/bin/node
# cat=mjml/Binary/2000; type=string; label=Path to mjml binary
mjmlBinaryPath = ../node_modules/.bin/
# cat=mjml/Binary/3000; type=string; label=mjml binary
mjmlBinary = mjml
# cat=mjml/Binary/4000; type=string; label=mjml params
mjmlParams = -s -m

32
ext_emconf.php Normal file
View file

@ -0,0 +1,32 @@
<?php
$EM_CONF[$_EXTKEY] = [
'title' => 'Mjml',
'description' => 'Mjml view using mjml over npm',
'category' => 'misc',
'shy' => 0,
'version' => '1.0.0',
'state' => 'stable',
'clearCacheOnLoad' => 1,
'author' => '',
'author_email' => '',
'author_company' => '',
'autoload' =>
[
'psr-4' => ['Saccas\\Mjml\\' => 'Classes']
],
'constraints' => [
'depends' => [
'php' => '7.0.0-0.0.0',
'typo3' => '8.7.*',
'extbase' => '',
],
'conflicts' => [
],
'suggests' => [
],
],
'_md5_values_when_last_written' => 'a:0:{}',
'suggests' => [
],
];

28
ext_icon.svg Normal file
View file

@ -0,0 +1,28 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generator: Adobe Illustrator 19.2.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Calque_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 1024 1024" style="enable-background:new 0 0 1024 1024;" xml:space="preserve">
<style type="text/css">
.st0{fill:url(#Rectangle-1_1_);}
.st1{fill:#FFFFFF;}
</style>
<title>Logo</title>
<desc>Created with Sketch.</desc>
<g id="Page-1">
<g id="Logo">
<linearGradient id="Rectangle-1_1_" gradientUnits="userSpaceOnUse" x1="-254.2534" y1="1536.5005" x2="-254.2485" y2="1535.5005" gradientTransform="matrix(1024 0 0 -1024 260865 1573377)">
<stop offset="0" style="stop-color:#F46E42"/>
<stop offset="1" style="stop-color:#E3515B"/>
</linearGradient>
<path id="Rectangle-1" class="st0" d="M62,0.5h900c34.2,0,62,27.8,62,62v900c0,34.2-27.8,62-62,62H62c-34.2,0-62-27.8-62-62v-900 C0,28.3,27.8,0.5,62,0.5z"/>
<g id="Group" transform="translate(288.000000, 318.000000)">
<circle id="Oval-1" class="st1" cx="398" cy="49.5" r="49"/>
<circle id="Oval-1-Copy-2" class="st1" cx="398" cy="338.5" r="49"/>
<circle id="Oval-1-Copy" class="st1" cx="50" cy="194.5" r="49"/>
<path class="st1" d="M261.4,98.5H49.5C22.3,98.5,0,76.2,0,49v0C0,21.8,22.3-0.5,49.5-0.5l211.9,0c27.2,0,49.5,22.3,49.5,49.5v0 C310.9,76.2,288.6,98.5,261.4,98.5z"/>
<path class="st1" d="M397.5,243.5H185.5c-27.2,0-49.5-22.3-49.5-49.5v0c0-27.2,22.3-49.5,49.5-49.5h211.9 c27.2,0,49.5,22.3,49.5,49.5v0C447,221.2,424.7,243.5,397.5,243.5z"/>
<path class="st1" d="M261.4,388H49.5C22.3,388,0,365.7,0,338.5v0C0,311.3,22.3,289,49.5,289h211.9c27.2,0,49.5,22.3,49.5,49.5v0 C310.9,365.7,288.6,388,261.4,388z"/>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.8 KiB

6
package.json Normal file
View file

@ -0,0 +1,6 @@
{
"name": "mjml-typo3",
"dependencies": {
"mjml": "^3.3.5"
}
}