Расширение свойств товаров minishop2

Эмоциональное вступление

Вы уже почувствовали боль?...
Мне кажется именно так нужно начинать все статьи про расширение таблиц в MODX, а не "Удобно и очень просто". (Хотя этот вариант еще более-менее). Это п@#$ц как неудобно и вообще нихрена не просто. По крайней мере, когда тебе нужен результат не в точности такой, как описан в инструкции. Потому что много всяких нюансов, отчетов об ошибках нет никаких, и нет понимание логики системы. Кхм.. итак, приступим:)

В общем есть на данный момент 2 статьи, которые дают более-менее понятное описание — winrecovery.ru и docs.modx.pro. Одну из них я беру за основу.

Тут я постараюсь резюмировать хоть что-то, чтобы в следующий раз не рвать на себе волосы, пытаясь в течение часа "быстро, легко и удобно" добавить поле в minishop2.

(Василий, и прочие умные программисты — к вам претензий нет. Но вообще сама схема работы MODX в такие моменты просто убивает — когда простейшая задача становится самым сложным этапом в разработке сайта)

По сути

работы ведутся в контексте minishop2 2.4.11

Вероятно, вы уже знаете, что для того чтобы добавить новые поля, или изменить существующие, нужно создать плагин для MiniShop2. (Не имеет отношения к стандартным плагинам MODX). Этот плагин будет состоять из трех файлов, которые будут расположены:

  1. core/components/minishop2/plugins/ms2extend1/index.php
  2. core/components/minishop2/plugins/ms2extend1/msproductdata.troy.map.inc.php
  3. assets/components/minishop2/plugins/ms2extend1/msproductdata.troy.js

ms2extend1 — это мое название плагина. Оно может быть произвольным

Сперва нужно вручную расширить таблицу MYSQL. То есть ручками через phpMyAdmin создаем нужную колонку в таблице [префикс]ms2_products.

ms2extend1/index.php

Расположение: core/components/minishop2/plugins/ms2extend1/index.php

Это не особо интересный файл с конфигурацией. Тут важно только чтобы пути до двух других файлов были указаны верно.
    return array(
    	'xpdo_meta_map' => array(
    		'msProductData' => require_once dirname(__FILE__) .'/msproductdata.troy.map.inc.php'
    	)
    	,'manager' => array(
    		'msProductData' => MODX_ASSETS_URL . 'components/minishop2/plugins/ms2extend1/msproductdata.troy.js'
    	)
    );

ms2extend1/msproductdata.troy.map.inc.php

Расположение: core/components/minishop2/plugins/ms2extend1/msproductdata.troy.map.inc.php

Расширенную версию этого файла можно посмотреть по ссылке. Там представлены поля разных типов данных. Также можете ориентироваться на файл core/components/minishop2/model/minishop2/mysql/msproductdata.map.inc.php — родной файл настроек minishop2. Он так же по ссылке.

  1. fields — значение по-умолчанию для поля
  2. fieldMeta — Meta-описание поля. Тут надо все четко заполнить:)
  3. indexes — Индексы. На сколько я понимаю - если вы создали индекс в таблице MySQL, то тут его тоже следует указать, а иначе можно не указывать.
return array(
	'fields' => array(
		'currency' => NULL
	)
	,'fieldMeta' => array(
		'currency' => array(
			'dbtype' => 'varchar'
			,'precision' => '5'
			,'phptype' => 'string'
			,'null' => true
			,'default' => NULL
		)
	)
	,'indexes' => array(
		'currency' => array (
			'alias' => 'currency'
			,'primary' => false
			,'unique' => false
			,'type' => 'BTREE'
			,'columns' => array (
				'action' => array (
					'length' => ''
					,'collation' => 'A'
					,'null' => false
				)
			)
		)
	)
);

ms2extend1/msproductdata.troy.js

Расположение: assets/components/minishop2/plugins/ms2extend1/msproductdata.troy.js

Этот файл отвечает за представление полей в админке, и соответственно тут вы можете указать какой будет тип инпута. Этих типов хренова туча, и вот в этом файле тоже есть примеры нескольких вариантов. Стандартные поля MiniShop2 можно посмотреть тут - это файлик минишопа (assets/components/minishop2/js/mgr/product/product.common.js).

Прочитайте еще комментарии в самом файле, там написано про заголовок поля:

miniShop2.plugin.pluginname = { //pluginname менять не надо.
	getFields: function(config) {
		return {
		    // То, что тут написано [[+currency]] - это просто выводится как есть, то есть это не плейсхолдер.
		    // А вот ms2_product_currency_help - это уже ключ словаря, и его нужно создать в разделе "Управление словарями -> minishop2 -> ru" или можно просто текстом прописать и не париться
			currency: {xtype: 'minishop2-combo-autocomplete', description: '[[+currency]]
'+_('ms2_product_currency_help')} } } ,getColumns: function() { return { currency: {width:50, sortable:false, editor: {xtype:'minishop2-combo-autocomplete', name: 'currency'}} } } };

Отображение заголовков у полей

Для того чтобы появились подписи у полей нужно добавить записи в разделе "Управление словарями -> minishop2 -> ru". Алгоритм формирования ключа такой — ms2_product_FIELDNAME

"And.. One more thing" (Почему не работает)

Нужно еще явно указать в настройках, что вы хотите отображать это новое поле.

Переходим в Настройки -> minisop2 -> Товар -> Дополнительные поля товара (ms2_product_extra_fields), и дописываем туда название вашего поля.

Если на данном этапе не отображается заголовок, прочитайте комментарии для файла JS настроек. Там про это написано.

И еще, у меня почему-то не отображались изменения, пока я не нажал Ctrl+F5 (В хроме — перезагрузка стрницы с очисткой кэша).

Форматирование нового поля цены при выводе

Для таких полей как цена, потребуется еще одна правка. В данном случае я решил ее костылем, хотя стоило бы реализовать все правильно, с расширением объекта.

В общем, открываем файлик core/components/minishop2/model/minishop2/msproduct.class.php, находим там public function process(), и дальше все станет понятно.

P.S.

Если я, так же, как и другие авторы, упустил какой-то важный нюанс, или посчитал что-то очевидным и не разъяснил, и от этого у вас ничего не работает, то излейте свою ненависть в комментариях. Спасибо. И простите меня..

Комментарии (10)

  1. Евгений 10 июля 2019, 16:32 # 0
    Пипец квест. Автор, вы молодец! К несчастью, судьба свела с modx minishop2 — печаль и боль… Главное, где бы ни натыкался на описания — часто встречается словосочетания «из коробки». И еще поражает отсутствие комментариев в большинстве русских солюшенов и мануалов.
    1. Николай 10 сентября 2019, 16:48 # 0
      require_once( dirname(__FILE__)) вот так наверное правильнее будет
      1. Михаил 29 января 2020, 11:53(Комментарий был изменён) # 0
        Ды бл… 3 мануал и опять ни х… ра не пашет… Что ж такое то ((( почему это так трудно сделать… Не ужели нельзя было как то упростить этот процесс. А в этой статье (https://docs.modx.pro/komponentyi/minishop2/razrabotka/plaginyi-tovarov) вообще не понятно как регистрировать плагин. Куда это тод писать… Автор вообще не задумывался про логику мануала… )))
        1. А 06 апреля 2020, 15:13 # 0
          А подскажите как можно новые созданные свойства товара поместить на свою вкладку.
          Вкладку свою сделал так.

          Ext.override(miniShop2.panel.Product, {
          ms__Originals: {
          getFields: miniShop2.panel.Product.prototype.getFields,
          },

          getFields: function (config) {
          var fields = this.ms__Originals.getFields.call(this, config);

          for (var i in fields) {
          if (!fields.hasOwnProperty(i)) {
          continue;
          }
          var item = fields[i];

          if (item.id == «modx-resource-tabs») {
          for (var i__2 in item.items) {
          if (!item.items.hasOwnProperty(i__2)) {
          continue;
          }

          var tab = item.items[i__2];
          if (tab.id == «minishop2-product-tab» && tab.items[0]) {
          tab.items[0].items.push({
          title: 'Название вкладки',
          autoHeight: true,
          hideMode: 'offsets',
          cls: 'x-panel-body main-wrapper x-panel-body-noheader x-panel-body-noborder',
          layout: 'form',
          anchor: '100%',
          items: [{
          html: 'Текст',
          bodyCssClass:'x-panel',
          border: false
          },{
          layout: 'column',

          items:[{
          columnWidth: .33,
          layout: 'form',
          items: [{
          // здесь список созданных полей 1, 4, 7
          }]
          },{
          columnWidth: .33,
          layout: 'form',
          items: [{
          // здесь список созданных полей 2, 5, 8
          }]
          },{
          columnWidth: .33,
          layout: 'form',
          items: [{
          // здесь список созданных полей 3, 6, 9
          }]
          }]

          }]
          });
          }
          }
          }
          }

          return fields;
          },

          });
          1. Александр 10 марта 2021, 09:06 # 0
            Подскажите, а как можно создать второе поле «цена» и использовать именно его? Нужно для указания цены в другой валюте (но не просто конвертация, а совсем другая логика/формула)
            1. Администратор 11 марта 2021, 19:23 # 0
              Видимо хранить вторую цену просто «как-нибудь» — в свойстве товара, TV, или не важно как по сути. Но вот уже на моменте оформления заказа — там да, уже может быть потребуются от вас какие-то действия.
              Вот пара заметок, в которых я описывал что-то подобное:

              Изменить цену на товар, если в корзине лежит товар из особой категории minishop2 — webstool.ru/izmenit-czenu-na-tovar-esli-v-korzine-lezhit-tovar-iz-osoboj-kategorii-minishop2.html

              Изменить цену на товар в зависимости от количества при добавлении в корзину minishop2 — webstool.ru/izmenit-czenu-na-tovar-minishop2.html
              1. Александр 11 марта 2021, 19:36 # 0
                Спасибо.
                А может знаете где minishop берет название столбца БД с ценой? Чтобы добавив новый столбец в базу данных указать его название. Тогда, по идее, будет меньше заморочек с обработкой цен в корзине
                1. Администратор 11 марта 2021, 19:48(Комментарий был изменён) # 0
                  Одним лишь добавлением столбца ограничиться вы вряд ли сможете, не создав лютые костыли.
                  По ссылкам, которые я дал вы можете увидеть как я обращаюсь к цене:
                  $product = $modx->getObject('msProduct', $id);
                  $price = $product->get('price');
                  
                  Соответственно, после создания ваших собственных полей с ценами у вас будет что-то то типа описанного вот тут webstool.ru/izmenit-czenu-na-tovar-minishop2.html
                  $product->get('priceUSD');
                  … Хм, вопрос был немного не о том, наверно… Ну minishop просто оперирует полем price, а это поле, соответственно находится в [префикс]ms2_products. Не думаю, что есть какая-то настройка, позволяющая передать функции этого поля какому-то другому полю.
                  А согласно инструкции, описанной на этой странице создавать свои поля вы можете расширив эту таблицу. Но просто очень важно, чтобы вы прошли через все необходимые круги ада, для того чтобы мочь воспользоваться конструкцией $product->get('priceUSD');
            2. Hero333 11 февраля 2022, 22:58 # 0
              Если кто-то читает статью, то уже давно появился бесплатный компонент msaddfield, который позволяет добавлять поля к товару за пару кликов из админки modx.
              1. Виктория 06 июля 2022, 17:37 # 0
                Спасибо вам, добрый человек! Все сработало! minishop2 2.5.0-pl, MODX Revolution 2.8.1-pl
                *Комментарий будет опубликован после проверки модератором

                Комментарии easyComm

                Дмитрий 25 октября 2018, 17:55

                Здравствуйте! Все сделал, получилось. А как можно в этот плагин добавить не одно, а два, три, четыре новых свойства? Я дописал, в файл php новые поля, добавил в БД, в словарь, на страничке они вышли, а в админке так и нет. Чего не так, интересно?


                miniShop2.plugin.pluginname = {
                // Изменение полей для панели товара
                getFields: function (config) {
                return {
                contract: {
                xtype: 'minishop2-combo-autocomplete',
                description: '<b>[[+contract]]</b><br />' + _('ms2_product_contract')
                },
                technics: {
                xtype: 'minishop2-combo-autocomplete',
                description: '<b>[[+technics]]</b><br />' + _('ms2_product_technics')
                },
                }
                },
                // Изменение колонок таблицы товаров в категории
                getColumns: function () {
                return {
                contract: {
                width: 50,
                sortable: false,
                editor: {
                xtype: 'minishop2-combo-autocomplete',
                name: 'contract'
                }
                },
                technics: {
                width: 50,
                sortable: false,
                editor: {
                xtype: 'minishop2-combo-autocomplete',
                name: 'technics'
                }
                },
                }
                },
                };

                Администратор

                Здравствуйте, в системной настройки (ms2_product_extra_fields) добавили поля?

                sdgjapdog 25 марта 2018, 15:46

                Спасибо огромное, автор. Я уже начала подбираться к грани отчаяния, но вы меня спасли)

                Александр 17 марта 2018, 22:37

                Наконец-то хоть что-то внятное про добавление новых свойств товаров в minishop2! Спасибо!

                Похожие статьи

                Генератор настроек MIGX

                Документация на русском по MODX MIGX

                Подсказки по работе и заготовки для MiniShop2

                pdoPage и getImageList - Постраничная навигация MIGX

                Импорт и экспорт в MiniShop2. Реализация 1

                Как включить HTTPS (SSL) в MODX - Подробная инструкция

                Генерация YML для выгрузки в маркет

                Примеры работы с API MODX

                Примеры выборки where, optionFilters, innerJoin

                pThumb - ресайз изображений. Примеры использования.

                Расширение свойств товаров minishop2

                Примеры использования

                Сайт на обслуживании (выключить сайт)

                Добавить в письмо контактную информацию

                Вывести getImageList только если он не пустой

                Тип поля "Список ресурсов" (resourcelist) с ограничением по родителю (parents)

                Оформление и настройка easyComm. Комментарии и отзывы на сайте.

                Поиск на сайте с пакетом SimpleSearch

                Простая и симпатичная галерея fancybox

                Подсчет и вывод количества потомков ресурса в MODX

                Вывод tv-параметров в формате -

                Галерея. Вывести обложки альбомов и фотографии

                Отредактировать письмо о заказе - добавить ТВ поле, или что-то еще

                Quip для MODX. Более рабочий вариант

                pdoResources Заготовки для работы

                Сниппет для вывода размера и расширения файла

                Простой аудио-плеер HTML5

                Вывести список всех опций MiniShop2

                Слайдер Slick slider в контенте ресурса

                Изменить цену на товар в зависимости от количества при добавлении в корзину minishop2

                Как контролировать кэш CSS и скриптов

                Подключить MODX в стороннем PHP файле

                Простейшая авторизация

                Как создать ресурс процессором $modx->runProcessor('resource/create', $props)

                Красивое адаптивное меню под pdoMenu

                Массово обновить ТВ, или другое поле через базу

                Создать свою страницу в админке

                Изменить формат номера заказа

                Сообщение о том, что сайт использует Cookie

                Получить grandparent. Вывести родитель родителя

                Симпатичный список файлов, загружаемых к ресурсу через MIGX

                Установить шаблон по-умолчанию для новых, создаваемых ресурсов

                Создать источник файлов

                Вывести все доступные плейсхолдеры

                Отредактировать шаблон письма

                Добавить скрипт перед тегом body

                Общая сумма по каждому товару в корзине Minishop2

                Создать раздел с паролем на сайте MODX

                Что делать если ее приходит почта администратору

                Фильтрация по TV параметрам в msProducts

                Дата на русском

                FontAwesome - часто используемые иконки для шаблонов MODX

                Создать пакет с пользовательской таблицей

                Курсы валют с cbr.ru на PHP

                Заготовки для работы

                Загрузка сниппета после загрузки страницы через AjaxSnippet

                getResources заготовки

                Обязательный чекбокс при оформлении заказа

                Соответствие названия классов с названиями таблиц в MySQL

                Обработка остатков заказа в miniShop2

                Разбить вывод pdoResources на несколько колонок (блоков)

                Баннеры с использованием BannerY

                Обновить alias (псевдоним) у всех ресурсов

                CSS для постраничной навигации pdoPage

                Вывести время загрузки (формирования) страницы

                Расширить таблицу site_content (объект modResource) за 5 минут

                Вырезать кавычки — фильтр-сниппет MODX

                Счетчик посещений и скачиваний для сортировки ресурсов

                Динамическое поле emailSubject в FormIt

                Бесплатная доставка от 5000 рублей в MiniShop2

                Скрыть информацию о том, что сайт работает на MODX

                Отсортировать ресурсы по количеству комментариев Quip MODx

                Изменить цену на товар, если в корзине лежит товар из особой категории minishop2

                Создать редирект через autoRedirector API

                Вывести 404 ошибку по настройке TV MODX

                Ответ для сервиса moneta.ru

                Email сделать не обязательным полем

                Как разместить исходный код сниппета на сайте, в документации

                Cортировать по списку id в pdoResources и pdoTools

                Ускорить установку MODX revo до пары кликов

                Постраничная навигация — набор параметров и CSS PdoPage

                Не работает подгрузка товаров ajax mfilter2 на мобильном

                Сделать все элементы статичными для Git и IDE

                Сделать поле размер обязательным

                Настройка стилей для комментариев Tickets

                Подключить текстовой редактор к доп. полям ресурса

                Кастомный чанк для AdminPanel

                Динамическая замена шаблона ресурса - плагин

                Разместить корзину внутри блока с оформлением заказа

                Плагин для формирования замороженных URL с редиректом

                Приветственный экран / заглушка на сайт

                Вывести список всех родителей в ТВ поле ресурса

                xPDO Выборка из одной таблицы с зацепкой значения из другой

                Вложенные условия в xPDO MODX

                Вывести список всех емэйлов miniShop2

                Если getParentIds не работает в плагине

                Как получить данные пользователя сразу после авторизации через API

                Контролировать кэширование файлов CSS и JS MiniShop2

                Не приходят / не отправляются письма - в чем причина?

                Кэширование в MODX: использование $modx->cacheManager

                Наш сайт использует куки, нажмите «ОК» если вы не против
                OK