Автоматическое создание артикула

Может кому пригодится.

Если храним артикул в ТВ и не охото заморачиватся с прописыванием каждого артикула в ручную.
Если нет изначальных артикулов, а их надо придумать.

Артикулы получаются типа: pl-38125 или 438125 во второй версии плагина.

Создаем ТВ с именем например articul, привязываем к шаблону карточки товара.

Создаем плагин с именем например CreateArticul, который проверяет если ТВ артикула пустое то при сохранении документа он будет создан.

Вешаем плагин на событие: OnDocFormSave
<?php
if ($modx->event->name=="OnDocFormSave") // Плагин срабатывает при сохранении ресурса
{    
    $tv = 'articul'; // ТВ артикула
    $id = $resource->get('id'); // Получаем id ресурса
    $parent = $resource->get('parent'); // Получаем id родительского ресурса
    $alias = $resource->get('alias'); // Получаем alias ресурса
    $tvv = $resource->getTVValue($tv); // Получаем ТВ
    
    if (empty($tvv)) // Если ТВ пустое то создаем артикул
    {
        $articul = substr($alias,0,2).'-'.$parent.$id; // Создаем артикул
        $resource->setTVValue($tv, $articul); // Записываем артикул в ТВ
    }
}
Артикулы получаются типа: pl-38125

Не много модифицировал плагин под числовые значения:
<?php
if ($modx->event->name == "OnDocFormSave") 
{    
    $tv = 'articul';
    $id = $resource->get('id');
    $parent = $resource->get('parent');
    $tvv = $resource->getTVValue($tv);
    
    if (empty($tvv))
    {
	   switch ($str=strlen($parent.$id))
       {
         case ($str <= 4): $article = mt_rand(0, 9).mt_rand(0, 9).$parent.$id; break;     
         case ($str == 5): $article = mt_rand(0, 9).$parent.$id; break;   
         case ($str == 6): $article = $parent.$id; break;
         case ($str >= 7): $article = substr($parent.$id, 1); break;
       }		
               $resource->setTVValue($tv, $article);
    }
}
Артикулы получаются в числовом формате типа: 438125
@ndrew
04 марта 2016, 00:52
modx.pro
15
5 457
+2

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

Сергей Фещуков
04 марта 2016, 05:08
0
Возьму на себя смелость переписать это дело под стандартное поле Артикул компонента miniShop2.
<?php
if ($modx->event->name=="OnDocFormSave") // Плагин срабатывает при сохранении ресурса
{
    $id = $resource->get('id'); // Получаем id ресурса
    $parent = $resource->get('parent'); // Получаем id родительского ресурса
    $alias = $resource->get('alias'); // Получаем alias ресурса
    $res = $modx->getObject('msProduct', $id); // Получаем объект товара
    $tvv = $res->get('article'); // Получаем артикул
    
    if (empty($tvv)) // Если артикул пустой то создаем его
    {
        $article = substr($alias,0,2).'-'.$parent.$id; // Создаем артикул
        $res->set('article', $article); // Записываем артикул в соответствующее поле
        $res->save(); // Сохраняем
        $res->clearCache(); // Чистим кеш
    }
}
Но в этом плагине смущают меня два момента:
1. Зачем снова получаем объект ресурса, если он есть в переменной $resource? По-моему, все функции, типа save() и clearCache() в нём тоже доступны.
2. Плагин выполняет код после сохранения страницы. При сохранении страницы чистится кэш (по умолчанию). И создаётся он только тогда, когда к странице снова обратятся на фронтенде (насколько я знаю). Зачем тогда снова чистить кэш после сохранения поля?
    @ndrew
    04 марта 2016, 05:41
    0
    Да с получением еще раз объекта перемудрил, поправил плагин, все работает.
    Кеш можно так же отключить плагином, что бы не чистился при сохранении каждого ресурса например.
    Так что подстраховка, если кеш не отключен плагином то можно строку $res->clearCache(); закомментировать или удалить, хотя вреда от нее нет никакого. ;)
      Сергей Фещуков
      04 марта 2016, 06:02
      3
      0
      Для товаров miniShop2 упрощённый вариант плагина:
      <?php
      if ( $modx->event->name != "OnDocFormSave" || $resource->get('class_key') != 'msProduct' || !empty($resource->get('article')) ) return;
      $resource->set('article', substr($resource->get('alias'),0,2).'-'.$resource->get('parent').$resource->get('id'));
      $resource->save();
      $resource->clearCache();
        Яна
        23 марта 2016, 10:34
        0
        Ой нужна такая штука. А для одаренных… в минишопе его как подключать: создать стандартно плагин повесить на событие? тогда при сохранении товара просто зависает бесконечное окошко «сохранение»
          @ndrew
          23 марта 2016, 14:48
          0
          Попробуйте так:
          <?php
          if ($modx->event->name=="OnDocFormSave") // Плагин срабатывает при сохранении ресурса
          {
              $id = $resource->get('id'); // Получаем id ресурса
              $parent = $resource->get('parent'); // Получаем id родительского ресурса
              $alias = $resource->get('alias'); // Получаем alias ресурса
              $res = $modx->getObject('msProduct', $id); // Получаем объект товара
              $tvv = $res->get('article'); // Получаем артикул
              
              if (empty($tvv)) // Если артикул пустой то создаем его
              {
                  $article = substr($alias,0,2).'-'.$parent.$id; // Создаем артикул
                  $res->set('article', $article); // Записываем артикул в соответствующее поле
              }
          }
            Яна
            23 марта 2016, 17:43
            0
            зависания теперь нет, но если вручную завожу артикул, то вывод в товаре есть, если пересохраняю или создаю новый товар, то поле [[+article]] остается пустым
              @ndrew
              23 марта 2016, 23:04
              0
              Я с минишопом не работал, а делал плагин где все товары это ресурсы. Для шопкипера или каталога ресурсов без магазина но с уникальным индификатором для каждого элемента.
              И просто скопировал модифицированный мой вариант предложенный Сергей Фещуков.

              Спросите автора минишопа Василий Наумкин как правильно получить объект товара.

              Потому что в коде выше:
              $id = $resource->get('id'); // Получаем id ресурса
              ................
              $res = $modx->getObject('msProduct', $id); // Получаем объект товара
    Григорий Коленько
    04 марта 2016, 10:20
    1
    +1
    Нет необходимости вызывать метод save(). И кэш чистить необязательно.
    rtfm.modx.com/revolution/2.x/developing-in-modx/basic-development/plugins/system-events/ondocformsave
      @ndrew
      04 марта 2016, 19:52
      0
      Спасибо, поправил.
        Алексей Смирнов
        19 августа 2016, 16:45
        0
        Ну для стандартных МОДх обьектов это может и сработает, для минишопа в рево 3.5 нужно было добавить сохранение…
        $resource->save();
        Проверено только что.
        kafked
        31 марта 2016, 16:32
        0
        Добрый день! Столкнулся с проблемой, при срабатывании события (сохранение карточки товара) выскакивает ошибка:
        « MODX Parse Error »
        MODX encountered the following error while attempting to parse the requested resource:
        « PHP Parse Error »
        PHP error debug
        Error : syntax error, unexpected '<'
        Parse error: syntax error, unexpected '<' in /home/site/www/site/manager/includes/document.parser.class.inc.php(964) : eval()'d code on line 1
        ErrorType[num] : 	PARSING ERROR[4]
        File : 	/home/site/www/site/manager/includes/document.parser.class.inc.php(964) : eval()'d code
        Line : 	1
        Source : 	Plugin
        Basic info
        REQUEST_URI : 	http://site/manager/index.php
        Manager action : 	5 - Saving resource
        Current Plugin : 	CreateArticul(OnDocFormSave)
        Referer : 	http://site/manager/index.php?a=27&id=10290
        User Agent : 	Mozilla/5.0 (Windows NT 6.3; WOW64; rv:45.0) Gecko/20100101 Firefox/45.0
        IP : 	93.84.44.184
        Benchmarks
        MySQL : 	0,0317 s (18 Requests)
        PHP : 	0,0430 s
        Total : 	0,0747 s
        Memory : 	6,8300399780273 mb
        
        Backtrace
        1	include_once()
        manager/index.php on line 300
        2	DocumentParser->invokeEvent()
        manager/processors/save_content.processor.php on line 645
        3	DocumentParser->evalPlugin()
        manager/includes/document.parser.class.inc.php on line 3361
        Версия ModX — 1.0.15. Каталог товаров организован через ресурсы. В чем может быть проблема? Использовал все возможные вариации кода плагина.
          kafked
          01 апреля 2016, 12:19
          0
          Насколько я разобрался — под modX Evo совсем другой язык. Документация и вики не прояснили никаких моментов касательно написания рабочего парсера. Буду благодарен за любую помощь!
            Воеводский Михаил
            01 апреля 2016, 13:10
            0
            По Эво Вам дорога на modx.im или modx.ru. Здесь таких специалистов почти нет.
          yani
          25 октября 2017, 23:25
          0
          Добрый вечер, а как сделать, чтобы значение присвоенное отобразилось тут же на форме?
            Авторизуйтесь или зарегистрируйтесь, чтобы оставлять комментарии.
            14