2020-05-26 16:32:22 +02:00
|
|
|
<?php
|
|
|
|
|
|
|
|
/**
|
2020-07-04 23:25:24 +02:00
|
|
|
* See LICENSE file for license details.
|
2020-05-26 16:32:22 +02:00
|
|
|
*
|
|
|
|
* @copyright (C) D3 Data Development (Inh. Thomas Dartsch)
|
2020-07-04 23:25:24 +02:00
|
|
|
* @author D3 Data Development - Max Buhe <support@shopmodule.com>
|
|
|
|
* @link http://www.oxidmodule.com
|
2020-05-26 16:32:22 +02:00
|
|
|
*/
|
|
|
|
|
|
|
|
namespace D3\PdfDocuments\Application\Model\AbstractClasses;
|
|
|
|
|
2023-09-19 23:32:55 +02:00
|
|
|
use Assert\InvalidArgumentException;
|
2021-02-22 10:07:26 +01:00
|
|
|
use D3\ModCfg\Application\Model\d3filesystem;
|
2020-06-04 10:31:38 +02:00
|
|
|
use D3\PdfDocuments\Application\Model\Exceptions\pdfGeneratorExceptionAbstract;
|
2020-05-30 01:17:27 +02:00
|
|
|
use D3\PdfDocuments\Application\Model\Interfaces\pdfdocumentsGenericInterface as genericInterface;
|
2020-06-04 10:31:38 +02:00
|
|
|
use OxidEsales\Eshop\Core\Base;
|
2020-05-26 16:32:22 +02:00
|
|
|
use OxidEsales\Eshop\Core\Registry;
|
2020-06-04 10:31:38 +02:00
|
|
|
use OxidEsales\Eshop\Core\UtilsView;
|
2024-08-26 23:43:09 +02:00
|
|
|
use OxidEsales\EshopCommunity\Internal\Framework\Templating\TemplateRenderer;
|
2020-05-27 09:46:44 +02:00
|
|
|
use Smarty;
|
2020-06-04 15:18:51 +02:00
|
|
|
use Spipu\Html2Pdf\Exception\Html2PdfException;
|
2020-05-26 16:32:22 +02:00
|
|
|
use Spipu\Html2Pdf\Html2Pdf;
|
|
|
|
|
2020-06-04 10:31:38 +02:00
|
|
|
abstract class pdfdocumentsGeneric extends Base implements genericInterface
|
2020-05-26 16:32:22 +02:00
|
|
|
{
|
2020-06-09 14:56:14 +02:00
|
|
|
const PDF_DESTINATION_DOWNLOAD = 'D'; // force download in browser
|
|
|
|
const PDF_DESTINATION_STDOUT = 'I'; // show in browser plugin if available, otherwise download
|
|
|
|
const PDF_DESTINATION_FILE = 'F'; // save as local file
|
|
|
|
const PDF_DESTINATION_FILEANDSTDOUT = 'FI'; // output as local file and show in browser plugin
|
|
|
|
const PDF_DESTINATION_FILEANDDOWNLOAD = 'FD'; // output as local file and force download in browser
|
|
|
|
const PDF_DESTINATION_STRING = 'S'; // output as string
|
2020-06-04 15:18:51 +02:00
|
|
|
|
|
|
|
const PDF_ORIENTATION_PORTRAIT = 'P';
|
|
|
|
const PDF_ORIENTATION_LANDSCAPE = 'L';
|
2020-06-04 10:31:38 +02:00
|
|
|
|
2020-06-05 10:06:58 +02:00
|
|
|
public $filenameExtension = 'pdf';
|
|
|
|
|
2020-05-28 12:21:11 +02:00
|
|
|
/** @var Smarty */
|
|
|
|
public $oSmarty;
|
|
|
|
|
2020-06-05 09:37:11 +02:00
|
|
|
/** @var string */
|
|
|
|
public $filename;
|
|
|
|
|
2020-05-28 12:21:11 +02:00
|
|
|
/**
|
2020-05-30 01:17:27 +02:00
|
|
|
* pdfDocumentsGeneric constructor.
|
2020-05-28 12:21:11 +02:00
|
|
|
*/
|
|
|
|
public function __construct()
|
|
|
|
{
|
2020-06-04 10:31:38 +02:00
|
|
|
parent::__construct();
|
2024-08-26 23:43:09 +02:00
|
|
|
|
|
|
|
/** @var TemplateRenderer $oTemplateRenderer */
|
|
|
|
$oTemplateRenderer = $this->getContainer()
|
|
|
|
->get(TemplateRendererBridgeInterface::class)
|
|
|
|
->getTemplateRenderer();
|
|
|
|
|
|
|
|
$this->oSmarty = $oTemplateRenderer->getTemplateEngine()->getSmarty();
|
2020-05-28 12:21:11 +02:00
|
|
|
}
|
|
|
|
|
2020-08-13 14:50:48 +02:00
|
|
|
public function runPreAction()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
public function runPostAction()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2020-05-27 09:46:44 +02:00
|
|
|
/**
|
2020-07-03 20:04:21 +02:00
|
|
|
* @param $sFilename
|
|
|
|
* @param int $iSelLang
|
2020-05-27 09:46:44 +02:00
|
|
|
* @param string $target
|
2020-07-03 20:04:21 +02:00
|
|
|
* @return mixed|string|null
|
2020-06-04 15:18:51 +02:00
|
|
|
* @throws Html2PdfException
|
2020-05-27 09:46:44 +02:00
|
|
|
*/
|
2020-06-04 15:18:51 +02:00
|
|
|
public function genPdf($sFilename, $iSelLang = 0, $target = self::PDF_DESTINATION_STDOUT)
|
2020-05-27 09:46:44 +02:00
|
|
|
{
|
2020-05-28 12:21:11 +02:00
|
|
|
$oPdf = oxNew(Html2Pdf::class, ...$this->getPdfProperties());
|
2020-06-09 22:49:47 +02:00
|
|
|
$oPdf->setTestIsImage(false);
|
2020-06-11 01:26:16 +02:00
|
|
|
$htmlContent = $this->getHTMLContent($iSelLang);
|
|
|
|
$oPdf->writeHTML($htmlContent);
|
2020-06-09 22:49:47 +02:00
|
|
|
$oPdf->pdf->SetAuthor(Registry::getConfig()->getActiveShop()->getFieldData('oxname'));
|
|
|
|
$oPdf->pdf->SetTitle(Registry::getLang()->translateString($this->getTitleIdent()));
|
|
|
|
$oPdf->pdf->SetCreator('D³ PDF Documents for OXID eShop');
|
|
|
|
$oPdf->pdf->SetSubject(NULL);
|
2020-06-11 01:26:16 +02:00
|
|
|
return $this->output($oPdf, $sFilename, $target, $htmlContent);
|
2020-05-27 09:46:44 +02:00
|
|
|
}
|
|
|
|
|
2020-06-04 15:18:51 +02:00
|
|
|
/**
|
|
|
|
* @param int $iLanguage
|
2020-07-03 20:04:21 +02:00
|
|
|
* @throws Html2PdfException
|
2020-06-04 15:18:51 +02:00
|
|
|
*/
|
2020-06-04 10:31:38 +02:00
|
|
|
public function downloadPdf($iLanguage = 0)
|
|
|
|
{
|
|
|
|
try {
|
2020-08-13 14:50:48 +02:00
|
|
|
$this->runPreAction();
|
2020-06-04 15:18:51 +02:00
|
|
|
$sFilename = $this->getFilename();
|
|
|
|
$this->genPdf($sFilename, $iLanguage, self::PDF_DESTINATION_DOWNLOAD);
|
2020-08-13 14:50:48 +02:00
|
|
|
$this->runPostAction();
|
2020-06-04 15:18:51 +02:00
|
|
|
Registry::getUtils()->showMessageAndExit('');
|
2020-06-04 10:31:38 +02:00
|
|
|
} catch (pdfGeneratorExceptionAbstract $e) {
|
|
|
|
Registry::get(UtilsView::class)->addErrorToDisplay($e);
|
|
|
|
Registry::getLogger()->error($e);
|
2023-09-19 23:32:55 +02:00
|
|
|
} catch (InvalidArgumentException $e) {
|
|
|
|
Registry::get(UtilsView::class)->addErrorToDisplay($e);
|
|
|
|
Registry::getLogger()->error($e);
|
2020-06-04 10:31:38 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-06-09 14:56:14 +02:00
|
|
|
/**
|
|
|
|
* @param string $path
|
|
|
|
* @param int $iLanguage
|
|
|
|
*
|
|
|
|
* @throws Html2PdfException
|
|
|
|
*/
|
|
|
|
public function savePdfFile($path, $iLanguage = 0)
|
|
|
|
{
|
|
|
|
try {
|
2020-08-13 14:50:48 +02:00
|
|
|
$this->runPreAction();
|
2020-06-09 14:56:14 +02:00
|
|
|
$sFilename = $this->getFilename();
|
|
|
|
$this->genPdf(
|
|
|
|
rtrim($path, DIRECTORY_SEPARATOR).DIRECTORY_SEPARATOR.$sFilename,
|
|
|
|
$iLanguage,
|
|
|
|
self::PDF_DESTINATION_FILE
|
|
|
|
);
|
2020-08-13 14:50:48 +02:00
|
|
|
$this->runPostAction();
|
2020-06-09 14:56:14 +02:00
|
|
|
} catch (pdfGeneratorExceptionAbstract $e) {
|
|
|
|
Registry::get(UtilsView::class)->addErrorToDisplay($e);
|
|
|
|
Registry::getLogger()->error($e);
|
2023-09-19 23:32:55 +02:00
|
|
|
} catch (InvalidArgumentException $e) {
|
|
|
|
Registry::get(UtilsView::class)->addErrorToDisplay($e);
|
|
|
|
Registry::getLogger()->error($e);
|
2020-06-09 14:56:14 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-06-08 16:39:33 +02:00
|
|
|
/**
|
|
|
|
* @param int $iLanguage
|
|
|
|
*
|
|
|
|
* @return null|string
|
|
|
|
* @throws Html2PdfException
|
|
|
|
*/
|
|
|
|
public function getPdfContent($iLanguage = 0)
|
|
|
|
{
|
|
|
|
try {
|
2020-08-13 14:50:48 +02:00
|
|
|
$this->runPreAction();
|
2020-06-08 16:39:33 +02:00
|
|
|
$sFilename = $this->getFilename();
|
2020-08-13 14:50:48 +02:00
|
|
|
$ret = $this->genPdf( $sFilename, $iLanguage, self::PDF_DESTINATION_STRING );
|
|
|
|
$this->runPostAction();
|
|
|
|
return $ret;
|
2020-06-08 16:39:33 +02:00
|
|
|
} catch (pdfGeneratorExceptionAbstract $e) {
|
|
|
|
Registry::get(UtilsView::class)->addErrorToDisplay($e);
|
|
|
|
Registry::getLogger()->error($e);
|
2023-09-19 23:32:55 +02:00
|
|
|
} catch (InvalidArgumentException $e) {
|
|
|
|
Registry::get(UtilsView::class)->addErrorToDisplay($e);
|
|
|
|
Registry::getLogger()->error($e);
|
2020-06-08 16:39:33 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
2020-07-02 01:21:14 +02:00
|
|
|
/**
|
|
|
|
* @param int $iSelLang
|
|
|
|
*/
|
|
|
|
public function setSmartyVars($iSelLang)
|
2020-05-27 09:46:44 +02:00
|
|
|
{
|
2020-07-02 01:21:14 +02:00
|
|
|
unset($iSelLang);
|
2024-08-26 23:43:09 +02:00
|
|
|
|
|
|
|
$this->oSmarty->assign('config', Registry::getConfig());
|
|
|
|
$this->oSmarty->assign('viewConfig', Registry::getConfig()->getActiveView()->getViewConfig());
|
|
|
|
$this->oSmarty->assign('shop', Registry::getConfig()->getActiveShop());
|
2020-05-28 12:21:11 +02:00
|
|
|
$this->oSmarty->assign('lang', Registry::getLang());
|
2020-07-02 01:21:14 +02:00
|
|
|
$this->oSmarty->assign('document', $this);
|
2020-05-27 09:46:44 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @param int $iSelLang
|
|
|
|
*
|
|
|
|
* @return mixed
|
2023-09-19 23:32:55 +02:00
|
|
|
* @throws InvalidArgumentException
|
2020-05-27 09:46:44 +02:00
|
|
|
*/
|
|
|
|
public function getHTMLContent($iSelLang = 0)
|
|
|
|
{
|
2020-06-09 22:49:47 +02:00
|
|
|
$blCurrentRenderFromAdmin = self::$_blIsAdmin;
|
2020-06-04 10:31:38 +02:00
|
|
|
self::$_blIsAdmin = $this->renderTemplateFromAdmin();
|
|
|
|
|
2020-05-27 09:46:44 +02:00
|
|
|
$lang = Registry::getLang();
|
|
|
|
|
|
|
|
$currTplLang = $lang->getTplLanguage();
|
|
|
|
$lang->setTplLanguage($iSelLang);
|
|
|
|
|
2020-07-02 01:21:14 +02:00
|
|
|
$this->setSmartyVars($iSelLang);
|
2020-05-27 09:46:44 +02:00
|
|
|
|
2020-05-28 12:21:11 +02:00
|
|
|
$content = $this->oSmarty->fetch($this->getTemplate());
|
2020-05-27 09:46:44 +02:00
|
|
|
|
|
|
|
$lang->setTplLanguage($currTplLang);
|
|
|
|
|
2020-06-09 22:49:47 +02:00
|
|
|
self::$_blIsAdmin = $blCurrentRenderFromAdmin;
|
|
|
|
|
2020-05-27 09:46:44 +02:00
|
|
|
return $content;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* arguments for Html2Pdf class constructor
|
|
|
|
* - $orientation = 'P',
|
|
|
|
* - $format = 'A4',
|
|
|
|
* - $lang = 'fr',
|
|
|
|
* - $unicode = true,
|
|
|
|
* - $encoding = 'UTF-8',
|
|
|
|
* - $margins = array(5, 5, 5, 8),
|
|
|
|
* - $pdfa = false
|
|
|
|
* @return string[]
|
|
|
|
*/
|
|
|
|
public function getPdfProperties()
|
|
|
|
{
|
2020-06-11 01:26:16 +02:00
|
|
|
$orientation = self::PDF_ORIENTATION_PORTRAIT;
|
|
|
|
$format = 'A4';
|
|
|
|
$lang = 'de';
|
|
|
|
$unicode = true;
|
|
|
|
$encoding = 'UTF-8';
|
|
|
|
$margins = [0, 0, 0, 0];
|
|
|
|
$pdfa = true;
|
|
|
|
return [$orientation, $format, $lang, $unicode, $encoding, $margins, $pdfa];
|
2020-05-27 09:46:44 +02:00
|
|
|
}
|
2020-06-04 10:31:38 +02:00
|
|
|
|
2020-06-05 09:37:11 +02:00
|
|
|
/**
|
|
|
|
* @param $filename
|
|
|
|
*/
|
|
|
|
public function setFilename($filename)
|
|
|
|
{
|
|
|
|
$this->filename = $filename;
|
|
|
|
}
|
|
|
|
|
2020-06-05 10:06:58 +02:00
|
|
|
/**
|
|
|
|
* @return string
|
|
|
|
*/
|
|
|
|
public function getFilename()
|
|
|
|
{
|
|
|
|
// forced filename from setFilename()
|
|
|
|
if ($this->filename) {
|
2021-02-22 10:07:26 +01:00
|
|
|
return $this->makeValidFileName(
|
|
|
|
$this->addFilenameExtension(
|
2020-06-17 09:05:49 +02:00
|
|
|
$this->filename
|
|
|
|
)
|
|
|
|
);
|
2020-06-05 10:06:58 +02:00
|
|
|
}
|
|
|
|
|
2021-02-22 10:07:26 +01:00
|
|
|
return $this->makeValidFileName(
|
|
|
|
$this->addFilenameExtension(
|
2020-06-17 09:05:49 +02:00
|
|
|
$this->getTypeForFilename()
|
|
|
|
)
|
|
|
|
);
|
2020-06-05 10:06:58 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @param string $filename
|
|
|
|
*
|
|
|
|
* @return string
|
|
|
|
*/
|
|
|
|
public function addFilenameExtension($filename)
|
|
|
|
{
|
|
|
|
$extension = $this->filenameExtension;
|
|
|
|
$extensionLength = (strlen($extension) + 1) * -1;
|
2023-09-19 23:32:55 +02:00
|
|
|
if (strlen($extension) && substr($filename, $extensionLength) != '.'.$extension) {
|
2020-06-05 10:06:58 +02:00
|
|
|
$filename .= '.'.$extension;
|
|
|
|
}
|
|
|
|
|
|
|
|
return $filename;
|
|
|
|
}
|
|
|
|
|
2020-06-04 10:31:38 +02:00
|
|
|
/**
|
|
|
|
* Gets proper file name
|
|
|
|
*
|
|
|
|
* @param string $sFilename file name
|
|
|
|
*
|
|
|
|
* @return string
|
|
|
|
*/
|
|
|
|
public function makeValidFileName($sFilename)
|
|
|
|
{
|
2021-02-22 10:07:26 +01:00
|
|
|
$fs = oxNew(d3filesystem::class);
|
|
|
|
return $fs->filterFilename($sFilename);
|
2020-06-04 10:31:38 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @return bool
|
|
|
|
*/
|
|
|
|
public function renderTemplateFromAdmin()
|
|
|
|
{
|
2020-06-30 00:44:07 +02:00
|
|
|
return false;
|
2020-06-04 10:31:38 +02:00
|
|
|
}
|
2020-06-11 01:26:16 +02:00
|
|
|
|
2020-07-03 20:04:21 +02:00
|
|
|
/**
|
|
|
|
* @param Html2Pdf $oPdf
|
|
|
|
* @param $sFilename
|
|
|
|
* @param $target
|
|
|
|
* @param $html
|
|
|
|
* @return string|null
|
|
|
|
* @throws Html2PdfException
|
|
|
|
*/
|
2020-06-11 01:26:16 +02:00
|
|
|
public function output(Html2Pdf $oPdf, $sFilename, $target, $html)
|
|
|
|
{
|
|
|
|
if ((bool) Registry::getConfig()->getConfigParam('d3PdfDocumentsbDev') === true) {
|
|
|
|
return $this->outputDev($oPdf, $sFilename, $target, $html);
|
|
|
|
} else {
|
|
|
|
return $oPdf->output($sFilename, $target);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @param Html2Pdf $oPdf
|
|
|
|
* @param $sFilename
|
|
|
|
* @param $target
|
|
|
|
* @param $html
|
2020-07-03 20:04:21 +02:00
|
|
|
* @return null
|
2020-06-11 01:26:16 +02:00
|
|
|
*/
|
|
|
|
public function outputDev(Html2Pdf $oPdf, $sFilename, $target, $html)
|
|
|
|
{
|
|
|
|
$sFilename = str_replace('.pdf', '.html', $sFilename);
|
|
|
|
|
|
|
|
switch($target) {
|
|
|
|
case 'I': {
|
|
|
|
// Send PDF to the standard output
|
|
|
|
if (ob_get_contents()) {
|
|
|
|
$oPdf->pdf->Error('Some data has already been output, can\'t send PDF file');
|
|
|
|
}
|
2021-11-29 10:07:56 +01:00
|
|
|
if (substr(php_sapi_name(), 0, 3) != 'cli') {
|
2020-06-11 01:26:16 +02:00
|
|
|
//We send to a browser
|
|
|
|
header('Content-Type: text/html');
|
|
|
|
if (headers_sent()) {
|
|
|
|
$oPdf->pdf->Error('Some data has already been output to browser, can\'t send PDF file');
|
|
|
|
}
|
|
|
|
header('Cache-Control: public, must-revalidate, max-age=0'); // HTTP/1.1
|
|
|
|
header('Pragma: public');
|
|
|
|
header('Expires: Sat, 26 Jul 1997 05:00:00 GMT'); // Date in the past
|
|
|
|
header('Last-Modified: '.gmdate('D, d M Y H:i:s').' GMT');
|
|
|
|
header('Content-Length: '.strlen($html));
|
|
|
|
header('Content-Disposition: inline; filename="'.basename($sFilename).'";');
|
|
|
|
}
|
|
|
|
echo $html;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case 'D': {
|
|
|
|
// Download PDF as file
|
|
|
|
if (ob_get_contents()) {
|
|
|
|
$oPdf->pdf->Error('Some data has already been output, can\'t send PDF file');
|
|
|
|
}
|
|
|
|
header('Content-Description: File Transfer');
|
|
|
|
if (headers_sent()) {
|
|
|
|
$oPdf->pdf->Error('Some data has already been output to browser, can\'t send PDF file');
|
|
|
|
}
|
|
|
|
header('Cache-Control: public, must-revalidate, max-age=0'); // HTTP/1.1
|
|
|
|
header('Pragma: public');
|
|
|
|
header('Expires: Sat, 26 Jul 1997 05:00:00 GMT'); // Date in the past
|
|
|
|
header('Last-Modified: '.gmdate('D, d M Y H:i:s').' GMT');
|
|
|
|
// force download dialog
|
|
|
|
header('Content-Type: application/force-download');
|
|
|
|
header('Content-Type: application/octet-stream', false);
|
|
|
|
header('Content-Type: application/download', false);
|
|
|
|
header('Content-Type: text/html', false);
|
|
|
|
// use the Content-Disposition header to supply a recommended filename
|
|
|
|
header('Content-Disposition: attachment; filename="'.basename($sFilename).'";');
|
|
|
|
header('Content-Transfer-Encoding: binary');
|
|
|
|
header('Content-Length: '.strlen($html));
|
|
|
|
echo $html;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case 'F': {
|
|
|
|
// Save PDF to a local file
|
|
|
|
$f = fopen($sFilename, 'wb');
|
|
|
|
if (!$f) {
|
|
|
|
$oPdf->pdf->Error('Unable to create output file: '.$sFilename);
|
|
|
|
}
|
|
|
|
fwrite($f, $html, strlen($html));
|
|
|
|
fclose($f);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case 'S': {
|
|
|
|
// Returns PDF as a string
|
|
|
|
return $html;
|
|
|
|
}
|
|
|
|
default: {
|
|
|
|
$oPdf->pdf->Error('Incorrect output destination: '.$target);
|
|
|
|
}
|
|
|
|
}
|
2020-07-03 20:04:21 +02:00
|
|
|
|
|
|
|
return null;
|
2020-06-11 01:26:16 +02:00
|
|
|
}
|
2020-05-26 16:32:22 +02:00
|
|
|
}
|