4

I'm in the process of writing a module. The module works very well. In the module, I generate a form which consists of one submit button, and in the .module file, I'm calling that form and the submitForm works too. I was asked to move that button into a block, so I did. submitForm still works, but the main functionality doesn't. How come?

<?php

namespace Drupal\my_module\Form;

use Drupal\Core\Form\FormBase;
use Drupal\Core\Form\FormStateInterface;

/**
* Generate button.
*/
class myModuleForm extends FormBase {

  /**
  * {@inheritdoc}.
  */
  public function getFormId() {
    return 'my_module_form';
  }

  /**
  * {@inheritdoc}.
  */
  public function buildForm(array $form, FormStateInterface $form_state) {
    $form['my_module_btn'] = [
      '#type' => 'submit',
      '#value' => 'Do something'        ];
    return $form;
  }

  /**
  * {@inheritdoc}.
  */
  public function validateForm(array &$form, FormStateInterface $form_state) {
  }

  /**
  * {@inheritdoc}.
  */
  public function submitForm(array &$form, FormStateInterface $form_state) {
    $mpdf = new \Mpdf\Mpdf(['tempDir' => 'sites/default/files/tmp', 'default_font' => 'roboto', 'margin_left' => 6, 'margin_top' => 6, 'margin_right' => 6, 'margin_bottom' => 11]);
    ...
    ...
    ...
    $mpdf->Output($title."-".date("Ymd-His").".pdf", 'D');
  }
}
4

Though 4k4 says its not usually advisable, you can add an exit; at the end of submitForm in your particular case since you are generating a PDF and immediately serving it to the client. This will stop any further code from executing and solve the immediate problem (though it sounds like more scalable ones exist).

9

I googled the Mpdf library and it supports a string output. So you can use the string output to build a response and return it via $form_state:

use Symfony\Component\HttpFoundation\Response;

  public function submitForm(array &$form, FormStateInterface $form_state) {
    $content = '%PDF-1.3...';
    $headers = [
      'Content-Type' => 'application/pdf',
    ];
    $response = new Response($content, 200, $headers);
    $form_state->setResponse($response);
  }
  • Even better. This is likely what you want. – Kevin Jun 22 '18 at 18:16
1

I think it will be because the form functionality will be attempting to reload/redirect back to the page the form is on and you can't interrupt that mid flow with your own output.

You should probably add a redirect in your form submit to go to a custom controller page that will output your PDF

  • What if you add an exit; at the end of submit form? Is that code just dumping a generated PDF? – Kevin Jun 22 '18 at 13:05
  • Yeah it might work but could potentially stop any other form submit hooks from firing. Not hat it will probably matter in this case but not a good habit to get into – Leigh Jun 22 '18 at 13:40
  • A D8 version of an exit; would be to throw a custom exception and then catch this in an exception event subscriber to set a response for the pdf. This is not exactly how you are supposed to control your code flow, but core does the same to return an ajax response, see FormAjaxSubscriber::onException – 4k4 Jun 22 '18 at 13:45
  • @Kevin please make that an answer, because adding exit; worked :) – Kartagis Jun 22 '18 at 15:14
0

You can update the code as follows-

public function submitForm(array &$form, FormStateInterface $form_state) {
    $mpdf = new \Mpdf\Mpdf(['tempDir' => 'sites/default/files/tmp', 'default_font' => 'roboto', 'margin_left' => 6, 'margin_top' => 6, 'margin_right' => 6, 'margin_bottom' => 11]);
    ...
    ...
    ...
    $mpdf->Output($title."-".date("Ymd-His").".pdf", 'D');

  // Add the line for custom redirect

  $form_state->setRedirect('NEW PATH');

  exit;

  }
  • Problem is poster doesn’t want a redirect they want to serve the PDF. – Kevin Jun 22 '18 at 16:20
  • You can use exit; or die($mpdf); in that case. – Varun Singh Jun 22 '18 at 16:27
  • Right.. that’s in the accepted answer. – Kevin Jun 22 '18 at 16:28

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.