Генерация PDF из формы FormIt + Генерация PDF из любых данных по кнопке (без FormIt) в MODX Revo


На modx.pro уже есть статья от Володи по генерации PDF.
Ниже хочу предложить альтернативный вариант формирования PDF файла из данных форм FormIt с использованием шаблонизатора Fenom и бесплатного компонента PDFresource

Итак, приступим:

Код вызова AjaxForm + FormIt:
Здесь добавлен hook pdf и 3 дополнительных параметра:

  • &pdfTpl – чанк шаблона будущего PDF файла
  • &author – Автор PDF
  • &title – Заголовок PDF
Остальное всё стандартно.
[[!AjaxForm?
    &snippet=`FormIt`
    &form=`tpl.form`
    &emailTpl=`tpl.email`
    &pdfTpl=`tpl.PDF`
    &hooks=`pdf,email`
    &author=`Автор PDF`
    &title=`Заголовок PDF`
    &emailSubject=`Тема письма`
    &emailTo=`[[++emailsender]]`
    &emailFrom=`[[++emailsender]]`
    &validate=`email:required`
    &validationErrorMessage=`Ошибка в форме`
    &successMessage=`Сообщение отправлено`
]]

Содержимое сниппета pdf, который используется в качестве hook для FormIt:
<?php
// для использования в чанке формирования PDF шаблонизатора Fenom, подключаем pdoFetch
$pdo = $modx->getService('pdoFetch'); 
$pdfTpl = $modx->getOption('pdfTpl', $formit->config, '', true);
$author = $modx->getOption('author', $formit->config, 'Автор', true);
$title = $modx->getOption('title', $formit->config, 'Заголовок PDF', true);
$content = $pdo->getChunk($pdfTpl, $fields);

$config = array();
$config = array_merge($config, $fields, array(
    'content' => $content,
    'author' => $author,
    'title' => $title,
));
// формируем ссылку на PDF
$hook->setValue('pdf_link', $modx->runSnippet('PdfCreate', $config)); 

return true;

Содержимое сниппета PdfCreate:
<?php
$date = date('Y-m-d_H-i-s', time()) . '_' .rand(1, 100);

$corePath = $modx->getOption('pdfresource.core_path', null, $modx->getOption('core_path') . 'components/pdfresource/');
$pdfresource = $modx->getService('pdfresource', 'PDFResource', $corePath . 'model/pdfresource/', array(
    'core_path' => $corePath
));

$content = $modx->getOption('content', $scriptProperties, '', true);
$title = $modx->getOption('title', $scriptProperties, '', true);
$author = $modx->getOption('author', $scriptProperties, '', true);

$aliasPath = MODX_ASSETS_PATH . 'pdf/';
$site_url = $modx->getOption('site_url');

// настройки PDFResource (подробнее почитать здесь: http://jako.github.io/PDFResource/usage/)
$pdfresource->initPDF(array(
    'mode' => 'utf-8',
    'format' => 'A4',
    'defaultFontSize' => intval(8),
    'defaultFont' => '',
    'mgl' => intval(10),    // margin left
    'mgr' => intval(10),    // margin right
    'mgt' => intval(7),     // margin top
    'mgb' => intval(7),     // margin bottom
    'mgh' => intval(10),    // margin header
    'mgf' => intval(10),    // margin footer
    'orientation' => 'P',   // ориентация PDF
    'customFonts' => '[]',
));

$pdfresource->pdf->SetTitle($title);
$pdfresource->pdf->SetAuthor($author);
$pdfresource->pdf->SetCreator($modx->getOption('site_url'));

$pdfresource->pdf->WriteHTML($content, 2);

$file_name = $date;
$pdfresource->pdf->Output($aliasPath . $file_name . '.pdf', 'F');
return $site_url . ltrim($modx->getOption('assets_url'), '/') . 'pdf/' .$file_name. '.pdf';

Содержимое чанка tpl.Email:
{if $name?}<p>Имя: {$name}</p>{/if}
{if $email?}<p>Email: {$email}</p>{/if}
{if $message?}<p>Сообщение: {$message}</p>{/if}
{if $pdf_link?}<p><a href="{$pdf_link}">Ссылка на PDF</a></p>{/if}

Содержимое чанка tpl.PDF:
{if $name?}<p>Имя: {$name}</p>{/if}
{if $email?}<p>Email: {$email}</p>{/if}
{if $message?}<p>Сообщение: {$message}</p>{/if}

В папке assets/pdf будут формироваться PDF файлы, ссылки на которые будут отправляться в письме.

=======================

Генерация PDF из любых данных с помощью PDFresource

К примеру, напишем в коде страницы (шаблон / чанк / содержимое и тд.) 2 ссылки:
  1. с data атрибутами (которые будем использовать в формировании PDF)
  2. для ссылки на готовый PDF
<a href="#" class="createPdf" 
	data-name="Имя" 
	data-email="mail@mail.ru" 
	data-message="Сообщение в PDF">Создать PDF</a>
<a href="#" class="linkPdf" style="display:none;">Ссылка на PDF</a>

Пишем AJAX вызов:
$('.createPdf').click(function(e){
    e.preventDefault();
    $.ajaxSetup({ async: false});
    $.ajax({
    	type: 'POST',
        url: 'pdf',
    	data: {
    	    'name' : $(this).data('name'),
            'email' : $(this).data('email'),
            'message' : $(this).data('message')
    	},
    	success: function(link){
            $('a.linkPdf').attr('href', link).fadeIn();
            window.open(link);
    	}
    });
});

Создаем страницу с пустым шаблоном и отключенным визуальным редактором, в псевдоним пишем pdf, В название – всё, что захочется. Можно дополнительно заморозить URI, туда пишем pdf. В содержимое:
[[!prePdfCreate?
    &pdfTpl=`tpl.PDF`
    &author=`Автор PDF`
    &title=`Заголовок PDF`
]]

Содержимое сниппета prePdfCreate:
<?php
if (!$_POST['name']) return;
$pdo = $modx->getService('pdoFetch');
$pdfTpl = $modx->getOption('pdfTpl', $scriptProperties, '', true);
$author = $modx->getOption('author', $scriptProperties, '', true);
$title = $modx->getOption('title', $scriptProperties, '', true);

$content = $pdo->getChunk($pdfTpl, $_POST);

$config = array();
$config = array_merge($config, $_POST, array(
	'content' => $content,
	'author' => $author,
    'title' => $title,
));

return $modx->runSnippet('PdfCreate', $config);

Сниппет PdfCreate есть выше, также, как и чанк tpl.PDF.

Готово! На странице жмём по ссылке, формируется PDF и открывается в новом окне. Для тех, у кого не сработает открытие в новом окне (блокировщик и другие штуки), появится ссылка на PDF файл.

p.s. Если добавить в ссылку на PDF файл атрибут download, то при клике будет происходить скачивание файла.

===================

UPD. Дополнительный скрипт для очистки папки с PDF файлами. Инструкция по настройке cron будет излишней, я думаю:

<?php
$files = glob(MODX_ASSETS_PATH.'pdf/*'); // получаем все файлы в папке
foreach($files as $file){
    if(is_file($file))
        unlink($file); // удаляем файл
}
06 ноября 2017, 13:49    Klike   
12    319 +12

Комментарии (2)

  1. Дмитрий 06 ноября 2017, 14:06 # +1
    Можно еще добавить скрипт для Cron, который будет удалять содержимое папки pdf, дабы не копить тонны мусора. И будет полностью готовое решение :)
    Недавно переносил скромную визитку на другой хостинг и долго не мог понять, почему папка с сайтом 8гб весит. Оказалось, что похожий хук хранил прикрепленные к форме фотографии с самого создания сайта. В итоге 6 гигабайт архивных файлов, никому не нужных.
    1. Klike 06 ноября 2017, 14:12 # +3
      Спасибо! Добавил скрипт очистки папки.
    Вы должны авторизоваться, чтобы оставлять комментарии.