Javascript events cart.updated params.notify undefined

  • Posts: 231
  • Thank you received: 28
  • Hikashop Business
2 years 1 month ago #345158

-- HikaShop version -- : 4.6.2
-- Joomla version -- : 3.10.11

Hi, this is what I get when I use params.notify in javascript events when I add a product in cart

if (window.Oby) {
    window.Oby.registerAjax(["cart.updated"], function (params) {
    console.log(params.notify); // undefined
}

This is the output for console.log(params);
{
   "id":36053,
   "el":{
      "uid:0":"j"
   },
   "product_id":"2266",
   "type":"cart",
   "resp":{
      "products":[
         {
            "product_id":2266,
            "cart_product_id":44412,
            "quantity":3,
            "product_name":"Product name"
         }
      ],
      "ret":36053,
      "product_id":2266,
      "cart_product_id":44412,
      "product_name":"Product name",
      "quantity":3,
      "image":"/images/img_produse/incarca/thumbnails/50x50/barcode.png"
   }
}

Last edit: 2 years 1 month ago by oxido. Reason: Details added

Please Log in or Create an account to join the conversation.

  • Posts: 82863
  • Thank you received: 13372
  • MODERATOR
2 years 1 month ago #345164

Hi,

Thank you for your feedback. Indeed, the wording in the developer documentation was not accurate. I've updated the text there for that event.

Please Log in or Create an account to join the conversation.

  • Posts: 231
  • Thank you received: 28
  • Hikashop Business
2 years 1 month ago #345176

Thank you for clariffications nicolas.
I have one more question, it is possible to recive more details in the resp.products, like resp.product.price ?
Now I'm working on a plugin to integrate newsman remarketing, and price it is a required info.
Thank you.

Please Log in or Create an account to join the conversation.

  • Posts: 82863
  • Thank you received: 13372
  • MODERATOR
2 years 1 month ago #345180

Hi,

There is no option for that at the moment.
What you can do is add the code:

JPluginHelper::importPlugin('hikashop');
$app = JFactory::getApplication();
$app->triggerEvent('onGetCartProductsInfo', array(&$cart, &$ret) );
at the end of the function getCartProductsInfo, just before the line:
return $ret;
in the file administrator/components/com_hikashop/classes/cart.php
That way, in your plugin, you can implement the onGetCartProductsInfo event to add things you need in $ret. What is in $ret will be what the javascript sees in params.resp.products

We'll add that code on our end for the next version of HikaShop because I think it will be useful in the future. So you won't have to worry about it.

The following user(s) said Thank You: oxido

Please Log in or Create an account to join the conversation.

  • Posts: 231
  • Thank you received: 28
  • Hikashop Business
2 years 1 month ago #345634

Hi,
I don't know if I should create a new topic or to continue here with the JS events :silly: , for now, I will continue here.

In the checkout the cart.updated is not called when I remove a product from cart, I know that for the checkout checkout.cart.updated it is the evenet that is triggered, but this event it doese't have any paramater regarding the product that was removed from the cart, same thing with cart.empty.

cart.updated get triggered only if the product it is removed from cart using the cart module.
In my remarketing implementation, I need to know the id and quantity of the product I remove from cart.

Thank you for your time.

Attachments:

Please Log in or Create an account to join the conversation.

  • Posts: 82863
  • Thank you received: 13372
  • MODERATOR
2 years 1 month ago #345639

Hi,

It would require calculating the changes in the function validate of the file administrator/components/com_hikashop/helpers/checkout.cart.php in order to add the extra information in $eventParams before the call to the addEvent function.
I guess it will be a few dozen lines of PHP.
If you write them, we can integrate them.

The following user(s) said Thank You: oxido

Please Log in or Create an account to join the conversation.

  • Posts: 231
  • Thank you received: 28
  • Hikashop Business
2 years 1 month ago #345652

administrator/components/com_hikashop/helpers/checkout/cart.php *, right?

Please Log in or Create an account to join the conversation.

  • Posts: 82863
  • Thank you received: 13372
  • MODERATOR
2 years 1 month ago #345655

yes

Please Log in or Create an account to join the conversation.

  • Posts: 231
  • Thank you received: 28
  • Hikashop Business
2 years 1 month ago #345659

Nicolas, when I dump($cart) in validate function I have this (I will paste only what I think is needed)
SdClass Object (cart)

 [array] cart_products
- [stdClass object] 44691
--Properties
 ---[string] cart_id = "36063"
 ---[integer] cart_product_id = 44691
 ---[integer] cart_product_modified = 1665653737
 ---[integer] cart_product_option_parent_id = 0
 ---[integer] cart_product_parent_id = 0
 [---[integer] cart_product_quantity = 4
 ---[string] cart_product_ref_price = "9.00000"
 ---[integer] product_id = 2300
.
.
.
 [array] products
- [stdClass object] 44691
--Properties
 ---[array] all_prices
 ---[string] cart_product_id = "44691"
 ---[string] cart_product_option_parent_id = "0"
 ---[string] cart_product_parent_id = "0"
 ---[string] cart_product_quantity = "4"
 ---[integer] cart_product_total_quantity = 4
 ---[integer] cart_product_total_variants_quantity = 4
 ---[stdClass object] old
 ----Properties
 -----[integer] quantity = 4  // <==== Isn't this supposed to be the old quantity of the product, before the product in the basket is updated?

Attachments:

Please Log in or Create an account to join the conversation.

  • Posts: 82863
  • Thank you received: 13372
  • MODERATOR
2 years 1 month ago #345664

Hi,

You should make a copy of $cart->products before the line $ret = $cartClass->updateProduct($cart->cart_id, $items); like this:
$oldProducts = hikashop_copy($cart->products);

Then, before the addEvent, you can compare $oldProducts and $cart->products

The following user(s) said Thank You: oxido

Please Log in or Create an account to join the conversation.

  • Posts: 231
  • Thank you received: 28
  • Hikashop Business
2 years 1 month ago #345762

Hi nicolas,
this is what I've managed to do, now in the javascript function checkout.cart.updated, in the params object is this new object, product.
Now, we get all the properties of that product, like... all even the custom fields.
Should I customize the objct, to contain only some of the properties?
Like price, category, quantity, and a new extra property I've added "action".
The action property can be:
qty_update: when only the quantity of one product was changed.
removed_product: when a product was removed from cart
last_product: when the last product from cart was removed.

Let me know if you have any suggestion, thank you!

	public function validate(&$controller, &$params, $data = array()) {
		if(empty($data))
			$data = hikaInput::get()->get('checkout', array(), 'array');
		if(empty($data['cart']))
			return true;
		if(empty($data['cart']['item']))
			return false;

		$items = array();
		foreach($data['cart']['item'] as $k => $v) {
			if((int)$v == 0 && !is_numeric($v))
				continue;
			$items[] = array(
				'id' => (int)$k,
				'qty' => (int)$v
			);
		}
		if(empty($items))
			return true;

		$checkoutHelper = hikashopCheckoutHelper::get();
		$cart = $checkoutHelper->getCart();

		$msg_cpt = !empty($cart->messages) ? count($cart->messages) : 0;

		$cartClass = hikashop_get('class.cart');
                
                $oldProducts = hikashop_copy($cart->products);
                
		$ret = $cartClass->updateProduct($cart->cart_id, $items);

		$cart = $checkoutHelper->getCart(true);

		if(empty($cart->products)) {
			$checkoutHelper->redirectBeforeDisplay = JText::_('CART_EMPTY');
		}

		if(!$ret && !empty($cart->messages) && count($cart->messages) > $msg_cpt) {
			return false;
		}

		if(!$ret)
			return true;

                // OLD VS NEW  CART======================== START
                $oldProductsCounter = count($oldProducts);
                $ProductsCounter = count($cart->products);
                $modifiedProduct = array();
                if($oldProductsCounter == $ProductsCounter){
                    // only quantity was modifyed
                    foreach($cart->products AS $c => $c_value){
                        // get only the modified product
                        if($c_value->cart_product_quantity != $oldProducts[$c]->cart_product_quantity){
                            $modifiedProduct[$c]=$c_value;
                            $modifiedProduct[$c]->old->quantity = $oldProducts[$c]->cart_product_quantity;
                            $modifiedProduct[$c]->action='qty_update';
                        }
                    }                    
                }else if($oldProductsCounter > $ProductsCounter and $ProductsCounter > 0){
                    // a product was removed from cart
                    foreach($oldProducts AS $o => $o_value){
                        if(!isset($cart->products[$o])){
                            $modifiedProduct[$o] = $o_value;
                            $modifiedProduct[$o]->action = 'removed_product';
                        }
                    }
                }else if(empty($cart->products)){
                    // the last product was removed from cart
                    foreach($oldProducts AS $o => $o_value){
                        $modifiedProduct[$o]=$o_value;
                        $modifiedProduct[$o]->action='last_product';
                    }
                }
              // OLD VS NEW  CART======================== END

		if(!empty($params['src']['context']) && $params['src']['context'] == 'submitstep') {
			$checkoutHelper->addMessage('cart.updated', array(
				JText::_('CART_UPDATED'),
				'success'
			));
		}

		$eventParams = null;
		if(!empty($params['src']))
			$eventParams = array('src' => $params['src'],'product'=>$modifiedProduct);
		$checkoutHelper->addEvent('checkout.cart.updated', $eventParams);
		return true;
	}

Please Log in or Create an account to join the conversation.

  • Posts: 82863
  • Thank you received: 13372
  • MODERATOR
2 years 1 month ago #345769

Hi,

That looks fine. Thanks for sharing your code. We'll include it for the next version of HikaShop.

The following user(s) said Thank You: oxido

Please Log in or Create an account to join the conversation.

  • Posts: 231
  • Thank you received: 28
  • Hikashop Business
2 years 1 month ago #345784

Nicolas, are you gonna allow all the attributes of that product to be returned by the function or are you gonna reduce to a shorter version of the list?
I need to know because I need to continue my work with the remarketing plugin ::silly::
Thank you!

This message contains confidential information

Please Log in or Create an account to join the conversation.

  • Posts: 82863
  • Thank you received: 13372
  • MODERATOR
2 years 1 month ago #345789

We'll keep everything. I don't see a problem with that.

The following user(s) said Thank You: oxido

Please Log in or Create an account to join the conversation.

  • Posts: 231
  • Thank you received: 28
  • Hikashop Business
2 years 1 month ago #345835

Hi nicolas,

I have one more issue with the js events :whistle:

From the code I made, the last condition it is running on the server side, but because the cart it is empty now, the checkout.cart.update event it is not triggered anymore and the one that is running is cart.empty and againe, this event does not have any params about the last product which was in cart.

Thank you!

Please Log in or Create an account to join the conversation.

  • Posts: 82863
  • Thank you received: 13372
  • MODERATOR
2 years 1 month ago #345846

Hi,

For this, you need two modifications:
1. In the same file, you want to add:
$checkoutHelper->modifiedProduct = $modifiedProduct;
before the line:
$checkoutHelper->redirectBeforeDisplay = JText::_('CART_EMPTY');
(and make sure that $modifiedProduct is generated before that.

2. In the components/com_hikashop/controllers/checkout.php view file, you want to change the line:
$checkoutHelper->addEvent('cart.empty', null);
to:

				$eventParams = null;
				if(!empty($checkoutHelper->modifiedProduct))
					$eventParams = array('src' => $content['params']['src'], 'product' => $checkoutHelper->modifiedProduct);
				$checkoutHelper->addEvent('cart.empty', $eventParams);

We'll add the changes on our end.

The following user(s) said Thank You: oxido

Please Log in or Create an account to join the conversation.

  • Posts: 231
  • Thank you received: 28
  • Hikashop Business
2 years 4 weeks ago #345938

Hi, nicolas

When I remove a product from cart using the cart module, in the javascript params I don't get any info about the product that was removed from cart.
I think I need to do the same think for js function cart.updated as I did for checkout.cart.updated. To compare the old cart with the new one, and to add the info in about the deleted product to params.resp.deleted_product.
Where I can do that?
I was looking to add the information using onGetCartProductsInfo(&$cart, &$ret) in my plugin, but the inside this function I have only the new cart.

Thank you!

Last edit: 2 years 4 weeks ago by oxido.

Please Log in or Create an account to join the conversation.

  • Posts: 82863
  • Thank you received: 13372
  • MODERATOR
2 years 4 weeks ago #345942

Hi,

What you can do is implement onAfterCartLoad(&$cart, &$options) in your plugin to store a copy of the cart in $this->oldCart when loaded before it is updated so that when the event onGetCartProductsInfo is called, you can compare the old one in $this->oldCart to $cart.

The following user(s) said Thank You: oxido

Please Log in or Create an account to join the conversation.

  • Posts: 231
  • Thank you received: 28
  • Hikashop Business
2 years 4 weeks ago #346036

Hi,
This last question it is not really about the javascript events, but it can be if we do it :silly:, but I wanted to keep the discussion in the same place, because it is related with the plugin I create and with the previous questions. I hope it is okay.
So now, in the last step, I need to get all the informations about the order that was created.
First I was thinking to use onAfterOrderConfirm function, but I saw that the function is not triggered, and I found this:
The onAfterOrderConfirm trigger is a trigger only available for payment plugins and which will be called only for the payment plugin that has been selected by the customer. #211085 (in my opinion, this should be in the documentations ;) )
So because my plugin is not a payment plugin, and it will not be used by the client, I can't use onAfterOrderConfirm in my plugin.

Now I'm think that my next best options are onAfterOrderCreate and onAfterOrderUpdate(&$order,&$send_email).
So basically, now I have to check if inside the onAfterOrderCreate(&$order,&$send_email) the status of the order is confirmed and do my things here.
Or, to do the same thing in onAfterOrderUpdate(&$order,&$send_email), when the status is changed manualy in the administrator, but is this gonna work if the status it is changed by the payment confirmation?
Can we push this as a javascript event with params, or can you suggest another approach?

What I need to do is to run some JS with that information from the order, I run js on every situations I discused untill now , when add a product in cart, when remove, when change quantity and when I place the order now.
Example:

_nzm.run( 'require', 'ec');
_nzm.run( 'set', 'currencyCode', 'EUR' );
_nzm.run( 'ec:addProduct', {
  'id': 'product_id',
  'name': 'product_name',
  'price': '84.00',
  'quantity': '1'
} );
_nzm.run( 'ec:setAction', 'purchase', {
  'id': '758',
  'revenue': '84.00',
  'tax': '0',
  'shipping': '4.00'
} );
_nzm.run('send', 'pageview');
Thank you for your time!

Please Log in or Create an account to join the conversation.

  • Posts: 82863
  • Thank you received: 13372
  • MODERATOR
2 years 3 weeks ago #346044

Hi,

Well, the short answer is that it depends on the payment plugins you're using.
When onAfterOrderUpdate is called, you might not be able to output any javascript.
For example, when the PayPal plugin changes the status of the order to "confirmed", after the payment is received for it, the HTTP request for the payment notification is sent by the PayPal servers. So if you output javascript code, it will be the PayPal server receiving it and it won't do anything with it.
And the bad news is that most payment plugins (payment gateways in fact) work like this.
If you implement onAfterOrderCreate, then with the PayPal plugin, the order is not yet paid, so you might count for an order which actually won't be paid.

A solution, supposing you're using the default thank you page of HikaShop, is to implement the event onHikashopOrderTrackingDisplay(&$order) in a plugin where you can directly echo your JS inside a script tag so it will appear on the thank you page of the user. However, it's not 100% accurate. If the user is not redirected automatically to your website after the payment, or if he closes his browser/tab before, his order won't be accounted for.

Looking at kb.newsman.ro/remarketing-javascript-api-pentru-dezvoltatori/ I can see it's based on Google Analytics' API.
In order to solve that issue, GA has implemented the "measurement protocol":
developers.google.com/analytics/devguide...lection/protocol/v1/
With it, you can implement onAfterOrderCreate and onAfterOrderUpdate, check the status, and send a cURL request to GA to notify it of the purchase. This works 100% of the time. That's actually what we've implemented in the GA plugin included in HikaShop.
But I don't know if your tracking solution offers that capability ?

The following user(s) said Thank You: oxido

Please Log in or Create an account to join the conversation.

Time to create page: 0.063 seconds
Powered by Kunena Forum