Source of file WkhtmlService.php
Size: 10,991 Bytes - Last Modified: 2023-11-16T22:56:03+01:00
/home/websites/teicee/packagist/site/phpdoc/conf/../vendor/teicee/dpdf-bundle/src/Service/WkhtmlService.php
| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268 | <?phpnamespace TIC\DpdfBundle\Service; use TIC\DpdfBundle\Base\PDFService as BaseService; use Symfony\Component\Process\Process; use Symfony\Component\Process\Exception\ProcessFailedException; /** * Service de génération de PDF avec wkhtml(topdf|toimage) * (à partir d'un contenu HMTL ou d'une vue Twig). */class WkhtmlService extends BaseService {protected $cmd_bin; protected $cmd_opt = array(); protected $cmd_src; protected $cmd_out; protected $timeout = 60; // ------------------------------------------------------------------------------------------ CONFIG/** * Initialisation de l'objet Dompdf avec ses options. * * @param array $pdf_options Surcharge d'options pour Dompdf * @return WkhtmlService */public function initEngine(array $pdf_options = []): WkhtmlService { $opts = array(); // options complétée avec la configuration par défaut (surchargée par parameters) $pdf_options+= $this->confs; if (isset($pdf_options['debug'])) $this->debug = (bool)$pdf_options['debug']; // binary: wkhtmltopdf | wkhtmltoimage switch (\strtolower($pdf_options['generator'])) { case "image": case "png": case "gd": $isPDF = false; $this->cmd_bin = $this->paths['wkhtml_image']; break; default: // auto, pdf... $isPDF = true; $this->cmd_bin = $this->paths['wkhtml_pdf']; break; } // options non disponibles avec wkhtmltoimage if ($isPDF) { // -s, --page-size <Size> Set paper size to: A4, Letter, etc. if ($pdf_options['paper_size'] && $isPDF) { $opts[] = "--page-size"; $opts[] = $pdf_options['paper_size']; } // -O, --orientation <orientation> Set orientation to Landscape or Portrait if ($pdf_options['orientation']) { $opts[] = "--orientation"; $opts[] = $pdf_options['orientation']; } // --print-media-type Use print media-type instead of screen // --no-print-media-type Do not use print media-type instead of screen (default) if ($pdf_options['media_type'] === 'print') { $opts[] = "--print-media-type"; } else { $opts[] = "--no-print-media-type"; } // -d, --dpi <dpi> Change the dpi explicitly (this has no effect on X11 based systems) (default 96) // --image-dpi <integer> When embedding images scale them down to this dpi (default 600) if (! empty($pdf_options['pdi']) && \is_numeric($pdf_options['pdi'])) { $opts[] = "--dpi"; $opts[] = \intval($pdf_options['pdi']); $opts[] = "--image-dpi"; $opts[] = \intval($pdf_options['pdi']); } // --no-background Do not print background if (isset($pdf_options['background']) && empty($pdf_options['background'])) { $opts[] = "--no-background"; } // --disable-smart-shrinking Disable the intelligent shrinking strategy used by WebKit that makes the pixel/dpi ratio none constant if (isset($pdf_options['smart_shrinking']) && empty($pdf_options['smart_shrinking'])) { $opts[] = "--disable-smart-shrinking"; } // -l, --lowquality Generates lower quality pdf/ps. Useful to shrink the result document space $opts[] = "--lowquality"; // @TODO // --viewport-size <> Set viewport size if you have custom scrollbars or css attribute overflow to emulate window size // -B, --margin-bottom <unitreal> Set the page bottom margin // -L, --margin-left <unitreal> Set the page left margin (default 10mm) // -R, --margin-right <unitreal> Set the page right margin (default 10mm) // -T, --margin-top <unitreal> Set the page top margin // --outline Put an outline into the pdf (default) // --no-outline Do not put an outline into the pdf // --outline-depth <level> Set the depth of the outline (default 4) // --footer-html <url> Adds a html footer // --header-html <url> Adds a html header // --replace <name> <value> Replace [name] with value in header and footer (repeatable) // --image-quality <integer> When jpeg compressing images use this quality (default 94) } // options spécifiques à wkhtmltoimage if (! $isPDF) { // -f, --format <format> Output file format $opts[] = "--format"; $opts[] = "PNG"; // @TODO // --height <int> Set screen height (default is calculated from page content) (default 0) // --crop-h <int> Set height for cropping // --crop-w <int> Set width for cropping // --crop-x <int> Set x coordinate for cropping // --crop-y <int> Set y coordinate for cropping // --quality <int> Output image quality (between 0 and 100) } // --cache-dir <path> Web cache directory if (! empty($this->paths['path_tmpdir'])) { if (! \is_dir($this->paths['path_tmpdir']."/wkweb")) @\mkdir($this->paths['path_tmpdir']."/wkweb", 0750, true); $opts[] = "--cache-dir"; $opts[] = $this->paths['path_tmpdir']."/wkweb"; } // --disable-local-file-access Do not allowed conversion of a local file to read in other local files, unless explicitly allowed with --allow $opts[] = "--disable-local-file-access"; // --allow <path> Allow the file or files from the specified folder to be loaded (repeatable) if (! empty($this->paths['path_source'])) { $opts[] = "--allow"; $opts[] = $this->paths['path_source']; } if (! empty($this->paths['root_dir'])) { $opts[] = "--allow"; $opts[] = $this->paths['root_dir']; } // -n, --disable-javascript Do not allow web pages to run javascript if (isset($pdf_options['javascript']) && empty($pdf_options['javascript'])) { $opts[] = "--disable-javascript"; } // --load-error-handling <handler> Specify how to handle pages that fail to load: abort, ignore or skip (default abort) $opts[] = "--load-error-handling"; $opts[] = "ignore"; // --load-media-error-handling <handler> Specify how to handle media files that fail to load: abort, ignore or skip (default ignore) $opts[] = "--load-media-error-handling"; $opts[] = "ignore"; // -q, --quiet Be less verbose $opts[] = "--quiet"; // @TODO // --zoom <float> Use this zoom factor (default 1) // --user-style-sheet <url> Specify a user style sheet, to load with // --javascript-delay <msec> Wait some milliseconds for javascript finish (default 200) if ($this->debug) dump($opts); $this->cmd_opt = $opts; return $this; } // ------------------------------------------------------------------------------------------ LOADER/** * Initialisation de l'objet Dompdf à partir d'un fichier HTML. * * @param string $html_file Chemin du fichier HTML à charger * @param array $pdf_options Surcharge d'options pour Dompdf * @return WkhtmlService */public function loadHtmlFile(string $html_file, array $pdf_options = []): WkhtmlService { $this->initEngine($pdf_options); $this->cmd_src = $this->fixHtmlFile($html_file); $this->cmd_out = $this->createTempFile("/wktmp", "out"); return $this; } /** * Initialisation de l'objet Dompdf à partir d'un contenu HTML. * * @param string $html_data Contenu du document HTML à charger * @param array $pdf_options Surcharge d'options pour Dompdf * @return WkhtmlService */public function loadHtmlData(string $html_data, array $pdf_options = []): WkhtmlService { $html_file = $this->createTempFile("/wktmp", "html", $html_data); return $this->loadHtmlFile($html_file, $pdf_options); } // ------------------------------------------------------------------------------------------ RENDER/** * Returns the PDF data as a string. * * @param bool $nocompress Désactivation de la compression PDF * @return string Données binaires du document PDF */public function renderData(bool $nocompress = false): string { list($status, $stdout, $stderr) = $this->executeCommand($nocompress); $this->checkCommandOutput($status, $stdout, $stderr, $this->cmd_out); return \file_get_contents($this->cmd_out); } // ------------------------------------------------------------------------------------------ PROCESS/** * Exécution de la commande de génération wkhtmlto(pdf|image). * * @param bool $nocompress Désactivation de la compression PDF * @return array Retour de la commande [status, stdout, stderr] */protected function executeCommand(bool $nocompress = false): array { if (! isset($this->cmd_bin)) throw new \LogicException("Initialisation error: wkhtml command is not defined!"); $cmd_args = array(); if ($nocompress) $cmd_args[] = "--no-pdf-compression"; $cmd_args[] = $this->cmd_src; $cmd_args[] = $this->cmd_out; $command = \array_merge([ $this->cmd_bin ], $this->cmd_opt, $cmd_args); $process = new Process($command); if ($this->debug) dump($command, $process->getCommandLine()); if (isset($this->timeout)) $process->setTimeout($this->timeout); $process->run(); # if (! $process->isSuccessful()) throw new ProcessFailedException($process);return [ $process->getExitCode(), $process->getOutput(), $process->getErrorOutput(), ]; } // ------------------------------------------------------------------------------------------ CHECKS/** * Vérification du résultat de la commande de génération wkhtmlto(pdf|image). * * @param int $status Command exit status code * @param string $stdout Command stdout content * @param string $stderr Command stderr content * @param string $output Command output fila path * @throws RuntimeException Message d'erreur sur échec de la génération * @return void */protected function checkCommandOutput(int $status, string $stdout, string $stderr, string $output) { if ($this->debug) dump($status, $stdout, $stderr, $output); $dbg = "\n*** stderr:\n%s\n*** stdout:\n%s\n"; # if (0 !== $status && '' !== $stderr)# throw new \RuntimeException(\sprintf("Process failed: wkhtml error (%d)".$dbg, $status, $stderr, $stdout));if (! \file_exists($output)) throw new \RuntimeException(\sprintf("Process failed: output not exists (%s)".$dbg, $output, $stderr, $stdout)); if (! \filesize($output)) throw new \RuntimeException(\sprintf("Process failed: output is empty (%s)".$dbg, $output, $stderr, $stdout)); } protected function getFileType(string $type = "PDF"): ?array { if (isset($this->cmd_bin) && (\strpos($this->cmd_bin, "image") !== false)) $type = "PNG"; return parent::getFileType($type); } } |