Prestashop 设置目录模式 ON/OFF 如果用户 unlogged/logged

Prestashop set catalog mode ON/OFF if user unlogged/logged

我正在使用 prestashop module 来设置目录 mode 在用户未登录或登录时打开或关闭。

效果很好,但遇到了问题。

我根本不希望未登录的用户看到价格并允许其订购。但是根据我发现的解决方案,当第一次连接(mode 目录关闭)未登录的用户加载页面时,目录 mod 打开,但他可以看到价格(必须重新加载以隐藏价格)所以,第一次加载设置目录 mode ON,第二次加载显示真实目录 mode。

我找到了一个 js 脚本,可以自动重新加载以使用新的 mode 生效,但显然,页面的加载时间要长两倍。

函数如下:

  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>
      ';
    }

希望有人能帮我解决这个问题。谢谢你。

你的解决方案有问题。 您正在更新数据库中的值:如果多个用户正在浏览该站点,则该值将变成 on/off/on/off/...,换句话说就是 "unstable"。 访问该站点的下一位客户将获得当前值(可以打开和关闭)。

相反,您应该仅为该客户切换值。我为 Configuration class 写了一个覆盖,检查你是否试图获取 PS_CATALOG_MODE,然后检查你是否登录和 returns 0 or 1 .小心使用 static 变量缓存此值(这样您就不必多次检查)。

但是这个解决方案也有一个缺陷。它每次都会检查请求配置变量的键。

更好的解决方案是在会话期间更改 this 的值。在会话期间,配置变量实际上保存在 PHP 数组中。 您应该在此处更改它:

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

可能通过覆盖

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

这是我通过重写想到的 loadConfiguration:

<?php

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

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

我从记忆中写了这篇文章,所以一定要检查 anmes 等。我假设你是 运行 > PS1.6

你为什么不直接使用组设置?例如,客户组设置允许您将访问者的 "show prices" 选项设置为 "false",而客户则设置为 "true"。

我们用 gskema 找到的解决方案是重写配置的 get() 函数 class :

<?php

// 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;
      }

      // If conf if not initialized, 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;
  }
}

/!\ 每次有人尝试获取配置变量时仍会比较键值,这可能会稍微减慢商店的速度。

编辑

如果上下文是前台,则添加条件以解决后台问题'Call isLogged on NULL'