Из коробки drupal commerce поддерживает связь между commerce_product и display_product только с одной стороны: cо стороны ноды (display_product). Многим этого достаточно, но бывают варианты, когда требуется при работе с продуктом получить доступ к данным из ноды. Есть один очень хороший способ наладить такую связь без больших затрат. Основан он на возможности объявлять у сущностей свои свойства.
Кстати, он реализован в модуле commerce_search_api, поэтому если у Вас установлен и включен данный модуль, то дальше можно не читать. А вот если Вы не планируете использовать в своем проекте search_api+commerce_search_api, то я просто рекомендую добавить в свой модуль две функции, приведенные ниже (код не мой, а взят из модуля commerce_search_api).
/**
* Implements hook_entity_property_info_alter().
*/
function ИМЯМОДУЛЯ_entity_property_info_alter(&$info) {
// Retrieve the product display from the product.
$properties = & $info['commerce_product']['properties'];
foreach (field_info_fields() as $field) {
if ($field['module'] != 'commerce_product_reference') {
continue;
}
$field_name = $field['field_name'];
foreach ($field['bundles'] as $entity_type => $bundles) {
$properties[$field_name . '_' . $entity_type] = array(
'description' => t('A bridge to @entity_type referenced by @field_name', array(
'@entity_type' => $entity_type,
'@field_name' => $field_name,
)),
'getter callback' => 'frz_tweaks_backreference_getter',
'field' => $field,
'label' => t('A bridge to @entity_type referenced by @field_name', array(
'@entity_type' => $entity_type,
'@field_name' => $field_name,
)),
'target type' => $entity_type,
'type' => 'list<' . $entity_type . '>',
);
}
}
}
/**
* Getter callback for retrieving related entities.
*/
function frz_tweaks_backreference_getter($entity, array $options, $name, $type, $info) {
$entities_ids = array();
// Retrieve the field.
$field = $info['field'];
$entity_target_type = $info['target type'];
$entity_wrapper = entity_metadata_wrapper($type, $entity);
$query = new EntityFieldQuery();
$query->entityCondition('entity_type', $entity_target_type, '=')
->fieldCondition($field['field_name'], 'product_id', $entity_wrapper->getIdentifier(), '=');
$result = $query->execute();
if (isset($result[$entity_target_type])) {
$entities_ids = array_keys($result[$entity_target_type]);
}
return $entities_ids;
}
Применение
Теперь для каждого созданного вами поля с типом commerce_product_reference, будет создана обратная связь товара и ноды. Для чего это все?
- Токены. Теперь у сущности commerce_product появляется возможность достучаться до всего набора токенов ноды display_product. Выглядит это примерно так [commerce-product:field-product-node:nid]. Может быть полезно, если для автоматической генерации заголовков товаров применяется модуль auto_entitylabel
- Views. Теперь работая в views с commerce_product вы всегда можете добавить в разделе Relationship связь с материалом, а дальше работать с его данными
Entity metadata wrappers. Работаете с товаром в корзине и хотите получить доступ к данным ноды? Не проблема:
$line_item_wrapper = entity_metadata_wrapper('commerce_line_item', $line_item); $product_img = $line_item_wrapper->commerce_product->field_product_node[0]->field_image->value();
- думаю, еще много интересного можно придумать
- 03.11.2016
- 92 просмотра