Задача: при каждом посещении статьи, на сайте, нужно создавать pdf файл с ее содержимым и записывать в свойство инфоблока.
Сконвертировать HTML в PDF файл и сохранить:
Для начала, нам нужно просто сгенерировать pdf файл и сохранить. Сделать это можно несколькими способами, но при всех нужно использовать дополнительные библиотеки. Я буду использовать DOMPDF так как, с помощью него можно как угодно сверстать pdf файл, используя обычный html.
Так же, можете обратить внимание на библиотеку FPDF- класс PHP, который позволяет создавать файлы PDF на чистом PHP, то есть без использования библиотеки PDFlib.
Pdf файл будем создавать из текста статьи. В детальном шаблоне статьи создаем файл result_modifier.php (если его еще нет) и создаем переменную с html кодом будущего pdf файла. Сверстать можете как угодно:
$articleTitle = $arResult['NAME']; // название статьи
$articleImg = base64_encode(
file_get_contents($arResult['DETAIL_PICTURE']['SRC'])
); // картинка
$articleText = $arResult['DETAIL_TEXT']; // текст статьи
$articleID = $arResult['ID']; // ID статьи-элемента
$articleToPdf =
'<html lang=ru><meta charset=utf-8><meta http-equiv=X-UA-Compatible content="IE=edge"><body>
<style type="text/css">
* {box-sizing: border-box; margin: 0; padding: 0;}
body {font-family: DejaVu Sans;}
h1 {font-size: 25px; text-align: center;}
img {margin:0px 20px; max-width: 100%;}
p {font-size: 15px; line-height: 23px;}
</style>
<body>'.
'<h1>' . $articleTitle . '</h1>'.
'<img src="data:image/jpg;base64,' . $articleImg . '" width="100%">'.
'<p>'. $articleText . '</p>'.
'</body></html>';
Обратите внимание: картинку статьи мы преобразовали в base64 иначе она не отобразится в pdf файле.
Теперь качаем библиотеку DOMPDF и загружаем на сайт и подключаем в этом же файле (result_modifier.php). Если планируете использовать библиотеку повсеместно на сайте, можете подключить ее глобально ко всему проекту. Мне нужно только в статьях.
require_once 'ПУТЬ_КУДА_ЗАГРУЗИЛИ_DOMPDF/dompdf/autoload.inc.php';
use Dompdf\Dompdf;
$dompdf = new Dompdf();
$dompdf->loadHtml($articleToPdf);
$dompdf->setPaper('a4', 'portrait');
$dompdf->render();
$output = $dompdf->output(0);
Пояснения:
- use Dompdf\Dompdf: подключили класс Dompdf
- dompdf->loadHtml: загрузили наш HTML код со статьей
- $dompdf->setPaper: установли формат бумаги в A4 с портретной ориентацией. В Dompdf много настроек, по поводу вывода. Смотрите в документации.
- dompdf->render: запустили генерацию pdf файла.
- $output = $dompdf->output: в переменной $output получили pdf файл возвращенный как строка.
Теперь, сохраним pdf файл в свойство инфоблока. Сделаем это методом CIBlockElement::Update.
$el = new CIBlockElement;
$PROP = array();
$PROP['ATT_PDF_FILE'] = CFile::MakeFileArray($pdfLink); // В переменной путь к созданному PDF файлу
$arUpdateArticle = Array(
"PROPERTY_VALUES"=> $PROP,
);
$res = $el->Update($articleID, $arUpdateArticle);
Если, хотите сразу сохранить файл в произвольное место, используйте:
file_put_contents('/ПУТЬ_КУДА_СОХРАНЯЕТЕ/'.$articleTitle.".pdf", $output);
Если хотите отдать файл на скачивание сразу, используйте
$dompdf->stream($articleTitle . ".pdf");
вместо $output = $dompdf->output(0);
Если не хотите, что бы файл создавался каждый раз и пересохранялся: обверните его в проверку на наличие файла.
if (empty($arResult['PROPERTY']['ATT_PDF_FILE']['VALUE'])) {
....
Весь наш код
....
}
Соотвественно, не используйте условие- если файл нужно создавать каждый раз. Например: статья постоянно меняется и нужно держать pdf файл в актуальном состоянии.
Pdf файл будет создаваться каждый раз при открытии статьи и для каждого пользователя будет максимально актуальным.
Отправить файл на электронную почту, через почтовое событие.
Если хотите реализовать отправку файла на электронную почту, можете использовать метод CEvent::Send
Создаем почтовое событие, например: SEND_ARTICLE_PDF_FILE примерно, с таким содержанием:
Ваш файл #PDF_NAME#.pdf во вложении к этому письму
И обработчик, в который получаем email пользователя
Event::send(array(
"EVENT_NAME" => "SEND_ARTICLE_PDF_FILE",
"LID" => "s1",
"C_FIELDS" => array(
"PDF_NAME" => $articleTitle,
"USER_MAIL" => $userEmail // Это используем в поле "Кому"
),
"FILE" => array($arResult['PROPERTY']['ATT_PDF_FILE']['VALUE']),
));
Данный метод поставит почтовое событие в очередь. Если хотите отправить вне очереди используйте Event::sendImmediate вместо Event::send
В параметр "FILE" можете передать массив ID зарегистрированных в системе файлов или полные пути до файлов - если не используете запись pdf файла в свойство элемента (или хотите приложить, еще несколько файлов).