mikehaertl / php-pdftk

A PDF conversion and form utility based on pdftk
MIT License
954 stars 128 forks source link

"sh: 1: pdftk: not found" error (command is fine and PDFTK accessible) #245

Closed hondaman900 closed 3 years ago

hondaman900 commented 3 years ago

Thank you for this great package. Works great for me in Laravel 6 on my Windows dev platform, but not on my Linux hosted server and I feel I'm super close on my deployed instance (a self-managed Ubuntu 18 server - Digital Ocean Droplet).

I'm getting this sh: 1: pdftk: not found error. It's not the issues covered many times where the path to the binary is not available. I can access PDFTKon both systems via CLI in my app folders and get --help and --version responses. Something else is missing. I checked all the paths to the source fillable PDF, both platforms are fine, as is the destination location, but on Ubuntu there's no end-result filled out PDF.

The following code works on Windows, but not on Ubuntu:

        $form = $this->getForm();
        $file = $this->getOutFile();
        $data = [ ....array provided here... ];
        $pdf = new Pdf($form);
        $result = $pdf->fillForm($data)
            ->saveAs($file);
        if ($result === false) {
            $error = $pdf->getError();
            dd($error);     //  <----- this is where the error in question shows up
        }

        $tmpFile = (string) $pdf->getTmpFile();

      $uid = Auth::user()->id;
      $showreport = asset('storage/reports/'.$uid.'/completed_form.pdf');

      return view('viewReport', compact('showreport'));
    }

    protected function getForm()
    {
        // Empty form
        return storage_path().'/reports/form-unlocked.pdf';
    }

    protected function getOutFile()
    {
        // tmp out file
        $uid = Auth::user()->id;
        $path = public_path().'/storage/reports/'.$uid;

        if(!File::isDirectory($path)){
            File::makeDirectory($path, 0755, true, true);
        }
        return $path.'/completed_form.pdf';
    }

Any suggestions as to what the error refer to, or what it "can't find"?

mikehaertl commented 3 years ago

Can you try a simple PHP script (without our library) with exec()? Something like

<?php
exec('pdftk', $output);
print_r($output)

Also try to add the full path to your pdftk command. If that works you should configure that path in the command option (see README). If that doesn't work either then it seems like pdftk is blocked in PHP. I can't really help you with that. It's a system/PHP configurationg thing then.

hondaman900 commented 3 years ago

Many thanks for the quick reply and suggestions.

Per your suggestion I added the following to my controller:

        exec('pdftk', $output);
        dd($output);

On the linux server I get the following output, essentially an empty array:

^ []

But on my Windows dev system, same code gives:

^ array:26 [▼
  0 => "SYNOPSIS"
  1 => "       pdftk <input PDF files | - | PROMPT>"
  2 => "\t    [ input_pw <input PDF owner passwords | PROMPT> ]"
  3 => "\t    [ <operation> <operation arguments> ]"
  4 => "\t    [ output <output filename | - | PROMPT> ]"
  5 => "\t    [ encrypt_40bit | encrypt_128bit ]"
  6 => "\t    [ allow <permissions> ]"
  7 => "\t    [ owner_pw <owner password | PROMPT> ]"
  8 => "\t    [ user_pw <user password | PROMPT> ]"
  9 => "\t    [ flatten ] [ need_appearances ]"
  10 => "\t    [ compress | uncompress ]"
  11 => "\t    [ keep_first_id | keep_final_id ] [ drop_xfa ] [ drop_xmp ]"
  12 => "\t    [ verbose ] [ dont_ask | do_ask ]"
  13 => "       Where:"
  14 => "\t    <operation> may be empty, or:"
  15 => "\t    [ cat | shuffle | burst | rotate |"
  16 => "\t      generate_fdf | fill_form |"
  17 => "\t      background | multibackground |"
  18 => "\t      stamp | multistamp |"
  19 => "\t      dump_data | dump_data_utf8 |"
  20 => "\t      dump_data_fields | dump_data_fields_utf8 |"
  21 => "\t      dump_data_annots |"
  22 => "\t      update_info | update_info_utf8 |"
  23 => "\t      attach_files | unpack_files ]"
  24 => ""
  25 => "       For Complete Help: pdftk --help"
]

As mentioned, on both platforms I can get version and help responses from PDFTK from any location on either server, and I know the path to the executable in Windows is in the system path (because I put it there), but it also looks like the snap installer also added PDFTK to the system path, given I can get a response.

I have run my code in Windows before with the absolute path to PDFTK.EXEhardcoded into the 'command' parameter, so happy to do that, but I can't find the PDFTK binary to point to. Do you know what the full path to the PDFTK binary is on Ubuntu after installing via snap?

When I search for PDFTK* from either ROOTor FORGEstarting point I get

forge@mysite1:~$ find pdftk*
find: ‘pdftk*’: No such file or directory

I read that I can copy the binaries to a location on the server and point 'command' to them, but that seems like a nasty hack that will some day in the future come back to bite me.

hondaman900 commented 3 years ago

To add to the above, I did find a folder "snap" in my server root with some folders but empty of content. Still can't find the pdftk binary to point to.

forge@mysite1:~/snap/pdftk$ ls
9  common  current
hondaman900 commented 3 years ago

I found the solution.

Seems the issue is that using snap to install PDFTK on an Ubuntu server needs an additional symlink created to allow access by the Laravel app when using Forge to manage the account. Logging into my server as root (as opposed to the Forge SSH connection) I found the location of the binary under the snap/pdftk folders.

I subsequently found an article that refers to my exact situation with PDFTK, Ubuntu and Forge. The following command resolved this for me:

sudo ln -fs /snap/pdftk/current/usr/bin/pdftk /usr/bin/pdftk

Here the article for your reference: https://www.webdesign101.net/install-pdftk-on-ubuntu-18-04-bionic/

Thank again for the support.

Stephen