I'm trying to use fcimg and wkhtmltoimage in order to export a chart to a PDF report. I keep getting an error from fcimg saying "Fatal error: Uncaught exception 'FCImageException' with message 'There was an error with wkhtmltopdf'[...]".
By debbuging the function inside de fcimg library I've noticed that a couple of 'fwrite()' functions in charge of writing the minified JS scripts of FusionCharts into the file are returning a value of '0' (no writing, but no error), even do the string to write is properly saved into a variable (as the code below). Is there some kind of limit or restrinction to the 'fwrite' function that I'm not aware of? Previous calls to the function work just fine. Any help or advice would be really appreciated.
[...]
function fusioncharts_to_image($outputFilePath, $swfName, $inputString, $height, $width, $options = array())
{
$jsonFlag = false;
if($inputString[0] === '<') // Check for the first character
{
// do nothing. jsonFlag is set to false anyways
}
else if($inputString[0] === "{")
{
$jsonFlag = true;
}
else
{
throw new FCImageException("The input string doesn't seem to be either JSON or XML");
}
$fileType = "png";
if(isset($options['imageType']))
$fileType = $options['imageType'];
$renderDelay = 1000;
if (isset($options['render_delay']) && is_numeric($options['render_delay']))
$renderDelay = $options['render_delay'];
/*
* Note: sys_get_temp_dir returns /tmp on Linux (don't know about osx)
* but on the other hand, it returns C:\user\foo\Local\Temp\ on Windows
*
* so we need to add a directory separator on Linux but not on windows
*/
$separator = "";
if(DIRECTORY_SEPARATOR === "/") // check if unix system. TODO: There will be better ways to do this
$separator = DIRECTORY_SEPARATOR;
$imageFileName = sys_get_temp_dir().$separator."\FCImage".rand(0, 1000).'.'.$fileType;
// $imageFileName = sys_get_temp_dir().”\FCImage”.rand(0, 1000).’.’.$fileType;
// $imageFileName = 'C:\PRUEBA\FCImage'.rand(0, 1000).'.'.$fileType;
$cwd = __DIR__; // change working directory to the current script's directory
$env = array(); // set any environment variables here
// configure the arguments
$args = "--format $fileType";
$args = $args." --crop-w ".($width - 1);
$args = $args." --crop-h ".($height - 1);
if(isset($options['nodelay']))
{
if($options['nodelay'] === true)
$args = $args." --javascript-delay 0";
}
else
{
$args = $args." --javascript-delay {$renderDelay}";
}
if(isset($options['quality']))
{
$args = $args." --quality {$options['quality']}";
}
$debugFlag = false;
if(isset($options['debug']))
{
$debugFlag = true;
$debugFile = fopen("debug.html", "w");
echo "\n\nCall to:\n fusioncharts_to_image ($outputFilePath, $swfName, [removing input string], $height, $width)";
}
// now, determine the platform this is running on
$os = php_uname("s");
$arch = php_uname("m");
if($os==="Windows NT"){
$platform = _FC_IMG_PLATFORM_WINDOWS;
// var_dump($platform);
}
else if($os === "Linux")
{
if($arch === "i386")
$platform = _FC_IMG_PLATFORM_LINUX;
else if($arch === "i686")
$platform = _FC_IMG_PLATFORM_LINUX;
else if ($arch === "x86_64")
$platform = _FC_IMG_PLATFORM_LINUX_64;
else
throw new FCImageException ("This Linux architecture is not supported");
}
else if($os === "Darwin") {
$platform = _FC_IMG_PLATFORM_OSX;
}
else
throw new FCImageException("Your server OS is currently not supported");
$fcRoot = dirname(__FILE__);
$wkCommand = $platform;
if(isset($options['wkhtmltoimage_path'])) {
$wkCommand = $options['wkhtmltoimage_path'];
}
$command = "$wkCommand $args - $imageFileName";
// var_dump($command); echo "<br>";
if($debugFlag)
{
echo "\n Command: $command";
}
$wkstdin = popen($command, "w");
// var_dump($wkstdin);
if(!is_resource($wkstdin))
{
throw new FCImageException("An error took place while trying to open wkhtmltopdf");
}
$templateHead = <<<TOP
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title></title>
<style>
body{
padding:0 0 0 0;
margin:0 0 0 0;
}
</style>
<script>
TOP;
// ok. write template.txt into the process stdin
fwrite($wkstdin, $templateHead);
if($debugFlag)
{
fwrite($debugFile, $templateHead);
}
$contFC = file_get_contents($options['licensed_fusioncharts_js']);
$contFCC = file_get_contents($options['licensed_fusioncharts_charts_js']);
// echo $contFC;
// echo $contFCC;
if(isset($options['licensed_fusioncharts_charts_js']) && isset($options['licensed_fusioncharts_js'])) {
$temp1 = fwrite($wkstdin, $contFC);
var_dump($temp1);
$temp2 = fwrite($wkstdin, $contFCC);
var_dump($temp2);
if($debugFlag)
{
fwrite($debugFile, file_get_contents($options['licensed_fusioncharts_js']));
}
if($debugFlag)
{
fwrite($debugFile, file_get_contents($options['licensed_fusioncharts_charts_js']));
}
}
else {
throw new FCImageException("Need to provide fusioncharts licensed version here");
}
$functionToCall = "setXMLData";
if($jsonFlag === true)
$functionToCall = "setJSONData";
// replace all EOL with ""
$escapedData = str_replace("\n", "", $inputString);
$escapedData = addslashes($escapedData);
$templateCode = "</script>
</head>
<body>
<div id='chartContainer'><small>Loading chart...</small></div>
</body>
<script>
FusionCharts.setCurrentRenderer('javascript');
var chart = new FusionCharts('$swfName', 'chart0', '$width', '$height', '0', '1');
chart.$functionToCall('$escapedData');
chart.render('chartContainer');
</script>
</html>";
$temp = fwrite($wkstdin, $templateCode);
var_dump($temp);
if($debugFlag)
{
fwrite($debugFile, $templateCode);
}
$returnCode = pclose($wkstdin);
// echo(var_dump($returnCode)." returnCode");
if($returnCode !== 0)
{
// var_dump($imageFileName);
if(file_exists($imageFileName)){
unlink($imageFileName);
}
throw new FCImageException("There was an error with wkhtmltopdf ");
}
// success!
rename($imageFileName, $outputFilePath);
return true;
}