Forum How do I...?

Permission Denied trying to convert simple XHTML document

Josh Prowse
I'm excited about this product, but I'm having no luck at all either converting or streaming docs at PDF files. I have installed and used many server-based products and PHP add-ons before, and I just spent two hours trying to figure out what I'm doing wrong, so hopefully it's something simple.

I installed prince on Ubuntu 7.10 with no errors. The executable is located in the /usr/lib/prince/bin folder.

I installed the prince.php file for PHP integration.

I created a simple XHTML document that validates fine, and all it contains in the body is a single "hello world" div.

The PHP file that attempts to convert this file looks like this:
<?php
require_once 'prince.php';
$prince = new prince('/usr/lib/prince/bin');
$prince->setHTML(false);
$errs = array();
if ($prince->convert_file_to_file('/home/josh/www/domain/file.html', '/home/josh/Desktop/pdftest.pdf', $errs) {
	echo 'Report OK!';
} else {
	var_dump($errs);
}
?>

When this PHP file executes, the $errs array contains this:
array(1) { [0]=> array(1) { [0]=> string(38) "/usr/lib/prince/bin: Permission denied" } }

I've tried setting the permissions of the /usr/lib/prince/bin folder, and the prince executable, to 777, but that didn't work.

I had a whole other (but equally unsuccessful) experience trying to get the file to "passthru" to the browser-- everything from MIME type errors to completely empty files with text/plain MIME types. Never a PDF.

Any suggestions? Is there setup documentation somewhere that I might've missed? I read the readme.html file, and checked the documentation here on the site, but I'm at my wit's end.

Thanks in advance,

-Josh

Edited by Josh Prowse

mikeday
It looks like the path is wrong:
$prince = new prince('/user/lib/prince/bin');

Should it be "usr", not "user"?
Josh Prowse
Sorry... I do my development on a VM on my mac, so I couldn't copy/paste the code in. Yes, it is written as /usr and not /user. I'll fix it in the original post.

The binary is being found just fine, and is giving me the "Permission Denied" error. I know the path is correct, because earlier when I tried pointing it to another folder, I got a "not found" error message instead.

Thanks for your sharp eye, though.
mikeday
Check the permissions on the binary, can you run it successfully from the terminal? Does your PHP script have read access to /usr/lib? You can enable logging in Prince, try $prince->setLog('/tmp/prince.log'), that way you can see if Prince is in fact running and whether it is reporting any errors there. It is quite possible that your PHP script does not have write access to your home directory to write the output file.
Josh Prowse
OK, so when I run it from the terminal, my PDF file is created, and I get a warning:
Fontconfig warning: "/etc/fonts/conf.d/53-monospace-lcd-filter.conf", line 17: invalid constant used : legacy

Umm... okay, I guess?

So Prince is doing its thing from the command line, but ideally, I want to have a PHP script take some buffered XHTML and write it to disk, or stream it to the browser, as a PDF file.

I really appreciate your feedback here. I'm happy to do any heavy lifting with testing permissions and stuff, but I'm not sure exactly what needs doing. When I set the log to /tmp/prince.log, the log never got created, which makes me think PHP doesn't have access there either.

I'm going to try giving PHP access to as many folders as it takes to get this working, but do you know what user name the PHP process runs as? Root? www-data? roflmao?

Thanks,

-Josh
mikeday
Oh hang on, the path you specify needs to be to the Prince binary, not just the directory, so it needs to be '/usr/lib/prince/bin/prince', not just '/usr/lib/prince/bin'. Sorry, not sure how I missed that!
Josh Prowse
We're getting there, but it's still not working.

Hilariously, in the documentation, the example path is '/usr/local/bin/prince' but on my machine, this location doesn't exist, but I found a '/usr/lib/prince' folder (so I stupidly assumed the /prince in the example was the folder containing the binary), which contained a subfolder called '/bin' which then contained the prince binary. I didn't take the "full path to the executable" instruction seriously enough.

More hunting uncovered that the prince binary is also found in '/usr/bin' just to keep me on my toes.

THE BAD NEWS

Whenever I run ->convert_string_to_passthru or ->convert_string_to_file, the prince.log shows these lines:
---- begin
-:1: error: Extra content at the end of the document
-: error: could not load input file
error: no input documents to process
finished: failure
---- end

I'm not sure where this extra content is coming from. Before we corrected the prince location, the pdf output files would be html, containing everything up to the end of the style tag in the head-- it would truncate the rest of the document-- could this be the "extra content"?

THE GOOD NEWS

If I run ->convert_file_to_file using the URL of the page I want to convert (which is just echo'ing the same XHTML I was trying to passthru as a string), it works perfectly.

It's great that this is working at all-- and I'm impressed with the results-- but ideally I'd like the passthru to work.

Tangent: can the prince code access the session variables of the web user who triggered the process? If the user were to start a conversion process on a PHP file that accessed session variables, what values would prince see?

-Josh
mikeday
When you use convert_string_to_passthru are you sure that the string contains well-formed XHTML? If it is not well-formed, you can pass true to setHTML to ensure that it is being parsed as an HTML document and not an XML document. Where are you getting the string from?
Josh Prowse
Basically, I buffer the entire document and store it in a variable.

When I want to test Prince, I send that variable to ->convert_string_to_passthru as the xmlstring parameter. When I want to see the output, I just echo it to the screen in my PHP. I ran the echoed page through the w3c validator and it was valid, and my DOCTYPE is XHTML Strict 1.0... does this mean it's well-formed?

I get the error message "Unhandled MIME type: text/html" whenever I ->setHTML to false. When I ->setHTML to true, I get a page streaming correctly, but the CSS page directives (orientation, breaks) and my table borders are incorrect.

Thanks again for all your help... this mystery is hopefully almost fully unravelled.

-Josh
mikeday
Hmm, is the output any different when you display the HTML, save it to a file, and run it through Prince from the command-line? (You can pass "-i html" on the command-line to ensure that the document is parsed as HTML if necessary).
Josh Prowse
If I save the html and run it through the command line as:
prince -i html /path/to/filename

I get the correct results-- that is, the same as when I run ->convert_file_to_file with a URL in my PHP scripts.

But I've just noticed something crazy: when I choose to "View Source" in Firefox, and copy and paste the code into the html document, everything looks fine. But if I choose to SAVE the document as an html document, it adds a bunch of newlines before the meta tag, and strips the meta tag ending (regardless of whether I use self-closing or a separate end tag).

This behaviour might explain why the streaming isn't working? I'm going to look into it, and get back to you. I have to go to bed now. It's almost sunrise...

-Josh