Для Prestashop 1.4.x: 1.Установить модуль через админку; 2.Из паки override/controllers скопировать файл AuthController.php в папку ваш_магазин/override/controllers на хостинге; 3.Из папки YOUR_THEME/modules/bkockuserinfo скопировать файл blockuserinfo.tpl в папку ваш_магазин/themes/ваша_тема/modules/bkockuserinfo на хостинге; в файле ваш_магазин/themes/ваша_тема/authentication.tpl после строки PHP: {include file="$tpl_dir./breadcrumb.tpl"} добавить PHP: {$HOOK_AUTH} Настроить модуль из админки Для Prestashop 1.5.x: 1.Установить модуль через админку; 2.В файле ваш_магазин/themes/ваша_тема/authentication.tpl после строки PHP: {include file="$tpl_dir./breadcrumb.tpl"} добавить PHP: {hook h='auth'} Если хотите добавить авторизацию/регистрацию через социальные сети на странице оформления заказа (one page checkauth) в файле ваш_магазин/themes/ваша_тема/order-opc-new-account.tpl после строки PHP: {l s='New Customer'} добавить PHP: {hook h='auth'} 3.Настроить модуль из админки Для Prestashop 1.6.x: 1.Установить модуль через админку; 2.В файле ваш_магазин/themes/ваша_тема/authentication.tpl перед строкой PHP: {include file="$tpl_dir./errors.tpl"} добавить PHP: {hook h='auth'} Если хотите добавить авторизацию/регистрацию через социальные сети на странице оформления заказа (one page checkauth) в файле ваш_магазин/themes/ваша_тема/order-opc-new-account.tplпосле строки PHP: {l s='New Customer'} добавить PHP: {hook h='auth'} 3.Настроить модуль из админки
В классе Tools.php замените функцию str2url на PHP: public static function str2url($str) { if (function_exists('mb_strtolower')) $str = mb_strtolower($str, 'utf-8'); // fix if (preg_match('/[а-я]+/', $str)) $cyr = array('а', 'б', 'в', 'г', 'д', 'е', 'ё', 'ж', 'з', 'и', 'й', 'к', 'л', 'м', 'н', 'о', 'п', 'р', 'с', 'т', 'у', 'ф', 'х', 'ц', 'ч', 'ш', 'щ', 'ъ', 'ы', 'ь', 'э', 'ю', 'я', ' '); $lat = array('a', 'b', 'v', 'g', 'd', 'e', 'yo', 'zh', 'z', 'i', 'y', 'k', 'l', 'm', 'n', 'o', 'p', 'r', 's', 't', 'u', 'f', 'h', 'c', 'ch', 'sch', 'sh', '', 'y', '', 'e', 'yu', 'ya', '-'); $str = @str_replace($cyr, $lat, $str); // fix $str = trim($str); $str = preg_replace('/[\x{0105}\x{0104}\x{00E0}\x{00E1}\x{00E2}\x{00E3}\x{00E4}\x{00E5}]/u','a', $str); $str = preg_replace('/[\x{00E7}\x{010D}\x{0107}\x{0106}]/u','c', $str); $str = preg_replace('/[\x{010F}]/u','d', $str); $str = preg_replace('/[\x{00E8}\x{00E9}\x{00EA}\x{00EB}\x{011B}\x{0119}\x{0118}]/u','e', $str); $str = preg_replace('/[\x{00EC}\x{00ED}\x{00EE}\x{00EF}]/u','i', $str); $str = preg_replace('/[\x{0142}\x{0141}\x{013E}\x{013A}]/u','l', $str); $str = preg_replace('/[\x{00F1}\x{0148}]/u','n', $str); $str = preg_replace('/[\x{00F2}\x{00F3}\x{00F4}\x{00F5}\x{00F6}\x{00F8}\x{00D3}]/u','o', $str); $str = preg_replace('/[\x{0159}\x{0155}]/u','r', $str); $str = preg_replace('/[\x{015B}\x{015A}\x{0161}]/u','s', $str); $str = preg_replace('/[\x{00DF}]/u','ss', $str); $str = preg_replace('/[\x{0165}]/u','t', $str); $str = preg_replace('/[\x{00F9}\x{00FA}\x{00FB}\x{00FC}\x{016F}]/u','u', $str); $str = preg_replace('/[\x{00FD}\x{00FF}]/u','y', $str); $str = preg_replace('/[\x{017C}\x{017A}\x{017B}\x{0179}\x{017E}]/u','z', $str); $str = preg_replace('/[\x{00E6}]/u','ae', $str); $str = preg_replace('/[\x{0153}]/u','oe', $str); // Remove all non-whitelist chars. $str = preg_replace('/[^a-zA-Z0-9\s\'\:\/\[\]-]/','', $str); $str = preg_replace('/[\s\'\:\/\[\]-]+/',' ', $str); $str = preg_replace('/[ ]/','-', $str); $str = preg_replace('/[\/]/','-', $str); // If it was not possible to lowercase the string with mb_strtolower, we do it after the transformations. // This way we lose fewer special chars. $str = strtolower($str); return $str; }
Модуль экспорта выдает таблицу с дублями товаров где указаны id товара, id дубля товара и наименование товара. Возможен случай, что это разные товары, но с одинаковым наименованием. В этом случае просто переименуйте товар, чтобы не было дубля по наименованию. Возможен вариант, когда действительно товары дублируются. Разберем на примере Постельное белье "Карвен" Т015 к которому относятся id 6 и 19. Для начала, отключите ЧПУ на сайте. Далее откройте любую карточку товара в адресную строку вместо 800, как на примере подставляем наши значения 6 и 19 Далее необходимо либо переименовать товар, либо удалить через админку модуля синхронизации ввев id товара и нажав конпку "Удалить товар"
МойСклад принимает и автоматически все статусы заказов которые есть в ИМ синхронизируються все заказы с ИМ у которых нет финального статуса (статусы с id = 5 и id =6). При создании по заказу в МС приходного кассового ордера ( Документ "Входящий платеж" либо "приходный кассовый ордер") МС автоматически согласно протокола обмена в определенный в настройках синхронизации интервал времении "сообщит" ИМ о поступлении платежа, и в ИМ изменится статус заказа на "Оплата получена". Статус в МС поменяется не сразу, а только через еще один интервал обмена данными ИМ сообщит МС о смене статуса. При создании по заказу в МС отгрузки МС автоматически согласно протокола обмена в определенный в настройках синхронизации интервал времении "сообщит" ИМ о отгрузке товара, и в ИМ изменится статус заказа на "Доставлен" и при последующих обменах этот заказ обрабатываться не будет. После этого в Мс нужно вручную изменить статус на "проведен"
Доступ к полям "CommerceML id" категорий для Prestashop 1.6 (возможно 1.5, не проверялось) Необходимо внести небольшие, интуитивно-понятные изменения в два файла стандартной поставки. Файл classes/Category.php 1. было: PHP: /** @var string Name */ public $name; /** @var boolean Status for display */ стало: PHP: /** @var string Name */ public $name; public $xml; /** @var boolean Status for display */ 2. было: PHP: 'date_add' => array('type' => self::TYPE_DATE, 'validate' => 'isDate'), 'date_upd' => array('type' => self::TYPE_DATE, 'validate' => 'isDate'), // Lang fields стало: PHP: 'date_add' => array('type' => self::TYPE_DATE, 'validate' => 'isDate'), 'date_upd' => array('type' => self::TYPE_DATE, 'validate' => 'isDate'), 'xml' => array('type' => self::TYPE_STRING, 'validate' => 'isGenericName', 'size' => 36), // Lang fields Файл controllers/admin/AdminCategoriesController.php 1. (видимость ГУИД-а в таблице категорий) было: PHP: 'name' => array( 'title' => $this->l('Name') ), 'description' => array( 'title' => $this->l('Description'), стало: PHP: 'name' => array( 'title' => $this->l('Name') ), 'xml' => array( 'title' => $this->l('CommerceML id') ), 'description' => array( 'title' => $this->l('Description'), 2. (доступ к редактированию ГУИД-а) было: PHP: 'class' => 'copy2friendlyUrl', 'hint' => $this->l('Invalid characters:').' <>;=#{}', ), array( 'type' => 'switch', 'label' => $this->l('Displayed'), стало: PHP: 'class' => 'copy2friendlyUrl', 'hint' => $this->l('Invalid characters:').' <>;=#{}', ), array( 'type' => 'text', 'label' => $this->l('CommerceML id'), 'name' => 'xml' ), array( 'type' => 'switch', 'label' => $this->l('Displayed'), Редактирование УИД-ов увлекатеельное занятие Для доступа к к аналогичным полям товаров написан бесплатный модуль, кторый можно скачать на сайте
Для того чтобы импортировать из интернет-магазина комментарии к заказу клиента, а также комментарии сотрудников интернет магазина добавьте в МС в форме заказов пользовательские поля "Комментарий клиента" и Комментарий менеджера"
Если не инсталлируется и не работает как модуль , то делаем по инструкции: - Удаляем файл: /cache/class_index.php - Выполняем SQL запрос: Код: "ALTER TABLE ps_feature_product DROP PRIMARY KEY, ADD PRIMARY KEY(`id_feature`, `id_product`, `id_feature_value`)" - Загружаем папку _override
Ошибка в 1С означает, что был не выставлен GUID типа цены по умолчанию в настройках модуля синхронизации и был запущен обмен с 1С. После получения такой ошибки, в модуле синхронизации заполняется таблица дополнительных цен, по данным пришедших с 1С и вам останется только выбрать тип цены по умолчанию из выпадающего списка
Установка ionCube PHP Loader Установка ionCube PHP loader достаточно проста, для этого вам необходимо скачать данный модуль соответствующий архитектуре Вашей ОС с сайта разработчика IonCube. Пример представлен по установке IonCube Loader на Debian 6.0 x86_64: Скачиваем архив с сайта разработчика следующей командой: Код: wget http://downloads2.ioncube.com/loader_downloads/ioncube_loaders_lin_x86-64.tar.gz Распаковываем архив выполнив команду: Код: # tar -xvf ioncube_loaders_lin_x86-64.tar.gz Смотрим версию PHP командой: Код: php -v PHP 5.3.3-7+squeeze3 with Suhosin-Patch (cli) (built: Jun 28 2011 08:24:40) Copyright (c) 1997-2009 The PHP Group Zend Engine v2.3.0, Copyright (c) 1998-2010 Zend Technologies Копируем модули соответствующие версии PHP на сервере в директорию с модулями php или создаем отдельную директорию ioncube/ и копируем в нее (в данном случае мы создали отдельную директорию для модуля), следующей командой: Код: # cp ioncube/ioncube_loader_lin_5.3.so /usr/lib/php5/ioncube/ # cp ioncube/ioncube_loader_lin_5.3_ts.so /usr/lib/php5/modules/ Добавляем в файл php.ini или создаем отдельный файл ioncube.ini, в данном примере создаем отдельный файл в /etc/php5/conf.d/ioncube.ini и добавляем следующие строки: Код: #vi /etc/php5/conf.d/ioncube.ini zend_extension = /usr/lib/php5/modules/ioncube_loader_lin_5.3.so zend_extension_ts = /usr/lib/php5/modules/ioncube_loader_lin_5.3_ts.so Cохраняем изменения в файле и перезагружаем web-сервер Apache: Код: # /etc/init.d/apache2 restart Проверяем результат установки модуля: Код: # php -m ... [Zend Modules] Zend Guard Loader the ionCube PHP Loader или Код: #php -v PHP 5.3.3-7+squeeze3 with Suhosin-Patch (cli) (built: Jun 28 2011 08:24:40) Copyright (c) 1997-2009 The PHP Group Zend Engine v2.3.0, Copyright (c) 1998-2010 Zend Technologies with the ionCube PHP Loader v4.2.0, Copyright (c) 2002-2012, by ionCube Ltd., and with Zend Guard Loader v3.3, Copyright (c) 1998-2010, by Zend Technologies with Suhosin v0.9.32.1, Copyright (c) 2007-2010, by SektionEins GmbH Установка IonCube Loader на FreeBSD 8.3 x86_64: Скачиваем с сайта модуль подходящий для нашей архитектуры ОС: Код: # wget http://downloads2.ioncube.com/loader_downloads/ioncube_loaders_fre_8_x86-64.tar.gz Распаковываем архив: Код: #tar -xvf ioncube_loaders_fre_8_x86-64.tar.gz Смотрим версию PHP: Код: #php -v PHP 5.2.17 with Suhosin-Patch 0.9.7 (cli) (built: Mar 16 2012 09:27:38) Copyright (c) 1997-2009 The PHP Group Zend Engine v2.2.0, Copyright (c) 1998-2010 Zend Technologies Копируем модуль подходящий для нашей версии php, в директорию с модулями: Код: #cp ioncube/ioncube_loader_fre_5.2.so /usr/local/lib/php/20060613/ Добавляем в файл php.ini строчку перед zend_extension: Код: # vi /usr/local/etc/php.ini zend_extension = /usr/local/lib/php/20060613/ioncube_loader_fre_5.2.so Перезапускаем web-сервер Apache: Код: #/usr/local/etc/rc.d/apache22 restart Проверяем: Код: # php -v PHP 5.2.17 with Suhosin-Patch 0.9.7 (cli) (built: Mar 16 2012 09:27:38) Copyright (c) 1997-2009 The PHP Group Zend Engine v2.2.0, Copyright (c) 1998-2010 Zend Technologies with the ionCube PHP Loader v4.2.0, Copyright (c) 2002-2012, by ionCube Ltd.
В 1С в настройках обмена с веб-сайтом делаем выгрузку файлов обмена в папку качаем модуль CMLid и устанавливаем его через админку штатными средствами Prestashop. 1)Связываем категории. Для этого открываем паку с выгруженными файлами обмена из 1С, открываем файл import.xml Копируем в буфер обмена идентификатор группы Затем открываем для редактирования соответствующую категорию в Престашоп и вставляем идентификатор в поле CommerceML id Не забываем сохранить. 2)Связываем товары Открываем карточку товара в Prestashop и идем во вкладку CommerceML id Открываем паку с выгруженными файлами обмена из 1С, открываем файл import.xml В нем находим соответствующий товар и копируем Ид товара в буфер обмена. и затем вставляем его в поле CML id Product в Prestashop и затем нажимаем кнопку сохранить. Все, товары связаны. Учтите, что если в модуле синхронизации не выбран соответствующих режим, описания товаров могут быть перезаписаны теми, что есть в 1С. 3)Связываем комбинации Для этого открываем папку с выгруженными файлами обмена из 1С, открываем файл offers.xml В нем находим товар с соответствующим набором характеристик к связываемой комбинации в Престашоп Копируем идентификатор после разделителя # и вставляем его в поле CML id Комбинации после вставки в поле автоматически добавится идентификатор товара с разделителем # Не забываем сохранить.
В "Мойсклад" В "Справочники" выбираем "Товары и услуги", затем выбираем группу товаров и нажимаем редактировать (изображение карандаша возле имени группы). В открывшемся окне нажимаем ссылку "Система", во вновь открывшемся окне ищем "внешний код" и копируем его в буфер обмена В Prestashop открываем для редактирования аналогичную категорию товаров (или ту которую Вы хотите связать с группой в "МойСклад") и в поле CommerceML id вставляем содержимое буфера обмена и нажимаем кнопку "Сохранить". Все, категория в Prestashop "связана" с группой в "МойСклад"
В "Мойсклад" идем во вкладку "Администрирование" Во вкладке "Товар" добавляем пользовательское поле с именем "Произодитель" с типом данных строка (ВАЖНО!!!) как показано на скрине. Затем идем в карточку товара и прописываем значение в карточке товара
В 1С, в Операции/Константы/Валюты смотрим валюту регламентированного учета и точно так же вводим в настройках модуля
В "МойСклад" открываем карточку товара и идем во вкладку "Внешний код" В открывшемся окне копируем в буфер обмена значение "Внешнего кода" В Интернет - магазине открываем карточку аналогичного товара , идем во вкладку CommerceML id и вставляем из буфера значение "Внешнего кода", в поле , как показано на скриншоте ниже Если в товаре в "МоемСкладе" предусмотрены модификации, а в Интернет-магазине в товаре присутствуют комбинации, тогда в "МойСклад" в карточке товара кликаем по модификации товара в открывшемся окне нажимаем "Внешний код" и копируем в буфер обмена значение "Внешнего кода" модификации В Интернет-магазине значение "внешнего кода" модификации вставляем в соответствующее поле на вкладке CommerceML id, как показано на скриншоте ниже для соответствующей комбинации
1. Зарегистрируйтесь на сайте ulogin.ru 2. В личном кабинете добавьте свой сайт 3. На вкладке "Виджеты" добавьте новый виджет 4. Сконфигурируйте виджет в конструкторе, не забыв указать обязательные параметры Тип авторизации : с редиректом вписав в значение authentication?back=my-account 5. Во вкладке Возвращаемые поля профиля пользователя обязательно отметьте поля Имя, Фамилия , email. Без этих полей авторизация в Prestashop работать не будет. Остальные по усмотрению, причем следует учесть, что с полями Псевдоним, Аватарка, Большая Аватарка Prestashop не работает. Закройте страницу конструктора, при этом сохранятся настройки. 6. Скопируйте ID виджета в буфер обмена и вставьте в соответствующее поле в настройках модуля
Если у вас не работает сортировка по цене Prestashop с учетом цен комбинаций товара, то переопределите функцию класса Category.php используя override. Для класса Category.php PHP: public function getProducts($id_lang, $p, $n, $order_by = null, $order_way = null, $get_total = false, $active = true, $random = false, $random_number_products = 1, $check_access = true, Context $context = null) { if (!$context) $context = Context::getContext(); if ($check_access && !$this->checkAccess($context->customer->id)) return false; $front = true; if (!in_array($context->controller->controller_type, array('front', 'modulefront'))) $front = false; if ($p < 1) $p = 1; if (empty($order_by)) $order_by = 'position'; else /* Fix for all modules which are now using lowercase values for 'orderBy' parameter */ $order_by = strtolower($order_by); if (empty($order_way)) $order_way = 'ASC'; $order_by_prefix = false; if ($order_by == 'id_product' || $order_by == 'date_add' || $order_by == 'date_upd') $order_by_prefix = 'p'; elseif ($order_by == 'name') $order_by_prefix = 'pl'; elseif ($order_by == 'manufacturer' || $order_by == 'manufacturer_name') { $order_by_prefix = 'm'; $order_by = 'name'; } elseif ($order_by == 'position') $order_by_prefix = 'cp'; if ($order_by == 'price') $order_by = 'orderprice'; if (!Validate::isBool($active) || !Validate::isOrderBy($order_by) || !Validate::isOrderWay($order_way)) die (Tools::displayError()); $id_supplier = (int)Tools::getValue('id_supplier'); /* Return only the number of products */ if ($get_total) { $sql = 'SELECT COUNT(cp.`id_product`) AS total FROM `'._DB_PREFIX_.'product` p '.Shop::addSqlAssociation('product', 'p').' LEFT JOIN `'._DB_PREFIX_.'category_product` cp ON p.`id_product` = cp.`id_product` WHERE cp.`id_category` = '.(int)$this->id. ($front ? ' AND product_shop.`visibility` IN ("both", "catalog")' : ''). ($active ? ' AND product_shop.`active` = 1' : ''). ($id_supplier ? 'AND p.id_supplier = '.(int)$id_supplier : ''); return (int)Db::getInstance(_PS_USE_SQL_SLAVE_)->getValue($sql); } $sql = 'SELECT p.*, product_shop.*, stock.out_of_stock, IFNULL(stock.quantity, 0) as quantity'.(Combination::isFeatureActive() ? ', MAX(product_attribute_shop.id_product_attribute) id_product_attribute, MAX(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`, MAX(image_shop.`id_image`) id_image, MAX(il.`legend`) as legend, m.`name` AS manufacturer_name, cl.`name` AS category_default, DATEDIFF(product_shop.`date_add`, DATE_SUB(NOW(), INTERVAL '.(Validate::isUnsignedInt(Configuration::get('PS_NB_DAYS_NEW_PRODUCT')) ? Configuration::get('PS_NB_DAYS_NEW_PRODUCT') : 20).' DAY)) > 0 AS new, IFNULL(MIN(product_attribute_shop.price),product_shop.price) AS orderprice, IFNULL(MIN(product_attribute_shop.price),product_shop.price) AS price 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` pa ON (p.`id_product` = pa.`id_product`) '.Shop::addSqlAssociation('product_attribute', 'pa', false, 'product_attribute_shop.`default_on` = 1').' '.Product::sqlStock('p', 'product_attribute_shop', false, $context->shop) : Product::sqlStock('p', 'product', false, Context::getContext()->shop)).' 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` i ON (i.`id_product` = p.`id_product`)'. Shop::addSqlAssociation('image', 'i', false, 'image_shop.cover=1').' 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 : '') .' GROUP BY product_shop.id_product'; if ($random === true) $sql .= ' ORDER BY RAND() LIMIT '.(int)$random_number_products; else $sql .= ' ORDER BY '.(!empty($order_by_prefix) ? $order_by_prefix.'.' : '').'`'.bqSQL($order_by).'` '.pSQL($order_way).' LIMIT '.(((int)$p - 1) * (int)$n).','.(int)$n; //d($sql); $result = Db::getInstance(_PS_USE_SQL_SLAVE_)->executeS($sql); if ($order_by == 'orderprice') Tools::orderbyPrice($result, $order_way); if (!$result) return array(); //d($result); /* Modify SQL result */ return Product::getProductsProperties($id_lang, $result); } ввв
Если у вас не работает сортировка по цене Prestashop с учетом цен комбинаций товара на странице производителей , то переопределите функцию класса Manufacturer.php используя override. Для класса Category.php Для класса Manufacturer.php PHP: public static function getProducts($id_manufacturer, $id_lang, $p, $n, $order_by = null, $order_way = null, $get_total = false, $active = true, $active_category = true, Context $context = null) { if (!$context) $context = Context::getContext(); $front = true; if (!in_array($context->controller->controller_type, array('front', 'modulefront'))) $front = false; if ($p < 1) $p = 1; if (empty($order_by) || $order_by == 'position') $order_by = 'name'; if (empty($order_way)) $order_way = 'ASC'; if (!Validate::isOrderBy($order_by) || !Validate::isOrderWay($order_way)) die (Tools::displayError()); $groups = FrontController::getCurrentCustomerGroups(); $sql_groups = count($groups) ? 'IN ('.implode(',', $groups).')' : '= 1'; /* Return only the number of products */ if ($get_total) { $sql = ' SELECT p.`id_product` FROM `'._DB_PREFIX_.'product` p '.Shop::addSqlAssociation('product', 'p').' WHERE p.id_manufacturer = '.(int)$id_manufacturer .($active ? ' AND product_shop.`active` = 1' : '').' '.($front ? ' AND product_shop.`visibility` IN ("both", "catalog")' : '').' AND p.`id_product` IN ( SELECT cp.`id_product` FROM `'._DB_PREFIX_.'category_group` cg LEFT JOIN `'._DB_PREFIX_.'category_product` cp ON (cp.`id_category` = cg.`id_category`)'. ($active_category ? ' INNER JOIN `'._DB_PREFIX_.'category` ca ON cp.`id_category` = ca.`id_category` AND ca.`active` = 1' : '').' WHERE cg.`id_group` '.$sql_groups.' )'; $result = Db::getInstance(_PS_USE_SQL_SLAVE_)->executeS($sql); return (int)count($result); } if (strpos($order_by, '.') > 0) { $order_by = explode('.', $order_by); $order_by = pSQL($order_by[0]).'.`'.pSQL($order_by[1]).'`'; } $alias = ''; if ($order_by == 'price') { $order_by = 'orderprice'; $alias = '';} elseif ($order_by == 'name') $alias = 'pl.'; elseif ($order_by == 'manufacturer_name') { $order_by = 'name'; $alias = 'm.'; } elseif ($order_by == 'quantity') $alias = 'stock.'; else $alias = 'p.'; $sql = 'SELECT p.*, product_shop.*, stock.out_of_stock, IFNULL(stock.quantity, 0) as quantity, IFNULL(MIN(product_attribute_shop.price),product_shop.price) AS orderprice ' .(Combination::isFeatureActive() ? ', MAX(product_attribute_shop.minimal_quantity) AS product_attribute_minimal_quantity' : '') .', MAX(product_attribute_shop.`id_product_attribute`) id_product_attribute , pl.`description`, pl.`description_short`, pl.`link_rewrite`, pl.`meta_description`, pl.`meta_keywords`, pl.`meta_title`, pl.`name`, pl.`available_now`, pl.`available_later`, MAX(image_shop.`id_image`) id_image, il.`legend`, m.`name` AS manufacturer_name, DATEDIFF( product_shop.`date_add`, DATE_SUB( NOW(), INTERVAL '.(Validate::isUnsignedInt(Configuration::get('PS_NB_DAYS_NEW_PRODUCT')) ? Configuration::get('PS_NB_DAYS_NEW_PRODUCT') : 20).' DAY ) ) > 0 AS new'.(Combination::isFeatureActive() ? ',MAX(product_attribute_shop.minimal_quantity) AS product_attribute_minimal_quantity' : '') .' FROM `'._DB_PREFIX_.'product` p '.Shop::addSqlAssociation('product', 'p'). (Combination::isFeatureActive() ? 'LEFT JOIN `'._DB_PREFIX_.'product_attribute` pa ON (p.`id_product` = pa.`id_product`) '.Shop::addSqlAssociation('product_attribute', 'pa', false, 'product_attribute_shop.`default_on` = 1') : '').' 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` i ON (i.`id_product` = p.`id_product`)'. Shop::addSqlAssociation('image', 'i', false, 'image_shop.cover=1').' LEFT JOIN `'._DB_PREFIX_.'image_lang` il ON (i.`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`) '.Product::sqlStock('p', 0); if (Group::isFeatureActive() || $active_category) { $sql .= 'JOIN `'._DB_PREFIX_.'category_product` cp ON (p.id_product = cp.id_product)'; if (Group::isFeatureActive()) $sql .= 'JOIN `'._DB_PREFIX_.'category_group` cg ON (cp.`id_category` = cg.`id_category` AND cg.`id_group` '.$sql_groups.')'; if ($active_category) $sql .= 'JOIN `'._DB_PREFIX_.'category` ca ON cp.`id_category` = ca.`id_category` AND ca.`active` = 1'; } $sql .= ' WHERE p.`id_manufacturer` = '.(int)$id_manufacturer.' '.($active ? ' AND product_shop.`active` = 1' : '').' '.($front ? ' AND product_shop.`visibility` IN ("both", "catalog")' : '').' GROUP BY product_shop.id_product ORDER BY '.$alias.'`'.bqSQL($order_by).'` '.pSQL($order_way).' LIMIT '.(((int)$p - 1) * (int)$n).','.(int)$n; $result = Db::getInstance(_PS_USE_SQL_SLAVE_)->executeS($sql); if (!$result) return false; if ($order_by == 'price') Tools::orderbyPrice($result, $order_way); return Product::getProductsProperties($id_lang, $result); } ddd
Для того чтобы поле отчество выводилось в формах заказов и адресов, зайдите в админ-части магазина в ЛОКАЛИЗАЦИИ/СТРАНЫ, выберите страну активную в Вашем интернет магазине и добавьте middlename в формат адреса, как показано на скрине
Открываем файл /themes/default-bootstrap/identity.tpl и после: PHP: <div class="required form-group"> <label for="lastname" class="required"> {l s='Last name'} </label> <input class="is_required validate form-control" data-validate="isName" type="text" name="lastname" id="lastname" value="{$smarty.post.lastname}" /></div> Добавляем это: PHP: <div class="required form-group"> <label for="middlename"> {l s='Middle name'} </label> <input class="validate form-control" data-validate="isName" type="text" name="middlename" id="middlename" value="{$smarty.post.middlename}" /></div> Открываем файл /themes/default-bootstrap/authentication.tpl и после: PHP: <div class="required form-group"> <label for="lastname">{l s='Last name'} <sup>*</sup></label> <input type="text" class="is_required validate form-control" data-validate="isName" id="lastname" name="lastname" value="{if isset($smarty.post.lastname)}{$smarty.post.lastname}{/if}" /></div> Вставляем это: PHP: <div class="required form-group"> <label for="middlename">{l s='Middle name'} <sup>*</sup></label> <input type="text" class="validate form-control" data-validate="isName" id="middlename" name="middlename" value="{if isset($smarty.post.middlename)}{$smarty.post.middlename}{/if}" /></div> Далее ищем: PHP: {elseif $field_name eq "lastname"}<div class="required form-group"> <label for="lastname_invoice">{l s='Last name'} <sup>*</sup></label> <input type="text" class="form-control" id="lastname_invoice" name="lastname_invoice" value="{if isset($guestInformations) && $guestInformations.lastname_invoice}{$guestInformations.lastname_invoice}{/if}" /></div> И после добавляем: PHP: {elseif $field_name eq "middlename"}<div class="required form-group"> <label for="middlename_invoice">{l s='Middle name'}</label> <input type="text" class="form-control" id="middlename_invoice" name="middlename_invoice" value="{if isset($guestInformations) && $guestInformations.middlename_invoice}{$guestInformations.middlename_invoice}{/if}" /></div> Ниже ищем: PHP: <div class="required form-group"> <label for="customer_lastname">{l s='Last name'} <sup>*</sup></label> <input onkeyup="$('#lastname').val(this.value);" type="text" class="is_required validate form-control" data-validate="isName" id="customer_lastname" name="customer_lastname" value="{if isset($smarty.post.customer_lastname)}{$smarty.post.customer_lastname}{/if}" /></div> И после добавляем: PHP: <div class="required form-group"> <label for="customer_middlename">{l s='Middle name'}</label> <input onkeyup="$('#middlename').val(this.value);" type="text" class="validate form-control" data-validate="isName" id="customer_middlename" name="customer_middlename" value="{if isset($smarty.post.customer_middlename)}{$smarty.post.customer_middlename}{/if}" /></div> Ниже находим: PHP: {elseif $field_name eq "lastname"} <p class="required form-group"> <label for="lastname">{l s='Last name'} <sup>*</sup></label> <input type="text" class="form-control" id="lastname" name="lastname" value="{if isset($smarty.post.lastname)}{$smarty.post.lastname}{/if}" /> </p> И после добавляем: PHP: {elseif $field_name eq "middlename"} <p class="required form-group"> <label for="middlename">{l s='Middle name'}</label> <input type="text" class="form-control" id="middlename" name="middlename" value="{if isset($smarty.post.middlename)}{$smarty.post.middlename}{/if}" /> </p> Открываем файл /themes/default-bootstrap/address.tpl и после: PHP: {if $field_name eq 'lastname'} <div class="required form-group"> <label for="lastname">{l s='Last name'} <sup>*</sup></label> <input class="is_required validate form-control" data-validate="{$address_validation.$field_name.validate}" type="text" id="lastname" name="lastname" value="{if isset($smarty.post.lastname)}{$smarty.post.lastname}{else}{if isset($address->lastname)}{$address->lastname|escape:'html':'UTF-8'}{/if}{/if}" /> </div>{/if} Вставляем: PHP: {if $field_name eq 'middlename'} <div class="required form-group"> <label for="middlename">{l s='Middle name'}</label> <input class="validate form-control" data-validate="{$address_validation.$field_name.validate}" type="text" id="middlename" name="middlename" value="{if isset($smarty.post.middlename)}{$smarty.post.middlename}{else}{if isset($address->middlename)}{$address->middlename|escape:'html':'UTF-8'}{/if}{/if}" /> </div>{/if} Открываем файл /themes/default-bootstrap/order-opc-new-account.tpl и после: PHP: <div class="required form-group"> <label for="lastname">{l s='Last name'} <sup>*</sup></label> <input type="text" class="form-control validate" id="customer_lastname" name="customer_lastname" onblur="$('#lastname').val($(this).val());" data-validate="isName" value="{if isset($guestInformations) && isset($guestInformations.customer_lastname) && $guestInformations.customer_lastname}{$guestInformations.customer_lastname}{/if}" /></div> Добавить: PHP: <div class="required form-group"> <label for="middlename">{l s='Middle name'} <sup>*</sup></label> <input type="text" class="form-control validate" id="customer_middlename" name="customer_middlename" onblur="$('#middlename').val($(this).val());" data-validate="isName" value="{if isset($guestInformations) && isset($guestInformations.customer_middlename) && $guestInformations.customer_middlename}{$guestInformations.customer_middlename}{/if}" /></div> Ниже находим: PHP: {elseif $field_name eq "lastname"}<div class="required text form-group"> <label for="lastname">{l s='Last name'} <sup>*</sup></label> <input type="text" class="text form-control validate" id="lastname" name="lastname" data-validate="isName" value="{if isset($guestInformations) && isset($guestInformations.lastname) && $guestInformations.lastname}{$guestInformations.lastname}{/if}" /></div> И после добавляем: PHP: {elseif $field_name eq "middlename"}<div class="required text form-group"> <label for="middlename">{l s='Middle name'} <sup>*</sup></label> <input type="text" class="text form-control validate" id="middlename" name="middlename" data-validate="isName" value="{if isset($guestInformations) && isset($guestInformations.middlename) && $guestInformations.middlename}{$guestInformations.middlename}{/if}" /></div> Ещё ниже находим: PHP: {elseif $field_name eq "lastname"}<div class="required form-group"> <label for="lastname_invoice">{l s='Last name'} <sup>*</sup></label> <input type="text" class="form-control validate" id="lastname_invoice" name="lastname_invoice" data-validate="isName" value="{if isset($guestInformations) && isset($guestInformations.lastname_invoice) && $guestInformations.lastname_invoice}{$guestInformations.lastname_invoice}{/if}" /></div> И после добавляем: PHP: {elseif $field_name eq "middlename"}<div class="required form-group"> <label for="middlename_invoice">{l s='Last name'} <sup>*</sup></label> <input type="text" class="form-control validate" id="middlename_invoice" name="middlename_invoice" data-validate="isName" value="{if isset($guestInformations) && isset($guestInformations.middlename_invoice) && $guestInformations.middlename_invoice}{$guestInformations.middlename_invoice}{/if}" /></div> На этом все.