如何仅显示每个属性

How to show only per attribute

我正在尝试使用 PRESTASHOP 开一家眼镜店,但我遇到了一个问题。我在 产品和客户 table 中创建了 4 个新列(左眼屈光度、右眼屈光度、鼻梁长度、腿长), 在 tables.

中相同

我想做的是当商店加载产品时,比较这些变量,如果它们相同则显示产品。这是为了尝试过滤眼镜给客户,只给他看适合他的眼镜。

原查询是下一个:

$sql = 'SELECT p.*, product_shop.*, stock.out_of_stock, IFNULL(stock.quantity, 0) AS quantity'.(Combination::isFeatureActive() ? ', IFNULL(product_attribute_shop.id_product_attribute, 0) AS id_product_attribute,
                    product_attribute_shop.minimal_quantity AS product_attribute_minimal_quantity' : '').', pl.`description`, pl.`description_short`, pl.`available_now`,
                    pl.`available_later`, pl.`link_rewrite`, pl.`meta_description`, pl.`meta_keywords`, pl.`meta_title`, pl.`name`, image_shop.`id_image` id_image,
                    il.`legend` as legend, m.`name` AS manufacturer_name, cl.`name` AS category_default,
                    DATEDIFF(product_shop.`date_add`, DATE_SUB("'.date('Y-m-d').' 00:00:00",
                    INTERVAL '.(int)$nb_days_new_product.' DAY)) > 0 AS new, product_shop.price AS orderprice
                FROM `'._DB_PREFIX_.'category_product` cp
                LEFT JOIN `'._DB_PREFIX_.'product` p
                    ON p.`id_product` = cp.`id_product`
                '.Shop::addSqlAssociation('product', 'p').
                (Combination::isFeatureActive() ? ' LEFT JOIN `'._DB_PREFIX_.'product_attribute_shop` product_attribute_shop
                ON (p.`id_product` = product_attribute_shop.`id_product` AND product_attribute_shop.`default_on` = 1 AND product_attribute_shop.id_shop='.(int)$context->shop->id.')':'').'
                '.Product::sqlStock('p', 0).'
                LEFT JOIN `'._DB_PREFIX_.'category_lang` cl
                    ON (product_shop.`id_category_default` = cl.`id_category`
                    AND cl.`id_lang` = '.(int)$id_lang.Shop::addSqlRestrictionOnLang('cl').')
                LEFT JOIN `'._DB_PREFIX_.'product_lang` pl
                    ON (p.`id_product` = pl.`id_product`
                    AND pl.`id_lang` = '.(int)$id_lang.Shop::addSqlRestrictionOnLang('pl').')
                LEFT JOIN `'._DB_PREFIX_.'image_shop` image_shop
                    ON (image_shop.`id_product` = p.`id_product` AND image_shop.cover=1 AND image_shop.id_shop='.(int)$context->shop->id.')
                LEFT JOIN `'._DB_PREFIX_.'image_lang` il
                    ON (image_shop.`id_image` = il.`id_image`
                    AND il.`id_lang` = '.(int)$id_lang.')
                LEFT JOIN `'._DB_PREFIX_.'manufacturer` m
                    ON m.`id_manufacturer` = p.`id_manufacturer`
                WHERE product_shop.`id_shop` = '.(int)$context->shop->id.'
                    AND cp.`id_category` = '.(int)$this->id
                    .($active ? ' AND product_shop.`active` = 1' : '')
                    .($front ? ' AND product_shop.`visibility` IN ("both", "catalog")' : '')
                    .($id_supplier ? ' AND p.id_supplier = '.(int)$id_supplier : '');

我正在尝试修改它,但我不太清楚如何修改。因此,我做错了事。我已将下一个左连接添加到查询中。

LEFT JOIN `'._DB_PREFIX_.'product_attribute` pa ON pa.`id_product` = p.`id_product`
LEFT JOIN `'._DB_PREFIX_.'product_attribute_combination` pac ON pac.`id_product_attribute` = pa.`id_product_attribute`
LEFT JOIN `'._DB_PREFIX_.'attribute` attr ON attr.`id_attribute` = pac.`id_attribute`
LEFT JOIN `'._DB_PREFIX_.'attribute_lang` attr_lang ON (attr_lang.`id_attribute` = pac.`id_attribute` AND attr_lang.`id_lang` = '.(int)$id_lang.')LEFT JOIN `'._DB_PREFIX_.'attribute_group` attr_group ON attr_group.`id_attribute_group` = attr.`id_attribute_group`
LEFT JOIN `'._DB_PREFIX_.'attribute_group_lang` attr_group_lang ON attr_group_lang.`id_attribute_group` = attr.`id_attribute_group`

感谢您的任何建议。

编辑:

产品的新字段是 prestashop 中的功能(产品中没有 table),请原谅我的错误。

我放了prestashop的数据模型供你参考。

编辑 2:

我现在正在尝试通过使用一个模块来实现这一点,所以我的模块的 php 文件有下一个代码。我已经按照 CategoryController.php 中的代码进行操作,但我不知道如何在不满足条件的情况下删除产品。

<?php

if (!defined('_PS_VERSION_'))
    exit;

class glassOptics extends Module
{
    /* @var boolean error */
    protected $_errors = false;

    public function __construct()
    {
        $this->name = 'glassOptics';
        $this->tab = 'front_office_features';
        $this->version = '1.0';
        $this->author = 'MAOL';
        $this->need_instance = 0;

        parent::__construct();

        $this->displayName = $this->l('glassOptics');
        $this->description = $this->l('...');
    }

    public function install()
    {
        if (!parent::install() OR
            !$this->veopticasCustomerDB('add') OR
            !$this->veopticasProductDB('add') OR            
            !$this->registerHook('hookActionProductListOverride')
            return false;
        return true;
    }

    public function uninstall()
    {
        if (!parent::uninstall() OR !$this->veopticasCustomerDB('remove') OR !$this->veopticasProductDB('remove'))
            return false;
        return true;
    }


    public function veopticasCustomerDB($method)
    {
        switch ($method) {
            case 'add': 
                $sql = 'CREATE TABLE IF EXISTS `'._DB_PREFIX_.'customer_optics_data` (
                `id_customer` int(10) UNSIGNED NOT NULL,
                `left_dioptrics` decimal(20,6) NOT NULL DEFAULT '0.000000',
                `right_dioptrics` decimal(20,6) NOT NULL DEFAULT '0.000000',
                `bridge` decimal(20,6) NOT NULL DEFAULT '0.000000',
                `leg` decimal(20,6) NOT NULL DEFAULT '0.000000',
                `glass_width` decimal(20,6) NOT NULL DEFAULT '0.000000',
                `glass_height` decimal(20,6) NOT NULL DEFAULT '0.000000'
                ) ENGINE='._MYSQL_ENGINE_.' DEFAULT CHARSET=utf8';

                break;

            case 'remove':
                $sql = 'DROP TABLE IF EXISTS `'._DB_PREFIX_ . 'customer_optics_data`';
                break;
        }

        if(!Db::getInstance()->Execute($sql))
            return false;
        return true;
    }

    public function veopticasProductDB($method)
    {
        switch ($method) {
            case 'add': 
                $sql = 'CREATE TABLE IF EXISTS `'._DB_PREFIX_.'product_optics_data` (
                `id_product` int(10) UNSIGNED NOT NULL,
                `left_dioptrics` decimal(20,6) NOT NULL DEFAULT '0.000000',
                `right_dioptrics` decimal(20,6) NOT NULL DEFAULT '0.000000',
                `bridge` decimal(20,6) NOT NULL DEFAULT '0.000000',
                `leg` decimal(20,6) NOT NULL DEFAULT '0.000000',
                `glass_width` decimal(20,6) NOT NULL DEFAULT '0.000000',
                `glass_height` decimal(20,6) NOT NULL DEFAULT '0.000000'
                ) ENGINE='._MYSQL_ENGINE_.' DEFAULT CHARSET=utf8';

                break;

            case 'remove':
                $sql = 'DROP TABLE IF EXISTS `'._DB_PREFIX_ . 'product_optics_data`';
                break;
        }

        if(!Db::getInstance()->Execute($sql))
            return false;
        return true;
    }


    public function hookActionProductListOverride($params)
    {
        $customer_settings = glassOptics::getCustomerSettings($this->context->customer);

        if ($customer_settings) {
            // Inform the hook was executed
            $params['hookExecuted'] = true;

            // Filter products here, you are now overriding the default
            // functionality of CategoryController class.
            // You can see blocklayered module for more details.

            if ((isset($this->context->controller->display_column_left) && !$this->context->controller->display_column_left)
            && (isset($this->context->controller->display_column_right) && !$this->context->controller->display_column_right))
            return false;

            global $smarty;
            if (!Configuration::getGlobalValue('PS_LAYERED_INDEXED'))
                return;

            $categories_count = Db::getInstance()->getValue('
                SELECT COUNT(*)
                FROM '._DB_PREFIX_.'layered_category
                WHERE id_category = '.(int)Tools::getValue('id_category', Tools::getValue('id_category_layered', Configuration::get('PS_HOME_CATEGORY'))).'
                AND id_shop = '.(int) Context::getContext()->shop->id
            );

            if ($categories_count == 0)
                return;


            // List of product to overrride categoryController
            $params['catProducts'] = array();
            $selected_filters = $this->getSelectedFilters();
            $filter_block = $this->getFilterBlock($selected_filters);
            $title = '';

            if (is_array($filter_block['title_values']))
                foreach ($filter_block['title_values'] as $key => $val)
                    $title .= ' > '.$key.' '.implode('/', $val);

            $smarty->assign('categoryNameComplement', $title);
            $this->getProducts($selected_filters, $params['catProducts'], $params['nbProducts'], $p, $n, $pages_nb, $start, $stop, $range);
            // Need a nofollow on the pagination links?
            $smarty->assign('no_follow', $filter_block['no_follow']);

            foreach ($params['nbProducts'] as $product) {

                $product_settings = glassOptics::getProductSettings($product);

                if($product_settings){
                    $same_bridge            = ($product_settings->bridge == $customer_settings->bridge ? true : false);
                    $same_leg           = ($product_settings->leg == $customer_settings->leg ? true : false);
                    $same_glass_width   = ($product_settings->glass_width == $customer_settings->glass_width ? true : false);
                    $same_glass_heigth      = ($product_settings->glass_heigth == $customer_settings->glass_heigth ? true : false);
                }

            }

        }
    }
}

我建议采用不同的方法并为此使用模块。您将创建一个模块,该模块在安装时会创建一个 table_ 类似 customer_optics_data 的东西。 Table 结构可能如下所示:

CREATE TABLE `'._DB_PREFIX_.'customer_optics_data` (
  `id_customer` int(10) UNSIGNED NOT NULL,
  `left_eye_diopter` int(10) UNSIGNED NOT NULL,
  `right_eye_diopter` int(10) UNSIGNED NOT NULL,
  `bridge_length` decimal(20,6) NOT NULL DEFAULT '0.000000',
  `leg_length` decimal(20,6) NOT NULL DEFAULT '0.000000'
) ENGINE='._MYSQL_ENGINE_.' DEFAULT CHARSET=utf8;

然后您的模块将挂接到 actionProductListOverride 挂钩,这就是您执行检查的地方:

public function hookActionProductListOverride($params)
{
    $customer_settings = MyDiopterModuleHelperClass::getCustomerSettings($this->context->customer);

    if ($customer_settings) {
        $params['hookExecuted'] = true;

        // Filter products here, you are now overriding the default
        // functionality of CategoryController class.
        // You can see blocklayered module for more details.
    }
}

该模块将有一个助手 class MyDiopterModuleHelperClass 用于注册和获取数据 to/from customer_optics_data table。 这样您就不会覆盖核心,您的更新仍将正常运行,可能发生的最糟糕的事情是如果挂钩突然从 PrestaShop 的未来版本中删除,这是不太可能的。

该模块还将使用以下挂钩:

  • displayCustomerIdentityForm - 在 My Personal information 中显示附加字段。这是您的客户输入模块信息的地方。

  • actionObjectCustomerAddAfter - 在这里您可以从 $_POST 获取数据并将其保存在模块的 table

  • actionObjectCustomerUpdateAfter - 如果数据已被客户更改,您将在此处更新数据,或者如果由于某种原因数据不存在,则插入数据。

可选地,您也可以将模块挂接到 displayAdminCustomersForm - 在后台显示 customers 表单中的附加字段。