diff --git a/core/pdfbulkexport.class.inc.php b/core/pdfbulkexport.class.inc.php index df22d7141..6794f3419 100644 --- a/core/pdfbulkexport.class.inc.php +++ b/core/pdfbulkexport.class.inc.php @@ -21,6 +21,19 @@ use Combodo\iTop\Application\UI\Base\Layout\MultiColumn\MultiColumnUIBlockFactor */ class PDFBulkExport extends HTMLBulkExport { + /** + * @var string For sample purposes + * @internal + * @since 2.7.8 + */ + const ENUM_OUTPUT_TYPE_SAMPLE = 'sample'; + /** + * @var string For the real export + * @internal + * @since 2.7.8 + */ + const ENUM_OUTPUT_TYPE_REAL = 'real'; + public function DisplayUsage(Page $oP) { $oP->p(" * pdf format options:"); @@ -197,6 +210,25 @@ EOF return $sPDF; } + /** + * @inheritDoc + * @since 2.7.8 + */ + protected function GetSampleData($oObj, $sAttCode) + { + if ($sAttCode !== 'id') + { + $oAttDef = MetaModel::GetAttributeDef(get_class($oObj), $sAttCode); + + // As sample data will be displayed in the web browser, AttributeImage needs to be rendered with a regular HTML format, meaning its "src" looking like "data:image/png;base64,iVBORw0KGgoAAAANSUh..." + // Whereas for the PDF generation it needs to be rendered with a TCPPDF-compatible format, meaning its "src" looking like "@iVBORw0KGgoAAAANSUh..." + if ($oAttDef instanceof AttributeImage) { + return $this->GetAttributeImageValue($oAttDef, $oObj->Get($sAttCode), static::ENUM_OUTPUT_TYPE_SAMPLE); + } + } + return parent::GetSampleData($oObj, $sAttCode); + } + protected function GetValue($oObj, $sAttCode) { switch($sAttCode) @@ -212,31 +244,7 @@ EOF $oAttDef = MetaModel::GetAttributeDef(get_class($oObj), $sAttCode); if ($oAttDef instanceof AttributeImage) { - // To limit the image size in the PDF output, we have to enforce the size as height/width because max-width/max-height have no effect - // - $iDefaultMaxWidthPx = 48; - $iDefaultMaxHeightPx = 48; - if ($value->IsEmpty()) - { - $iNewWidth = $iDefaultMaxWidthPx; - $iNewHeight = $iDefaultMaxHeightPx; - - $sUrl = $oAttDef->Get('default_image'); - } - else - { - list($iWidth, $iHeight) = utils::GetImageSize($value->GetData()); - $iMaxWidthPx = min($iDefaultMaxWidthPx, $oAttDef->Get('display_max_width')); - $iMaxHeightPx = min($iDefaultMaxHeightPx, $oAttDef->Get('display_max_height')); - - $fScale = min($iMaxWidthPx / $iWidth, $iMaxHeightPx / $iHeight); - $iNewWidth = $iWidth * $fScale; - $iNewHeight = $iHeight * $fScale; - - $sUrl = 'data:'.$value->GetMimeType().';base64,'.base64_encode($value->GetData()); - } - $sRet = ($sUrl !== null) ? '' : ''; - $sRet = '
'.$sRet.'
'; + $sRet = $this->GetAttributeImageValue($oAttDef, $value, static::ENUM_OUTPUT_TYPE_REAL); } else { @@ -251,6 +259,55 @@ EOF return $sRet; } + /** + * @param \AttributeImage $oAttDef Instance of image attribute + * @param \ormDocument $oValue Value of image attribute + * @param string $sOutputType {@see \PDFBulkExport::ENUM_OUTPUT_TYPE_SAMPLE}, {@see \PDFBulkExport::ENUM_OUTPUT_TYPE_REAL} + * + * @return string Rendered value of $oAttDef / $oValue according to the desired $sOutputType + * @since 2.7.8 + */ + protected function GetAttributeImageValue(AttributeImage $oAttDef, ormDocument $oValue, string $sOutputType) + { + // To limit the image size in the PDF output, we have to enforce the size as height/width because max-width/max-height have no effect + // + $iDefaultMaxWidthPx = 48; + $iDefaultMaxHeightPx = 48; + if ($oValue->IsEmpty()) { + $iNewWidth = $iDefaultMaxWidthPx; + $iNewHeight = $iDefaultMaxHeightPx; + + $sUrl = $oAttDef->Get('default_image'); + } else { + list($iWidth, $iHeight) = utils::GetImageSize($oValue->GetData()); + $iMaxWidthPx = min($iDefaultMaxWidthPx, $oAttDef->Get('display_max_width')); + $iMaxHeightPx = min($iDefaultMaxHeightPx, $oAttDef->Get('display_max_height')); + + $fScale = min($iMaxWidthPx / $iWidth, $iMaxHeightPx / $iHeight); + $iNewWidth = $iWidth * $fScale; + $iNewHeight = $iHeight * $fScale; + + $sValueAsBase64 = base64_encode($oValue->GetData()); + switch ($sOutputType) { + case static::ENUM_OUTPUT_TYPE_SAMPLE: + $sUrl = 'data:'.$oValue->GetMimeType().';base64,'.$sValueAsBase64; + break; + + case static::ENUM_OUTPUT_TYPE_REAL: + default: + // TCPDF requires base64-encoded images to be rendered without the usual "data:;base64" header but with an "@" + // @link https://tcpdf.org/examples/example_009/ + $sUrl = '@'.$sValueAsBase64; + break; + } + } + + $sRet = ($sUrl !== null) ? '' : ''; + $sRet = '
'.$sRet.'
'; + + return $sRet; + } + public function GetSupportedFormats() { return array('pdf' => Dict::S('Core:BulkExport:PDFFormat')); diff --git a/test/application/TestAutoload.php b/test/application/TestAutoload.php new file mode 100644 index 000000000..60a57f45d --- /dev/null +++ b/test/application/TestAutoload.php @@ -0,0 +1,27 @@ +assertTrue(true); + return; + } + $this->assertTrue(false, 'You should run composer install on the faulty module'); + } +}