Расширение свойств товаров 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.

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

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

  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');
            *Комментарий будет опубликован после проверки модератором

            Комментарии 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! Спасибо!

            [MODX] Генератор настроек MIGX

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

            [JS] Маска для ввода телефона +7(___)___-__-__

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

            jQuery.Maskedinput js - документация на русском с примерами

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

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

            [MODx, miniShop2] Генерация YML для выгрузки в маркет

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

            [OpenCart] Вывести на главную все категории с картинками

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

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

            [MODX, MIGX] Примеры использования

            Пример перевода с помощью Yandex Translate API

            Универсальная форма обратной связи — feedBackForm

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

            [MODX, MiniShop2] Примеры выборки where, optionFilters, innerJoin

            [Opencart] Вернуть английский язык, если вы его удалили

            Отключить автозаполнение input

            Настройка Webpack - несколько точек входа и разделение на чанки

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

            [OpenCart] Вывести модуль напрямую через контроллер

            [MODX, MIGX] Вывести getImageList только если он не пустой

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

            [MODX, Quip] Более рабочий вариант

            Все записи

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