4

I'm trying to use Docverter to convert LaTeX/markdown files to PDF but am having trouble using PHP to do CURL to access Docverter via their API. I'm know I'm not a total idiot b/c i can get this to work adapting the shell script in this Docverter example and running from command line (Mac OSX).

Using PHP's exec():

$url=$_SERVER["DOCUMENT_ROOT"];
$file='/markdown.md';
$output= $url.'/markdown_to_pdf.pdf';
$command="curl --form from=markdown \ 
               --form to=pdf \ 
               --form input_files[]=@".$url.$file." \
               http://c.docverter.com/convert > ".$output;
exec("$command");

This gives no error messages but doesn't work. Is there a path issue somewhere?

UPDATE Based on @John's suggestion, here's an example using PHP's curl_exec() adapted from here. Unfortunately this also doesn't work though at least it gives error messages.

$url = 'http://c.docverter.com/convert';
$fields_string ='';
$fields = array('from' => 'markdown',
        'to' => 'pdf',
        'input_files[]' => $_SERVER['DOCUMENT_ROOT'].'/markdown.md',
    );

    //url-ify the data for the POST
    foreach($fields as $key=>$value) { $fields_string .= $key.'='.$value.'&'; }
    rtrim($fields_string, '&');

    //open connection
    $ch = curl_init();

    //set the url, number of POST vars, POST data
    curl_setopt($ch,CURLOPT_URL, $url);
    curl_setopt($ch,CURLOPT_POST, count($fields));
    curl_setopt($ch,CURLOPT_POSTFIELDS, $fields_string);

    //execute post
    $result = curl_exec($ch);

    //close connection
    curl_close($ch);
tim peterson
  • 23,653
  • 59
  • 177
  • 299
  • Did you try `shell_exec` ? – Peon Feb 15 '13 at 16:32
  • -@Dainis, not yet, i've gotten `exec()` to work on other things and admit i'm not sure of the distinction with `shell_exec()`. The reason I don't want to run as a shell script is because the file names and paths will change so I need those to be variables. – tim peterson Feb 15 '13 at 16:34
  • 1
    Why dont you use the curl functions written for PHP instead of exec? – Green Black Feb 15 '13 at 16:46
  • @John, i'd be happy to use PHP's `curl()` i just wasn't sure how to do that either. I'd gotten `exec()` to work on something else so that's what i've started with. Could you provide an answer using `curl()`? – tim peterson Feb 15 '13 at 16:52
  • 1
    Look at the docs for `curl_init`, `curl_setopt`, `curl_exec`. – ceejayoz Feb 15 '13 at 17:36
  • @ceejayoz, thanks, it now appears that my problem is that the output isn't ![formatted correctly](https://f.cloud.github.com/assets/1173307/161823/ada16ca8-779f-11e2-975f-2fa0a791dc50.png)., would you mind taking a look at this [Gist](https://gist.github.com/tim-peterson/4962406)? – tim peterson Feb 15 '13 at 20:16
  • You likely need to use `header()` to send a `Content-Type: application/pdf` header before you spit the contents out to the browser. – ceejayoz Feb 15 '13 at 20:18
  • but the CURL needs to be `Content-type: multipart/form-data`. If set that, then change it to `Content-Type: application/pdf`, get error saying `Message: Cannot modify header information - headers already sent by...`. – tim peterson Feb 15 '13 at 20:23

1 Answers1

12

I solved my own problem. There were two main problems with the above code:

1) The $fields array was incorrectly formatted for the input_files[]. It needed a @/ and mime-type declaration (see code below)

2) The curl_exec() output (the actual newly created file contents) needed to be returned and not just true/false which is this function's default behavior. This is accomplished by setting the curl option curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); (see code below).

Full working example

//set POST variables
$url = 'http://c.docverter.com/convert';
$fields = array('from' => 'markdown',
    'to' => 'pdf',
    'input_files[]' => "@/".realpath('markdown.md').";type=text/x-markdown; charset=UTF-8"
    );

//open connection
$ch = curl_init();

//set options 
curl_setopt($ch, CURLOPT_HTTPHEADER, array("Content-type: multipart/form-data"));
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POSTFIELDS, $fields); 
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); //needed so that the $result=curl_exec() output is the file and isn't just true/false

//execute post
$result = curl_exec($ch);

//close connection
curl_close($ch);

//write to file
$fp = fopen('uploads/result.pdf', 'w');  //make sure the directory markdown.md is in and the result.pdf will go to has proper permissions
fwrite($fp, $result);
fclose($fp);
tim peterson
  • 23,653
  • 59
  • 177
  • 299