Question

My task is automatically convert image files to pdf, when they are attached to a certain field. So the field accepts both the images and pdf files, but converts uploaded images to pdf. The field saves files to private directory. If I do not apply the conversion, the files are accessible well. But when I apply conversion, I convert images to PDF then save the PDF file into the same directory with the same name but with .pdf extension using the following code in hook_entity_presave:

$file_field = $entity->get('field_invoice_file');
if ($file_field) {

  $file_value = $file_field->getValue();

  if ($file_value && !empty($file_value[0]['target_id'])) {
    $entity_manager = \Drupal::entityTypeManager();
    $file_entity = $entity_manager->getStorage('file')->load($file_value[0]['target_id']);

    if ($file_entity) {

      $filename = reset_m($file_entity->get('filename')->getValue()); //reset_m is my custom function that extracts string from an array of any deepness, do not focus on it
      $uri = reset_m($file_entity->get('uri')->getValue());

      $type = pathinfo($uri, PATHINFO_EXTENSION);


      if (in_array($type, ['png', 'jpg', 'jpeg', 'gif'])) {

        $file_dir_arr = array_reverse(explode('/', $uri));
        unset($file_dir_arr[0]);
        $file_dir = implode('/', array_reverse($file_dir_arr));


        $file_name_arr = array_reverse(explode('.', $filename));
        unset($file_name_arr[0]);
        $file_name_no_ext = implode('.', array_reverse($file_name_arr));

        $new_uri = $file_dir . '/' . $file_name_no_ext . '.pdf';
        $new_filename = $file_name_no_ext . '.pdf';

        mymodule_image_to_pdf($uri,
            $file_dir . '/' . $file_name_no_ext . '.pdf');

        $file_entity->set('filename', $new_filename);
        $file_entity->set('uri', $new_uri);


        $file_entity->save();
      }
    }

  }
}

I made sure that the pdf has been generated successfuly and can be opened in acrobat if downloaded and can be viewed in browser if it is in a public directory. So here is some permissions issue: http://mysite/system/files/myfile.pdf returns dark gray page with a little gray square with white borders in the middle of the page. If I upload pdf without conversion, it works good, if I upload an image without conversion, it also works good. If I use the same conversion behavior but with files in public storage it also works good. Please note that I do not get 403 or 404 error (I checked in browser console too), I get 200 response but it looks as I wrote above.

Was it helpful?

Solution

It sounds like Drupal is telling the browser that the PDF file is an image.

When you're modifying an existing file entity, File::save() will not change the filemime property of a file automatically. Drupal only does this during execution of ::preCreate().

The filemime property isn't being used when serving from the public dir, but is being used when serving from the private dir (where Drupal is serving the headers/payload instead of your web server).

Try executing $file_entity->setMimeType('application/pdf') or create a new file entity with your PDF artifact.

Licensed under: CC-BY-SA with attribution
Not affiliated with drupal.stackexchange
scroll top