Практика: Работа с Entity API

Аватар пользователя man-1982

В этой статье я хочу поделиться опытом программного создания товаров c использование Drupal commerce и Entyti API.

Почему именно товаров? Потому что программное создание нод, терминов и пользователей в интернете встречается довольно часто, а вот работа с товарами в drupal commerce это прямо скажем целая трагедия, информации не сильно много.

Цель работы:
Научиться программно создавать продукт(товар).
Научиться использовать Entity API.
Программно заполнять различные типы полей.

Приборы и Материалы:
Drupal commerce
entity
Field collection
Devel

Ход работы:
Скачиваем и устанавливаем.
Создаем словарь Brand и заполняем его 5-6 терминами

Для дальнейшей работы нам необходимо создать набор полей для нашего товара.
Переходим по admin/commerce/config/product-variation-types/product
Ставим отметку "Автоматическая генерация Артикула" и указываем токен для генерации
2014-03-25_164757.png
Далее переходим в раздел "Управление полями"
Здесь добавляем следующие поля:
Image -> тип "Изображение" в настройках поля "Количество значений" поставить не ограничено.
Brand -> тип "Ссылка на термин" в настройках поля "Количество значений" поставить 1.
Features -> тип "Feild collection" в настройках поля "Количество значений" поставить не ограничено.
Weght -> тип "Десятичное число" в настройках поля "Количество значений" поставить 1
2014-03-26_100904.png

Поле Features (field collection) состоит из двух полей "Наименование" - это имя свойства(цвет, версия и т.д) и "Значение" - значение свойства (красный, ver 5.0).
2014-03-26_101304.png
Теперь можно приступать непосредственно к разработке.
Создадим новый модуль и назовем его devel_product. Весь код для генерации продуктов будем писать там.
Делаем папку devel_product и два файла в ней devel_product.info, devel_product.module.
Код в devel_product.info

name = Devel generate product
core = 7.x
package = Development
description = Generate commerce product
version = 7.x-1.0
project = devel_product
configure = admin/config/development/devel-product

Код devel_product.module

<?php

/**
* hook_menu
*/
function devel_product_menu() {
  $items['admin/config/development/devel-product'] = array(
    'title'             => 'Generate product',
    'page callback'     => 'drupal_get_form',
    'page arguments'    => array('devel_product_generate_form'),
    'access arguments'  => array('administer site configuration'),
  );

  return $items;
}

/**
* Form for generate product
*/
function devel_product_generate_form($form) {
  $form['submit'] = array(
    '#type'  => 'submit',
    '#value' => t('Generate product'),
    '#submit' => array('devel_product_generate_form_submit'),
  );
  return $form;
}

/**
* Callback for submit form
*/
function devel_product_generate_form_submit($form, &$form_state) {
  devel_product_generate_product();
}

/**
* Generate product
* @param $count
*/
function devel_product_generate_product() {

}

Как мы видим реализован hook_menu и сделана форма с кнопкой "Generate product".
На данном этапе все основные действия будут крутится в функции devel_product_generate_product .
В дальнейшем мы будем использовать ряд функций из модуля devel_generate, рекомендую его включить
drush en devel_generate -y

Дальнейший порядок наших действий следующий.

  1. В нашей функции создаем новый продукт
  2. Используем entity api создадим и заполним поля

Перед началом работы рекомендую быстро пробежаться по документации entity
У проекта entity довольно хорошая документация . Но кто же ее читает? (с)
Я ее читал, но как это частенько бывает в комментариях к документации я больше узнал и почерпнул, чем в самой документации.
Суть модуля entity: Предоставляет единый механизм для работы с сущностями Drupal.

/**
* Generate product
* @param $count
*/
function devel_product_generate_product() {
  $product = commerce_product_new('product'); //создаем новый product
  $epw = entity_metadata_wrapper('commerce_product', $product);

  $instances = field_info_instances('commerce_product', 'product');// Получаем екзепляры полей для вариации товара типа 'product'
  dpm($instances);// Выводим структуру всех екземпляров связанных с типом product
  $field_image = field_info_field('field_image');// Получаем информа
  $instance_image = $instances['field_image'];
  module_load_include('inc', 'devel_generate', 'devel_generate');
  module_load_include('inc', 'devel_generate', 'image.devel_generate');
  module_load_include('inc', 'devel_generate', 'devel_generate.fields');
  $image = image_devel_generate($product, $field_image, $instance_image, 'product'); // Генерим картинку с использованием модуля devel_generate

  $epw->field_image           = $image; // Устанавливаем картинки для товара
  $epw->title                 = "Title " . rand(1, 100); // Заголовок
    $epw->commerce_price->data = array(
    'amount_desimal'  => rand(1, 600),// Цена
    'amount'          => 1, //количество товара по этой цене
    'currency_code'   => commerce_default_currency() // получаем валюту по умолчанию
  );
  $voc = taxonomy_vocabulary_machine_name_load('brends'); // Получаем словарь брендов
  $terms = taxonomy_get_tree($voc->vid);
  shuffle($terms);
  $epw->field_brand = $terms[0]->tid; // Устнанавливаем Brand. Прим: эта форма записи когда значение единично.

  $epw->save(); // сохраняем product

  //Создаем новый field collection
  /**
   * Для field collection необходмио использовать так назывваемый host entity.
   * Соответсвенно перед тем как создавать collection field необходимо создать продукт. $epw->save()
   */
  $field_collection_new_item = entity_create('field_collection_item', array('field_name' => 'field_feature'));
  $fcw = entity_metadata_wrapper('field_collection', $field_collection_new_item); // Получаем "обертку" для field collection
  $fcw->field_name_prop = 'Свойство' . rand(1, 100); // field_name_prop - поле для наименования свойтсва, создали через веб-интерфейс
  $fcw->field_value_prop = 'Значение свойства' . rand(1, 100); // field_value_prop - значение свойсва, создали через веб-интерфейс

  $field_collection_new_item->setHostEntity('commerce_product', $product);// Устанавливам host entity
  $fcw->value()->save();

  $field_collection[] = $field_collection_new_item;
  $epw->field_feature = $field_collection;


  $id    = $epw->getIdentifier(); // Получаем индентификатор
  $label = $epw->label();         // Получаем заголовок
  dpm($product, $label . ' : ' . $id);
}

В принципе все основные комментарии и разъяснения в коде.
Результаты работы можно посмотреть admin/commerce/products/variations.
Хочу акцентировать внимание, что в данной работе мы научились создавать только "варианты продукта". А в commerce есть еще такое понятие как "Представление продукта". Как создать программно "Представление продукта" я напишу чуть позже.

Выводы:
Научились использовать основные функции Entity API, программно создавать сущности и заполнять поля, в частности поля field collection

Основные методы которые стоит запомнить:
commerce_product_new - Создаем новый продукт
entity_metadata_wrapper - Экземпляр класса обертки для сущности.
entity_create - создаем новый объект сущности.

Методы Entity warapper:
save() - сохраняем сущность в базу
getIdentifier() - получаем идентификатор (nid, tid, fid)
label() - получаем заголовок (title, name)

Методы и функции полей (field):
field_info_instances - получить экземпляры полей для определенного типа сущности
field_info_field - получить конкретное поле по имени

Комментарии