Insert PHP code into my page.xml - php

page.xml.php will not show any output, in firebug I can see the get response for page.xml.php with my class responsible for extracting the data isn't seeing the content as xml data
How can i get this to work?
index.php
// Load config file
$config = simplexml_load_file("resources/pinboard/config.xml.php");
page.xml.php
<?php header("Content-type: text/xml"); ?>
...
<module name="Weather" id="23">
<title>Weather</title>
<location><?php echo $_COOKIE['zip_code']; ?></location>
</module>
...
weather.php
...
protected $default_config = array(
'title' => 'Weather',
'refresh' => '200000', // Every 20 minutes
'location' => "Los+Angeles",
'format' => 'f'
);
...
site.js
...
$.ajax({
type: "GET",
url: "resources/pinboard/config.xml.php?" + new Date().getTime(),
dataType: "xml",
success: function(xml) {
// Parse config
$(xml).find('settings').children().each(function(test){
settings[$(this)[0].localName] = $(this).text();
});
// Call init (startup the picboard)
init();
}
});
...

Your loading your xml.php file with
$config = simplexml_load_file("resources/pinboard/config.xml.php");
But that would not return a parsed file, just the source. Now I don't know if your other xml.php files are loaded like that, -but you need to "go trough the webserver" for it to work.
The ajax call does seem correct though.
As suggested in the comments:
use more sensible application structure

Related

How to use ajax to execute php function that will push a file to the browser?

I'm trying to write a method in a php class that will use ajax to execute a php function that will push a file back to the browser.
It seems like its trying to write the file to the modx log, getting a lot of binary garbage in there.
Here is the method:
public function pushDocuments($formdata){
$data = $formdata['formdata'];
$file = MODX_PROTECTED_STORAGE . $data['target'];
$file_name = basename($file);
if (file_exists($file)) {
header("Content-Disposition: attachment; filename=\"$file_name\"");
header("Content-Length: " . filesize($file));
header("Content-Type: application/octet-stream;");
readfile($file);
};
$output = array(
'status' => 'success',
'error_messages' => array(),
'success_messages' => array(),
);
$output = $this->modx->toJSON($output);
return $output;
}
and here is the jquery:
$('.btn-get-document').click(function(){
var target = $(this).attr('data-target');
var postdata = {"snippet":"DataSync", "function":"pushDocuments", "target": target}; // data object ~ not json!!
console.log('target = ' + target + postdata );
$.ajax({
type: "POST",
url: "processors/processor.ajax.generic/",
dataType : "json",
cache : false,
data: postdata, // posting object, not json
success: function(data){
if(data.status == 'success'){
console.log("SUCCESS status posting data");
}else if(data.status == 'error'){
console.log("error status posting data");
}
},
error: function(data){
console.log("FATAL: error posting data");
}
});
});
it's running through the scripts and giving a success in the console [because I am forcing success] but no file is prompted for download and the binary garbage shows up in the modx log
What am I doing wrong?
In order to download a file, you'd have to use JS to redirect to the file's location. You can't pull the file contents through AJAX and direct the browser to save those contents as a file.
You would need to structurally change your setup. For instance, your PHP script can verify the existence of the file to be downloaded, then send a link to JS in order to download the file. Something like this:
if ( file_exists( $file )) {
$success_message = array(
'file_url' => 'http://example.com/file/to/download.zip'
);
}
$output = array(
'status' => 'success',
'error_messages' => array(),
'success_messages' => $success_message
);
Then modify the "success" portion of your AJAX return like this:
success: function( data ) {
if ( data.status == 'success' ) {
location.href = data.success_messages.file_url;
} else if ( data.status == 'error' ) {
console.log( 'error status posting data' );
}
},
Since you're directing to a file, the browser window won't actually go anywhere, so long as the file's content-disposition is set to attachment. Typically this would happen if you directed to any file the browser didn't internally handle (like a ZIP file). If you want control over this so that it downloads all files (including things the browser may handle with plugins), you can direct to another PHP script that would send the appropriate headers and then send the file (similar to the way you're sending the headers and using readfile() in your example).
#sean-kimball,
You might want to extend MODX's class based processor instead:
https://github.com/modxcms/revolution/blob/master/core/model/modx/processors/browser/file/download.class.php
It does the download from any media source and also access checking if you want.
Its implementation on manager side is:
https://github.com/modxcms/revolution/blob/master/manager/assets/modext/widgets/system/modx.tree.directory.js#L553
Back to your case, these examples might bring you some ideas.
JS Example:
$.ajax({
type: "POST",
// read my note down below about connector file
url: "assets/components/mypackage/connectors/web.php",
dataType : "json",
cache : false,
data: {
action: 'mypath/to/processor/classfile'
}
success: function(data){
},
error: function(data){
console.log("FATAL: error posting data");
}
});
Processor example:
<?php
require_once MODX_CORE_PATH . 'model/modx/processors/browser/file/download.class.php';
class myDownloadProcessor extends modBrowserFileDownloadProcessor {
// override things in here
}
return 'myDownloadProcessor';
For this, I also suggest you to use MODX's index.php main file as the AJAX's connector so the $modx object in processor inherits the access permission as well.
http://www.virtudraft.com/blog/ajaxs-connector-file-using-modxs-main-index.php.html

PHP AJAX response in XML string

I have a web page that is making an AJAX call which echoes a XML string in below format:
<ECG>Abnormal</ECG><SP>10.99</SP><BP>120/90</BP><OXY>139</OXY><TMP>23</TMP>
AJAX call
$.ajax({
type:'post',
url: 'check_status.php',
dataType: 'xml',
success: function(xml) {
var ecg = $(xml).find("ECG").text();
var sp = $(xml).find("SP").text();
var bp = $(xml).find("BP").text();
var oxy = $(xml).find("OXY").text();
var tmp = $(xml).find("TMP").text();
alert(tmp);
},
error: function(){
alert('Error');
update();
}
});
The XML response is simply created by PHP backend script by constructing the XML string:
$resp = "<ECG>" . $ecg . "</ECG>" ....
echo $resp;
But still the alert in the AJAX error method is called - is there something else that I need to do from backend script.
As I told in comments, the response isn't well formed XML. You're missing a document node which wraps the other nodes. Like this:
<?xml version="1.0"?>
<RESPONSE>
<ECG>Abnormal</ECG>
<SP>10.99</SP>
<BP>120/90</BP>
<OXY>139</OXY>
<TMP>23</TMP>
</RESPONSE>
Also you are encouraged to set the proper content type header from PHP:
header('Content-Type: text/xml');
(before the output)

403 Forbidden Access to CodeIgniter controller from ajax request

Im having trouble with sending an ajax request to codeigniter controller. It is throwing back a 404 Forbidden Access error. I have found some sort of similar question to this but im not sure if its particular to CodeIgniter framework, and also the solution give in that thread did not solve my problem. below is my ajax request. Im wondering this is probably because of the .htaccess of the root folder of CI Application folder, but i dont want to change its default configuration yet.
Is sending ajax request to CI controller the correct way of implementing this? if not, any suggestion please. Thanks!
var ajax_load = '{loading gif img html}';
var ajax_processor = 'http://localhost/patientcare-v1/application/controller/ajax_processor/save_physical_info';
$("#save").click(function(){
$("#dialog-form").html(ajax_load);
$.post(
ajax_processor,
$("#physical-info").serialize(),
function(responseText){
$("#dialog-form").html(responseText);
},
"json"
);
});
CodeIgniter use csrf_protection, you can use it with Ajax and JQuery simply.
This (ultimate ?) solution work on multiple Ajax request (no 403 ;-) and preserve the security).
Change the configuration
Open the file /application/config/config.php
and change the line $config['csrf_token_name'] by :
$config['csrf_token_name'] = 'token';
You can use another name, but change it everywhere in future steps.
Add CSRF in your Javascript
Add script in a view; for me is in footer.php to display the code in all views.
<script type="text/javascript">
var CFG = {
url: '<?php echo $this->config->item('base_url');?>',
token: '<?php echo $this->security->get_csrf_hash();?>'
};
</script>
This script create an object named CFG. This object can be used in your Javascript code. CFG.url contain the url of your website and CFG.token ... the token.
Automatically renew the CSRF
Add this code in your part $(document).ready(function($){---}) as
$(document).ready(function($){
$.ajaxSetup({data: {token: CFG.token}});
$(document).ajaxSuccess(function(e,x) {
var result = $.parseJSON(x.responseText);
$('input:hidden[name="token"]').val(result.token);
$.ajaxSetup({data: {token: result.token}});
});
});
This script initialize the CSRF token and update it everytime when a request Ajax is sended.
Send the CSRF in PHP
I've created a new controller, named Ajax. In CodeIgniter, the link to use it is http://www.domain.ltd/ajax/foo
<?php
defined('BASEPATH') OR exit('No direct script access allowed');
class Ajax extends CI_Controller {
public function foo() {
$this->send(array('foo' => 'bar'));
}
private function send($array) {
if (!is_array($array)) return false;
$send = array('token' => $this->security->get_csrf_hash()) + $array;
if (!headers_sent()) {
header('Cache-Control: no-cache, must-revalidate');
header('Expires: ' . date('r'));
header('Content-type: application/json');
}
exit(json_encode($send, JSON_FORCE_OBJECT));
}
}
The send function add the CSRF automatically and transform an array in object.
The final result
Now, you can use Ajax with JQuery very simply !
$.post(CFG.url + 'ajax/foo/', function(data) {
console.log(data)
}, 'json');
Result :
{"token":"8f65cf8e54ae8b71f4dc1f996ed4dc59","foo":"bar"}
When the request get data, the CSRF is automatically updated to the next Ajax request.
Et voilà !
Remove the <code> and application/controller from your ajax_processor like,
var ajax_processor = 'http://localhost/patientcare-v1/index.php/ajax_porcessor/save_physical_info';
If you are hiding index.php from url by using htaccess or routing then try this url,
var ajax_processor = 'http://localhost/patientcare-v1/ajax_porcessor/save_physical_info';
I was facing same problem but now I have fixed this problem.
First of all, I have created csrf_token in header.php for every pages like below code
$csrf = array(
'name' => $this->security->get_csrf_token_name(),
'hash' => $this->security->get_csrf_hash()
);
<script type="text/javascript">
var cct = "<?php echo $csrf ['hash']; ?>";
</script>
After that, when we are sending particular value through ajax then we will have to sent csrf token like below code
$.ajax({
url:"<?php echo APPPATHS.'staff_leave/leaveapproval/getAppliedLeaveDetails'; ?>",
data:{id:id,status:status,'<?php echo $this->security->get_csrf_token_name(); ?>': cct},
method:"post",
dataType:"json",
success:function(response)
{
alert('success');
}
});
I hope this code will help you because this is working for me.
// Select URIs can be whitelisted from csrf protection (for example API
// endpoints expecting externally POSTed content).
// You can add these URIs by editing the
// ‘csrf_exclude_uris’ config parameter:
// config.php
// Below setting will fix 403 forbidden issue permanently
$config['csrf_exclude_uris'] = array(
'admin/users/view/fetch_user', // use ajax URL here
);
$('#zero-config').DataTable({
"processing" : true,
"serverSide" : true,
"order" : [],
"searching" : true,
"ordering": false,
"ajax" : {
url:"<?php echo site_url(); ?>admin/users/view/fetch_user",
type:"POST",
data: {
},
},
});

Drupal module jQuery PHP script location issue

I am developing a module which has a jQuery script with some AJAX code. The ajax code calls a php script located in the same location as the jQuery script.
My problem is, AJAX appends the domain name in front of the PHP script name and of course, my script does not exist at that location and so the process breaks.
The AJAX code is as follows:
$(document).ready(
function(){
$.ajax({
url: "/testscript.core.php",
asych: false,
success: function($data){
$('textarea#edit-simplechat-messages').text( $data );
}
});
}
);
And the following is the link that shows up in firebug:
http://testsite.co.uk/testscript.core.php
Again, the jQuery script and the php script are in the same directory.
I thought the forward slash before my php script name would eliminate the domain name but it did not work.
Use
Drupal.settings.basePath
url: Drupal.settings.basePath+'your file path',
This link might be useful
http://www.akchauhan.com/how-know-base-path-of-drupal-in-javascript/
EDIT :
Or you can use this approach if you are creating your own custom module then follow these steps
1] First create your module, Here my module name is "mymodule", So i created a file name mymodule.module
<?php
function mymodule_init() {
drupal_add_js(drupal_get_path('module', 'mymodule') . '/mymodule.js');
// this call my js file when module is initialized.
}
function mymodule_menu(){
$items = array();
$items['mypath'] = array(
'title' => t('To get series of the selected brand'),
'page callback' => 'mymodule_page',
'page arguments' => array(1),
// get test_parameter from url, which is your first argument
//http://domain.com/mypath/test_parameter
// here mypath is arg(0), and test_parameter is arg(1)
'access arguments' => array('access content'),
'type' => MENU_CALLBACK,
);
return $items;
}
function mymodule_page($termID){
return drupal_json(array('message'=> $itemID));
}
2] Secondly create js file with the same name so name it mymodule.js under the same module file.
// $Id$
Drupal.behaviors.mymodule = function (context) {
var $basepath = Drupal.settings.basePath;
$('selector').change(function(e){
$.ajax({
type: 'POST',
url: $basepath+'mypath/test_parameter',
// test_parameter :value you are sending to you module.
dataType:'json',
cache:false,
beforeSend:function(){
},
success:function(data){
alert(data.message);
},
complete:function(){
},
error:function(xhr, status, error){
}
});
});
}
Notice in js file i have used mypath. your js file will call this path which is defined in the hook_menu().
the way it is now it looks like your problem is the slash before the file name.. that means "domain web root"

Dynamic XML Generated from PHP

I have a PHP script that loads XML content dynamically:
require_once 'directory/directory/';
$nice= '1149632';
$key = 'adf995jdfdfddda44rfg';
$mixer = new Live_Products($key);
$result = $mixer->product($nice)
->show(array('name','Price'))
->query();
echo $result
This will work fine when it is loaded. But I am trying to use an ajax/jquery script to send the value $nice to the PHP script; and to ultimately send the result back from the dynamically created XML file. I've been trying to figure this out for hours
Here is the ajax Script
function sendValues() {
$("$nice")
$.ajax({
url: "/myphp.php",
data: {str}
cache: false
});
}
Has anybody done something similar to this concept?
Why not pass it as a GET param like so...
jQuery
function sendValues(something) {
$.ajax({
url: "/myphp.php?nice=" + something,
cache: false,
dataType: 'xml',
success: function(xml) {
// Work with the XML
}
});
}
PHP
require_once 'directory/directory/';
$nice= '1149632';
$key = 'adf995jdfdfddda44rfg';
$mixer = new Live_Products($key);
$result = $mixer->product($_GET['nice'])
->show(array('name','Price'))
->query();
// You said it is XML?
header('Content-Type: text/xml');
echo $result;

Categories