Support for Drupal 7 is ending on 5 January 2025—it’s time to migrate to Drupal 10! Learn about the many benefits of Drupal 10 and find migration tools in our resource center.
Problem/Motivation
In the EntityPrintController, the viewPrint method is sending the response rather than returning the response object.
public function viewPrint($export_type, $entity_type, $entity_id) {
// Create the Print engine plugin.
$config = $this->config('entity_print.settings');
$entity = $this->entityTypeManager->getStorage($entity_type)->load($entity_id);
$print_engine = $this->pluginManager->createSelectedInstance($export_type);
return (new StreamedResponse(function () use ($entity, $print_engine, $config) {
// The Print is sent straight to the browser.
$this->printBuilder->deliverPrintable([$entity], $print_engine, $config->get('force_download'), $config->get('default_css'));
}))->send();
}
In a decoupled setting, if you try to fetch the route to be able to get the PDF, you get the following error in the Drupal site:
RuntimeException: Failed to start the session because headers have already been sent by "/var/www/html/vendor/dompdf/dompdf/src/Adapter/CPDF.php"
Steps to reproduce
Example JS:
const response = await fetch(`https://example.com/print/pdf/commerce_order/${order.drupal_internal__order_id}`, {
headers: {
'Authorization': `Bearer ${token.access_token}`,
},
});
if (response.ok) {
const blob = await response.blob();
const file = window.URL.createObjectURL(blob);
window.location.assign(file);
}
Proposed resolution
Return the response object and let Drupal handle sending it.
Comment | File | Size | Author |
---|---|---|---|
#2 | 3276260-2.patch | 606 bytes | ericchew |
Comments
Comment #2
ericchew CreditAttribution: ericchew commentedHere is the patch.
Comment #4
ericchew CreditAttribution: ericchew commentedIt turns out the reason the controller sends the response is because entity print catches an exception thrown by the print engine and then redirects to the entity and displays a message:
https://git.drupalcode.org/project/entity_print/-/blob/8.x-2.x/src/Event...
If the response is not sent in the controller, the exception is never caught by the event subscriber.
I'm not really sure the best way forward.
Comment #5
mglamanOh wow, that's interesting. So it streams and then throws an exception to THEN send a redirect back to the entity's canonical view?