Allow to generate multiple labels at once (multiple pages in 1 PDF file).

This commit is contained in:
Jan Böhmer 2020-04-21 00:00:29 +02:00
parent 4c5820ee22
commit e89cc4bb01
12 changed files with 389 additions and 228 deletions

View file

@ -45,17 +45,35 @@ class LabelGenerator
$this->labelHTMLGenerator = $labelHTMLGenerator;
}
public function generateLabel(LabelOptions $options, object $element): string
/**
* @param LabelOptions $options
* @param object|object[] $element An element or an array of elements for which labels should be generated
* @return string
*/
public function generateLabel(LabelOptions $options, $elements): string
{
if (!$this->supports($options, $element)) {
throw new \InvalidArgumentException('The given options are not compatible with the given element!');
if (!is_array($elements) && !is_object($elements)) {
throw new \InvalidArgumentException('$element must be an object or an array of objects!');
}
if (!is_array($elements)) {
$elements = [$elements];
}
$elements_html = [];
dump($elements);
foreach ($elements as $element) {
if (!$this->supports($options, $element)) {
throw new \InvalidArgumentException('The given options are not compatible with the given element!');
}
}
$dompdf = new Dompdf();
$dompdf->loadHtml($this->labelHTMLGenerator->getLabelHTML($options, $element));
$dompdf->setPaper($this->mmToPointsArray($options->getWidth(), $options->getHeight()));
$dompdf->loadHtml($this->labelHTMLGenerator->getLabelHTML($options, $elements));
$dompdf->render();
return $dompdf->output();
}

View file

@ -38,11 +38,23 @@ class LabelHTMLGenerator
$this->replacer = $replacer;
}
public function getLabelHTML(LabelOptions $options, object $element): string
public function getLabelHTML(LabelOptions $options, array $elements): string
{
if (empty($elements)) {
throw new \InvalidArgumentException('$elements must not be empty');
}
$twig_elements = [];
foreach ($elements as $element) {
$twig_elements[] = [
'element' => $element,
'lines' => $this->replacer->replace($options->getLines(), $element)
];
}
return $this->twig->render('LabelSystem/labels/base_label.html.twig', [
'meta_title' => $this->getPDFTitle($options, $element),
'lines' => $this->replacer->replace($options->getLines(), $element),
'meta_title' => $this->getPDFTitle($options, $elements[0]),
'elements' => $twig_elements,
]);
}

View file

@ -0,0 +1,94 @@
<?php
/**
* This file is part of Part-DB (https://github.com/Part-DB/Part-DB-symfony).
*
* Copyright (C) 2019 - 2020 Jan Böhmer (https://github.com/jbtronics)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published
* by the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
namespace App\Services\Misc;
/**
* This Parser allows to parse number ranges like 1-3, 4, 5
*/
class RangeParser
{
/**
* Converts the given range string to an array of all numbers in the given range.
* @param string $range A range string like '1-3, 5, 6'
* @return int[] An array with all numbers from the range (e.g. [1, 2, 3, 5, 6]
*/
public function parse(string $range_str): array
{
//Normalize number separator (we allow , and ;):
$range_str = str_replace(';', ',', $range_str);
$numbers = explode(',', $range_str);
$ranges = [];
foreach ($numbers as $number) {
$number = trim($number);
//Extract min / max if token is a range
$matches = [];
if (preg_match('/^(-?\s*\d+)\s*-\s*(-?\s*\d+)$/', $number, $matches)) {
$ranges[] = $this->generateMinMaxRange($matches[1], $matches[2]);
} elseif (is_numeric($number)) {
$ranges[] = [(int) $number];
} elseif (empty($number)) { //Allow empty tokens
continue;
} else {
throw new \InvalidArgumentException('Invalid range encoutered: ' . $number);
}
}
//Flatten ranges array
return array_merge([], ...$ranges);
}
/**
* Checks if the given string is a valid range.
* @param string $range_str The string that should be checked
* @return bool True if the string is valid, false if not.
*/
public function isValidRange(string $range_str): bool
{
try {
$this->parse($range_str);
return true;
} catch (\InvalidArgumentException $exception) {
return false;
}
}
protected function generateMinMaxRange(string $min, string $max): array
{
$min = (int) $min;
$max = (int) $max;
//Ensure that $max > $min
if ($min > $max) {
$a = $max;
$max = $min;
$min = $a;
}
$tmp = [];
while ($min <= $max) {
$tmp[] = $min;
$min++;
};
return $tmp;
}
}