I use the following code (simplified) to load the content of a gpx file for displaying tracks on maps within the next release of my plugin from [[LINK href="http://www.mapsmarker.com"]]http://www.mapsmarker.com[[/LINK]]:
//info: PHP for fetching content of gpx-file
$gpx_url = $row['gpx_url'];
$gpx_url_proxy = LEAFLET_PLUGIN_URL . 'inc/proxy.php?url='.$gpx_url;
$curl = curl_init($gpx_url_proxy);
$gpx_content = curl_exec($curl);
//info: JS for loading track below
function display_gpx() {
new L.GPX(gpx_url, {
gpx_content: "'.esc_js($gpx_content).'",
}).addTo(map);
}
display_gpx();
On frontend this works fine (see [[LINK href="http://pro.mapsmarker.com/?p=51"]]http://pro.mapsmarker.com/?p=51[[/LINK]] for an example).
Within the plugins backend on the page for creating maps I would like the track to be automatically displayed after the file has been selected from the media library. Currently the use has to save the map first before being able to center the map on it and see the track. Below the code which does not work, as PHP is executed on server-side and JS on client-side (so the JS variable gpx_content stays empty):
custom_uploader.on('select', function() {
attachment = custom_uploader.state().get('selection').first().toJSON();
new L.GPX(attachment.url, {
//info: just added next 4 lines for demo what I would need - I know that this doesnt work
$gpx_url_proxy = LEAFLET_PLUGIN_URL . 'inc/proxy.php?url=attachment.url
$curl = curl_init($gpx_url_proxy);
$gpx_content = curl_exec($curl);
gpx_content: '".esc_js($gpx_content)."',
}).addTo(map);
});
custom_uploader.open();
As far as I understand, the only way to load the content of the gpx track here dynamically would be by using AJAX.
How would I need to have to change the code above, in order to use the value of attachment.url (sent from the media library after clicking "insert file") for fetching $gpx_content? jQuery could be used here.
Thx,
John Cotton answers:
Hi Robert
Why do you need to use AJAX? Surely attachment.url is the url of another site? If so, could you use JSONP (https://github.com/jaubourg/jquery-jsonp) and call it's contents directly?
JC
Robert Seyfriedsberger comments:
Hi John,
I guess AJAX is the solution - at least as I searched for "using JS Variables in PHP" and every answer said this is only possible via AJAX. attachment.url is the URL to a gpx-file in the media library. Using JSONP might not really be an option, as I built a php proxy which gets the content of the gpx file, because it can also be fetched from an exernal server (and a proxy was the only way to overcome cross domain issues).
Any idea how to implement AJAX here? Or might there be another solution I am missing?
best & thx,
Robert
John Cotton comments:
Using the proxy on your own server to get around cross-domain is certainly an option and you could just pass the attachment url back to the server via ajax and receive the response that way. That's easy enough.
However, I thought the GPX was json, but it's xml, so you can just do this:
$.get( attachment.url, function(xml){
new L.GPX(attachment.url, {
gpx_content: xml,
}).addTo(map);
}
John Cotton comments:
..in your client-side javascript...
Robert Seyfriedsberger comments:
well yes, but how do I call my proxy with $.get? (the php code from my example)
John Cotton comments:
Why do you need to? The client side js does it all for you?
But if you want to then like this:
JS
$.ajax({
type : 'POST',
url : ajax_url,
data : { action: 'external_proxy', gpx_url: attachment.url }, // Add further params if you need to
success : function(r) {
new L.GPX(attachment.url, {
gpx_content: r,
}).addTo(map);
}
});
PHP
function call_external_proxy() {
$gpx_url = $_POST['gpx_url'];
$gpx_url_proxy = LEAFLET_PLUGIN_URL . 'inc/proxy.php?url='.$gpx_url;
$curl = curl_init($gpx_url_proxy);
$gpx_content = curl_exec($curl);
echo $gpx_content
}
add_action('wp_ajax_external_proxy', 'call_external_proxy');
add_action('wp_ajax_nopriv_external_proxy', 'call_external_proxy');
...but I can't quite see the point....
John Cotton comments:
PS ajax_url is a js var set somewhere else, in the header or whatever, by PHP:
<script>ajax_url = '<?php echo admin_url('admin-ajax.php'); ?>';</script>
Or, if the js is being output directly in php (although that's horrible) then just:
$.ajax({
type : 'POST',
url : '<?php echo admin_url('admin-ajax.php'); ?>',
data : { action: 'external_proxy', gpx_url: attachment.url }, // Add further params if you need to
success : function(r) {
new L.GPX(attachment.url, {
gpx_content: r,
}).addTo(map);
}
});
Robert Seyfriedsberger comments:
thanks for the example code - will try that & let you know the results
Robert Seyfriedsberger comments:
it worked - actually it was not very hard, thanks for pointing me into the right direction John!
Liam Bailey answers:
If this js:
custom_uploader.on('select', function() {
attachment = custom_uploader.state().get('selection').first().toJSON();
new L.GPX(attachment.url, {
//info: just added next 4 lines for demo what I would need - I know that this doesnt work
$gpx_url_proxy = LEAFLET_PLUGIN_URL . 'inc/proxy.php?url=attachment.url
$curl = curl_init($gpx_url_proxy);
$gpx_content = curl_exec($curl);
gpx_content: '".esc_js($gpx_content)."',
}).addTo(map);
});
custom_uploader.open();
Is located in a .js file, simply move it to a php file and do:
[LATEST AVOID QUOTES]
?><script>
custom_uploader.on('select', function() {
attachment = custom_uploader.state().get('selection').first().toJSON();
new L.GPX(attachment.url, {
//info: just added next 4 lines for demo what I would need - I know that this doesnt work
<?php $gpx_url_proxy = LEAFLET_PLUGIN_URL . 'inc/proxy.php?url=attachment.url
$curl = curl_init($gpx_url_proxy);
$gpx_content = curl_exec($curl);
?> gpx_content: "<?php echo esc_js($gpx_content); ?>";//No Quote Problem
}).addTo(map);
});
custom_uploader.open();</script><?php //rest of php
Obviously it will need to go in your php where you want the map to appear.
Robert Seyfriedsberger comments:
that would not work <?php $gpx_url_proxy...> code is executed on the server, while the attachment.url is retrieved afterwards when the page is already loaded via javascript. This is why I would need Ajax.