PHP var->Javascript->PHP - javascript

I'm working on a project that has the following problem:
The database gives(via php) an array with a list of JavaScript files that need to be loaded. it is stored in the variable $array(php). I need to extract those source files with php(foreach loop) and load them via JavaScript. It is like this:
document.write("<?php foreach($js_files as $filename) {if( trim($filename) <> "" ){echo '<script type=\'text/javascript\' src=$filename></script> \n';}} ?> ");
The problem is that it loads a couple of files but goes wrong with the first one(a google api file). Does anyone have a sollution to this? Or any ideas in which direction i have to look.

This is a bad idea on multiple levels, but can be fairly easily resolved. But first:
1) Never use document.write(). To dynamically load a script it is better to use:
var script = document.createElement('script'); //create a script element
script.src = 'javascript.js'; //path to src file
//now get the body element and append the new script element
document.getElementsByTagName('body')[0].appendChild(script);
2) Loading scripts like this will likely not work if they need to be loaded in a particular order, as the downloading of dynamic scripts occurs asynchronously (non-deterministic)
3) Generally speaking, you should concatenate your js files to reduce http requests, you can use a tool like grunt to make an automatic build process.
4) If you really, really want those scripts to be dynamically loaded though, you can use the process I outlined in (1) to get the file names use ajax:
//depends on jQuery, but could be written vanilla if needed
$.get('myPhp.php', function(resp){
var arr = resp.split(','); //splits returned string on the comma
var i = arr.length;
//iterate through the results set
while (i--) {
//do process from (1) above
}
});
Note that this will still have the unordered problem. If you need sequential dynamic loading check out something like require.js

If the code needs to be fired from a JavaScript function then you can get rid of the document.write, in favor of creating new script objects, and appending to the head tag.
<?php
foreach($js_files as $filename){
if(trim($filename) != ''){
echo 'var s = document.createElement("script");';
echo 's.type = "text/javascript";';
echo 's.src = "' . $filename . '";';
echo 'document.getElementsByTagName("head")[0].appendChild(s);'
}
}
?>

You have to escape the code "" in if( trim($filename) <> "" ) because the " breaks the javascript string.

Related

Php cookie and assigned JS var with same value mismatch if img url on html element isn't correct

I'm pretty sure this question will be marked as not clear at the minimum. But 'i'll try due to the strange behavior I've seen on tests, so i'm asking to skilled guys.
I try to write a plugin for Wordpress that on the PHP side set up a token, that is so sent out as cookie value, and as js var on page header.
All is working fine, when after the js flow/code execute an XHR request to an external PHP file to execute some tasks, one is to check against the value of the cookie, and the passed post var via JS XHR needed to control the access at some features.
Since after the response, i need to push some result into a Wordpress widget, i've start to add in the html of this widget, some html line like this:
<div class="myclass">
<img src="/img/button.svg" onerror="this.onerror=null; this.src=\'/img/button64.png\'">
</div>
the problem: i've note that
IF the button.svg file not exist, the token cookie value and the passed js var mismatch when page has been loaded, while all work fine, if the src url point to a correct file image that exist.
In theory, the fact that an img src URL isn't correct, should not interfere with the fact that a cookie is setup via php with a value and a js var with same value: the HTML code is part of the widget where the js code is executed, but I can't find any relation with the explained behavior, because the outputted html code still have nothing to do with the js/php code in any way.
Anyone know, how this can happen and why? (admitted that you have understood the problem as I've explained it!)
RESUME AND FOLLOW:
Since last night i've follow coding the plugin, i would like to resume the situation in few words and report another behavior (the same in different element): so i have a php code, that setup a cookie, then a JS var that output on header (by php): all ok, values on cookie and JS var on header are the same when page load, until i add:
<video id="w3vtp_WVO" controls preload="auto" width="640" height="264" poster="animageThatNotExist.png" data-setup="{}">
<source id="w3vtp_WVS" src="http://localhost/wp49/myfolder/mymedia.webm" type="video/webm">
<p class="vtp-no-js">
To view this video please enable JavaScript, and consider upgrading to a web browser that supports HTML5 video
</p>
</video>
IF the URL of attribute poster not point to an existing image, then the cookie value and the JS var on header when page load, mismatch. I've check to log the flow, and values are exactly the same on exit the code when these values are setup in php: i've not follow further checks, so no light in my mind about this behavior until now. When the cookie OR the JS var are overwritten, OR the value of one or other is not set? I will check as i can.
Anybody have any idea?
this the code, wrapped into a function (+-) that is fired inside an hook just like this:
add_action('init', 'w3all_vtp');
function w3all_vtp() { .... ... ..... if (isset($_COOKIE[ LOGGED_IN_COOKIE ])){ // a cookie should exist in WP for a logged in user, so this maybe isn't really needed
$ps = explode("|", $_COOKIE[ LOGGED_IN_COOKIE ]);
if( !$ps OR empty($ps) OR preg_match('/[^_\-0-9A-Za-z]/',$ps[3]) ){
//return;
echo 'bad cookie'; exit;
}
$ck = str_shuffle( substr($ps[3], 0, 9) . md5(microtime()) . md5(substr(NONCE_KEY, 0, 12)) . $current_user->ID );
$cv_cn = $ck . '|' . LOGGED_IN_COOKIE . '|' . $current_user->ID . '|' . $user_where; // to js: 0 admin // 1 front end // 2 elsewhere
setcookie( "w3allCKvtp", $cv_cn, 0, '/', COOKIE_DOMAIN, is_ssl(), true );
// echo $cv_cn . '<br />'.$ck;//exit;
$umeta = array("w3allCKvtp" => $ck, array("vtp_udata" => array( "last_exec_time" => time(), "exec_times" => 'set the value here' ))); // last_exec_time should be decreased if the curl fail, to reset the count
update_user_meta( $current_user->ID, 'w3all_vtp', $umeta );
$w3allWLoc = $user_where == 0 ? $w3allWLoc = '..' : 1;
define("W3ALLULOC", $w3allWLoc);
$pjV = "<script type=\"text/javascript\">var w3allCKvtp = '".$ck."'; var w3allWLocvtp = '".$w3allWLoc."'; var w3allUWherevtp = '".$user_where."'; var w3allPURLvtp = '".plugins_url(). "/w3all-plugin/"."'; var w3allPATHvtp = '".WP_PLUGIN_DIR."';</script>"; // global js var, output just after latest meta on header, and before any other enqueued script
$pjV = serialize($pjV);
define("W3ALLJVARS", $pjV);
} }

getting OnLoad HTML/DOM for an HTML page in PHP

I am trying to get the HTML (ie what you see initially when the page completes loading) for some web-page URI. Stripping out all error checking and assuming static HTML, it's a single line of code:
function GetDisplayedHTML($uri) {
return file_get_contents($uri);
}
This works fine for static HTML, and is easy to extend by simple parsing, if the page has static file dependencies/references. So tags like <script src="XXX">, <a href="XXX">, <img src="XXX">, and CSS, can also be detected and the dependencies returned in an array, if they matter.
But what about web pages where the HTML is dynamically created using events/AJAX? For example suppose the HTML for the web page is just a brief AJAX-based or OnLoad script that builds the visible web page? Then parsing alone won't work.
I guess what I need is a way from within PHP, to open and render the http response (ie the HTML we get at first) via some javascript engine or browser, and once it 'stabilises', capture the HTML (or static DOM?) that's now present, which will be what the user's actually seeing.
Since such a webpage could continually change itself, I'd have to define "stable" (OnLoad or after X seconds?). I also don't need to capture any timer or async event states (ie "things set in motion that might cause web page updates at some future time"). I only need enough of the DOM to represent the static appearance the user could see, at that time.
What would I need to do, to achieve this programmatically in PHP?
To render page with JS you need to use some browser. PhantomJS was created for tasks like this. Here is simple script to run with Phantom:
var webPage = require('webpage');
var page = webPage.create();
var system = require('system');
var args = system.args;
if (args.length === 1) {
console.log('First argument must be page URL!');
} else {
page.open(args[1], function (status) {
window.setTimeout(function () { //Wait for scripts to run
var content = page.content;
console.log(content);
phantom.exit();
}, 500);
});
}
It returns resulting HTML to console output.
You can run it from console like this:
./phantomjs.exe render.js http://yandex.ru
Or you can use PHP to run it:
<?php
$path = dirname(__FILE__);
$html = shell_exec($path . DIRECTORY_SEPARATOR . 'phantomjs.exe render.js http://phantomjs.org/');
echo htmlspecialchars($html);
My PHP code assumes that PhantomJS executable is in the same directory as PHP script.

PHP Get Rendered Javascript Page

I'm developing application using AngularJS. Everything seems to be nice until I meet something that leads me to headache: SEO.
From many references, I found out that AJAX content crawled and indexed by Google bot or Bing bot 'is not that easy' since the crawlers don't render Javascript.
Currently I need a solution using PHP. I use PHP Slim Framework so my main file is index.php which contains function to echo the content of my index.html. My question is:
Is it possible to make a snapshot of rendered Javascript in HTML?
My strategy is:
If the request query string contains _escaped_fragment_, the application will generate a snapshot and give that snapshot as response instead of the exact file.
Any help would be appreciated. Thanks.
After plenty of times searching and researching, I finally managed to solve my problem by mixing PHP with PhantomJS (version 2.0). I use exec() function in PHP to run phantomJS and create Javascript file to take get the content of the targeted URL. Here are the snippets:
index.php
// Let's assume that you have a bin folder under your root folder directory which contains phantomjs.exe and content.js
$script = __DIR__ ."/bin/content.js";
$target = "http://www.kincir.com"; // target URL
$cmd = __DIR__."/bin/phantomjs.exe $script $target";
exec($cmd, $output);
return implode("", $output);
content.js
var webPage = require('webpage');
var system = require('system');
var page = webPage.create();
var url = system.args[1]; // This will get the second argument from $cmd, in this example, it will be the value of $target on index.php which is "http://www.kincir.com"
page.open(url, function (status) {
page.onLoadFinished = function () { // Make sure to return the content of the page once the page is finish loaded
var content = page.content;
console.log(content);
phantom.exit();
};
});
I recently published a project that gives PHP access to a browser. Get it here: https://github.com/merlinthemagic/MTS. It also relies on PhantomJS.
After downloading and setup you would simply use the following code:
$myUrl = "http://www.example.com";
$windowObj = \MTS\Factories::getDevices()->getLocalHost()->getBrowser('phantomjs')->getNewWindow($myUrl);
//now you can either retrive the DOM and parse it, like this:
$domData = $windowObj->getDom();
//this project also lets you manipulate the live page. Click, fill forms, submit etc.

Can't populate <div> with elements of a json_encoded php array

This function worked previously (the last time I opened this project over a week ago), but now I can't seem to get it to work at all and I have no idea how to figure out what's going wrong! First, I'll diagram my file architecture in case my file paths are incorrect and causing my php to not even be called:
~/Sites
proj1
htdocs
index.html
ajax.php
scripts
java_script.js
styles
style_sheet.css
includes
scrapedImages
.
.
.
Here's the JS function that uses AJAX to call a .php script:
function requestServer() {
$.getJSON('/Users/aweeeezy/Sites/proj1/htdocs/ajax.php', function(data) {
$.each(data, function(key, val) {
var html = "<img src='/Users/aweeeezy/Sites/proj1/includes/scrapedImages/"+val+"' style='display:block;max-width:20px;max-height:20px;width:auto;height:auto' alt=null />"
$('#puppy-box').prepend(html);
});
});
}
The line setting var html was <img src='...'+images[i]+"... when I first opened the project this morning, but I'm not sure why...I think because I was testing the site out, it was faster to only load a fraction of the images and used a for loop to cycle through only the first 10 or so pictures, hence the i index. Anyway, shouldn't it be data[i], or val[i]...or data[val]? I have no idea what's going on here.
Here's the ajax.php file that the JS function is trying to call:
<?php
$images = scandir('/Users/aweeeezy/Sites/proj1/includes/scrapedImages/');
/*foreach ($images as $key => $image) {
if ($image == '.' || $image == '..') {
unset($images[$key]);
}
}*/
echo json_encode($images);
?>
I commented out the middle part because I wasn't sure if this was causing a complication. I tried putting both echo and print lines in here to see if the script is being called, but even if they are working, I can't really see them because they're being returned as data (I think) to the JS function that calls the script.
How do I even go about debugging this mess and get my girlfriend's valentine's day project back on track!

Can I get the location of where a JavaScript library is loaded from, from within the script?

Lets say I have a page with this code on it on www.foo.com:
<script src="http://www.bar.com/script.js" />
Can I write code from within script.js that can check that it was served from bar.com? Obviously document.location.href would give me foo.com.
Thanks!
var scripts = document.getElementsByTagName("script");
give you a collection of all the scripts in the page
After this you can read their src property to find your target (I hope you know how the script is called)
for (var i=0, limit=scripts.lenght; i< limit; i++) {
if (scripts[i].src.substr(<calculate your offset>) == scriptName) {
// Have you found your script, extract your data
}
}
The only way to find out the location of a non-worker script is the non-standard error.fileName, which is only supported by Firefox and Opera:
var loc = (new Error).fileName;
If the script is a worker thread (which of course it isn't), then you could just use the location object.
If it's really important, you could work around it by defining a string containing the script URL in front of each script tag:
<script type="text/javascript">SCRIPT_URL = "http://www.bar.com/script.js"</script>
<script src="http://www.bar.com/script.js" />
Inside the script file you can then access the URL
alert("my URL is "+SCRIPT_URL);
Not too elegant but should work.
You could also, if you have a server-side language like PHP and don't mind sending JS files through the interpreter (Big performance caveat!), do something like this within the JS file:
<script type="text/javascript">var my_url = "<? echo $_SERVER["REQUEST_URI"]; ?>"</script>
but that should really, really be the last resort.
You can wrap your script in a condition, kind of like an adult diaper, if you insist.
if(top.location.host==='www.bar.com'){
//the whole script goes here
}
else alert('Nyah Nyah Nyah!')

Categories