Adjustments for design and dom elements / attributes
This commit is contained in:
parent
8ce6e6a44e
commit
406cc52279
|
|
@ -55,8 +55,8 @@ class EpcQrGenerator
|
|||
|
||||
$qr = $writer->writeString($this->encodeMessage(), 'utf-8');
|
||||
|
||||
return "<svg viewBox='0 0 200 200' width='200' height='200' x='0' y='0' xmlns='http://www.w3.org/2000/svg'>
|
||||
<rect x='0' y='0' width='100%'' height='100%' />{$qr}</svg>";
|
||||
return htmlspecialchars("<svg viewBox='0 0 200 200' width='200' height='200' x='0' y='0' xmlns='http://www.w3.org/2000/svg'>
|
||||
<rect x='0' y='0' width='100%'' height='100%' />{$qr}</svg>");
|
||||
|
||||
} catch (\Throwable $e) {
|
||||
nlog("EPC QR failure => ".$e->getMessage());
|
||||
|
|
|
|||
|
|
@ -172,7 +172,7 @@ class SwissQrGenerator
|
|||
->setPrintable(false)
|
||||
->getPaymentPart();
|
||||
|
||||
return $html;
|
||||
return htmlspecialchars($html);
|
||||
} catch (\Exception $e) {
|
||||
|
||||
// if (is_iterable($qrBill->getViolations())) {
|
||||
|
|
|
|||
|
|
@ -212,6 +212,7 @@ class PreviewController extends BaseController
|
|||
->build();
|
||||
|
||||
if (request()->query('html') == 'true') {
|
||||
|
||||
return $maker->getCompiledHTML();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -83,6 +83,7 @@ class PdfBuilder
|
|||
|
||||
private function removeEmptyElements(): self
|
||||
{
|
||||
|
||||
$elements =[
|
||||
'product-table', 'task-table', 'delivery-note-table',
|
||||
'statement-invoice-table', 'statement-payment-table', 'statement-aging-table-totals',
|
||||
|
|
@ -96,45 +97,59 @@ class PdfBuilder
|
|||
|
||||
if ($el && $el->childElementCount === 0) {
|
||||
$el->parentNode->removeChild($el); // This removes the element completely
|
||||
// $el->setAttribute('style', 'display: none !important;');
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// $xpath = new \DOMXPath($this->document);
|
||||
// $elements = $xpath->query('//*[@data-state="encoded-html"]');
|
||||
|
||||
// foreach ($elements as $element) {
|
||||
$xpath = new \DOMXPath($this->document);
|
||||
$elements = $xpath->query('//*[@data-state="encoded-html"]');
|
||||
|
||||
// // Decode the HTML content
|
||||
// $html = htmlspecialchars_decode($element->textContent, ENT_QUOTES | ENT_HTML5);
|
||||
// $html = str_ireplace(['<br>'], '<br/>', $html);
|
||||
foreach ($elements as $element) {
|
||||
|
||||
// // Create a temporary document to properly parse the HTML
|
||||
// $temp = new \DOMDocument();
|
||||
// Decode the HTML content
|
||||
$html = htmlspecialchars_decode($element->textContent, ENT_QUOTES | ENT_HTML5);
|
||||
$html = str_ireplace(['<br>','<?xml encoding="UTF-8">'], ['<br/>',''], $html);
|
||||
|
||||
// // Add UTF-8 wrapper and div container
|
||||
// $wrappedHtml = '<?xml encoding="UTF-8"><div>' . $html . '</div>';
|
||||
// Create a temporary document to properly parse the HTML
|
||||
$temp = new \DOMDocument();
|
||||
|
||||
// // Load the HTML, suppressing any parsing warnings
|
||||
// @$temp->loadHTML($wrappedHtml, LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD);
|
||||
// Add UTF-8 wrapper and div container
|
||||
$wrappedHtml = '<?xml encoding="UTF-8"><div>' . $html . '</div>';
|
||||
|
||||
// // Import the div's contents
|
||||
// $imported = $this->document->importNode($temp->getElementsByTagName('div')->item(0), true);
|
||||
// Load the HTML, suppressing any parsing warnings
|
||||
@$temp->loadHTML($wrappedHtml, LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD);
|
||||
|
||||
// // Clear existing content of the element
|
||||
// while ($element->firstChild) {
|
||||
// $element->removeChild($element->firstChild);
|
||||
// }
|
||||
// Import the div's contents
|
||||
$imported = $this->document->importNode($temp->getElementsByTagName('div')->item(0), true);
|
||||
|
||||
// // Append the new content to the element
|
||||
// $element->appendChild($imported);
|
||||
// Clear existing content - more efficient
|
||||
$element->textContent = '';
|
||||
// Get the first div's content
|
||||
$divContent = $temp->getElementsByTagName('div')->item(0);
|
||||
|
||||
if ($divContent) {
|
||||
// Import all nodes from the temporary div
|
||||
foreach ($divContent->childNodes as $child) {
|
||||
$imported = $this->document->importNode($child, true);
|
||||
$element->appendChild($imported);
|
||||
}
|
||||
} else {
|
||||
// Fallback - import the entire content if no div found
|
||||
$imported = $this->document->importNode($temp->documentElement, true);
|
||||
$element->appendChild($imported);
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
// }
|
||||
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Final method to get compiled HTML.
|
||||
*
|
||||
|
|
@ -1131,7 +1146,7 @@ class PdfBuilder
|
|||
}
|
||||
|
||||
if(array_key_exists($column, $column_visibility)){
|
||||
return $column_visibility[$column] ? false: true;
|
||||
return !$column_visibility[$column];
|
||||
}
|
||||
|
||||
return true;
|
||||
|
|
@ -1386,9 +1401,11 @@ class PdfBuilder
|
|||
|
||||
$elements = [
|
||||
['element' => 'div', 'properties' => ['style' => 'display: flex; flex-direction: column;'], 'elements' => [
|
||||
['element' => 'p', 'content' => strtr(str_replace(["labels", "values"], ["",""], $_variables['values']['$entity.public_notes']), $_variables), 'properties' => ['data-ref' => 'total_table-public_notes', 'style' => 'text-align: left;']],
|
||||
['element' => 'p', 'content' => '', 'properties' => ['style' => 'text-align: left; display: flex; flex-direction: column; page-break-inside: auto;'], 'elements' => [
|
||||
['element' => 'span', 'content' => '$entity.terms_label: ', 'properties' => ['data-ref' => 'total_table-terms-label', 'style' => "font-weight: bold; text-align: left; margin-top: 1rem; {$show_terms_label}"]],
|
||||
['element' => 'div', 'properties' => ['data-ref' => 'total_table-public_notes', 'style' => 'text-align: left;'], 'elements' => [
|
||||
['element' => 'span', 'content' => strtr(str_replace(["labels", "values"], ["",""], $_variables['values']['$entity.public_notes']), $_variables)]
|
||||
]],
|
||||
['element' => 'div', 'content' => '', 'properties' => ['style' => 'text-align: left; display: flex; flex-direction: column; page-break-inside: auto;'], 'elements' => [
|
||||
['element' => 'span', 'content' => '$entity.terms_label: ', 'properties' => ['data-ref' => 'total_table-terms-label', 'style' => "text-align: left; margin-top: 1rem; {$show_terms_label}"]],
|
||||
['element' => 'span', 'content' => strtr(str_replace("labels", "", $_variables['values']['$entity.terms']), $_variables['labels']), 'properties' => ['data-ref' => 'total_table-terms', 'style' => 'text-align: left;']],
|
||||
]],
|
||||
['element' => 'img', 'properties' => ['style' => 'max-width: 50%; height: auto;', 'src' => '$contact.signature', 'id' => 'contact-signature']],
|
||||
|
|
@ -1495,6 +1512,7 @@ class PdfBuilder
|
|||
['element' => 'span', 'content' => ''],
|
||||
]];
|
||||
|
||||
|
||||
return $elements;
|
||||
}
|
||||
|
||||
|
|
@ -2037,11 +2055,15 @@ class PdfBuilder
|
|||
$html = strtr($this->getCompiledHTML(), $this->service->html_variables['labels']);
|
||||
$html = strtr($html, $this->service->html_variables['values']);
|
||||
|
||||
$html = htmlspecialchars_decode($html, ENT_QUOTES | ENT_HTML5);
|
||||
$html = str_ireplace(['<br>'], '<br/>', $html);
|
||||
//old block
|
||||
@$this->document->loadHTML(mb_convert_encoding($html, 'HTML-ENTITIES', 'UTF-8'));
|
||||
|
||||
@$this->document->loadHTML('<?xml encoding="UTF-8">'.$html, LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD);
|
||||
//new block
|
||||
// $html = htmlspecialchars_decode($html, ENT_QUOTES | ENT_HTML5);
|
||||
// $html = str_ireplace(['<br>','<?xml encoding="UTF-8">'], ['<br/>',''], $html);
|
||||
// @$this->document->loadHTML('<?xml encoding="UTF-8">'.$html, LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD);
|
||||
|
||||
//continues
|
||||
$this->document->saveHTML();
|
||||
|
||||
return $this;
|
||||
|
|
|
|||
|
|
@ -90,7 +90,10 @@ class PdfService
|
|||
public function getPdf()
|
||||
{
|
||||
try {
|
||||
$pdf = $this->resolvePdfEngine($this->getHtml());
|
||||
|
||||
$html = $this->getHtml();
|
||||
// nlog($html);
|
||||
$pdf = $this->resolvePdfEngine($html);
|
||||
|
||||
$numbered_pdf = $this->pageNumbering($pdf, $this->company);
|
||||
|
||||
|
|
|
|||
|
|
@ -40,6 +40,7 @@ class Purify
|
|||
'polygon', 'g', 'text', 'tspan', 'defs', 'use', 'title',
|
||||
];
|
||||
|
||||
|
||||
private static array $allowed_attributes = [
|
||||
// Global Attributes
|
||||
'class' => ['*'],
|
||||
|
|
@ -71,7 +72,7 @@ class Purify
|
|||
'preserveAspectRatio' => ['*'],
|
||||
'version' => ['*'],
|
||||
'xlink:href' => ['#*'], // Only allow internal references
|
||||
|
||||
'fill-rule' => ['nonzero', 'evenodd'],
|
||||
// Layout & Presentation
|
||||
'align' => ['left', 'center', 'right', 'justify'],
|
||||
'valign' => ['top', 'middle', 'bottom', 'baseline'],
|
||||
|
|
@ -115,6 +116,8 @@ class Purify
|
|||
'content' => ['*'],
|
||||
'http-equiv' => ['*'],
|
||||
'viewport' => ['*'],
|
||||
'xmlns' => ['http://www.w3.org/2000/svg'],
|
||||
|
||||
];
|
||||
|
||||
private static array $dangerous_css_patterns = [
|
||||
|
|
@ -214,6 +217,24 @@ class Purify
|
|||
return implode('; ', $safe_declarations);
|
||||
}
|
||||
|
||||
private static array $dangerous_svg_elements = [
|
||||
'script',
|
||||
'handler',
|
||||
'foreignObject',
|
||||
'annotation-xml',
|
||||
'color-profile',
|
||||
'style', // or carefully sanitize if needed
|
||||
'onload',
|
||||
'onerror',
|
||||
'onunload',
|
||||
'onabort'
|
||||
];
|
||||
|
||||
private static function isDangerousSvgElement(string $tagName): bool
|
||||
{
|
||||
return in_array(strtolower($tagName), self::$dangerous_svg_elements);
|
||||
}
|
||||
|
||||
public static function clean(string $html): string
|
||||
{
|
||||
if(config('ninja.disable_purify_html')){
|
||||
|
|
@ -221,9 +242,9 @@ class Purify
|
|||
}
|
||||
|
||||
$html = str_replace('%24', '$', $html);
|
||||
|
||||
libxml_use_internal_errors(true);
|
||||
libxml_disable_entity_loader(true);
|
||||
// nlog("pre purify => {$html}");
|
||||
|
||||
$document = new \DOMDocument();
|
||||
@$document->loadHTML(htmlspecialchars_decode(htmlspecialchars($html, ENT_QUOTES, 'UTF-8')));
|
||||
|
|
@ -267,11 +288,25 @@ class Purify
|
|||
$current_attributes[$attr->name] = $attr->value;
|
||||
}
|
||||
|
||||
// Handle SVG node separately
|
||||
if ($node->tagName === 'svg') {
|
||||
// Keep only allowed SVG attributes
|
||||
$current_attributes = [];
|
||||
foreach ($node->attributes as $attr) {
|
||||
|
||||
if (in_array($attr->name, self::$dangerous_svg_elements)) {
|
||||
$node->removeAttribute($attr->name);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
} else {
|
||||
// First, remove ALL attributes from the node
|
||||
while ($node->attributes->length > 0) {
|
||||
$attr = $node->attributes->item(0);
|
||||
$node->removeAttribute($attr->nodeName);
|
||||
}
|
||||
}
|
||||
|
||||
// Then add back only the allowed attributes
|
||||
foreach ($current_attributes as $name => $value) {
|
||||
|
|
@ -361,15 +396,18 @@ class Purify
|
|||
|
||||
$html = str_replace('%24', '$', $document->saveHTML());
|
||||
|
||||
// nlog("post purify => {$html}");
|
||||
return $html;
|
||||
|
||||
} catch (\Exception $e) {
|
||||
|
||||
nlog('Error cleaning HTML: ' . $e->getMessage());
|
||||
|
||||
libxml_disable_entity_loader(false);
|
||||
libxml_clear_errors();
|
||||
|
||||
throw new \RuntimeException('HTML sanitization failed');
|
||||
} finally {
|
||||
// Restore original setting
|
||||
libxml_disable_entity_loader(false);
|
||||
libxml_clear_errors();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -839,7 +839,6 @@ class Design extends BaseDesign
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
$visible_elements = array_filter($elements, function ($element) {
|
||||
return $element['properties']['visi'] ?? true;
|
||||
});
|
||||
|
|
@ -883,7 +882,7 @@ class Design extends BaseDesign
|
|||
}
|
||||
|
||||
if(array_key_exists($column, $column_visibility)){
|
||||
return $column_visibility[$column] ? false: true;
|
||||
return !$column_visibility[$column];
|
||||
}
|
||||
|
||||
return true;
|
||||
|
|
@ -957,20 +956,6 @@ class Design extends BaseDesign
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
// Then, filter the elements array
|
||||
$element['elements'] = array_map(function ($el) {
|
||||
if (isset($el['properties']['visi'])) {
|
||||
if ($el['properties']['visi'] === false) {
|
||||
$el['properties']['style'] = 'display: none;';
|
||||
}
|
||||
unset($el['properties']['visi']);
|
||||
}
|
||||
return $el;
|
||||
}, $element['elements']);
|
||||
|
||||
|
||||
$elements[] = $element;
|
||||
}
|
||||
|
||||
return $elements;
|
||||
|
|
@ -1030,6 +1015,14 @@ class Design extends BaseDesign
|
|||
$element['elements'][] = ['element' => 'td', 'content' => $row[$cell], 'properties' => ['data-ref' => 'product_table-product.tax2-td', 'visi' => $this->visibilityCheck($column_visibility, $cell)]];
|
||||
} elseif ($cell == '$product.tax_rate3') {
|
||||
$element['elements'][] = ['element' => 'td', 'content' => $row[$cell], 'properties' => ['data-ref' => 'product_table-product.tax3-td', 'visi' => $this->visibilityCheck($column_visibility, $cell)]];
|
||||
} elseif ($cell == '$task.discount' && !$this->company->enable_product_discount) {
|
||||
$element['elements'][] = ['element' => 'td', 'content' => $row['$task.discount'], 'properties' => ['data-ref' => 'task_table-task.discount-td', 'style' => 'display: none;']];
|
||||
} elseif ($cell == '$task.tax_rate1') {
|
||||
$element['elements'][] = ['element' => 'td', 'content' => $row[$cell], 'properties' => ['data-ref' => 'task_table-task.tax1-td', 'visi' => $this->visibilityCheck($column_visibility, $cell)]];
|
||||
} elseif ($cell == '$task.tax_rate2') {
|
||||
$element['elements'][] = ['element' => 'td', 'content' => $row[$cell], 'properties' => ['data-ref' => 'task_table-task.tax2-td', 'visi' => $this->visibilityCheck($column_visibility, $cell)]];
|
||||
} elseif ($cell == '$task.tax_rate3') {
|
||||
$element['elements'][] = ['element' => 'td', 'content' => $row[$cell], 'properties' => ['data-ref' => 'task_table-task.tax3-td', 'visi' => $this->visibilityCheck($column_visibility, $cell)]];
|
||||
}elseif ($cell == '$product.unit_cost' || $cell == '$task.rate') {
|
||||
$element['elements'][] = ['element' => 'td', 'content' => $row[$cell], 'properties' => ['style' => 'white-space: nowrap;', 'data-ref' => "{$_type}_table-" . substr($cell, 1) . '-td', 'visi' => $this->visibilityCheck($column_visibility, $cell)]];
|
||||
} else {
|
||||
|
|
@ -1038,7 +1031,19 @@ class Design extends BaseDesign
|
|||
}
|
||||
}
|
||||
|
||||
// Then, filter the elements array
|
||||
$element['elements'] = array_map(function ($el) {
|
||||
if (isset($el['properties']['visi'])) {
|
||||
if ($el['properties']['visi'] === false) {
|
||||
$el['properties']['style'] = 'display: none;';
|
||||
}
|
||||
unset($el['properties']['visi']);
|
||||
}
|
||||
return $el;
|
||||
}, $element['elements']);
|
||||
|
||||
$elements[] = $element;
|
||||
|
||||
}
|
||||
|
||||
$document = null;
|
||||
|
|
@ -1058,10 +1063,11 @@ class Design extends BaseDesign
|
|||
});
|
||||
|
||||
// Transform the items first
|
||||
$transformed_items = $this->transformLineItems($filtered_items,
|
||||
$transformed_items = $this->transformLineItems(
|
||||
$filtered_items->toArray(),
|
||||
$type_id === '1' ? '$product' : '$task'
|
||||
);
|
||||
|
||||
nlog($transformed_items);
|
||||
$columns = [];
|
||||
|
||||
// Initialize all columns as empty
|
||||
|
|
@ -1105,9 +1111,12 @@ class Design extends BaseDesign
|
|||
$variables = $this->context['pdf_variables']['total_columns'];
|
||||
$show_terms_label = $this->entityVariableCheck('$entity.terms') ? 'display: none;' : '';
|
||||
|
||||
|
||||
$elements = [
|
||||
['element' => 'div', 'properties' => ['style' => 'display: flex; flex-direction: column;'], 'elements' => [
|
||||
['element' => 'p', 'content' => strtr(str_replace(["labels","values"], ["",""], $_variables['values']['$entity.public_notes']), $_variables), 'properties' => ['data-ref' => 'total_table-public_notes', 'style' => 'text-align: left;']],
|
||||
['element' => 'p', 'properties' => ['data-ref' => 'total_table-public_notes', 'style' => 'text-align: left;'], 'elements' => [
|
||||
['element' => 'span', 'content' => strtr(str_replace(["labels", "values"], ["",""], $_variables['values']['$entity.public_notes']), $_variables)]
|
||||
]],
|
||||
['element' => 'p', 'content' => '', 'properties' => ['style' => 'text-align: left; display: flex; flex-direction: column; page-break-inside: auto;'], 'elements' => [
|
||||
['element' => 'span', 'content' => '$entity.terms_label: ', 'properties' => ['data-ref' => 'total_table-terms-label', 'style' => "font-weight: bold; text-align: left; margin-top: 1rem; {$show_terms_label}"]],
|
||||
['element' => 'span', 'content' => strtr(str_replace("labels", "", $_variables['values']['$entity.terms']), $_variables['labels']), 'properties' => ['data-ref' => 'total_table-terms', 'style' => 'text-align: left;']],
|
||||
|
|
@ -1192,9 +1201,6 @@ class Design extends BaseDesign
|
|||
}
|
||||
} elseif (Str::startsWith($variable, '$custom_surcharge')) {
|
||||
$_variable = ltrim($variable, '$'); // $custom_surcharge1 -> custom_surcharge1
|
||||
|
||||
//07/09/2023 don't show custom values if they are empty
|
||||
// $visible = intval($this->entity->{$_variable}) != 0;
|
||||
$visible = intval(str_replace(['0','.'], '', $this->entity->{$_variable})) != 0;
|
||||
|
||||
$elements[1]['elements'][] = ['element' => 'div', 'elements' => [
|
||||
|
|
|
|||
|
|
@ -75,7 +75,7 @@ class PdfMaker
|
|||
|
||||
$ts = new TemplateService();
|
||||
|
||||
if (isset($this->options['client'])) {
|
||||
if (isset($this->options['client']) && !empty($this->options['client'])) {
|
||||
$client = $this->options['client'];
|
||||
try {
|
||||
$ts->setCompany($client->company);
|
||||
|
|
@ -85,7 +85,7 @@ class PdfMaker
|
|||
}
|
||||
}
|
||||
|
||||
if (isset($this->options['vendor'])) {
|
||||
if (isset($this->options['vendor']) && !empty($this->options['vendor'])) {
|
||||
$vendor = $this->options['vendor'];
|
||||
try {
|
||||
$ts->setCompany($vendor->company);
|
||||
|
|
@ -139,40 +139,48 @@ class PdfMaker
|
|||
|
||||
}
|
||||
|
||||
// $xpath = new \DOMXPath($this->document);
|
||||
// $elements = $xpath->query('//*[@data-state="encoded-html"]');
|
||||
$xpath = new \DOMXPath($this->document);
|
||||
$elements = $xpath->query('//*[@data-state="encoded-html"]');
|
||||
|
||||
// foreach ($elements as $element) {
|
||||
foreach ($elements as $element) {
|
||||
|
||||
|
||||
// // Decode the HTML content
|
||||
// $html = htmlspecialchars_decode($element->textContent, ENT_QUOTES | ENT_HTML5);
|
||||
// $html = str_ireplace(['<br>'], '<br/>', $html);
|
||||
// Decode the HTML content
|
||||
$html = htmlspecialchars_decode($element->textContent, ENT_QUOTES | ENT_HTML5);
|
||||
$html = str_ireplace(['<br>','<?xml encoding="UTF-8">'], ['<br/>',''], $html);
|
||||
|
||||
// // Create a temporary document to properly parse the HTML
|
||||
// $temp = new \DOMDocument();
|
||||
// Create a temporary document to properly parse the HTML
|
||||
$temp = new \DOMDocument();
|
||||
|
||||
// // Add UTF-8 wrapper and div container
|
||||
// $wrappedHtml = '<?xml encoding="UTF-8"><div>' . $html . '</div>';
|
||||
// Add UTF-8 wrapper and div container
|
||||
$wrappedHtml = '<?xml encoding="UTF-8"><div>' . $html . '</div>';
|
||||
|
||||
// // Load the HTML, suppressing any parsing warnings
|
||||
// @$temp->loadHTML($wrappedHtml, LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD);
|
||||
// Load the HTML, suppressing any parsing warnings
|
||||
@$temp->loadHTML($wrappedHtml, LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD);
|
||||
|
||||
// // Import the div's contents
|
||||
// $imported = $this->document->importNode($temp->getElementsByTagName('div')->item(0), true);
|
||||
// Import the div's contents
|
||||
$imported = $this->document->importNode($temp->getElementsByTagName('div')->item(0), true);
|
||||
|
||||
// // Clear existing content of the element
|
||||
// while ($element->firstChild) {
|
||||
// $element->removeChild($element->firstChild);
|
||||
// }
|
||||
// Clear existing content - more efficient
|
||||
$element->textContent = '';
|
||||
// Get the first div's content
|
||||
$divContent = $temp->getElementsByTagName('div')->item(0);
|
||||
|
||||
// // Append the new content to the element
|
||||
// $element->appendChild($imported);
|
||||
|
||||
// }
|
||||
if ($divContent) {
|
||||
// Import all nodes from the temporary div
|
||||
foreach ($divContent->childNodes as $child) {
|
||||
$imported = $this->document->importNode($child, true);
|
||||
$element->appendChild($imported);
|
||||
}
|
||||
} else {
|
||||
// Fallback - import the entire content if no div found
|
||||
$imported = $this->document->importNode($temp->documentElement, true);
|
||||
$element->appendChild($imported);
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -143,13 +143,15 @@ trait PdfMakerUtilities
|
|||
|
||||
$html = strtr($html, $variables['values']);
|
||||
|
||||
// @$this->document->loadHTML(mb_convert_encoding($html, 'HTML-ENTITIES', 'UTF-8'));
|
||||
//old block
|
||||
@$this->document->loadHTML(mb_convert_encoding($html, 'HTML-ENTITIES', 'UTF-8'));
|
||||
|
||||
$html = htmlspecialchars_decode($html, ENT_QUOTES | ENT_HTML5);
|
||||
$html = str_ireplace(['<br>'], '<br/>', $html);
|
||||
|
||||
@$this->document->loadHTML('<?xml encoding="UTF-8">'.$html, LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD);
|
||||
//new block
|
||||
// $html = htmlspecialchars_decode($html, ENT_QUOTES | ENT_HTML5);
|
||||
// $html = str_ireplace(['<br>'], '<br/>', $html);
|
||||
// @$this->document->loadHTML('<?xml encoding="UTF-8">'.$html, LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD);
|
||||
|
||||
//continues
|
||||
$this->document->saveHTML();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -95,7 +95,6 @@ trait PdfMaker
|
|||
|
||||
$html = str_ireplace(['file:/', 'iframe', '<embed', '<embed', '<object', '<object', '127.0.0.1', 'localhost', '<?xml encoding="UTF-8">'], '', $html);
|
||||
|
||||
// nlog($html);
|
||||
$generated = $pdf
|
||||
->setHtml($html)
|
||||
->generate();
|
||||
|
|
|
|||
|
|
@ -414,7 +414,7 @@
|
|||
}
|
||||
|
||||
#qr-bill{
|
||||
width:100%;
|
||||
width:100% !important;
|
||||
}
|
||||
|
||||
/** Useful snippets, uncomment to enable. **/
|
||||
|
|
|
|||
|
|
@ -348,7 +348,7 @@
|
|||
}
|
||||
|
||||
#qr-bill{
|
||||
width:100%;
|
||||
width:100% !important;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -348,6 +348,10 @@
|
|||
|
||||
.pqrcode {}
|
||||
|
||||
#qr-bill{
|
||||
width:100% !important;
|
||||
}
|
||||
|
||||
/** Useful snippets, uncomment to enable. **/
|
||||
|
||||
/** Hide company logo **/
|
||||
|
|
|
|||
|
|
@ -37,17 +37,6 @@
|
|||
padding: 0;
|
||||
}
|
||||
|
||||
#qr-bill {
|
||||
width:100% !important;
|
||||
box-sizing: border-box;
|
||||
border-collapse: collapse;
|
||||
color: #000;
|
||||
}
|
||||
|
||||
#qr-bill td {
|
||||
max-width: none;
|
||||
}
|
||||
|
||||
.header-container {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(3, 1fr);
|
||||
|
|
@ -360,7 +349,7 @@
|
|||
}
|
||||
|
||||
#qr-bill{
|
||||
width:100%;
|
||||
width:100% !important;
|
||||
}
|
||||
|
||||
/** Useful snippets, uncomment to enable. **/
|
||||
|
|
|
|||
|
|
@ -311,7 +311,7 @@
|
|||
}
|
||||
|
||||
#qr-bill{
|
||||
width:100%;
|
||||
width:100% !important;
|
||||
}
|
||||
|
||||
/** Useful snippets, uncomment to enable. **/
|
||||
|
|
|
|||
|
|
@ -331,7 +331,7 @@
|
|||
}
|
||||
|
||||
#qr-bill{
|
||||
width:100%;
|
||||
width:100% !important;
|
||||
}
|
||||
|
||||
/** Useful snippets, uncomment to enable. **/
|
||||
|
|
|
|||
|
|
@ -392,7 +392,7 @@
|
|||
|
||||
}
|
||||
#qr-bill{
|
||||
width:100%;
|
||||
width:100% !important;
|
||||
}
|
||||
|
||||
/** Useful snippets, uncomment to enable. **/
|
||||
|
|
|
|||
|
|
@ -395,7 +395,7 @@
|
|||
}
|
||||
|
||||
#qr-bill{
|
||||
width:100%;
|
||||
width:100% !important;
|
||||
}
|
||||
/** Useful snippets, uncomment to enable. **/
|
||||
|
||||
|
|
|
|||
|
|
@ -354,7 +354,7 @@
|
|||
|
||||
|
||||
#qr-bill{
|
||||
width:100%;
|
||||
width:100% !important;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -383,6 +383,10 @@
|
|||
|
||||
}
|
||||
|
||||
#qr-bill{
|
||||
width:100% !important;
|
||||
}
|
||||
|
||||
/** Useful snippets, uncomment to enable. **/
|
||||
|
||||
/** Hide company logo **/
|
||||
|
|
|
|||
|
|
@ -388,7 +388,7 @@
|
|||
}
|
||||
|
||||
#qr-bill{
|
||||
width:100%;
|
||||
width:100% !important;
|
||||
}
|
||||
|
||||
/** Useful snippets, uncomment to enable. **/
|
||||
|
|
|
|||
Loading…
Reference in New Issue