3

I have a Magento 2 website which has been set up to allow customers to have their own pricing. However, as a result of this the FPC (for category and product pages) is now being generated uniquely for each user.

To get round this, I want to load the price via Knockout JS so that the FPC can be shared across all logged in users, yet the pricing will be loaded dynamically depending on what pricing system that user has been assigned.

I started off by following this article: https://magently.com/blog/full-page-cache-hole-punching-in-magento-2/

I have been able to successfully configure the Knockout JS to render the 'timestamp' (from the above tutorial) on a category page and I have tested that the FPC is being shared across all logged-in users.

However, the problem I am now having is that I need to pass the product ID to the block, from the knockoutjs component so that I can use the class to return the correct price for that product. I have looked through various articles, questions on here etc. but can't seem to find an answer to this.

Here is the code:

Vendor/Module/CustomerData/CustomerPricing.php

<?php
namespace Vendor\Module\CustomerData;

use Magento\Customer\CustomerData\SectionSourceInterface;

class CustomerPricing implements SectionSourceInterface
{
    public function getSectionData()
    {
    return ['price' => 'XX.XX'];
    }
}

/Vendor/Module/etc/frontend/di.xml

<type name="Magento\Customer\CustomerData\SectionPoolInterface">
    <arguments>
        <argument name="sectionSourceMap" xsi:type="array">
            <item name="custom-price" xsi:type="string">
                Vendor\Module\CustomerData\CustomerPricing
            </item>
        </argument>
    </arguments>
</type>

Vendor/Module/view/frontend/js/customer-pricing.js

define([
  'uiComponent',
  'Magento_Customer/js/customer-data'
], function (Component, customerData) {
  return Component.extend({
    initialize: function (config) {
      this._super();
      this.privateVariable = customerData.get('custom-price');
      console.log("ProductID =",config.product_id);
    }
  });
});

Vendor/Module/view/frontend/templates/product/list.phtml

<div data-bind="scope: 'customer-pricing'">
    <span><?= __('£') ?></span>
    <span data-bind="text: privateVariable().price"><?= __("Loading...") ?></span>
</div>
<script type="text/x-magento-init">
{
  "*": {
    "Magento_Ui/js/core/app": {
      "components": {
      "customer-pricing": {
        "component": "Vendor_Module/js/customer-pricing",
        "product_id": "<?= $block->escapeJs($_product->getId()) ?>"
        }
      }
    }
  }
}
</script>
  • Can you share how you have implemented your solution so far please? As the answer may depend on that. Also, by product ID to the block, I presume you mean the layout XML block (template)? – Ben Crook Nov 5 '20 at 11:38
  • Hi Ben, added the code used. And no, I did not mean the XML block, I need to be able to access the product ID within PHP so that I can use it (along with the store ID and the user ID) to return the correct price to the customer. I haven't wrote this part yet, but If I cannot pass the ID of the product back to the PHP function, I cannot return the correct price. At the moment, the frontend is rendering XX.XX for the price, so the only thing that remains is to write the php to return the price, but I cannot do that without the ID. – Dean Morgan Nov 5 '20 at 11:59
  • I see, I think your best option is a Knockout observable and a PHP controller. So the JS will hit your controller passing in the data you need, and that controller will return the price, then in JS you update the KO observable to the price which will automatically update the frontend. I don't do much backend work so I can't advise on the controller sorry, this answer may help with the Knockout side though. – Ben Crook Nov 5 '20 at 12:56

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.