Toggle catalog mode in Prestashop based on user login status: logged in or unlogged

I am currently developing a PrestaShop module that allows users to switch the catalog mode on or off depending on whether they are logged in or not.

Everything is working well, but I have encountered an issue.

I want unlogged users to not be able to see prices or make orders. However, with the current solution I have implemented, when an unlogged user first loads the page (with the catalog mode off), the catalog mode turns on and they can see prices (they have to reload the page to hide the prices). So, the first load sets the catalog mode on and the second load displays the real catalog mode.

I have found a JavaScript script that auto-reloads the page to apply the new mode, but this results in the page loading time being twice as long.

Here is the function:

  public function hookHeader()
    {
      $logged = $this->context->customer->isLogged();
      if (!$logged) {
        Configuration::updateValue('PS_CATALOG_MODE', true);
      } else {
        Configuration::updateValue('PS_CATALOG_MODE', false);
      }
      // reload the page once more
      echo '
        <script type="text/javascript">
          (function() {
            if( window.localStorage ) {
              if( !localStorage.getItem( "firstLoad" ) ) {
                localStorage[ "firstLoad" ] = true;
                window.location.reload();
              } else {
                localStorage.removeItem( "firstLoad" );
              }
            }
          })();
        </script>
      ';
    }

I hope someone can assist me with resolving this issue. Thank you.

Answer №1

There seems to be an issue with your solution. By updating the value in the database directly, it can cause instability when multiple users are accessing the site simultaneously. The value may flip-flop between on and off states, creating an inconsistent experience for users.

A better approach would be to toggle the value on a per-customer basis. A suggested override for the Configuration class is provided, which checks if the customer is logged in and returns the appropriate value of 0 or 1. It's important to cache this value using static variables to avoid repetitive checks.

However, this solution also has its drawback as it checks the key of the request configuration variable each time.

An improved method would involve changing the value during the session itself. Configuration variables are stored in a PHP array during the session, allowing for direct manipulation at that level.

To implement this change, consider modifying the code at:

https://github.com/PrestaShop/PrestaShop/blob/1.6.1.x/classes/Configuration.php#L203

Possibly by overriding:

https://github.com/PrestaShop/PrestaShop/blob/1.6.1.x/classes/Configuration.php#L140

My suggestion for overriding loadConfiguration:

<?php

// placed in /override/classes/Configuration.php

class Configuration extends ConfigurationCore
{
    public static function loadConfiguration()
    {
        parent::loadConfiguration();
        // 'global' assumed since not running multishop
        self::$_cache[self::$definition['table']][0]['global']['PS_CATALOG_MODE'] = !Context::getContext()->customer->isLogged();
    }
}

Note that this was written from memory, so verify names and details. This is tailored for PS1.6 and later versions.

Answer №2

Have you considered utilizing the group settings feature? With customer group settings, you have the ability to adjust the visibility of prices by setting it to "false" for visitors and "true" for customers.

Answer №3

To address the issue at hand, gskema proposes a solution that involves overriding the get() function within the Configuration class:

<?php

// This code should be placed in /override/classes/Configuration.php

class Configuration extends ConfigurationCore
{
  public static function get($key, $id_lang = null, $id_shop_group = null, $id_shop = null)
  {
      if (defined('_PS_DO_NOT_LOAD_CONFIGURATION_') && _PS_DO_NOT_LOAD_CONFIGURATION_) {
          return false;
      }

      // Check if configuration is initialized, if not try manual query
      if (!isset(self::$_cache[self::$definition['table']])) {
          Configuration::loadConfiguration();
          if (!self::$_cache[self::$definition['table']]) {
              return Db::getInstance()->getValue('SELECT `value` FROM `'._DB_PREFIX_.bqSQL(self::$definition['table']).'` WHERE `name` = "'.pSQL($key).'"');
          }
      }
      $id_lang = (int)$id_lang;
      if ($id_shop === null || !Shop::isFeatureActive()) {
          $id_shop = Shop::getContextShopID(true);
      }
      if ($id_shop_group === null || !Shop::isFeatureActive()) {
          $id_shop_group = Shop::getContextShopGroupID(true);
      }

      if (!isset(self::$_cache[self::$definition['table']][$id_lang])) {
          $id_lang = 0;
      }

      if ($id_shop && Configuration::hasKey($key, $id_lang, null, $id_shop)) {
          if($key == 'PS_CATALOG_MODE' && Context::getContext()->controller->controller_type == 'front')
          {
              return !Context::getContext()->customer->isLogged() || self::$_cache[self::$definition['table']][$id_lang]['shop'][$id_shop][$key];
          } else {
              return self::$_cache[self::$definition['table']][$id_lang]['shop'][$id_shop][$key];
          }
      } elseif ($id_shop_group && Configuration::hasKey($key, $id_lang, $id_shop_group)) {
          if($key == 'PS_CATALOG_MODE' && Context::getContext()->controller->controller_type == 'front')
          {
              return !Context::getContext()->customer->isLogged() || self::$_cache[self::$definition['table']][$id_lang]['group'][$id_shop_group][$key];
          } else {
              return self::$_cache[self::$definition['table']][$id_lang]['group'][$id_shop_group][$key];
          }
      } elseif (Configuration::hasKey($key, $id_lang)) {
          if($key == 'PS_CATALOG_MODE' && Context::getContext()->controller->controller_type == 'front')
          {
              return !Context::getContext()->customer->isLogged() || self::$_cache[self::$definition['table']][$id_lang]['global'][$key];
          } else {
              return self::$_cache[self::$definition['table']][$id_lang]['global'][$key];
          }
      }
      return false;
  }
}

/!\ Note: The comparison of key values every time someone tries to retrieve a config variable may slightly slow down the shop.

EDIT

A condition has been added for when the Context is in the front office to resolve the back office issue regarding 'Call isLogged on NULL'.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

How can I invoke a personalized function in angularjs from HTML?

One way to organize methods within js controllers is by defining them separately like this: angular.module('test').controller('mycontroller', mycontroller); function mycontroller() { //do something }; function ...

Using PHP to identify the origin of a JavaScript file on a webpage

I have been attempting to locate an embedded stream link from a certain webpage. After inspecting the source code of the page, I found the following snippet: <script type='text/javascript'> swidth='640', sheight='460';& ...

The alignment of elements in the div seems to be slightly skewed

Currently, I am in the process of creating a website with the temporary name yeet.io. I am facing an issue where I am attempting to center both an input and h1 element inside a div vertically and horizontally, but they keep appearing misaligned for some r ...

Setting the maximum width in TinyMce

I have encountered an issue with TinyMce involving tables. When a user inserts a table that is larger than the main body layout, it causes the layout to become misaligned. Therefore, I am seeking the best solution to restrict users from inserting a table ...

Jstree's select_node function is failing to trigger

I am having an issue with the select_node.jstree function not firing properly. Below is the code snippet: $(document).ready(function () { //$("#MySplitter").splitter(); setupSplitter(); $("#divJsTreeDemo").jstree({ "themes": { "theme": "d ...

Shifting Angular Component Declarations to a New Location

Here's a question that might sound silly: In my Angular project, I am looking to reorganize my component declarations by moving them from angular.module.ts to modules/modules.modules.ts. The goal is to structure my src/app directory as follows: src ...

Retrieve the value from every dynamically generated text box by its corresponding number

Trying to create a new Online Quiz System. The challenge I'm facing is extracting the values of each option associated with a specific question number. For example: Question # 1: a. elephant b. lion c. zebra Question # 2: a. green b. ...

Toggle Jquery menu with a click of a button

I need help with creating a menu for a forum that opens on click and closes on click. Here is the code I have so far: /*Custom BBPress admin links menu*/ function wpmudev_bbp_admin_links_in_menu($retval, $r, $args) { if ( is_user_logged_in() ) { $me ...

Using Selenium with C# to find elements within a chart

I am trying to locate and interact with the stimulusFrequency circles on this chart so that I can click and drag them. <svg class="svg-graph-content graphEventHandler ng-valid" ng-model="hearingGraph" viewBox="0 0 470 355" preserveAspectRatio="none"> ...

Load JSON data in Javascript with the condition where the 'id' is equal to 'x'

I have a coding dilemma where I need to extract specific information from a .json file in JavaScript and load it into an array. function loadContacts(filter) { var contacts = (function () { var contacts = null; $.ajax({ 'asy ...

Using AngularJS to filter JSON data

Greetings! I possess the following JSON data: $scope.Facilities= [ { Name: "-Select-", Value: 0, RegionNumber: 0 }, { Name: "Facility1", Value: 1, RegionNumber: 1 }, { Name: ...

The toLowerCase method seems to be malfunctioning along with several other functions

JS var score = 0 var yes = "yes" var pokemonName = []; var bg = []; var index = 0; document.getElementById('repete').style.visibility = 'hidden'; (function asyncLoop() { background = bg[num = Math.floor(Math.random() ...

Look for a regular expression that matches numbers ranging from 1 to 31, either with or without a leading

I am in the process of setting up validation on an <input> element to prevent the user from inputting incorrect characters. Currently, I am utilizing ng-pattern for this purpose, which successfully restricts the user from entering invalid characters. ...

Adding an interactive element to a predetermined collection

CSS <button class='btn' data-next="games" data-prev="games1" data-storage="128" data-graphcard="2" data-processor="i3">Click Here</button> JavaScript. let components = ["storage", "graphcard", "processor"]; const allBtnsToStore = d ...

The successful execution of $.ajax does not occur

Starting out with ajax, I wanted to create a simple add operation. Here is the code that I came up with: HTML: <!doctype html> <html> <head> <title>Add two numbers</title> <meta content="text/html;charset=utf-8" h ...

Incorporate additional text to the downloads hyperlink using jquery

Is it possible to achieve this using jQuery since I am unable to directly modify the HTML markup? I am looking to append download.php?file= to a URL without replacing the entire href attribute. Here's an example of what I'm trying to achieve: & ...

Using jQuery: in the event that $(this) or a different element loses focus, then

I am looking to execute a function when either the currently active element $(this) or another specific element (e.g.: div#tooltip) loses focus. However, I have not been successful in finding the right approach. I have attempted the following: $(this).add ...

Images in Next.js are appearing as broken images on certain pages

When using Next Image, it functions correctly on files located in the root of the page folder. However, images appear broken when accessed from the sub-folder within the page folder. ...

I am getting NaN as the output from my function, but I am unsure of the reason behind

For pracitce, I have created this code to calculate the total amount spent on gas and food using arrays. However, I am encountering an issue where it is returning NaN. const gas = [20, 40, 100]; const food = [10, 40, 50]; function total(gas, food) { ...

Add elements to an array following an AJAX request

On my .cshtml page, I have the following script: $(function () { var tempArray = []; var tbValue = $('#tb1').val(); $.ajax({ url: "/ControllerName/getdata", dataType: 'json', ...