Extend session lifetime in Symfony2 - ajax

I am trying to extend sesion_liftime before Symfony2 sesion will be destroyed.
I am showing the user that he will be log out in few seconds, and when he/she confirm to extend the sesion I send an ajax request to controller which should extend the sesion. But the problem is that the request is not working.
I try few diferent solutions but none of them worked.
<script type="text/javascript">
var timeoutID;
function delayedAlert() {
timeoutID = window.setTimeout(slowAlert, 15000);
}
function slowAlert() {
setTimeout(logout, 5500)
var r=confirm("You will be logout in 5 seconds!");
if (r==true)
{
$.ajax({
url: 'http://localhost/interactivo/web/app_dev.php/check',
xhrFields: {
withCredentials: true
}
});
alert("You wont be logout");
}
}
function logout() {alert("You are logout");};
delayedAlert();
</script>
/**
* #Route("/check")
*/
public function indexAction()
{
// FIRST ATTEMPT
// $value = 'something from somewhere';
//
// setcookie("TestCookie", $value);
// setcookie("TestCookie", $value, time()+3600); /* expire in 1 hour */
// setcookie("TestCookie", $value, time()+3600, "/~rasmus/", "example.com", 1);
// SECOND ATTEMPT
// header('Content-type: text/html; charset=utf-8');
// echo 'TEST';
// THIRD ATTEMPT
$session = $this->container->get('session');
$lastUsed = new \DateTime();
$lastUsed->setTimestamp($session->getMetadataBag()->getLastUsed());
return $this->render('GLHomeBundle:Default:sesion.html.twig', array( 'entities'=> $lastUsed));
}
What I'm doing wrong?

I think that it's not a good solution (if it works), but the session's cookie in symfony is called "PHPSESSID". Try to set the life time of this cookie to the time needed ? I use this method to pass my session accross Drupal and Varnish to the client, so I think that it could work to extend life time of the session.
Regards,
Peekmo

I finaly found the solution for this. I used SessionKeepAliveListener from this site.
I am calling the controller via AJAX like this:
function slowAlert() {
setTimeout(logout, 40000)
var r=confirm("You will be logout in 20s!");
if (r==true)
{
$.ajax({
url: "{{ url('_demo_hello') }}",
xhrFields: {
withCredentials: true
}
});
alert("You wont be logout");
}
}
The controller is very easy :D
/**
* #Route("/check", name="_demo_hello")
*/
public function checkAction()
{
$response = new Response();
return $response;
}

Related

How to get update ACF fields from AJAX form data

I can send the data to admin-ajax.php and see that the data exists via my dev tools, however, I cannot seem to be able to take that data and update an ACF field, or perhaps my function to do that is not running.
Here is my PHP:
// define the actions for the two hooks created, first for logged in users and the next for logged out users
add_action( 'wp_ajax_add_dog_to_favorites', 'add_dog_to_favorites' );
add_action( 'wp_ajax_nopriv_add_dog_to_favorites', 'login_to_add_to_favorites' );
// define the function to be fired for logged in users
function add_dog_to_favorites() {
// nonce check for an extra layer of security, the function will exit if it fails
if (!wp_verify_nonce( $_REQUEST['nonce'], 'add_dog_to_favorites_nonce' )) {
exit('Woof Woof Woof');
}
// Get the post_id and user_id value from the form and update the ACF form "test_field".
$post_id = $_REQUEST["post_id"];
$userID = $_REQUEST('user_id');
$current_field = get_field('test_field', $userID);
update_field('test_field', $post_id, $userID);
if ($current_field === false) {
$result['type'] = 'error';
} else {
$result['type'] = 'success';
}
// Check if action was fired via Ajax call. If yes, JS code will be triggered, else the user is redirected to the post page
if (!empty($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest') {
$result = json_encode($result);
echo $result;
} else {
header("Location: " . $_SERVER['HTTP_REFERER']);
}
// don't forget to end your scripts with a die() function - very important
die();
}
// define the function to be fired for logged out users
function login_to_add_to_favorites() {
echo 'You must log in to like';
die();
}
// used here only for enabling syntax highlighting. Leave this out if it's already included in your plugin file.
// Fires after WordPress has finished loading, but before any headers are sent.
add_action( 'init', 'enqueue_add_dog_to_favorites_script' );
function enqueue_add_dog_to_favorites_script() {
// Register the JS file with a unique handle, file location, and an array of dependencies
wp_register_script( 'add_favorites_script', plugin_dir_url( __FILE__ ) . 'add_favorites_script.js', array('jquery') );
// localize the script to your domain name, so that you can reference the url to admin-ajax.php file easily
wp_localize_script( 'add_favorites_script', 'myAjax', array( 'ajaxurl' => admin_url( 'admin-ajax.php' ) ) );
// enqueue jQuery library and the script you registered above
wp_enqueue_script( 'jquery' );
wp_enqueue_script( 'add_favorites_script' );
}
and my JS:
jQuery(document).ready( function() {
jQuery(".not-favorite").click( function(e) {
e.preventDefault();
post_id = jQuery(this).attr("data-post_id");
nonce = jQuery(this).attr("data-nonce");
user_id = jQuery(this).attr("data-user_id");
jQuery.ajax({
type : "post",
dataType : "json",
url : myAjax.ajaxurl,
data : {action: "add_dog_to_favorites", post_id : post_id, nonce: nonce, user_id : user_id},
success: function(response) {
if(response.type == "success") {
console.log('success!');
}
else {
alert("Your like could not be added");
}
}
});
});
});
I have a console.log('success!'); line that should trigger if successful, but it is not triggering. The failure alert is also not triggering, which leads me to believe the function is not running at all? I feel like it's pretty close to working, but just can't get there.
Any help would be greatly appreciated!
Update: Ok. I found that the function is actually exiting because of the nonce verification:
if (!wp_verify_nonce( $_REQUEST['nonce'], 'add_dog_to_favorites_nonce' )) {
exit('Woof Woof Woof');
}
I have tried commenting this block of code out to see what would happen and I get a critical error.
Update: Fixed an error in my code that allows it to work without the nonce check.
$userID = $_REQUEST('user_id'); needs to be $userID = $_REQUEST['user_id'];
I still will need to get the nonce check working, but progress is being made. If anyone knows why that is not working, that would wrap this up!

How to refresh content when using CrossroadJS and HasherJS with KnockoutJS

I was following Lazy Blogger for getting started with routing in knockoutJS using crossroads and hasher and it worked correctly.
Now I needed to refresh the content using ajax for Home and Settings page every time they are clicked. So I googled but could not find some useful resources. Only these two links
Stack Overflow Here I could not understand where to place the ignoreState property and tried these. But could not make it work.
define(["jquery", "knockout", "crossroads", "hasher"], function ($, ko, crossroads, hasher) {
return new Router({
routes:
[
{ url: '', params: { page: 'product' } },
{ url: 'log', params: { page: 'log' } }
]
});
function Router(config) {
var currentRoute = this.currentRoute = ko.observable({});
ko.utils.arrayForEach(config.routes, function (route) {
crossroads.addRoute(route.url, function (requestParams) {
currentRoute(ko.utils.extend(requestParams, route.params));
});
});
activateCrossroads();
}
function activateCrossroads() {
function parseHash(newHash, oldHash) {
//crossroads.ignoreState = true; First try
crossroads.parse(newHash);
}
crossroads.normalizeFn = crossroads.NORM_AS_OBJECT;
hasher.initialized.add(parseHash);
hasher.changed.add(parseHash);
hasher.init();
$('a').on('click', function (e) {
crossroads.ignoreState = true; //Second try
});
}
});
Crossroads Official Page Here too I could not find where this property need to be set.
If you know then please point me to some url where I can get more details about this.

Angularjs multiple ajax requests optimization

I am still learning Angular JS and have this controller which is making two ajax requests to the lastfm api using different parameters. I want to know when each request has been finished, so that I can display a loading indicator for both requests. I have researched it and read about promises and the $q service but cant get my head around how to incorporate it into this. Is there a better way to set this up? and how can I know when each request is done. Thanks.
angular.module('lastfm')
.controller('ProfileCtrl', function ($scope, ajaxData, usersSharedInformation, $routeParams) {
var username = $routeParams.user;
//Get Recent tracks
ajaxData.get({
method: 'user.getrecenttracks',
api_key: 'key would go here',
limit: 20,
user: username,
format: 'json'
})
.then(function (response) {
//Check reponse for error message
if (response.data.message) {
$scope.error = response.data.message;
} else {
$scope.songs = response.data.recenttracks.track;
}
});
//Get user info
ajaxData.get({
method: 'user.getInfo',
api_key: 'key would go here',
limit: 20,
user: username,
format: 'json'
})
.then(function (response) {
//Check reponse for error message
if (response.data.message) {
$scope.error = response.data.message;
} else {
$scope.user = response.data.user;
}
});
});
I have this factory which handles all the requests
angular.module('lastfm')
.factory('ajaxData', function ($http, $q) {
return {
get: function (params) {
return $http.get('http://ws.audioscrobbler.com/2.0/', {
params : params
});
}
}
});
Quite easy using $q.all(). $http itself returns a promise and $q.all() won't resolve until an array of promises are resolved
var ajax1=ajaxData.get(....).then(....);
var ajax2=ajaxData.get(....).then(....);
$q.all([ajax1,ajax2]).then(function(){
/* all done, hide loader*/
})

AJAX Form will only either show success message OR post data to database not both

I am using Codeigniter as my framework and have a simple contact form. This uses the form helper and i have used AJAX and a fallback in the controller if AJAX is not present.
At the moment, my code with only either show the success message from the ajax form OR post the data to the database depending on if i change them around in the controller - my error messages work fine.
I am confused to how it will not both post and show success message - i think i may be missing something in my controller or AJAX request?
Here is my code as a guidance and if anyone can spot anything that would be great as it's getting on my nerves now!
*The code i am posting now lets the data be posted into the database. When i move the post data elements below this -> return $this->output->set_output(json_encode($respond)); It doesn't post to the database but shows the success message and vice versa.
CONTROLLER,
// if ajax request
if($this->input->is_ajax_request()) {
$respond = array();
if($this->form_validation->run() == FALSE) {
$respond['result'] = 'false';
$respond['error_message'] = $error_message;
$respond['errors'] = validation_errors();
// set individual errors - for warning classes
$respond['first_name_error'] = form_error('first_name');
$respond['country_error'] = form_error('country');
$respond['email_error'] = form_error('email');
$respond['message_error'] = form_error('message');
} else {
$respond['result'] = 'true';
$respond['success_message'] = $success_message;
// add contact message to the database
$this->contact_model->insert_contact_message($curr_lang, $this->input->post('first_name'), $this->input->post('country'), $this->input->post('email'), $this->input->post('phone'), $this->input->post('message'));
}
return $this->output->set_output(json_encode($respond));
} else {
// if ajax request failed - use CI
if($this->form_validation->run() == FALSE) {
$data['error_message'] = $error_message;
$data['errors'] = validation_errors();
} else {
// add contact message to the database
$this->contact_model->insert_contact_message($curr_lang, $this->input->post('first_name'), $this->input->post('country'), $this->input->post('email'), $this->input->post('phone'), $this->input->post('message'));
$data['success_message'] = $success_message;
}
}
// set field labels
$data['first_name'] = $first_name;
$data['country'] = $country;
$data['email'] = $email;
$data['phone'] = $phone;
$data['message'] = $message;
// initialize view name
$data['content'] = $page;
// load the view
$this->load->view('template', $data);
}
AJAX
$('#submit').click(function(e) {
e.preventDefault();
// send the form data to the controller
$.ajax({
url: $(this).attr('action'),
type: 'POST',
data: $('form').serialize(),
dataType: 'json',
success: function(respond) {
if(respond.result === 'false'){
// function to add warning class
function add_error(response, field){
if(response){
$(field).addClass('warning');
}
}
// add warning classes - doing this individually as some inputs have more than one error message
add_error(respond.first_name_error, 'input[name="first_name"]');
add_error(respond.country_error, 'input[name="country"]');
add_error(respond.email_error, 'input[name="email"]');
add_error(respond.message_error, 'textarea');
// post all errors to the view
var error_msg = respond.error_message + respond.errors;
$('#error_message').html(error_msg);
}
if(respond.result === 'true'){
// empty the form
$('#error_message').empty();
$('form').find("input[type=text], textarea").val('');
// set the success message
var success_msg = respond.success_message;
$('#success_message').html(success_msg).fadeOut(6000);
}
}
});
return false;
});
It's likely because you aren't parsing the JSON response so your if statements will never be true (as respond.result is probably evaluating to 'undefined').
In your Ajax respond.result === true or false not 'true' or 'false'. You just need to remove the quotes because it is a Boolean not a string.

Codeigniter rest issue with backbone

I just started using rest library wrote by Phil Sturgeon. I started using it by writing some simple examples. I short of get 'post' and 'get' work, but not for put and delete. I have some questions based on the code below.
// a simple backbone model
var User = Backbone.Model.extend({
urlRoot: '/user',
defaults:{
'name':'John',
'age': 17
}
});
var user1 = new User();
//user1.save(); // request method will be post unless the id attr is specified(put)
//user1.fetch(); // request method will be get unless the id attr is specified
//user1.destroy(); // request method will be Delete with id attr specified
In my CI REST controller
class User extends REST_Controller
{
public function index_get()
{
echo $this->get(null); //I can see the response data
}
public function index_post()
{
echo $this->post(null); //I can see the response data
}
public function index_put()
{
}
public function index_delete()
{
}
}
Basically, the get and post in the controller will be called when I save a model or fetch a model. With a id specified in the model, I can make a put or delete request to the server using model.save() and model.destroy(). however, I got a server error. it looks like index_put or index_delete can not be called. does anyone know How I can handle:
put request in the controller
delete request in the controller
get a single record with id specified
From the git, I only saw him to list index_post and index_put. there is no index_put and index_delete demo. should anyone can help me out? thanks
I faced the same exact problem, it looks like that DELETE, PUT, PATCH methods are not fully supported by browsers/html/server yet. You may want to look at this stack overflow question: Are the PUT, DELETE, HEAD, etc methods available in most web browsers?
A simple solution would be to change the methodMap of backbone line 1191 to the following:
// Map from CRUD to HTTP for our default `Backbone.sync` implementation.
var methodMap = {
'create': 'POST',
'update': 'POST', //'PUT',
'patch': 'POST', //'PATCH',
'delete': 'POST', //'DELETE',
'read': 'GET'
};
and then include the action type as an attribute of the model
var Person = Backbone.Model.extend({
defaults:{
action_type : null,
/*
* rest of the attributes goes here
*/
},
url : 'index.php/person'
});
now when you want to save a model, do the following
var person = new Person({ action_type: 'create' });
person.set( attribute , value ); // do this for all attributes
person.save();
in the application/controllers folder you should have a controller called person.php with class named Person extending REST_Controller, that has the following methods:
class Person extends REST_Controller {
function index_get() { /* this method will be invoked by read action */ }
/* the reason those methods are prefixed with underscore is to make them
* private, not invokable by code ignitor router. Also, because delete is
* might be a reserved word
*/
function _create() { /* insert new record */ }
function _update() { /* update existing record */ }
function _delete() { /* delete this record */ }
function _patch () { /* patch this record */ }
function index_post() {
$action_type = $this->post('action_type');
switch($action_type){
case 'create' : $this->_create(); break;
case 'update' : $this->_update(); break;
case 'delete' : $this->_delete(); break;
case 'patch' : $this->_patch(); break;
default:
$this->response( array( 'Action '. $action_type .' not Found' , 404) );
break;
}
}
}
Having said that, this solution is an ugly one. If you scroll up in the backbone implementation, you will find the following code at line 1160:
// For older servers, emulate HTTP by mimicking the HTTP method with `_method`
// And an `X-HTTP-Method-Override` header.
if (options.emulateHTTP && (type === 'PUT' || type === 'DELETE' || type === 'PATCH')) {
params.type = 'POST';
which means you need to set the emulate options of backbone configurations. add the following lines to your main.js
Backbone.emulateHTTP = true;
Backbone.emulateJSON = true;
To test the effect of that, I created a simple model and here are the results
you need a controller called Api in applications/controllers folder, in a file named api.php
<?php defined('BASEPATH') OR exit('No direct script access allowed');
require_once APPPATH.'/libraries/REST_Controller.php';
class Api extends REST_Controller
{
function index_get()
{
$this->response(array("GET is invoked"));
}
function index_put()
{
$this->response(array("PUT is invoked"));
}
function index_post()
{
$this->response(array("POST is invoked"));
}
function index_patch()
{
$this->response(array("PATCH is invoked"));
}
function index_delete()
{
$this->response(array("DELETE is invoked"));
}
}
and in your js/models folder, create a model called api_model.js
var Api = Backbone.Model.extend({
defaults:{
id: null,
name: null
},
url: "index.php/api/"
});
var api = new Api();
api.fetch({ success: function(r,s) { console.log(s); } }); // GET is invoked
api.save({},{ success: function(r,s) { console.log(s); } }); // POST is invoked
//to make the record old ( api.isNew() = false now )
api.save({id:1},{ success: function(r,s) { console.log(s); } }); // PUT is invoked
api.destroy({ success: function(r,s) { console.log(s); } }); //DELETE is invoked
I don't know how to do patch, but hope this helps.
Edit
I found out how to do patch, which is not included in the REST implementation of code ignitor. In REST_Controller line 39, you will find the following,
protected $allowed_http_methods = array('get', 'delete', 'post', 'put');
you need to add 'patch' at the end, to accept this method, also, after doing that add this code
/**
* The arguments for the PATCH request method
*
* #var array
*/
protected $_patch_args = array();
also, you need to add the following code to parse patch arguments:
/**
* Parse PATCH
*/
protected function _parse_patch()
{
// It might be a HTTP body
if ($this->request->format)
{
$this->request->body = file_get_contents('php://input');
}
// If no file type is provided, this is probably just arguments
else
{
parse_str(file_get_contents('php://input'), $this->_patch_args);
}
}
Now, according to backbone docs, you need to pass {patch: true} to send a PATCH method, when you call the following line, you execute a patch:
api.save({age:20},{patch: true, success: function(r,s) { console.log(s); } });
// PATCH is invoked

Resources