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.

CommentFileSizeAuthor
#2 3276260-2.patch606 bytesericchew
Support from Acquia helps fund testing for Drupal Acquia logo

Comments

ericchew created an issue. See original summary.

ericchew’s picture

Status: Active » Needs review
FileSize
606 bytes

Here is the patch.

Status: Needs review » Needs work

The last submitted patch, 2: 3276260-2.patch, failed testing. View results
- codesniffer_fixes.patch Interdiff of automated coding standards fixes only.

ericchew’s picture

It 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.

mglaman’s picture

Oh wow, that's interesting. So it streams and then throws an exception to THEN send a redirect back to the entity's canonical view?