В Drupal Commerce имеется одна неприятная особенность, с которой может столкнуться каждый. Проблема заключается в том, что в базе данных у цен размер равен int(11). Но существует ряд стран, например Беларусь, где цена 30 000 000.00 и больше - вполне нормальное явление. И тут начинаются проблемы, при попытке оформить заказ с такой ценой - система безотказно будет информировать нас о том, что цена выходит за границы размера поля.
Чтобы исправить эту проблему, имплементируем хук hook_field_create_field():
<?php
/**
* Implements hook_field_create_field().
*/
function example_field_create_field($field) {
if ($field['module'] == 'commerce_price'
&& $field['type'] == 'commerce_price'
&& isset($field['columns']['amount']['type'])
&& $field['columns']['amount']['type'] == 'int'
&& (!isset($field['columns']['amount']['type']) || $field['columns']['amount']['type'] != 'big')) {
$spec = $field['columns']['amount'];
$spec['size'] = 'big';
foreach (array('field_data_', 'field_revision_') as $prefix) {
$table = $prefix . $field['field_name'];
$column = $field['field_name'] . '_amount';
db_change_field($table, $column, $column, $spec);
}
}
}
Теперь при создании новых "commerce_price" полей, их размер будет изменен на big. Модуль с этим хуком необходимо включить до того, как будет установлен Drupal Commerce.
Для обновления всех существующих полей, необходимо открыть консоль и воспользоваться командой:
drush eval 'foreach (field_info_fields() as $field) { example_field_create_field($field); }'
Update
С момента написания урока, прошло немало времени и код, который работал в момент написания вдруг перестал работать. Вооружившись дебагером я посмотрел, что же пошло не так и как оказалось, что каждый раз, когда мы сохраняем настройки поля, вызвается функция field_update_field(), которая обновляет схему поля на дефолтную. Что ж, немного модифицируем наш модуль.
Для начала напишем новую функцию, которая будет изменять схему поля:
/**
* Updates a size of "amount" column for commerce_price field.
*
* @param array $field
* A field structure. $field['field_name'] must provided; it identifies the
* field that will be updated to match this structure. Any other properties
* of the field that are not specified in $field will be left unchanged,
* so it is not necessary to pass in a fully populated $field structure.
*/
function _example_commerce_price_update_field($field) {
if ($field['module'] == 'commerce_price'
&& $field['type'] == 'commerce_price'
&& isset($field['columns']['amount']['type'])
&& $field['columns']['amount']['type'] == 'int'
&& (!isset($field['columns']['amount']['type']) || $field['columns']['amount']['type'] != 'big')) {
$spec = $field['columns']['amount'];
$spec['size'] = 'big';
foreach (array('field_data_', 'field_revision_') as $prefix) {
$table = $prefix . $field['field_name'];
if (db_table_exists($table)) {
$column = $field['field_name'] . '_amount';
db_change_field($table, $column, $column, $spec);
}
}
}
}
Далее имплементируем хуки hook_field_create_field() и hook_field_update_field():
/**
* Implements hook_field_create_field().
*/
function example_field_create_field($field) {
_example_commerce_price_update_field($field);
}
/**
* Implements hook_field_update_field().
*/
function example_field_update_field($field, $prior_field, $has_data) {
_example_commerce_price_update_field($field);
}