Модуль Migrate это фреймворк для миграции (импорта) данных в Drupal из любых источников.
В сети можно найти много примеров, как им пользоваться. Вот хорошая статья с примером импорта материалов типа "page". Данный модуль отлично справляется со стандартным набором свойст сущностей и их полями, добавленными через fieldAPI.
Те, кто работал с ubercart знает, что данный модуль для хранения общей (базовой) информации о товаре использует свою, отдельную таблицу. Принцип работы прост - при загрузке ноды срабатывает hook_load() и данные из таблиц подгружаются к текущему объекту $node. Когда на форме создания/редактирования товара вы меняете информацию, то новые значения сразу меняются в объекте $node, затем отрабатывает hook_insert() или hook_update() и данные попадают в таблицу. Вообще, это не новая практика (подробнее)... Для чего я это описал подробно - что-бы стала понятна одна очевидная и важная деталь - "что бы изменить ubercart-цену у товара, просто необходимо изменить ее значение в объекте $node до вызова функции node_save".
Итак, с механизмом понятно... Заветный "node_save" вызывает migrate во время импорта. Проблема в том, что он из коробки понятия не имеет про такие ubercart-свойства товара, как 'model', 'list_price', 'cost', 'sell_price' и т.д и т.п. Ничего не поделаешь, придется его "научить".
У migrate естьподдержка своих destination плагинов. Стандартный класс для импорта в ноды - MigrateDestinationNode. Создадим свой класс MigrateDestinationProductNode унаследовав все методы и свойства родителя (мы же не хотим переделывать всю обработку импорта ноды):
class MigrateDestinationProductNode extends MigrateDestinationNode { ... }
Список доступных полей для импорта выводит метод MigrateDestinationNode::fields($migration); Вот его то мы и изменим (просто дополним):
class MigrateDestinationProductNode extends MigrateDestinationNode { public function fields($migration = NULL) { //подгрузим список полей для ноды "по-умолчанию" $fields = MigrateDestinationNode::fields($migration); //добавим проверку на тип материала $node_type = node_type_load($this->bundle); if($node_type->type == 'product'){ //Добавим базовые поля от ubercart $fields['model'] = t('Product SKU/model.'); $fields['list_price'] = t('The listed MSRP.'); $fields['cost'] = t("Your store's cost."); $fields['sell_price'] = t('Customer purchase price.'); } return $fields; } }
Ну вот, в принципе на сегодня у меня все :-)
Реализацию данного класса можно расположить в том же файле, где Вы создаете свой класс для миграции.
Теперь наш migrate будет в курсе базовых полей ubercart.
Раньше в своем классе для импорта вы использовали такую конструкцию:
// Destination $this->destination = new MigrateDestinationNode('product');
теперь просто используйте новый класс:
// Destination $this->destination = new MigrateDestinationProductNode('product');
Если включен migrateUI, то новые поля будут доступны для "привязки":
P.S. Кстати, такой метод подойдет для любых "своих" данных, у которых аналогичный механизм хранения/обновления.
Актуально для:
migrate7.x-2.8
Комментарии
Добавить комментарий