I am trying to modify a Cookie through an Ajax petition but it doesn't work. It modifies the Session but not the cookie. Here is my code:
HTML:
<li class="en_GB" id="1" onclick="changeLanguage('en_GB;1')"><span></span>ENGLISH</li>
Javascript:
function changeLanguage(lang){
$.ajax({
url: 'lib/loadLanguageList.php',
data: {lan: lang},
type: 'POST',
success: function(data){
location.reload();
}
});
}
PHP (loadLanguageList.php) / Action:
if(isset($_POST['lan']) && preg_match("/([a-z]+_[A-Z]+;[0-9]+)/", $_POST['lan'])){
setUserLanguage($_POST['lan']);
}
PHP (loadLanguageList.php) / function EDITED*:
(Following the suggestion of #MikeBrant, I've edited the function)
function setUserLanguage($lan){
$locale['value'] = "";
$locale['id'] = "";
if(isset($lan)){
$lan = explode(";", $lan);
$locale['value'] = $lan[0];
$locale['id'] = $lan[1];
} else if (!isset($_COOKIE["locale"])){
$lan = $this->getUserLanguage();
$locale['value'] = $lan[0]['value'];
$locale['id'] = $lan[0]['id'];
}
setcookie("locale","",time()-2592000);
setcookie("locale_id","",time()-2592000);
setcookie("locale",$locale['value'],time()+60*60*24*30);
setcookie("locale_id",$locale['id'],time()+60*60*24*30);
print_r($locale);
$_SESSION['locale'] = $locale['value'];
$_SESSION['locale_id'] = $locale['id'];
require_once(ROOT."/lib/utils/localization.php");
}
But the cookie is not being deleted and the print_r print $locale variable as it should be. I don't understand why the setcookie function didn't work.
First, let's rewrite your function to where it makes better logic sense in terms of the code path flow (i.e. we have simplified the conditionals).
function setUserLanguage($lan){
$locale['value'] = "";
$locale['id'] = "";
if(isset($lan)){
$lan = explode(";", $lan);
$locale['value'] = $lan[0];
$locale['id'] = $lan[1];
if(!isset($_COOKIE["locale"])){
setcookie("locale",$locale['value'],time()+60*60*24*30);
setcookie("locale_id",$locale['id'],time()+60*60*24*30);
} else {
$_COOKIE["locale"] = $locale['value'];
$_COOKIE["locale_id"] = $locale['id'];
}
} else if (!isset($_COOKIE["locale"])){
$lan = $this->getUserLanguage();
$locale['value'] = $lan[0]['value'];
$locale['id'] = $lan[0]['id'];
setcookie("locale",$locale['value'],time()+60*60*24*30);
setcookie("locale_id",$locale['id'],time()+60*60*24*30);
}
$_SESSION['locale'] = $locale['value'];
$_SESSION['locale_id'] = $locale['id'];
require_once(ROOT."/lib/utils/localization.php");
}
Now let's walk through the use cases here. Let's say the user already has a locale cookie set and they are trying to change it.
This user would pass this conditional:
if(isset($lan))
And should fail this conditional
if(!isset($_COOKIE["locale"]))
This means this code block would be executed:
$_COOKIE["locale"] = $locale['value'];
$_COOKIE["locale_id"] = $locale['id'];
This would change the cookie value for the duration of the script execution only, as nothing in the response to the browser would trigger a change in cookie value.
My guess is that you want to ALWAYS call setcookie().
Also I would think the whole (!isset($lan)) section of code could be removed in favor for throwing some kind of error, as having a "set" function without passing it a value doesn't seem to make much sense.
Related
I would like to test if the ajax request is identical so it can be aborted or some other alert action taken?
In reality clients can change the request via a few form elements then hit the refresh button.
I have made a poor attempt at catching the identical request. Need to keep the timer refresh functionality.
<script type="text/javascript" src="http://code.jquery.com/jquery-latest.js"></script>
<script type="text/javascript">
var current_request_id = 0;
var currentRequest = null;
var lastSuccessfulRequest = null;
function refreshTable() {
$('#select').html('Loading');
window.clearTimeout(timer);
//MY CATCH FOR DUPLICATE REQUEST NEEDS WORK
if (lastSuccessfulRequest == currentRequest)
{
//currentRequest.abort();
alert('Duplicate query submitted. Please update query before resubmission.');
}
var data = {
"hide_blanks": $("#hide_blanks").prop('checked'),
"hide_disabled": $("#hide_disabled").prop('checked'),
};
json_data = JSON.stringify(data);
current_request_id++;
currentRequest = $.ajax({
url: "/calendar_table",
method: "POST",
data: {'data': json_data},
request_id: current_request_id,
beforeSend : function(){
if(currentRequest != null) {
currentRequest.abort();
}
},
success: function(response) {
if (this.request_id == current_request_id) {
$("#job_table").html(response);
$("#error_panel").hide();
setFixedTableHeader();
}
},
error: function(xhr) {
if (this.request_id == current_request_id) {
$("#error_panel").show().html("Error " + xhr.status + ": " + xhr.statusText + "<br/>" + xhr.responseText.replace(/(?:\r\n|\r|\n)/g, "<br/>"));
}
},
complete: function(response) {
if (this.request_id == current_request_id) {
$("#select").html("Refresh");
window.clearTimeout(timer);
stopRefreshTable();
window.refreshTableTimer = window.setTimeout(refreshTable, 10000);
lastSuccessfulRequest = currentRequest;
}
}
});
}
//TIMER STUFF TO refreshTable()
//THIS SECTION WORKS FINE
var startDate = new Date();
var endDate = new Date();
var timer = new Date();
function startRefreshTable() {
if(!window.refreshTableTimer) {
window.refreshTableTimer = window.setTimeout(refreshTable, 0);
}
}
function stopRefreshTable() {
if(window.refreshTableTimer) {
self.clearTimeout(window.refreshTableTimer);
}
window.refreshTableTimer = null;
}
function resetActive(){
clearTimeout(activityTimeout);
activityTimeout = setTimeout(inActive, 300000);
startRefreshTable();
}
function inActive(){
stopRefreshTable();
}
var activityTimeout = setTimeout(inActive, 300000);
$(document).bind('mousemove click keypress', function(){resetActive()});
</script>
<input type="checkbox" name="hide_disabled" id="hide_disabled" onchange="refreshTable()">Hide disabled task<br>
<br><br>
<button id="select" type="button" onclick="refreshTable();">Refresh</button>
I'd use the power of .ajaxSend and .ajaxSuccess global handlers.
We'll use ajaxSuccess to store a cache and ajaxSend will try to read it first, if it succeeds it will trigger the success handler of the request immediately, and abort the request that is about to be done. Else it will let it be...
var ajax_cache = {};
function cache_key(settings){
//Produce a unique key from settings object;
return settings.url+'///'+JSON.encode(settings.data);
}
$(document).ajaxSuccess(function(event,xhr,settings,data){
ajax_cache[cache_key(settings)] = {data:data};
// Store other useful properties like current timestamp to be able to prune old cache maybe?
});
$(document.ajaxSend(function(event,xhr,settings){
if(ajax_cache[cache_key(settings)]){
//Add checks for cache age maybe?
//Add check for nocache setting to be able to override it?
xhr.abort();
settings.success(ajax_cache[cache_key(settings)].data);
}
});
What I've demonstrated here is a very naïve but functional approach to your problem. This has the benefit to make this work for every ajax calls you may have, without having to change them. You'd need to build up on this to consider failures, and to make sure that the abortion of the request from a cache hit is not getting dispatched to abort handlers.
One valid option here is to JSON.Stringify() the objects and compare the strings. If the objects are identical the resulting serialised strings should be identical.
There may be edge cases causing slight differences if you use an already JSONified string directly from the response so you'll have to double check by testing.
Additionally, if you're trying to figure out how to persist it across page loads use localStorage.setItem("lastSuccessfulRequest", lastSuccessfulRequest) and localStorage.getItem("lastSuccessfulRequest"). (If not, let me know and I'll remove this.)
I'm trying to send data to a php file to save in database, but I don't have any response. If a checkbox is check, the [obj][idCheckbox] = 1, else [obj][idCheckbox] = 0.
File that sends
var i=0;
var objetoTodasPermissoes = function(){};
var objTodasPermissoes = new objetoTodasPermissoes();
$.each($(".classePermissoes"), function(){
objTodasPermissoes[$(this)[0].id] = 0
i++;
});
$.each($(".classePermissoes:checked"), function(){
alert('ok');
objTodasPermissoes[$(this)[0].id] = 1;
});
console.log(objTodasPermissoes);
$.each($("#userList tr"),function(){
alert(this.id);
var iduser = this.id;
$.ajax({
url:'../json/usuarioperm/savePermissions.php',
data:({
idusuario:iduser,
objTodasPermissoes:objTodasPermissoes,
}),
success:function(a){
Alert("Saved!");
}
});
});
}
the savePermissions.php file.
$iduser = $_POST["iduser"];
$perm_usuarios = $_POST["objTodasPermissoes"]["perm_usuarios"];
$perm_importar = $_POST["objTodasPermissoes"]["perm_importar"];
$perm_log = $_POST["objTodasPermissoes"]["perm_log"];
$perm_proto = $_POST["objTodasPermissoes"]["perm_proto"];
$perm_limpeza = $_POST["objTodasPermissoes"]["perm_limpeza"];
$perm_lixeira = $_POST["objTodasPermissoes"]["perm_lixeira"];
$perm_relatusuarios = $_POST["objTodasPermissoes"]["perm_relatusuarios"];
$perm_deptos = $_POST["objTodasPermissoes"]["perm_deptos"];
$perm_deptospastas = $_POST["objTodasPermissoes"]["perm_deptospastas"];
$perm_empresas = $_POST["objTodasPermissoes"]["perm_empresas"];
mysql_query("UPDATE hospital.users set
perm_usuarios=".$perm_usuarios.",
perm_importar=".$perm_importar.",
perm_log=".$perm_log.",
perm_proto=".$perm_proto.",
perm_limpeza=".$perm_limpeza.",
perm_lixeira=".$perm_lixeira.",
perm_relatusuarios=".$perm_relatusuarios.",
perm_deptos=".$perm_deptos.",
perm_deptospastas=".$perm_deptospastas.",
perm_empresas=".$perm_empresas." where id=".$iduser) or die (mysql_error());
Thank you.
PHP is kind of interesting in that it doesn't pull from $_POST like other forms when Ajax is involved. You actually will need to read the input from php://input
Here is a tiny example
$data = file_get_contents("php://input");
$response = json_decode($data, true ); // True converts to array; blank converts to object
$emailAddr = $response["email"];
Hopefully you can apply that successfully.
Edit: You can add the filter_var command to strip bad characters and sanitize the input.
$emailAddr = filter_var($response["email"], FILTER_SANITIZE_EMAIL);
$firstName = filter_var($response["firstName"], FILTER_SANITIZE_STRING);
While debugging this I would highly recommend using Chrome's Developer mode with the 'network' tab. Find your ajax call near the bottom and you can view exact header info.
I've inherited a website with an obscure PHP framework called syndrome for which I can't find any documentation, but the problem I'm trying to solve should be fairly simple for a good PHP developer.
I am trying to make ajax requests from javascript to a php file to execute a particular function. The ajax request is simply:
loadNewImage = function(){
$.ajax({ url: '/app/library/Controller/Reel.php',
data: {action: 'test'},
type: 'post',
success: function(output) {
alert(output);
}
});
}
The current PHP file is structured like this:
<?php
class Controller_Reel extends BaseController_Web {
protected function defaultAction() {
parent::getPage($this->template, 'home');
$homepage = Homepage::getInstance()->getHomepage();
$this->template->title = 'Homepage';
$this->template->image = $homepage['asset_image'];
$this->template->center = array('reel');
$this->setResponse($this->template);
}
}
What I want to do is add to the file a check for post data. I'm not good with PHP, but I tried:
<?php
if(isset($_POST['action']) && !empty($_POST['action'])) {
echo 'TEST POST';
}
class Controller_Reel extends BaseController_Web {
protected function defaultAction() {
parent::getPage($this->template, 'home');
$homepage = Homepage::getInstance()->getHomepage();
$this->template->title = 'Homepage';
$this->template->image = $homepage['asset_image'];
$this->template->center = array('reel');
$this->setResponse($this->template);
}
}
I'm assuming that's maybe because the check for post data is not happening within the class itself, but I'm not exactly sure how to structure the code. Can anybody help straighten me out?
UPDATE: I found this inside a file called ControllerSite.php -> (of which baseController_Web is extended:
protected function respond() {
switch($this->response_type) {
case self::RESPONSE_PAGE:
// always try to make ie use the latest rendering engine
case self::RESPONSE_TEXT:
Helper_Request::respond($this->processed_response, Helper_Request::RESPONSE_PRINT, Config::$platform);
break;
case self::RESPONSE_JSON:
Helper_Request::respond($this->processed_response, Helper_Request::RESPONSE_JSON, Config::$platform);
break;
case self::RESPONSE_REDIR:
Helper_Request::respond($this->processed_response, Helper_Request::RESPONSE_REDIR, Config::$platform);
break;
case self::RESPONSE_CONTENT:
// TODO: we'll need to figure the out, but don't need to worry about it for now
break;
}
return $this;
}
and then in Controller.php (of which ControllerSite.php is extended), this:
final private function execute() {
$action = $this->getMethodName();
$is_ajax = Helper_Request::isAjax();
$data_type = strtolower(Helper_Request::setDefault($_SERVER['HTTP_ACCEPT'], ''));
if($is_ajax && preg_match('/\w+\/json|\w+\/javascript/i', $data_type) && method_exists($this, $action . 'JsonAction')) {
// it there was a ajax json request and the ajax json specific method exists, execute it
return $this->{$action . 'JsonAction'}();
}
return $this;
}
Try this:
class Controller_Reel extends BaseController_Web {
protected function defaultAction() {
parent::getPage($this->template, 'home');
$homepage = Homepage::getInstance()->getHomepage();
$this->template->title = 'Homepage';
$this->template->image = $homepage['asset_image'];
$this->template->center = array('reel');
if(isset($_POST['action']) && !empty($_POST['action'])) {
$reponse['success'] = true;
$response['responseVal'] = 'This is a test';
$this->setResponse($response);
} else {
$this->setResponse($this->template);
}
}
}
Try to make a class method named testAction:
protected function testAction() {
parent::getPage($this->template, 'home');
$homepage = Homepage::getInstance()->getHomepage();
$this->template->title = 'Homepage';
$this->template->image = $homepage['asset_image'];
$this->template->center = array('reel');
$this->setResponse($this->template);
}
In ajax request you are trying to send action parameter with test value and i suppose it is the framework's duty to call the related method named with 'test' .
This may hep.
I have a page where I use jQuery load() method to display a table of results based on a post request of some fields. But I need this load() to display the table and also inform javascript if a condition is met in the PHP script, so probably I need a json response. I don't know if it's possible to use the complete() callback to achieve that. I only need a single variable to pass from my PHP script to javascript.
I'm using load() because I believe other ajax methods need to do the HTML template part from javascript, am I right?
Hope I made myself clear, thanks
UPDATE1:
Here is my js code:
$("#listaNegraView").load('procesos/funcionesAjax.php',
{accion: 'listaNegra',
nombres: $("#nombres").val(),
apellidoP: $("#apellidoP").val(),
apellidoM: $("#apellidoM").val(),
nacimiento: $("#nacimiento").val()},
function(data){console.log(data);}
);
And here is PHP script:
case 'listaNegra':
$_POST['nombres'] = mb_convert_encoding($_POST['nombres'], 'Windows-1252', 'UTF-8');
$_POST['apellidoP'] = mb_convert_encoding($_POST['apellidoP'], 'Windows-1252', 'UTF-8');
$_POST['apellidoM'] = mb_convert_encoding($_POST['apellidoM'], 'Windows-1252', 'UTF-8');
$listaNegra = $personaDB->existsPersonaListaNegra($_POST);
$pct100 = false;
if(!empty($listaNegra) && is_array($listaNegra)){
foreach($listaNegra as &$persona){
$persona['match'] = '';
$porcentaje = 80;
if(strtolower($persona['nombres']) == strtolower($_POST['nombres'])){
$persona['match'] .= 'name';
$porcentaje += 10;
}
if($_POST['nacimiento'] == $persona['fecha_nacimiento']){
$persona['match'] .= 'date';
$porcentaje += 10;
}
$persona['porcentaje'] = $porcentaje;
if($porcentaje == 100)
$pct100 = true;
}
unset($persona);
}
include(ROOT.RUTA_TPL.'ventas/listanegra.tpl.php');
break;
UPDATE 2:
Specifically the condition I want to pass to jasvascript is variable $pct100
You are "directly" outputting HTML code so I think, as a quick workaround, you should write the $pct100 in a hidden field/dom element and then access it with the complete callback in your javascript code.
This is an example of what I am suggesting
$("#listaNegraView").load(
'procesos/funcionesAjax.php',
{accion: 'listaNegra',
nombres: $("#nombres").val(),
apellidoP: $("#apellidoP").val(),
apellidoM: $("#apellidoM").val(),
nacimiento: $("#nacimiento").val()
},
function(data){
$('#where-to-put-html-code').html(data);
var pct100 = $('#where-to-put-html-code #hidden-field-id').val() == '1' ? true : false;
}
);
Answer added by the suggestion of the asker.
I have used this function to submit to any url or 'self',
with or without a querystring, many times without any problems.
function submitu(url, q) {
var frm = document.<?php echo $formname ?>;
if (url == '') {url = '<?php echo $thispage?>'; }
frm.action = url+q; frm.submit(); }
If I try to move the PHP vars outside the function, as below, it stops working (frm undefined error)
var thispage = '<?php echo $thispage?>';
var frm = document.<?php echo $formname?>;
function submitu(url, q) {
if (url == '') {url = thispage;}
frm.action = url+q; frm.submit();}
I also tried var frm = document.forms[''];
I don't have any other conflicting javascript,
(1). Can anyone tell me why this is not working?
(2). And why the first method also fails if the function is placed
inside and at the top of the jquery $(function() {.....} ready function?
Many thanks
It fails because when outside the function, var frm = document.formname;
will be run immediately when the page loads, i.e. before the form element has actually been constructed, so you get 'undefined'. When inside the function, it is only run when the function is run, by which time the DOM is complete and it can find it.