I am developing a plugin in which I get data from API, and then the user has an option to add this data to the cart and purchase the product. Everything works perfectly, except once we reload the page, the user cart value gets lost. How can I solve this?
I think one solution is, If we add the cart object to the session, it will be easy to use that session value to get the cart object. For this, I added the below function
my_file.js
function savecartObj(cartObj) {
$.post(
'cartObj.php',
{
cartobj : cartObj
},
function success(data) {
console.log(data);
}
);
}
and in my cartObj.php
<?php
/** Set up WordPress environment, just in case */
$path = preg_replace('/wp-content(?!.*wp-content).*/','',__DIR__);
require_once($path.'wp-load.php');
session_id() || session_start();
nocache_headers();
$_SESSION['ajjx'] = $_POST;
$value = '';
if (array_key_exists('ajjx', $_SESSION)) {
if (array_key_exists('cartobj', $_SESSION['ajjx']) {
$value = $_SESSION['ajjx']['cartobj'];
}
}
Header('Content-Type: application/json;charset=utf8');
die(json_encode(array(
'result' => $_SESSION['ajjx']['cart_obj'],
)));
Now I can see that $_SESSION['ajjx']['cart_obj'] is set and in console.log(data); I can see the session value. How can i use this value from $_SESSION['ajjx']['cartobj'] as cartobj in my_file.js
What I need is will create one file named get_session.php and in
that file, I will call the value of $_SESSION['ajjx']['cart_obj'] .
And then once my plugin is loaded I will call the value in
get_session.php & need to take the obj from the file and then add that value to add to cart function in the my_file.js. In that way, page reload doesn't
affect my cart.
Update
For getting the value I write the following function in my my_file.js
function get_cartObj(){
$.post(
'get_cartObj.php',
function success(data) {
console.log(data);
}
);
}
and in get_cartObj.php
<?php
/** Set up WordPress environment, just in case */
$path = preg_replace('/wp-content(?!.*wp-content).*/','',__DIR__);
require_once($path.'wp-load.php');
session_id() || session_start();
nocache_headers();
Header('Content-Type: application/json;charset=utf8');
json_encode(array(
'result' => $_SESSION['ajjx']['cart_obj'], // This in case you want to return something to the caller
));
but here get_cartObj() is not working as expected. No data coming in console.log(data);
The same way you saved it. Actually you can add a parameter to (save)CartObj:
function cartObj(operation, cartObj) {
$.post(
'cartObj.php',
{
op : operation,
cartobj : cartObj
},
function success(data) {
console.log(data);
}
);
}
and in the PHP code (7.4+ required because of the ?? operator)
if ($_POST['operation'] === 'set') {
$_SESSION['ajjx']['cartObj'] = $_POST['cartObj'] ?? [ ];
}
$value = $_SESSION['ajjx']['cartObj'] ?? [ ];
Header('Content-Type: application/json;charset=utf8');
die(json_encode(['result' => $value]));
Now calling the function with 'set' will save the Javascript cart into session, using 'get' will recover the cart.
update
You can also do it like this:
assuming that your page might receive a cart or it might not,
and you will always run the same AJAX code regardless,
then the PHP code must avoid removing the cart if the cartObj parameter is empty (you will need a different call to remove the cart when you need to do this; or you may do it from PHP).
session_id()||session_start();
if ('set' === $_POST['operation'] && !empty($_POST['cartObj'])) {
$_SESSION['ajjx']['cartObj'] = $_POST['cartObj'];
}
Header('Content-Type: application/json;charset=utf8');
die(json_encode(['result'=>$_SESSION['ajjx']['cartObj']??[]]));
This way, if you reload the page but the POSTed cart is now empty (because it's a reload), the AJAX script will not update the session, and it will return the previous session value.
Before im going to answer the question i have some dubt to clear, it looks like you are in a wordpress environment but you are not using his AJAX standard procedures. Check it out here https://codex.wordpress.org/AJAX_in_Plugins
About the issue since JS is client side and PHP is server side you need something to have the values available in JS. I can think of two option:
Print into the page with some PHP a little script tag which is made like this:
<script>
var myObjectVar = '<?php echo json_encode($_SESSION['ajjx']['cart_obj']); ?>';
</script>
You make a new AJAX call as soon as the page load to read that same value from PHP again and then use it to make what you need to do
Related
I have a Model Class which has a function which takes an array of filenames as an argument. It runs a foreach on the files and processes them.
The 1st line of the foreach is $_SESSION["file_processing"] = $file;
I have a js function that is called periodically and fetches $_SESSION["file_processing"] and outputs it in a div. This is how i plan to show to the user what file is being processed at the moment.
My js Functions :
function call_files_all_together() {
alert("You will start getting emails for all files. Thanks !");
var log = setInterval(function(){ProcessingFilesLog()},5000);
$("#ajax-loader-gif").html("<img src = \"/images/ajax-loader.gif\" />");
$.ajax({
type : 'POST',
url : '/query-set/create-all-files/'
}).done(function(data) {
alert(data);
clearInterval(log);
$("#ajax-loader-gif").empty();
});
}
function ProcessingFilesLog() {
console.log("get log called");
$.ajax({
type : 'POST',
url : '/query-set/file-log'
}).done(function(data){
console.log(data);
if(data != "")
$("#files-log").append(data + "<br/>");
else
console.log("empty data");
});
}
My controller function is below :
public function createAllFilesAction() {
$this->_helper->viewRenderer->setNoRender();
$this->_helper->layout->disableLayout();
$qs = new Model_QuerySet;
$qs->createAllFiles();
echo "Files Sent!";
// unset($_SESSION["file_processing"]);
}
public function FileLogAction() {
$this->_helper->viewRenderer->setNoRender();
$this->_helper->layout->disableLayout();
$log = $_SESSION["file_processing"] ;
var_dump($_SESSION);
echo $log;
}
My Model Functions :
public function createAllFiles() { #all
$db = Zend_Db_Table::getDefaultAdapter();
$ex = new Model_ExcelHandling;
foreach ($this->filename as $name=>$data){
echo $name.PHP_EOL;
$_SESSION["file_processing"] = $name;
//Do my things here.
}
}
The 1st time I run the script, I do not see the key "file_processing" in the $_SESSION array. The second time I run it, I see that $_SESSION["file_processing"] holds the value of last file that was processed when executed previously.
I seems like $_SESSION gets updated only after the loop ends or something down those line, I am not 100% sure.
I would appreciate any help..
Thank you
The $_SESSION variable is only updated after the script finishes, according to php.net:
Session data is usually stored after your script terminated without the need to call session_write_close(), but as session data is locked to prevent concurrent writes only one script may operate on a session at any time. When using framesets together with sessions you will experience the frames loading one by one due to this locking. You can reduce the time needed to load all the frames by ending the session as soon as all changes to session variables are done.
You will need to use something other than $_SESSION to persistently store the data, because I don't believe you can get $_SESSION to save multiple times for in a single script/request. One possible solution is to save the data in a database. It is up to you to figure out which persistent storage method you wish to use.
EDIT:
I may have spoken too soon. Perhaps you can use session_write_close() and then follow it up with session_start() after each assignment to the $_SESSION variable.
I need an assistance on how to transfer this value $row[COMPONENT] in my class1.php into another page process_class.php with jQuery using post method.
i did this but it seems doesnt work ,
$('.cuttingCheckbox').change(function() {
if (this.checked) {
$.post('process_class.php',
{ comp : $($row[COMPONENT]).val(), comp_id : $($row[ID]).val() },
function(response) {
this.setAttribute("disabled", true), alert(comp,comp_id); });
}
});
Does anyone willing to help me ?
you can save that $row[COMPONENT] into session like this:
$_SESSION['row_component'] = $row[COMPONENT];
and in your next page, you just retrieve it:
$row = $_SESSION['row_component'];
As Jonast said (thanks dude), you should initiate the session first at the top of your php file: session_start();
This is my first attempt at trying to update a database with ajax & wordpress. I am trying to set a field to a status of 'complete' when a link is clicked. Everything seems to go fine, I get a "200 ok" response from the console, and the jQuery even shows the success actions that I'm taking. However the php doesn't update the database. The proper variables are being echoed out to the console, so I know those are being set correctly. I don't know if it's my MySQL query that I'm trying or if there's something that I'm overlooking. Any help or suggestions would be greatly appreciated.
Here's my jQuery:
// Click to Complete Activity Functionality
jQuery(".complete-activity").click( function( e ) {
e.preventDefault();
nonce = jQuery(this).attr("data-nonce")
wp_user_id = jQuery(this).attr("wp_user_id")
activity_post_id = jQuery(this).attr("activity_post_id")
wp_user_id = parseInt(wp_user_id);
activity_post_id = parseInt(activity_post_id);
console.log('My wp user id is: ' + wp_user_id);
console.log('My Activity id is: ' + activity_post_id);
jQuery.ajax({
type : "post",
url : myAjax.ajaxurl,
data : {
action: "gw_complete_activity",
"wp_user_id" : wp_user_id,
"activity_post_id" : activity_post_id,
"nonce" : nonce
},
success: function(response) {
console.log('Your field has been set as completed');
jQuery('li#active-'+ activity_post_id).css('display', 'none');
}
})
}) // End click to complete activity
Here's my php code:
<?php
//Complete Activity in Database (AJAX)
add_action("wp_ajax_gw_complete_activity", "gw_complete_activity");
add_action("wp_ajax_nopriv_gw_complete_activity", "my_must_login_to_complete");
function gw_complete_activity() {
if ( !wp_verify_nonce( $_REQUEST['nonce'], "gw_complete_activity")) {
exit("No naughty business please");
}
$wp_user_id = $_REQUEST['wp_user_id'];
$activity_post_id_complete = $_REQUEST['activity_post_id'];
$date_completed = current_time('mysql', 1);
global $wpdb;
$wpdb->update (
'wp_gwactivities',
array( 'date_completed' => $date_completed, 'activity_status' => 'complete'),
array( 'wp_user_id' => $wp_user_id)
);
if(!empty($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest') {
$result_add = json_encode($result_add);
echo $result_add;
}
else {
header("Location: ".$_SERVER["HTTP_REFERER"]);
}
die();
}
function my_must_login_to_complete() {
echo "You must be logged in to complete your activities.";
die();
}
?>
Just because you get a 200 (OK) from the requested page, doesn't mean the requested page didn't error out :) Secondly, it looks like this is going to be used in Wordpress... with that said, you can't use add_action without having wordpress loaded.
For files outside the normal wordpress install, you need to include wp-load.php include "/path/to/wordpress/wp-load.php", for example. Then you can use its functions.
After your update query ,put below code and check query in mysql directly.
print_r($wpdb->last_query);
provide your query here also if its not work.
I have the following javascript loop which correctly alerts the value I need to use in a Codeigniter method. Here is the js loop:
function myInsert(){
$('input[name=r_maybe].r_box').each(function(){
if( $(this).prop('checked') ){
// need to replace this alert with codeigniter method below
alert ($(this).prop('value'));
}
});
}
Instead of alerting the required value, I need to somehow execute this Codeigniter method:
//this would never work because it mixes JS with PHP, but I need a workaround
$this->appeal_model->myMethod($(this).prop('value'), 888, 999);
Is there someway that I can run this PHP code inside the javascript loop? I know about PHP being server-side and JS being client-side, but I'm sure there must be a solution to my problem that I'm just not aware of yet. Thanks.
The solution to this is to make an ajax call to the server, you can have a method on your controller which calls your codeigniter method. This divides your php call and your client side call.
If you are inserting something into the database, you should use the ajax post method.
http://api.jquery.com/jQuery.post/
function myInsert() {
$('input[name=r_maybe].r_box').each(function(){
if( $(this).prop('checked') ){
var value = $(this).prop('value');
$.post("controllername/functionname", { value: value }, function(data) {
alert(data); // Returned message from the server
});
}
});
}
Use ajax to store data to the server side:
The code should be something like this:
function myInsert(){
$dataArray=[];
$('input[name=r_maybe].r_box').each(function(){
if( $(this).prop('checked') ){
// need to replace this alert with codeigniter method below
dataArray.push($(this).prop('value'))
}
});
if(dataArray.length>0)
{
$.ajax({
url:"your file name",//this file should contain your server side scripting
type:"POST",
data:{dataName : dataArray}
success:function(){
}
});
}
}
you can use $.post from jquery
function myInsert(){
$('input[name=r_maybe].r_box').each(function(){
if( $(this).prop('checked') ){
$.post('<?php echo site_url("controllerName/functionName")?>',
{"post1": $(this).prop('value'), "post2":888, "post3": 999 },
function(data.res == "something"){
//here you can process your returned data.
}, "json"); //**
}
});
}
In your controller you can have:
function functionName()
{
//getting your posted sec token.
$post1 = $this->input->post('post1');
$post2 = $this->input->post('post2');
$post3 = $this->input->post('post3');
$data['res'] = "something";// return anything you like.
// you should use json_encode here because your post's return specified as json. see **
echo json_encode($data); //$data is checked in the callback function in jquery.
}
Since this will be dumping data directly into your db, make sure this is secured in some manner as well, in terms of who has access to that controller function and the amount of scrubbing/verification done on the data being passed.
I have a jQuery code that is going to check when the user is near the bottom of the page. That's not the problem though. This jQuery is going to send a AJAX request, giving it some details on what to load when the user is near the bottom of the page. The code looks a bit like this at the moment:
$("<div>").load('?ajax=y&offset=something', function() {
$(".empty-div").append($(this));
setTimeout(function(){ console.log('after', $(document).height()); }, 0);
setTimeout(function(){ console.log('after', $(window).height()); }, 0);
});
My main problem is that I don't know what to query or how to go about sending the information to the PHP function in functions.php. For example, I have at the moment this as my PHP function (until it's working):
function get_posts_page() {
if(isset($_GET['offset'])) {
echo"Hello!";
}
}
I'm aware the wordpress has add_action and all that but I have no idea what I would apply as an action to either function to make the PHP recieve the data the Javascript is sending. Is there a URL where all functions are parsed or something? Thanks for any help in advance. So how do I get the data from the Javascript to the PHP function in functions.php, in my theme directory?
I just made a video to show you how to use the add_action request in WordPress. You can watch it here.
Here's my javascript
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.4.3/jquery.min.js"></script>
<script>
$('#branding img').click(function() {
$.post('<?php bloginfo('siteurl') ?>/wp-admin/admin-ajax.php', {
action: 'my_unique_action',
offset: 5
}, function(data) {
$('#content').prepend('<p>' + data + '</p>');
});
});
</script>
And the php that I used in functions.php
// Make sure it runs when the user is logged in,
// and when they are not.
add_action('wp_ajax_my_unique_action', 'get_offset');
add_action('wp_ajax_nopriv_my_unique_action', 'get_offset');
function get_offset() {
if( isset($_POST['offset']) ) {
echo 'Your ajax request was successful. Here was your offset: <strong>' . $_POST['offset'] . '</strong>';
}
die;
}
Reference: http://codex.wordpress.org/AJAX_in_Plugins
You're trying to call a PHP function from Javascript, correct?
You'll need some logic on some page which calls get_posts_page(). Either you can create a new page getPostsPage.php?offset= or you can put some logic in functions.php, something like
if(isset($_GET['function']) {
switch($_GET['function']) {
case 'get_posts_page':
get_posts_page();
}
}
However, the former approach is recommended; you don't want someone to be able to modify the function parameter and access deleteAllPosts() maliciously.
Therefore:
// getPostsPage.php
require PATH . 'functions.php';
get_posts_page(); //checks $_GET['offset']
And remember to fail gracefully (do not expose an error message) if 'offset' is not set, or whatever.