Drupal 7 Field API hook_field_validate не получает данные? - PullRequest
2 голосов
/ 02 августа 2011

Мой модуль реализует ряд функций API поля, чтобы обеспечить пользовательский тип поля, состоящий из текстового поля и текстовой области. Функция hook_field_validate вызывается со всеми правильными ключами, но без каких-либо значений - будет очень признателен, если кто-нибудь просмотрит весь код и скажет, есть ли какие-либо проблемы.

function brooklands_field_info() {
    return array(
        'brooklands_heading_text' => array(
            'label' => t('Heading with text'),
            'description' => t('Heading with text - says it all.'),
            'default_widget' => 'brooklands_heading_text_widget',
            'default_formatter' => 'brooklands_heading_text_formatter',
        ),
    );
}

function brooklands_field_validate($entity_type, $entity, $field, 
                        $instance, $langcode, $items, &$errors) {
    /*foreach ($items as $delta => $item) {

            // $item never contains any data!!!!!

        $heading = check_plain($item['brooklandsheading']);
        $text = check_markup($item['value'], $item['format']);
        if(!empty($heading) || !empty($text) && empty($heading) || empty($text)) {
            $errors[$field['field_name']][$langcode][$delta][] = array(
                'error' => 'brooklands_invalid',
            'message' => t('Must have both heading and text'),
        );
        }
    }*/
}

function brooklands_field_widget_error($element, $error, $form, &$form_state) {
    switch ($error['error']) {
        case 'brooklands_invalid':
        form_error($element, $error['message']);
        break;
    }
}

function brooklands_field_is_empty($item, $field) {
    return empty($item['brooklandsheading']) || empty($item['value']);
}

function brooklands_field_formatter_info() {
    return array(
        'brooklands_heading_text_formatter' => array(
            'label' => t('Heading text formatter'),
            'field types' => array('brooklands_heading_text'),
        ),
    );
}

function brooklands_field_formatter_view($entity_type, $entity, $field, 
                        $instance, $langcode, $items, $display) {
    $element = array();
    foreach ($items as $delta => $item) {
        $element[$delta]['#markup'] = '<div class="brooklands-heading-text"><h3>'
        .check_plain($item['brooklandsheading']).'</h3>'
        .check_markup($item['value'], $item['format']).'</div>';
    }
    return $element;
}

function brooklands_field_widget_info() {
    return array(
        'brooklands_heading_text_widget' => array(
            'label' => 'Heading/text widget',
            'field types' => array('brooklands_heading_text'),
        ),
    );
}

function brooklands_field_widget_form(&$form, &$form_state, $field, 
                        $instance, $langcode, $items, $delta, $element) {
    $element['brooklandsheading'] = array(
        '#delta' => $delta,
        '#default_value' => isset($items[$delta]['brooklandsheading']) ? 
            $items[$delta]['brooklandsheading'] : '',
        '#type' => 'textfield',
        '#size' => 64,
        '#maxlength' => 256,
        '#title' => t('Heading')
    );
    $text = array(
        '#type' => 'textarea',
        '#default_value' => isset($items[$delta]['value']) ? 
            $items[$delta]['value'] : '',
    );
    $element += $text;
    $element['#format'] = isset($items[$delta]['format']) ? 
                            $items[$delta]['format'] : NULL;
    $element['#base_type'] = $element['#type'];
    $element['#type'] = 'text_format';
    $element['#title'] = t('Text');
    return $element;
}

РЕДАКТИРОВАТЬ: Это реализация hook_field_schema из установочного файла моего модуля-

function brooklands_field_schema($field) {
    $columns = array(
        'brooklandsheading' => array(
            'type' => 'varchar',
            'length' => 256,
            'not null' => FALSE
        ),
        'value' => array(
            'type' => 'text',
            'not null' => FALSE
        ),
        'format' => array(
            'type' => 'varchar',
            'length' => 255,
            'not null' => FALSE,
        ),
    );
    return array(
        'columns' => $columns,
        'indexes' => array(
            'format' => array('format'),
        ),
        'foreign keys' => array(
            'format' => array(
                'table' => 'filter_format',
                'columns' => array('format' => 'format'),
            ),
        ),
    );
}

1 Ответ

0 голосов
/ 17 октября 2011

Я нахожу этот код немного запутанным, и я не эксперт, но я только что решил и исправил подобную проблему, и я чувствую, что этот вопрос заслуживает хотя бы осторожного частичного ответа для записи.

Я понимаю, что форма генерируется путем циклического прохождения и рендеринга массива $ element, и она выясняет, как сопоставить полученную входную информацию со схемой по ключам каждого элемента в массиве.

Итак, тут мне сразу кажется неправильным то, что схема устанавливает 3 типа данных для хранения: 'brooklandsheading', 'value' и 'format', поэтому я ожидаю, чтоМассив $ element содержит $ element ['brooklandsheading'], который определяет текстовое поле, $ element ['value'], который определяет текстовую область, и $ element ['format'], который определяет другое текстовое поле.

(Кстати, путающие имена! Лично я бы избегал использования 'value' и 'format', чтобы избежать путаницы с ['#value'] и форматерами)

Как это выглядитпроблема с этим кодом состоит в том, что он размещает форму, которая должна отображаться на ['value'] прямо на $ element без ключа ['value'].Я не могу понять, как форма узнает, к какому столбцу ее передать.

Я действительно не знаю, что происходит с ['#format'], честно говоря, это выглядит неправильно, но я не могу понять, что он пытается сделать.

Так что для этого кода я бы сразу предложил заменить $text = array( '#type' => 'textarea', ... на $element['value'] = array( ' '#type' => 'textarea',

Что касается того, почему $ element ['brooklandsheading'] не проходит, в коде ничего не выскакивает как неправильное,так что я подозреваю, что это может быть из-за еще одной маленькой «ошибки»: после изменения схемы в hook__field_schema () вам нужно удалить всех экземпляров поля, затем отключить и затемполностью удалить модуль с вкладки Модули -> Удалить, затем повторно включите модуль и заново создайте все поля.Чтобы применить измененную схему, Drupal необходимо удалить и воссоздать таблицы из вашей базы данных, и Drupal не сделает этого, если не будет уверен, что не собирается уничтожать ценные данные.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...