2016-04-11 4 views
0

Я пытаюсь сделать магазин оптики с PRESTASHOP, но у меня возникла проблема. Я создал 4 новых столбца в Таблица продуктов и клиентов (диоптрий левого глаза, диоптрий с правым глазом, длина моста, длина ноги), то же самое в обеих таблицах.Как показать только по атрибуту

Что я хочу сделать, когда магазин загружает продукты, сравнивает эти переменные, и если они одинаковы, тогда покажите продукт. Это попытка фильтровать очки клиенту, только показывая ему очки, которые совместимы с ним.

Исходный запрос является следующим:

$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` 

Благодарим за любые советы.

EDIT:

Новые поля продукции являются особенности внутри PrestaShop (есть не в таблицу продукта) извините за ошибку.

Я разместил модель данных prestashop для вашей информации.

DataModel

EDIT 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); 
       } 

      } 

     } 
    } 
} 
+0

Показать схему базы данных пожалуйста. –

+0

@davidstrachan Я только что добавил данные, чтобы знать отношения. Я покрасил таблицы, которые нужно объединить. – MAOL

+0

Вы не должны связываться с базой данных базы данных, это приведет к сбоям обновлений для вас. Почему вы не можете просто добавить две дополнительные таблицы, такие как 'customer_diopter' и' product_diopter', а затем использовать встроенный механизм переопределения, чтобы изменить способ выбора продуктов? Или еще лучше - избавиться от 'product_diopter' все вместе, заменить его функциями/атрибутами и построить простой фильтр, который будет принимать значения клиента из вашей таблицы' customer_diopter' и выбирать продукты, имеющие соответствующие функции? – Eihwaz

ответ

2

Я бы рекомендовал использовать другой подход и использовать для этого модуль. Вы должны создать модуль, который при установке создает таблицу_ что-то вроде customer_optics_data. Структура таблицы может выглядеть следующим образом:

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. 
    } 
} 

модуль будет иметь вспомогательный класс MyDiopterModuleHelperClass что необходимо зарегистрировать и получить данные в/из таблицы customer_optics_data. Таким образом, вы не переопределяете ядро, ваши обновления по-прежнему будут работать нормально, самое худшее, что может случиться, - это если крючок внезапно удален из будущих версий PrestaShop, что маловероятно.

Модуль также использовать следующие перехватчики:

  • displayCustomerIdentityForm - отображение дополнительных полей в My Personal information. Здесь ваши клиенты будут вводить свою информацию для модуля.

  • actionObjectCustomerAddAfter - это где вы бы получать эти данные из $_POST и сохранить его в таблице модуля

  • actionObjectCustomerUpdateAfter - это где вы бы обновить данные, если он был изменен заказчиком или вставить данные если по какой-то причине его там нет.

При желании можно также подключить модуль на displayAdminCustomersForm - для отображения дополнительных полей в форме customers в вашем бэк-офисе.

+0

Привет, @Eihwaz, я редактировал свое сообщение, чтобы добавить код моего модуля. Мне удалось добраться до случая, когда условия выполнены, но я не знаю, как удалить/удалить/скрыть продукты, которые не соответствуют условиям. Во всяком случае, я не знаю, правильный ли исходный код или нет, я еще не смог его протестировать. Не могли бы вы взглянуть? благодаря – MAOL