Добавление своих полей в форму заказа [обновлено]

При разработке нескольких проектов, возникала необходимость в получении дополнительных данных от покупателей, а полей в miniShop2 ограниченное количество. Поиск готового решения результата не дал, поэтому предлагаю свой вариант.

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

Решалось это следующим образом:
1. Добавлялись необходимые поля, для примера взяты тип плательщика, название организации и инн.
2. Добавлялся плагин срабатывающий при сохранении заказа и при подключении js минишопа в админке.
3. Редактировались настройки и записи словарей.

Более подробно далее

1. В форму оформления заказа добавляем нужные поля:
<label><input type="radio" name="extfld_type" value="Юридическое лицо">Юридическое лицо</label>
<label><input type="radio" name="extfld_type" value="Физическое лицо">Физическое лицо</label>
<label><input type="text" name="extfld_org">Название организации</label>
<label><input type="text" name="extfld_inn">ИНН</label>
Все поля с префиксом extfld_ попадут в заказ.

2. Создаем плагин msExtraAddressFields и вешаем его на события msOnBeforeCreateOrder и msOnManagerCustomCssJs. Плагин сохраняет нужные поля при оформлении заказа в json в поле properties таблицы modx_ms2_order_addresses, а так же подключает нужный js в админке.
<?php
switch ($modx->event->name) {
    case 'msOnBeforeCreateOrder':
        $address = $msOrder->getOne('Address');
        $properties = array();
        foreach ($_POST as $key => $value){
            if (strpos($key,'extfld_') !== false){
                $properties[$key] = htmlentities($value,ENT_COMPAT | ENT_HTML401,'UTF-8');
            }
        }
        if (count($properties) > 0){
            $address->set('properties', json_encode($properties));    
        }
    break;
    
    case 'msOnManagerCustomCssJs':
        if ($page != 'orders') return;
	$modx->controller->addHtml("
            <script type='text/javascript'>
                Ext.ComponentMgr.onAvailable('minishop2-window-order-update', function(){
                	if (miniShop2.config['order_address_fields'].in_array('properties')){
                		if (this.record.addr_properties){
                		    var key;
                			for (key in this.record.addr_properties) {
                				this.fields.items[2].items.push(
                					{
                						xtype: 'displayfield',
                						name: 'addr_properties_'+key,
                						fieldLabel: _('ms2_properties_'+key),
                						anchor: '100%',
                						style: 'border:1px solid #efefef;width:95%;padding:5px;',
                						html: this.record.addr_properties[key]
                					}
                				);
                			}
                		}		
                	}
                });                
            </script>");
    break;
}

3. Добавляем вывод поля properties:
Заходим в системные настройки, там выбираем minishop2, блок Заказы.
Добавляем к значению «Поля адреса доставки» properties.


Добавляем записи словарей:
Заходим в Управление словарями, выбираем пространство имен minishop2, тема — manager, язык — ru.
Создаем новые записи с именами вида: ms2_properties_имя_вашего_поля (в данном случае ms2_properties_extfld_type, ms2_properties_extfld_org, ms2_properties_extfld_inn), значения — названия полей, которые будут отображаться в админке.

Поля не редактируемые, только выводят отправленные покупателем данные

Итоговый результат:

Дмитрий Меркурьев
11 октября 2016, 16:38
modx.pro
97
18 887
+11

Комментарии: 40

Павел Гвоздь
11 октября 2016, 20:42
+1
Сорцы править не хорошо.
    Дмитрий Меркурьев
    11 октября 2016, 21:30
    1
    0
    Согласен, и предупредил в посте о перезаписи при обновлении.
    Но все же лучше иметь хотя бы такое решение, чем не иметь его вообще. Каждый сам взвесит все плюсы и минусы и решит стоит ли использовать данный подход.
    А я в свою очередь постараюсь найти способ использования без правки исходного кода. Если есть мысли в какую сторону копать, то буду рад услышать.
    Дмитрий Меркурьев
    12 октября 2016, 14:52
    +2
    Решение обновлено, убраны правки исходного кода минишопа, теперь при обновлении ничего не затрется, изменены ключи у полей
      Марина Шипилова
      11 февраля 2017, 03:49
      0
      Здравствуйте. Все делаю, как вы написали. Но почему-то когда добавляю extfld_ в name — форма вообще не хочет отправлятся. Ругается, что ошибки в полях, хотя их нет. Подскажите, в чем может быть проблема?
      Марат Марабар
      12 октября 2016, 15:15
      0
      Чтобы js не подключался на каждой странице админки, я бы добавил ещё проверку
      ...
      ...
      case 'msOnManagerCustomCssJs':
      	if ($_GET['a'] != 'mgr/orders' && $_GET['namespace'] != 'minishop2') {
      		return;
      	}
      ...
      ...
      Алексей
      20 октября 2016, 12:22
      0
      Большое спасибо! все работает, только страничка заказов в админке не отображает заказы при первой загрузке (если нажать «обновить» в табличке -грузит ок.) и в консоль пишет:
      ms2.utils.js?v=2.4.4-pl:13 Uncaught TypeError: date.strftime is not a function
      вот этот файлик:
      github.com/bezumkin/miniShop2/blob/master/assets/components/minishop2/js/mgr/misc/ms2.utils.js#L13
      странно, но почемуто в последнем chrome видимо нету функции date.strftime?
        Дмитрий Меркурьев
        20 октября 2016, 12:35
        0
        В плагине не используются функции и методы из ms2.utils.js, так что скорее всего ошибка не из за него, при отключении плагина ошибка уходит и все работает нормально?
          Алексей
          20 октября 2016, 12:52
          0
          Нет, ошибка остается. При чем странно — при перезагрузке странички заказов в админке то все ок, то появляется эта ошибка, то нет. Никакой четкой зависимости не прослеживается. Вот скрин:

          и табличка заказов пуста…
            Дмитрий Меркурьев
            20 октября 2016, 13:09
            0
            Скорее всего какая то из дат приходит в неправильном формате и функции miniShop2.utils.formatDate не удается отформатировать ее в нужный вид. Я бы отправил в консоль string в этой функции и посмотреть что будет выдавать в случае появления ошибки.
        Oracul22
        21 октября 2016, 09:36
        0
        А как тогда значение этих доп полей вывести в чанке письма менеджерам?
        Следующий способ не срабатывает:
        [[+address.extfld_org]]
        и этот тоже не срабатывает
        [[+extfld_org]]
          Дмитрий Меркурьев
          21 октября 2016, 11:47
          +1
          Если используется Fenom то:
          {$address.properties.extfld_org}
          Если нет то:
          [[+address.properties.extfld_org]]
            Oracul22
            21 октября 2016, 12:43
            0
            Спасибо
              Андрей
              22 декабря 2016, 10:59
              0
              А скиньте пожалуйста свой чанк для отправки менеджеру с использованием Fenom, чтобы все поля приходили (тип оплаты, доставка и т.д.), а то не могу разобраться…
            Максим
            22 ноября 2016, 19:35
            0
            Странно, что вот это решение с сайта bezumkin.ru больше не доступно в интернете:
            web.archive.org/web/20150419200400/https://bezumkin.ru/modx/minishop2/solutions/2052/

            Или оно больше не работает?
              ck
              ck
              14 февраля 2017, 00:55
              0
              Вот здесь ещё предлагают вариант решения.
              Так всё-так как лучше добавить дополнительные поля к форме заказа, чтобы вывести их и на сайте и в админке MS2?
                Максим
                14 февраля 2017, 06:15
                0
                Не знаю, я делал как по ссылке, которую скидывал выше
              Максим
              24 ноября 2016, 21:00
              0
              А зачем вообще изначально в таблице modx_ms2_oerder_address поле properites? Что туда записывается?
                Олег Щавелев
                20 января 2017, 23:45
                +1
                Cпасибо, большое за плагин. Он классный.
                Но у меня вопрос, а как можно добавить поле, в профайл приложения Office? Если есть решение, то вообще плагин супер классный)
                  uzunhair
                  09 января 2018, 19:20
                  0
                  А как сделать обязательными чекбокс? Установил в админке обязательные поля, обычные новые поля не позволяют оформить заказ пока пусты, а вот чекбокс проходит в любом случае.
                  <label class="form-check-label">
                      <input class="form-check-input" type="checkbox" value="0" name="extfld_person" id="extfld_person">
                      C условиями обработки персональных данных ознакомлен
                  </label>
                    Рафис
                    27 июня 2018, 15:59
                    0
                    Просто добавь required:
                    <label class="form-check-label">
                        <input class="form-check-input" type="checkbox" value="0" name="extfld_person" id="extfld_person" required>
                        C условиями обработки персональных данных ознакомлен
                    </label>
                    Работает во всех современных браузерах. Но только для html5!
                      Михаил
                      08 ноября 2021, 10:15
                      0
                      А если все же не средствами html, как то можно передать чекбокс, что бы в аджике отображался?
                    Рафис
                    27 июня 2018, 16:00
                    0
                    Спасибо большое за плагин)
                      Рафис
                      12 июля 2018, 15:20
                      0
                      1
                        Max Roganov
                        11 октября 2018, 16:52
                        0
                        Всем привет, а плагин еще актуален для самой свежей версии minishop и modx?
                        Все сделал по гайду правильно но поле в админке не выводится и ошибок в js консоли нет…
                          Павел Романов
                          11 октября 2018, 19:14
                          +1
                          Да, актуален, работает исправно.
                          Проверьте имена полей и префикс.
                            Илья
                            09 февраля 2019, 21:21
                            0
                            разобрался? у меня тоже не работает :(
                              Дмитрий Мансуров
                              15 апреля 2019, 22:24
                              0
                              В системных настройках в поле
                              ms2_order_address_fields
                              проверь чтобы в списке значилось
                              properties
                              Вася
                              24 декабря 2018, 16:04
                              0
                              А есть где то туториал как добавить редактируемые?
                                Игорь Терентьев
                                04 февраля 2019, 07:50
                                0
                                Не нужно ли проверить нет ли свойств в $properties, перед тем, как объявлять массив?
                                case 'msOnBeforeCreateOrder':
                                        $address = $msOrder->getOne('Address');
                                        $properties = $address->get('properties');
                                        if (!is_array($properties)) {
                                            $properties = array();
                                        }
                                        ...
                                  Илья Александрович
                                  14 февраля 2019, 11:22
                                  0
                                  Скажите, а как вытащить свои поля? Мне нужно их передать в плагин.
                                  $this->Order->Address->get('extfld_ * ')
                                  — как то так пробовал, не получилось
                                    Михаил
                                    29 января 2020, 11:31
                                    0
                                    У меня почему-то не заработало(((. ЧТо то как то трудно добавляются поля в админку в заказы. Не получается сделать… Уже много всяких мануалов прочитал… Непонятно как это сделать. Слишком намудрили в этом минишопе
                                      Алексей Шумаев
                                      29 января 2020, 12:18
                                      1
                                      +2
                                      Расширить модель msOrder: https://modx.pro/solutions/7037.
                                      case 'OnMODXInit':
                                      
                                          # добавим расширение для msOrderAddress
                                          $modx->loadClass('msOrderAddress');
                                          #добавить новое поле для адреса 
                                      	$modx->map['msOrderAddress']['fields']['new_field'] = 0;
                                      	$modx->map['msOrderAddress']['fieldMeta']['new_field'] = array(
                                                  'dbtype' => 'varchar',
                                                  'phptype' => 'string',
                                                  'precision' => 100,
                                                  'null' => true,
                                                  'default' => null,
                                      	);
                                      
                                              # добавим расширение для msOrder
                                              $modx->loadClass('msOrder');
                                      	$modx->map['msOrder']['fields']['new_field'] = 0;
                                      	$modx->map['msOrder']['fieldMeta']['new_field'] = [
                                                  'dbtype' => 'int',
                                                  'precision' => 8,
                                                  'phptype' => 'integer',
                                                  'null' => true,
                                                  'default' => 0
                                      	];
                                      Всё. Работаете со своими полями, как и с любыми другими.
                                      Александр
                                      20 апреля 2020, 17:09
                                      0
                                      Кто-нибудь может подсказать, как сделать поле редактируемым? Пробую так:

                                      $modx->controller->addHtml("
                                                  <script type='text/javascript'>
                                                      Ext.ComponentMgr.onAvailable('minishop2-window-order-update', function(){
                                                      	if (miniShop2.config['order_address_fields'].in_array('properties')){
                                                      		if (this.record.addr_properties){
                                                      		    var key;
                                                      			for (key in this.record.addr_properties) {
                                                      				this.fields.items[2].items.push(
                                                      					{
                                                      						xtype: 'textfield',
                                                                                                      id: 'addr_properties_'+key,
                                                      						name: 'addr_properties_'+key,
                                                      						fieldLabel: _('ms2_properties_'+key),
                                                      						anchor: '100%',
                                                      						style: 'border:1px solid #efefef;width:95%;padding:5px;',
                                                      						value: this.record.addr_properties[key]
                                                      					}
                                                      				);
                                                      			}
                                                      		}		
                                                      	}
                                                      });                
                                                  </script>");
                                      Поле создаётся редактируемым, но при этом пустое. И не задаётся значение, если его вручную заполнить.
                                      Есть тут знатоки ExtXS?
                                        Александр
                                        20 апреля 2020, 17:48
                                        0
                                        ExtJS вернее…

                                        пока писал понял, что смысла делать редактируемое поле, нет, т.к. оно в json-формате
                                        Pavel Kravchuk
                                        10 октября 2023, 23:05
                                        0
                                        Здравствуйте
                                        подскажите пожалуйста, как используя данный плагин вывести лейбл поля? я его передаю в плагине и на вкладке Адрес он отображается, а вот на вкладке Заказы только общая DIV со значением.
                                        Спасибо.

                                          Авторизуйтесь или зарегистрируйтесь, чтобы оставлять комментарии.
                                          40