Codeigniter - detect the sender of a request - ajax

I'm building a commercial website, with a shopping cart.
On most pages (i.e - product page, category page), I want to display the cart contents on a sidebar, which will get updated via AJAX when an item is added to the cart.
On the "display cart" page I want to show a full version of the contents.
Obviously, it seems logical to use the same model and functions to get and/or update the cart, but send the data to a different view (sidebar or full cart), depending on the caller page.
The question is, in the cart model, how can I detect where did the request come from.
I thought I'd check if the request came via AJAX, like so:
if(!empty($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest') // i.e - the request came as AJAX
{
$this->load->view('cart_sidebar_view', $data);
}else{ /* not ajax */
$data['main_content'] = 'cart_view';
$this->load->view('includes/template', $data);
}
But that is not good enough, because I want to use AJAX on the "display cart" page as well, to allow updating the cart from there.
So, is there a way to detect, in the cart model, where did the request come from? Or will I have to send that info in a hidden form field with every "add to cart" or "remove" button?

There is a simple way. when you are sending request from the display cart page send an additional variable. Than in the controller check for this variable if variable is coming call a logic if variable is not coming do something else.
if($this->input->is_ajax_request())
{
$this->load->view('cart_sidebar_view', $data);
}else{
if($this->input->post('another_variable')){
// do something else
}else{
$data['main_content'] = 'cart_view';
$this->load->view('includes/template', $data);
}
}

Related

WooCommerce ajax add to cart variation

I am using this code to enable ajax add to cart on single product pages. I also have enables ajax in WooCommerce settings in Products tab:
Enable AJAX add to cart buttons on archives
This works well when I am on simple products.
add_action('woocommerce_before_single_product', 'wpv_remove_woocommerce_template_single_add_to_cart');
add_action('woocommerce_before_single_product', 'wpv_add_woocommerce_template_loop_add_to_cart');
function wpv_remove_woocommerce_template_single_add_to_cart(){
global $product;
if ($product->is_type('simple')) {
remove_action('woocommerce_single_product_summary', 'woocommerce_template_single_add_to_cart', 30);
}
}
function wpv_add_woocommerce_template_loop_add_to_cart(){
global $product;
if ($product->is_type('simple')) {
add_action('woocommerce_single_product_summary', 'woocommerce_template_loop_add_to_cart', 30);
}
}
However when I try to use add to cart on variable product I get 400 (Bad Request) ajax error. I cant really see in network panel what to look as reason.
I use default WordPress theme 2022, no other plugins. This only happens when I add this code above, it works without.

Prestashop: how to display messages in the cart

i'm working in a quota module for PrestaShop 1.6 and in one of the features is that a need to display a message in the cart's page and in that modal that opens when you add an item to the cart from the home page.
I'm working with the hookCart the hook function, public function hookCart($params), is in my module's class. From it I can get the instance of the Controller like this $this->context->controller
My question is how to display messages in these two views? I tried adding them to the errors array. I can see the message but not the way I'm supposed to display. I would like to display in those alert classes from bootstrap.
The views:
Can you help me?
To display a message on the checkout page you can use whatever front controller hook you want. I guess the one that makes most sense would be displayTop. We won't be outputting any html to the top but just add a message to the controller's errors array.
public function hookDisplayTop()
{
$controller = $this->context->controller;
if ($controller->php_self != 'order' && $controller->php_self != 'order-opc') {
return false;
}
/*
You can do custom logic here if you want to display message only
on some conditions or only on specific step of the checkout
*/
$controller->errors[] = $this->l('Some message');
return false;
}
For the popup the things get messy because:
Popup doesn't have an error display area
Blockcart AJAX uses weird logic that calls CartController which includes blockcart-ajax.php which loads blockcart module method which loads a JSON template file to output data (???)
One way to do this is to use the hook actionCartSave. This hook gets executed on pretty much all cart operations, so we need to make sure we are adding our message when a product is added to cart, uses ajax etc.
public function hookActionCartSave()
{
// If cart doesn't exist or product is not being added to cart in ajax mode - do nothing
if (!$this->context->cart || !Tools::getValue('id_product) || !Tools::getValue('add') || !Tools::getValue('ajax')) {
return false;
}
/*
You can do custom logic here if you want to display message only
on some conditions
*/
$this->context->smarty->assign('mycartpopupmessage', $this->l('Message');
return false;
}
Then you will have to modify themes/default-bootstrap/modules/blockcart/blockcart-json.tpl file to add your message into JSON template.
...
"wrappingCost": {$wrapping_cost|json_encode},
"nbTotalProducts": {$nb_total_products|intval},
"total": {$total|json_encode},
{if isset($mycartpopupmessage)}
"mycartpopupmessage": {$mycartpopupmessage|json_encode},
{/if}
....
Then you need to modify themes/default-bootstrap/js/modules/blockcart/ajax-cart.js and add the following
if (jsonData.mycartpopupmessage) {
$('#layer_cart .alert-message').html(jsonData.mycartpopupmessage);
$('#layer_cart .alert').removeClass('hidden');
}
else {
$('#layer_cart .alert').addClass('hidden');
}
And at last modify themes/default-bootstrap/modules/blockcart/blockcart.tpl
and add alert div
<div class="alert alert-danger hidden">
<button data-dismiss="alert" type="button" class="close">×</button>
<p>{l s='There is 1 error' mod='mymodule'}</p>
<ol>
<li class="alert-message"></li>
</ol>
</div>
Now you should be getting a bootstrap alert inside a popup.
Quite some native prestashop modules haven't been (I guess) updated in years as a lot of them are good candidates for an extensive rework or at least compliant with the MVC workflow which would make modifications like yours much more simple.

How to disable cart page from showing coupon notice when adding coupons with ajax?

I am adding coupons in woocommerce programmatically, and is working quite fine via ajax from another page, not the checkout page. However, everytime I go to the checkout page, it says, "Coupon has been applied", but I already applied the coupon from a different page. How do I disable this message from showing when going to the checkout page, after I have performed my ajax for applying a coupon dynamically? Is there some sort of setting or function to call to disable this message from showing on the cart page when a coupon has already been applied from an ajax function?
Here's my php for applying the coupon via ajax from a separate page (not the checkout page):
if (!WC()->cart->add_discount( sanitize_text_field( $coupon_code )))
{
$notices = wc_get_notices();
if (!empty($notices) && isset($notices['error'])) {
$last_fail = end($notices['error']);
echo $last_fail;
}
die();
}
else
{
$notices = wc_get_notices();
// Get last element of array only!
if (!empty($notices) && isset($notices['success'])) {
$last_success = end($notices['success']);
echo $last_success;
}
die();
}
And this works fine. As you can see, I grab errors and have them returned within the response of the ajax call, and output errors that way. I also output something for success, which is fine. The problem I'm having is that after this function executes via ajax, and I browse to the checkout page to see my product and coupon code that was applied, it puts notice at the top of the page, saying "Coupon applied Successfully." and I don't want this notice to appear, but I don't want to get rid of all notices, just this one, if the coupon was not applied on the checkout page, there is no need for this wc_notice to appear when browsing to the checkout page.
How to tell woocommerce not to apply this coupon notice to the checkout page when I browse to the checkout page after adding coupons manually from another page (via ajax)?
You can use the "woocommerce_coupon_message" filter to hide the success message for the coupon. As you want to remove it for checkout page only, just check if current page is checkout page or not.
You can use the following code :
function remove_msg_filter($msg, $msg_code, $this){
if(is_checkout()){
return "";
}
return $msg;
}
add_filter('woocommerce_coupon_message','remove_msg_filter',10,3);
Note : If you also want to change message for error then use "woocommerce_coupon_error" filter.
The way to fix this is to add wc_clear_notices(); before die(); in the function call, so as to remove all notices that the function add_discount adds to the array that gets returned from wc_get_notices() function call.
if (!WC()->cart->add_discount( sanitize_text_field( $coupon_code )))
{
$notices = wc_get_notices();
if (!empty($notices) && isset($notices['error'])) {
$last_fail = end($notices['error']);
echo $last_fail;
}
wc_clear_notices();
die();
}
else
{
$notices = wc_get_notices();
// Get last element of array only!
if (!empty($notices) && isset($notices['success'])) {
$last_success = end($notices['success']);
echo $last_success;
}
wc_clear_notices();
die();
}
This way may be a bit of a lazy way of approaching this. But if you inspect element of the page, find the message, target it and add 'display:none;' in the CSS.
That should do the trick. Try and make it specific for that page only. A unique class is usually page-id found at the top of the page in inspect element

how to use last insert id when redirect same form page in codeigniter

I just try to prevent re submission problem when refresh form page. so I use session flashdata() method and redirect same form page. but I want also display recent inputed data on form VIEW page. then I am try $this->db->insert_id() on my form VIEW page . but it always show 0. how can I solve it?
when you redirect the user after the successful form submission then add the parameter in the url just a exapmle with dummy code to make an idea for you
$insertedid=$this->my_model->add_info();
//your add_info() should return the inserted id
redirect("/myformcontroller/myformpage/".$this->db->insert_id());// add id in redirect url
on your myformcontroller controller's myformpage function
function myformpage() {
$insertedid=$this->url->segment(3);
if(!empty($insertedid)){
//get new added information and pass it to view
}
// your other code
}
hope it makes sense

Magento Auto Add Items Based on Quantity

I'm designing a custom product page with a button that when clicked I need to have an alert come up with a "Yes" or "No" option.
If "Yes" is selected I then need the following to happen.
Add another product into the cart based on the products quantity i.e. between 1 & 2 items add product A between 3 & 4 Items product B, between 5 & 12 product C and so on.
Any idea of the best way to accomplish this?
It has to be a alert style popup (ajax popup preferred) cannot be a checkbox on the product page.
Thanks!
So I've come across a solution to my problem... I'm using a Simple Modal (That TheBlackBenzKid hinted me to) that I'm either going to call from a custom button or with the add to cart button. This in turn will redirect to a php page that will redirect to the cart. For the php page I'll just include the code to put a item into the cart from there anyone could figure out how to customize it to there own needs.
<?php
// Include Magento application (URL to Mage.php)
require_once ( "app/Mage.php" );
umask(0);
//specified quantity my own variable I'm using for quantities
$spqty = 9;
// Initialize Magento
Mage::app("default");
// You have two options here,
// "frontend" for frontend session or "adminhtml" for admin session
Mage::getSingleton("core/session", array("name" => "frontend"));
$session = Mage::getSingleton("customer/session");
// get the current Magento cart
$cart = Mage::getSingleton('checkout/cart');
if ($spqty <= 2) {
// insert item to cart where "98" is the product ID (NOT SKU!) Where "2" is the quantity
$cart->addProduct(98, array('qty' => 2));
} elseif ($spqty >= 4 ){
// you can add multiple products at the same time by adding this line multiple times
$cart->addProduct(96, array('qty' => 3));
}
// save the cart
$cart->save();
// very straightforward, set the cart as updated
Mage::getSingleton('checkout/session')->setCartWasUpdated(true);
// redirect to index.php
header("Location: index.php/checkout/cart");
I also found some of this information from this guys blog I'll link to the article
How to add a product from an external site into Magento
I'm happy to answer any questions on this...
This is not the best answer, but code to get you started:
You could make the cart function use:
<input type="button" onClick="javascript:nValidateForm();"/>
And your form code:
<form name="m2mform" id="m2mform" method="post" onSubmit="javascript:nValidateForm();">
And then just call an external JavaScript in your page XML headers and add it to cart so that JS file will always be checked and validate the popup.

Resources