KoolReport's Forum

Official Support Area, Q&As, Discussions, Suggestions and Bug reports.
Forum's Guidelines

Issues in packages/export/Handler.php #569

Open Alex Chartier opened this topic on on Dec 20, 2018 - 9 comments

Alex Chartier commented on Dec 20, 2018

I find that the function saveTempContent is not correctly detecting the url paths correctly and hence not inserting the full url into the href.

In both pre-replace_callback functions the test for a '/' as the first character in the url does not imply an absolute path, in fact, koolreports is placing a '/' immediately before the path like this: <script type='text/javascript' src=/libraries/koolreport/src/clients/core/KoolReport.js'> and as a result the script is not loaded. I don't know if the script is actually required or not but it is certainly not if it is.

Of a more pressing issue is the CSS. When we add bootstrap css via the use statement the css is loaded via javascript and the KoolReport.load.resources. Now this may be correct, however, if the javascript is not loading then the css will not load.

So in order to get the CSS to load I inserted the link statements in the pdf view, but, again the preg_replace_callback fails to find and matches when the link tag is in the form: <link href="/libraries/koolreport/src/clients/bootstrap/css/bootstrap.min.css" rel="stylesheet" type="text/css" />

It appears the preg_replace_callback will only match when the link tag is in this form: <link rel="stylesheet" type="text/css" href="/libraries/koolreport/src/clients/bootstrap/css/bootstrap.min.css" />

It seems the regex is expecting something between the link tag and the href.

For the moment I have commented out the isAbsolutePath test of substr($href, 0, 1) === "/", and I have ensured that my link tags are in the correct format and it seems to work.

I assume these worked in the past because chromeBinary and nodeBinary work with local executables and they do everything relative to the site root, but these will not work using any offsite pdf renering engine such as PhantomjsCloud.

David Winterburn commented on Dec 24, 2018

Hi Alex,

Thanks much for such an in depth feedback!

The idea of the method saveTempContent() is that as we save a report in html rendered file to a temporary folder, it no longer resides in the web root so all relative paths in the html file can not work.

Thus, we use regular expression to convert all relative paths (by conditions 1. doesn't start with "http" and 2. doesn't start with "/") to absolute ones.

Following your post, I realized there's a bug in the regex which mismaches sometimes. Please open the file export/Handler.php, go to method saveTempContent and replace the regex with these new ones:

~<link([^>]+)href=["\']([^>]*)["\']~
~<script([^>]+)src=["\']([^>]*)["\']~

Then let us know if there's any issue with using nodeBinary or chromeBinary. Thanks for an interesting discussion!

Alex Chartier commented on Dec 24, 2018

Sorry David, this change made no difference. I must still have the rel and type for the css before the href for the regex to match, and I must still comment out the substr part of the $isAbsolutePath tests.

David Winterburn commented on Dec 25, 2018

Hi Alex,

Would you please put these code into a php page, says "test.php", on your web server and check it result:

$url = "http://localhost";
$content = '<link href="/libraries/koolreport/src/clients/bootstrap/css/bootstrap.min.css" rel="stylesheet" type="text/css" />';
$content = preg_replace_callback('~<link([^>]+)href=["\']([^>]*)["\']~', 
	function($matches) use ($url) {
		// echo "matches = "; print_r($matches); echo '<br>';
		$href = $matches[2];
		$isAbsolutePath = substr($href, 0, 1) === "/" || 
			substr($href, 0, 4) === "http";
		if (! $isAbsolutePath) {
			echo 'is relative path<br>';
			$href = $url . "/" . $href;
		} else
			echo 'is absolute path<br>';
		return "<link $matches[1] href='$href'";
	}
, $content);
$content = htmlspecialchars($content);
echo "<pre>{$content}</pre>";

Thanks!

Alex Chartier commented on Dec 25, 2018

Here is the result:

is absolute path <link href='/libraries/koolreport/src/clients/bootstrap/css/bootstrap.min.css" rel="stylesheet" type="text/css' />

David Winterburn commented on Dec 26, 2018

Thanks, Alex. So the regex should detect an absolute/relative link even without the rel or type attribute between link and href.

Can you update the regex in Hanlder.php and uncomment $isAbsolutePath = subtr... command to see what saveTempContent() results in?

Alex Chartier commented on Dec 26, 2018

Here is the top part of the content using the new regex and not commenting the substr part.

<!DOCTYPE html>
<html>
    <body style="margin:1in"><script  type='text/javascript'  src='/libraries/koolreport/src/clients/core/KoolReport.js'></script><script  type='text/javascript'  src='/libraries/koolreport/src/clients/jquery/jquery.min.js'></script>
        <header>

David Winterburn commented on Dec 28, 2018

Hi Alex,

If you open the temp html file on your server (localhost), could it retrieve resource files like "/libraries/koolreport/src/clients/core/KoolReport.js" or "/libraries/koolreport/src/clients/jquery/jquery.min.js"?

I think these links are same as the one in your report. So if your report could retrieve them, the temp html file should, too. Let me know if there's an issue with these links. Thanks!

Alex Chartier commented on Dec 28, 2018

The preg_match_replace is not matching those script tags so no processing is done on them.

How would I know if processing was done in the temp html file? The temp file is as I show above.

I have changed the Handler.php file to use the simple_html_dom parser to find the link and script files and make the appropriate changes.

Alex Chartier commented on Dec 28, 2018

I think that when you are using phantomjs, chromebinary or nodebinary locally, then the code you have supplied would work. The issue comes into play when you are using an offsite system to generate the image such as phantomjsCloud. phantomjsCloud works fine for people who are not on a closed network or behind a firewall, i.e. a public server. It just needs to have the full URL of the assets.

I have been able to get it working using simple_html_dom as mentioned above. I must also hard include the link and script assets for the koolreport libraries as well as the function which handles the remove duplicate.

It is working for me for the task I have. To make it more robust the included javascript at the end of the file that calls the Koolreport.widget.init function should be modified to place full URLs for the inclusions. This would make it more dynamically friendly for other reports.

The changes I made should not affect any other processing, or any other export method. If you would like me to provide these to you I can.

Build Your Excellent Data Report

Let KoolReport help you to make great reports. It's free & open-source released under MIT license.

Download KoolReport View demo
bug

None