I've found what I think is a bug in the way the caching of images is handled.
(Apologies if my line numbers are wrong - I added some debug lines, so may have introduced some blanks which mean they don;t match... I'll include the code too to confirm...)
I have a PDF which is essentially created from a pure HTML layout. That HTML contains IMG tags. On my local server, the paths could be specified as relative paths and the library would find them relative to the document root. However, on my ISP server, this was failing with errors saying that the GD functions couldn't find the image.
On closer inspection, the problem was built up on the following:
On my ISP server, RewriteEngine ON was specified meaning that $SERVER['SCRIPTURI'] had a value. It was not set on my local server, so this led to the different operation of the same code.
In 'tcpdf.php', line 6857: $imgdata = TCPDF_STATIC::fileGetContents($file); - the following if block checks if $imgdata is empty and seems to assume that the above call returns either the file content or nothing. If there's content, write that to a cache file. If nothing, just return the original filename.
However, TCPDF_STATIC, line 1909(ish):
if (isset($_SERVER['SCRIPT_URI'])
&& !preg_match('%^(https?|ftp)://%', $file)
&& !preg_match('%^//%', $file)
).....
if this evaluates to true, it causes fileGetContents to return an absolute URL to the file. If RewriteEngine ON is set in apache's httpd.conf, then that happens.
This means that imgdata is not empty, so the caching attempts to fire. That then fails to return an image size on tcpdf.php line 6875(ish): $imsize = @getimagesize($file);
That in turn means the original filename is reset and the later code which attempts to get the image from GD etc fails.
To fix it (I can't simply force absolute URLs in my code), I added a check to see if $imgdata is a URL first. This update then allows the code to function correctly and makes use of the abosluet URL made by fileGetContents:
// tcpdf.php, line 6863(ish)....
if (!empty($imgdata)) {
// check if $imgdata is actually a url rather than data... (as returned by tcpdf_static::fileGetContents in certain situations)
if (filter_var($imgdata, FILTER_VALIDATE_URL)) {
// if it is, use this as the target file name!
$file = $imgdata;
} else {
// copy image to cache
$original_file = $file;
$file = TCPDF_STATIC::getObjFilename('img', $this->file_id);
$fp = TCPDF_STATIC::fopenLocal($file, 'w');
if (!$fp) {
$this->Error('Unable to write file: '.$file);
}
fwrite($fp, $imgdata);
fclose($fp);
unset($imgdata);
$imsize = @getimagesize($file);
if ($imsize === FALSE) {
unlink($file);
$file = $original_file;
}
}
}
Hope that's helpful? Is it likely to break anything else?
Many thanks for such a great library!
Kieran