在邮件中显示来自 tinymce 编辑器的图像
Show images from tinymce editor in mail
我正在使用 2amigos 的 yii2 TinyMCE 插件。
我需要在编辑器中输入的所有内容通过电子邮件发送。
据我测试,它在背景、标题颜色文本方面做得很好。
但是用图片显示标签如下:
虽然在编辑器中它看起来不错:
我的看法:
<?php
/* @var $this yii\web\View */
$this->title = 'My Yii Application';
use dosamigos\tinymce\TinyMce;
use yii\helpers\Html;
use yii\widgets\ActiveForm;
use app\models\SendEmailForm;
$model = new SendEmailForm;
?>
<div class="site-index">
<div class="body-content">
<div class="row">
<?php
$form = ActiveForm::begin([
'id' => 'sendemail-form',
'options' => ['class' => ''],
'action' => 'site/enviarcorreo'
])
?>
<?= $form->field($model, 'correo') ?>
<?= $form->field($model, 'contenido')->widget(TinyMce::className(), [
'options' => ['rows' => 30],
'language' => 'es',
'clientOptions' => [
'plugins' => [
"print preview powerpaste casechange importcss tinydrive searchreplace autolink autosave directionality advcode visualblocks visualchars fullscreen image link media mediaembed template codesample table charmap hr pagebreak nonbreaking anchor toc insertdatetime advlist lists checklist wordcount tinymcespellchecker a11ychecker imagetools textpattern noneditable help formatpainter permanentpen pageembed charmap quickbars linkchecker emoticons advtable"
],
'toolbar' => "undo redo | bold italic underline strikethrough | fontselect fontsizeselect formatselect | alignleft aligncenter alignright alignjustify | outdent indent | numlist bullist checklist | forecolor backcolor casechange permanentpen formatpainter removeformat | pagebreak | charmap emoticons | fullscreen preview print | insertfile image media pageembed template link anchor codesample | a11ycheck ltr rtl",
'menubar' => false,
'convert_urls' => false,
'file_picker_types' => 'image',
]
]);?>
<div class="form-group">
<?= Html::submitButton('Enviar', ['class' => 'btn btn-primary']) ?>
</div>
<?php ActiveForm::end() ?>
</div>
</div>
</div>
控制器动作:
public function actionEnviarcorreo()
{
$model = new \app\models\SendEmailForm;
if ($model->load(Yii::$app->request->post()) && $model->validate())
{
Yii::$app->mailer->compose()
->setFrom('darknightedm@gmail.com')
->setTo($model->correo)
->setSubject('Email enviado desde Yii2-Swiftmailer')
->setHtmlBody($model->contenido)
->send();
}
}
我该怎么做才能使这成为可能?。感谢阅读。
你在这里真正问的是两个不同的问题...
- 如何从 TinyMCE 获取 Base64 二进制图像并将它们存储为 适当的 格式?
- 在 HTML 电子邮件中包含图像的最佳方式是什么?
如何从 TinyMCE 获取 Base64 二进制图像并以适当的格式存储它们
TinyMCE 有一个内置的机制来通过它的 images_upload_url
配置选项来解决这个问题。 TinyMCE 文档中有一整页介绍其工作原理:
https://www.tiny.cloud/docs/advanced/handle-async-image-uploads/
网络是您可以让 TinyMCE 将图像文件发送到您选择的端点,然后将其转换为您需要的任何格式。您不需要将其保留为 Base64 二进制文件,并且您很少希望将 Base64 二进制文件作为永久格式。
至于另一个问题...
在 HTML 电子邮件中包含图片的最佳方式是什么?
最终,您需要回答的真正问题是“(对于我的用例)在电子邮件中插入图像的最佳方式是什么”。这是一个非常广泛的话题,已经回答了很多次 - 稍微研究一下应该会引导您找到最常见的方法及其 pros/cons:
https://sendgrid.com/blog/embedding-images-emails-facts/
https://www.campaignmonitor.com/blog/how-to/2008/08/embedding-images-in-email/
https://www.quora.com/Whats-the-best-practices-for-embedding-images-into-HTML-emails
由于有多个选项,因此真正归结为每个选项的 pro/cons 如何满足您的要求。
好的,根据 Michael 的回答(非常感谢您的帮助),我阅读了有关插件功能的更多详细信息。
经过多次尝试获取正确的 url 图片,我终于找到了解决方案,它如何帮助别人,我将它保存在这里作为经验。
我是根据他们要求我做的:
查看:
<div class="row">
<div class="col-lg-12">
<?= $form->field($model, 'contenido')->widget(TinyMce::className(), [
'options' => ['rows' => 20],
'language' => 'es',
'clientOptions' => [
'plugins' => [
"print preview paste importcss searchreplace autolink autosave save directionality code visualblocks visualchars fullscreen image link codesample table charmap hr pagebreak nonbreaking anchor toc insertdatetime advlist lists wordcount imagetools textpattern noneditable help charmap quickbars emoticons"
],
'toolbar' => "undo redo | bold italic underline strikethrough | fontselect fontsizeselect formatselect | alignleft aligncenter alignright alignjustify | outdent indent | numlist bullist | forecolor backcolor removeformat | pagebreak | charmap emoticons | fullscreen preview save print | insertfile image link anchor codesample | ltr rtl",
'menubar' => false,
'convert_urls' => false,
'file_picker_types' => 'image',
'images_upload_url' => 'site/uploadtinyimg', //This is the url to upload automatically to your server and can embed later for the email
'autosave_ask_before_unload' => false
]
]);?>
</div>
</div>
每次您将图像上传到编辑器时,它都会从站点控制器调用操作 uploadtinyimg,因此该控制器将执行的操作是从临时文件夹中取出文件并将其移动到服务器内的文件夹中并给出一个 url 以通过编辑器访问:
/**
* Realiza carga de imagenes por el editor TinyMCE.
*
* @return JSON
*/
public function actionUploadtinyimg()
{
// Se valida si hay archivos cargados
$temp = current($_FILES);
if ($temp)
{
// Se obtiene el nombre del usuario para crear la carpeta temporal
$user = Yii::$app->user->identity->username;
/*********************************************
* Cambia esta linea para definir la ruta a almacenar imagenes *
*********************************************/
$imageFolder = Yii::getAlias('@tmpimages/').$user."/";
// Se valida si la carpeta esta creada, si no es asi procedemos a crearla y darle permisos
if (!file_exists($imageFolder))
{
// Crear carpeta
FileHelper::createDirectory($imageFolder);
// Otorgar permisos
chmod($imageFolder, 0750);
}
// No permite la manipulacion de los datos mediante el atributo OPTIONS
if ($_SERVER['REQUEST_METHOD'] == 'OPTIONS') {
header("Access-Control-Allow-Methods: POST, OPTIONS");
return;
}
reset ($_FILES);
// Se valida si esta cargado algun archivo en el almacenamiento temporal
if (is_uploaded_file($temp['tmp_name'])){
// Se valida el nombre del archivo
if (preg_match("/([^\w\s\d\-_~,;:\[\]\(\).])|([\.]{2,})/", $temp['name'])) {
header("HTTP/1.1 400 Invalid file name.");
return;
}
// Validamos la extensión
if (!in_array(strtolower(pathinfo($temp['name'], PATHINFO_EXTENSION)), array("gif", "jpg", "png"))) {
header("HTTP/1.1 400 Invalid extension.");
return;
}
// Se procede a indicar donde va a ser movido el archivo
$filetowrite = $imageFolder.$temp['name'];
// Movemos el archivo desde la carpeta temporal a nuestra carpeta seleccionada
move_uploaded_file($temp['tmp_name'], $filetowrite);
// Se responde con JSON si la carga fue exitosa.
echo json_encode(array('location' => Yii::getAlias('@web/').$filetowrite));
}
else
{
// Si la carga ha fallado se indica
header("HTTP/1.1 500 Server Error");
}
}
}
发送表单以将编辑器中的内容发送到邮件后,我在控制器中执行了此操作:
我使用了一个名为 DOMDocument 的 class 来检测内容中使用的图像,并在文件夹中查找它们,这表明它们将被加载以执行嵌入过程,并且可以在电子邮件中看到它们,因此稍后删除文件,因为这些文件是临时的且未固定,一旦嵌入过程完成,嵌入图像的内容更改将被保存并通过电子邮件发送:
// Se inicializa la clase DOM para incrustar las imagenes subidas en el editor y se puedan ver en el correo
$dom = new \DOMDocument();
// Cargamos el contenido realizado en el editor
$dom->loadHTML($model->contenido);
// Procedemos a buscar las imagenes
$images = $dom->getElementsByTagName('img');
foreach ($images as $image)
{
// Obtenemos la antigua URL para luego obtener el nombre del archivo
$old_src = $image->getAttribute('src');
// Se obtiene el nombre del archivo
$imgname = basename($old_src);
// Se indica la ruta donde esta ubicada
$imgroute = Yii::getAlias('@app/web/images/tmp/').$user."/".$imgname;
// Se procede a incrustar las imagenes
$new_src = $message->embed($imgroute);
// Del codigo generado se cambia el SRC de la imagen por el generado
$image->setAttribute('src', $new_src);
}
// Guardamos los cambios y procedemos a indicar que el html editado es el contenido del correo
$model->contenido = $dom->saveHTML();
$message->setHtmlBody($model->contenido);
我正在使用 2amigos 的 yii2 TinyMCE 插件。
我需要在编辑器中输入的所有内容通过电子邮件发送。
据我测试,它在背景、标题颜色文本方面做得很好。
但是用图片显示标签如下:
虽然在编辑器中它看起来不错:
我的看法:
<?php
/* @var $this yii\web\View */
$this->title = 'My Yii Application';
use dosamigos\tinymce\TinyMce;
use yii\helpers\Html;
use yii\widgets\ActiveForm;
use app\models\SendEmailForm;
$model = new SendEmailForm;
?>
<div class="site-index">
<div class="body-content">
<div class="row">
<?php
$form = ActiveForm::begin([
'id' => 'sendemail-form',
'options' => ['class' => ''],
'action' => 'site/enviarcorreo'
])
?>
<?= $form->field($model, 'correo') ?>
<?= $form->field($model, 'contenido')->widget(TinyMce::className(), [
'options' => ['rows' => 30],
'language' => 'es',
'clientOptions' => [
'plugins' => [
"print preview powerpaste casechange importcss tinydrive searchreplace autolink autosave directionality advcode visualblocks visualchars fullscreen image link media mediaembed template codesample table charmap hr pagebreak nonbreaking anchor toc insertdatetime advlist lists checklist wordcount tinymcespellchecker a11ychecker imagetools textpattern noneditable help formatpainter permanentpen pageembed charmap quickbars linkchecker emoticons advtable"
],
'toolbar' => "undo redo | bold italic underline strikethrough | fontselect fontsizeselect formatselect | alignleft aligncenter alignright alignjustify | outdent indent | numlist bullist checklist | forecolor backcolor casechange permanentpen formatpainter removeformat | pagebreak | charmap emoticons | fullscreen preview print | insertfile image media pageembed template link anchor codesample | a11ycheck ltr rtl",
'menubar' => false,
'convert_urls' => false,
'file_picker_types' => 'image',
]
]);?>
<div class="form-group">
<?= Html::submitButton('Enviar', ['class' => 'btn btn-primary']) ?>
</div>
<?php ActiveForm::end() ?>
</div>
</div>
</div>
控制器动作:
public function actionEnviarcorreo()
{
$model = new \app\models\SendEmailForm;
if ($model->load(Yii::$app->request->post()) && $model->validate())
{
Yii::$app->mailer->compose()
->setFrom('darknightedm@gmail.com')
->setTo($model->correo)
->setSubject('Email enviado desde Yii2-Swiftmailer')
->setHtmlBody($model->contenido)
->send();
}
}
我该怎么做才能使这成为可能?。感谢阅读。
你在这里真正问的是两个不同的问题...
- 如何从 TinyMCE 获取 Base64 二进制图像并将它们存储为 适当的 格式?
- 在 HTML 电子邮件中包含图像的最佳方式是什么?
如何从 TinyMCE 获取 Base64 二进制图像并以适当的格式存储它们
TinyMCE 有一个内置的机制来通过它的 images_upload_url
配置选项来解决这个问题。 TinyMCE 文档中有一整页介绍其工作原理:
https://www.tiny.cloud/docs/advanced/handle-async-image-uploads/
网络是您可以让 TinyMCE 将图像文件发送到您选择的端点,然后将其转换为您需要的任何格式。您不需要将其保留为 Base64 二进制文件,并且您很少希望将 Base64 二进制文件作为永久格式。
至于另一个问题...
在 HTML 电子邮件中包含图片的最佳方式是什么?
最终,您需要回答的真正问题是“(对于我的用例)在电子邮件中插入图像的最佳方式是什么”。这是一个非常广泛的话题,已经回答了很多次 - 稍微研究一下应该会引导您找到最常见的方法及其 pros/cons:
https://sendgrid.com/blog/embedding-images-emails-facts/ https://www.campaignmonitor.com/blog/how-to/2008/08/embedding-images-in-email/ https://www.quora.com/Whats-the-best-practices-for-embedding-images-into-HTML-emails
由于有多个选项,因此真正归结为每个选项的 pro/cons 如何满足您的要求。
好的,根据 Michael 的回答(非常感谢您的帮助),我阅读了有关插件功能的更多详细信息。
经过多次尝试获取正确的 url 图片,我终于找到了解决方案,它如何帮助别人,我将它保存在这里作为经验。
我是根据他们要求我做的:
查看:
<div class="row">
<div class="col-lg-12">
<?= $form->field($model, 'contenido')->widget(TinyMce::className(), [
'options' => ['rows' => 20],
'language' => 'es',
'clientOptions' => [
'plugins' => [
"print preview paste importcss searchreplace autolink autosave save directionality code visualblocks visualchars fullscreen image link codesample table charmap hr pagebreak nonbreaking anchor toc insertdatetime advlist lists wordcount imagetools textpattern noneditable help charmap quickbars emoticons"
],
'toolbar' => "undo redo | bold italic underline strikethrough | fontselect fontsizeselect formatselect | alignleft aligncenter alignright alignjustify | outdent indent | numlist bullist | forecolor backcolor removeformat | pagebreak | charmap emoticons | fullscreen preview save print | insertfile image link anchor codesample | ltr rtl",
'menubar' => false,
'convert_urls' => false,
'file_picker_types' => 'image',
'images_upload_url' => 'site/uploadtinyimg', //This is the url to upload automatically to your server and can embed later for the email
'autosave_ask_before_unload' => false
]
]);?>
</div>
</div>
每次您将图像上传到编辑器时,它都会从站点控制器调用操作 uploadtinyimg,因此该控制器将执行的操作是从临时文件夹中取出文件并将其移动到服务器内的文件夹中并给出一个 url 以通过编辑器访问:
/**
* Realiza carga de imagenes por el editor TinyMCE.
*
* @return JSON
*/
public function actionUploadtinyimg()
{
// Se valida si hay archivos cargados
$temp = current($_FILES);
if ($temp)
{
// Se obtiene el nombre del usuario para crear la carpeta temporal
$user = Yii::$app->user->identity->username;
/*********************************************
* Cambia esta linea para definir la ruta a almacenar imagenes *
*********************************************/
$imageFolder = Yii::getAlias('@tmpimages/').$user."/";
// Se valida si la carpeta esta creada, si no es asi procedemos a crearla y darle permisos
if (!file_exists($imageFolder))
{
// Crear carpeta
FileHelper::createDirectory($imageFolder);
// Otorgar permisos
chmod($imageFolder, 0750);
}
// No permite la manipulacion de los datos mediante el atributo OPTIONS
if ($_SERVER['REQUEST_METHOD'] == 'OPTIONS') {
header("Access-Control-Allow-Methods: POST, OPTIONS");
return;
}
reset ($_FILES);
// Se valida si esta cargado algun archivo en el almacenamiento temporal
if (is_uploaded_file($temp['tmp_name'])){
// Se valida el nombre del archivo
if (preg_match("/([^\w\s\d\-_~,;:\[\]\(\).])|([\.]{2,})/", $temp['name'])) {
header("HTTP/1.1 400 Invalid file name.");
return;
}
// Validamos la extensión
if (!in_array(strtolower(pathinfo($temp['name'], PATHINFO_EXTENSION)), array("gif", "jpg", "png"))) {
header("HTTP/1.1 400 Invalid extension.");
return;
}
// Se procede a indicar donde va a ser movido el archivo
$filetowrite = $imageFolder.$temp['name'];
// Movemos el archivo desde la carpeta temporal a nuestra carpeta seleccionada
move_uploaded_file($temp['tmp_name'], $filetowrite);
// Se responde con JSON si la carga fue exitosa.
echo json_encode(array('location' => Yii::getAlias('@web/').$filetowrite));
}
else
{
// Si la carga ha fallado se indica
header("HTTP/1.1 500 Server Error");
}
}
}
发送表单以将编辑器中的内容发送到邮件后,我在控制器中执行了此操作:
我使用了一个名为 DOMDocument 的 class 来检测内容中使用的图像,并在文件夹中查找它们,这表明它们将被加载以执行嵌入过程,并且可以在电子邮件中看到它们,因此稍后删除文件,因为这些文件是临时的且未固定,一旦嵌入过程完成,嵌入图像的内容更改将被保存并通过电子邮件发送:
// Se inicializa la clase DOM para incrustar las imagenes subidas en el editor y se puedan ver en el correo
$dom = new \DOMDocument();
// Cargamos el contenido realizado en el editor
$dom->loadHTML($model->contenido);
// Procedemos a buscar las imagenes
$images = $dom->getElementsByTagName('img');
foreach ($images as $image)
{
// Obtenemos la antigua URL para luego obtener el nombre del archivo
$old_src = $image->getAttribute('src');
// Se obtiene el nombre del archivo
$imgname = basename($old_src);
// Se indica la ruta donde esta ubicada
$imgroute = Yii::getAlias('@app/web/images/tmp/').$user."/".$imgname;
// Se procede a incrustar las imagenes
$new_src = $message->embed($imgroute);
// Del codigo generado se cambia el SRC de la imagen por el generado
$image->setAttribute('src', $new_src);
}
// Guardamos los cambios y procedemos a indicar que el html editado es el contenido del correo
$model->contenido = $dom->saveHTML();
$message->setHtmlBody($model->contenido);