Skip to content

Commit

Permalink
Load the dumped HTML from a public URL instead of the file:// method.
Browse files Browse the repository at this point in the history
The file:// method introduces CORS issues when loading local files like fonts. By going through the
web server we can load anything we want without issues.
  • Loading branch information
Sander De la Marche committed Apr 19, 2021
1 parent 8f7764d commit 1ca04e6
Showing 1 changed file with 33 additions and 7 deletions.
40 changes: 33 additions & 7 deletions src/Service/PdfGenerator.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,25 @@
namespace Dreadnip\ChromePdfBundle\Service;

use HeadlessChromium\BrowserFactory;
use HeadlessChromium\Page;
use Symfony\Component\Filesystem\Filesystem;
use Symfony\Component\HttpFoundation\RequestStack;

final class PdfGenerator
{
private BrowserFactory $browserFactory;
private RequestStack $requestStack;
private Filesystem $fileSystem;

private const TEMP_FOLDER = 'tmp/';

public function __construct(
BrowserFactory $browserFactory,
RequestStack $requestStack,
Filesystem $fileSystem
) {
$this->browserFactory = $browserFactory;
$this->requestStack = $requestStack;
$this->fileSystem = $fileSystem;
}

Expand All @@ -28,25 +35,32 @@ public function __construct(
* @param array $options The PDF options you want to use during the PDF creation
*
* @return string
* @throws \Exception
*/
public function generate(string $html, string $path, array $options = []): string
public function generate(string $html, string $path, array $printOptions = [], array $browserOptions = []): string
{
/*
* Chrome can't load HTML straight from a string so we have to
* save the passed HTML to a temp file and read it from there.
*/
$tempPath = $this->generateTemporaryFilePath();

$tempUrl = $this->getAbsoluteUrl($tempPath);

$this->fileSystem->dumpFile($tempPath, $html);

$browser = $this->browserFactory->createBrowser();
$browser = $this->browserFactory->createBrowser($browserOptions);

try {
$page = $browser->createPage();
$page->navigate('file://' . $tempPath)->waitForNavigation();

$pdf = $page->pdf($options);
/*
* We check for "network idle" instead of "load" by default to avoid
* missing resources like images and webfonts that can take a split second longer to load
*/
$page->navigate($tempUrl)->waitForNavigation(Page::NETWORK_IDLE);

$pdf->saveToFile($path);
$page->pdf($printOptions)->saveToFile($path);

// Clean up the temp file
$this->fileSystem->remove($tempPath);
Expand All @@ -58,12 +72,24 @@ public function generate(string $html, string $path, array $options = []): strin
}

/**
* Generates a temporary file name in the system temp dir
* Generates a temporary file name in your project's public folder
*
* @return string
* @throws \Exception
*/
private function generateTemporaryFilePath(): string
{
return sys_get_temp_dir() . '/' . bin2hex(random_bytes(32)) . '.html';
return self::TEMP_FOLDER . bin2hex(random_bytes(32)) . '.html';
}

/**
* Return the absolute URL for our temporary dump file
*
* @param string $tempPath
* @return string
*/
private function getAbsoluteUrl(string $tempPath): string
{
return $this->requestStack->getCurrentRequest()->getSchemeAndHttpHost() . '/' . $tempPath;
}
}

0 comments on commit 1ca04e6

Please sign in to comment.