Эмоциональное вступление
Вы уже почувствовали боль?...
Мне кажется именно так нужно начинать все статьи про расширение таблиц в MODX, а не "Удобно и очень просто". (Хотя этот вариант еще более-менее). Это п@#$ц как неудобно и вообще нихрена не просто. По крайней мере, когда тебе нужен результат не в точности такой, как описан в инструкции. Потому что много всяких нюансов, отчетов об ошибках нет никаких, и нет понимание логики системы. Кхм.. итак, приступим:)
В общем есть на данный момент 2 статьи, которые дают более-менее понятное описание — winrecovery.ru и docs.modx.pro. Одну из них я беру за основу.
Тут я постараюсь резюмировать хоть что-то, чтобы в следующий раз не рвать на себе волосы, пытаясь в течение часа "быстро, легко и удобно" добавить поле в minishop2.
(Василий, и прочие умные программисты — к вам претензий нет. Но вообще сама схема работы MODX в такие моменты просто убивает — когда простейшая задача становится самым сложным этапом в разработке сайта)
По сути
работы ведутся в контексте minishop2 2.4.11
Вероятно, вы уже знаете, что для того чтобы добавить новые поля, или изменить существующие, нужно создать плагин для MiniShop2. (Не имеет отношения к стандартным плагинам MODX). Этот плагин будет состоять из трех файлов, которые будут расположены:
core/components/minishop2/plugins/ms2extend1/index.php
core/components/minishop2/plugins/ms2extend1/msproductdata.troy.map.inc.php
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. Он так же по ссылке.
fields
— значение по-умолчанию для поляfieldMeta
— Meta-описание поля. Тут надо все четко заполнить:)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.
Если я, так же, как и другие авторы, упустил какой-то важный нюанс, или посчитал что-то очевидным и не разъяснил, и от этого у вас ничего не работает, то излейте свою ненависть в комментариях. Спасибо. И простите меня..
Вкладку свою сделал так.
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;
},
});