Общая идея
Идея разработки данного модуля была (как это часто бывает) продиктована острой в нём необходимостью.
Представьте, что вы организуете интернет магазин (или любой другой проект в котором планируется создавать много различных типов содержимого). Предположим, что в качестве программного комплекса Вы выбрали связку Drupal 7 + Commerce. Commerce дает возможность создавать разные типы продуктов. Это полезно, когда Вы торгуете разными категориями товаров, для каждой из которых характерны какие-то свои данные. Например для мониторов Вы скорее всего захотите указать тип матрицы, а для процессоров неплохо будет указать тактовую частоту.
Теперь представим ситуацию, когда Вам нужно организовать каталог с множеством категорий связанных между собой иерархическими отношениями. Для наглядности представим подобную структуру.
Предположим, для всех товаров Вы хотите указать страну изготовителя, производителя и год выпуска. Назовем это базовым типом. Предположим, Вы продаете компьютеры. У всех компьютеров есть общие характеристики (операционная система, количество usb портов и т.п.). Вы продаете ноутбуки, настольные ПК и планшеты. Все они обладают характеристиками компьютеров и у каждого есть характерные только для них признаки (например время работы батареи для ноутбуков).
Таким образом получается следующая схема.
- Базовый тип
- Компьютеры (наследуют базовый тип)
- Ноутбуки, ПК, планшеты (наследуют тип «компьютеры»)
Что дает модуль
Модуль Bundle Inherit позволяет при создании нового типа содержимого (entity bundles) наследовать его от одного из имеющихся типов того же типа сущности. При этом все поля имеющиеся в типе-родителе автоматически прикрепляются к новосозданному типе.
Дальше интереснее. Модуль поддерживает два типа наследования: мягкий (soft) и строгий (strict).
В случае с мягким типом наследования процесс будет следующим. При создании нового типа сущности к нему будут просто прикреплены поля выбранного родительского типа. На этом модуль закончит свою работу и не будет никак отслеживать эти типы.
В случае со строгим наследованием происходит следующее. Как и в случае с мягким наследованием к новому типу прикрепляются все поля родительского типа. При этом экземпляры унаследованных полей в новом типе блокируются и становятся недоступными для редактирования и удаления. Далее модуль начинает отслеживать родительский тип. Модуль реагирует на 3 ситуации:
- При создании нового поля, экземпляр данного поля автоматически прикрепляется ко всем дочерним типам (типам унаследованным от родительского).
- При изменении экземпляра поля в родительском типе, все изменения автоматически переносятся на унаследованные экземпляры.
- При удалении экземпляра поля из родительского типа, во всех дочерних типах поле разблокируется и становится доступным для редактирования и удаления. В последующем планируется предоставить пользователю возможность согласится или отказаться от автоматического удаления полей и всех связанных данных из дочерних типов.
Как организован модуль
Модуль фактически является комплектом из двух модулей.
Первый (модуль bundle_inherit) предоставляет API для разработчиков модулей и не дает никакого функционала конечному пользователю.
Второй (модуль bundle_inherit_node) является примером использования Bundle Inherit API. Состоя всего-лишь из 40 строчек кода включая комментарии, модуль расширяет системный модуль node позволяя наследовать типы содержимого.
Использование модуля
С точки зрения конечного пользователя
При создании нового типа содержимого найдите вкладку Inherit (Наследование) отметьте галочкой соответствующий пункт и выберете родительский тип. This is it.
С точки зрения разработчика
Посмотрите реализацию на примере модуля bundle_inherit_node.
Все что нужно, чтобы добавить возможность наследования к произвольному типу сущностей — это найти форму создания нового типа и использовать на ней функцию bundle_inherit_attach_inherit_form. Также не забудьте добавить к ней свой submit callback и в нем вызвать функцию bundle_inherit_attach_inherit_form_submit. И что называется «that is the magic».
Перспективы
Они есть. Планируется расширять функциональность Bundle Inherit API чтобы позволить применять логику наследования не только к полям но и интегрироваться с внутренней логикой разных типов сущностей.
Еще одно возможное направления для расширения модуля — возможность создавать абстрактные типы сущностей. Типы, которые можно использовать только для наследования.
Где взять
Drupal.org: drupal.org/project/bundle_inherit
GitHub: github.com/numesmat/Drupal-Bundle-Inherit