Drupal 7 Field API hook_field_validate没有收到数据?

时间:2011-08-02 15:54:55

标签: drupal-7

我的模块实现了一系列字段api函数,以便提供由文本字段和textarea组成的自定义字段类型。 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 :(得分:0)

我发现这段代码有点令人困惑,我不是专家,但我只是努力解决并解决了类似的问题,我觉得这个问题至少值得为记录提供一个谨慎的部分答案。

我理解它,表单通过循环并呈现$ element数组生成,并且它计算出如何通过数组中每个项的键将结果输入与模式匹配。

所以,我这里立刻看错了的是,架构设置了3种类型的数据来存储:'brooklandsheading','value'和'format',所以我期待$ element数组使用$ element ['brooklandsheading']定义文本字段,$ element ['value']定义文本区域,$ element ['format']定义另一个文本字段。

(令人困惑的名字,顺便说一句!我个人不会使用'value'和'format',以避免与['#value']和格式化程序混淆)

这段代码的一个问题是,它正在将应该映射到['value']的表单插入到没有['value']键的$ element上。我无法看到表单如何知道将哪个列提供给它。

我真的不知道['#format']发生了什么,说实话,它看起来并不正确,但我无法弄清楚它正在尝试做什么。

因此,对于此代码,我立即建议将$text = array( '#type' => 'textarea', ...替换为$element['value'] = array( ' '#type' => 'textarea',

至于为什么$ element ['brooklandsheading']没有通过,没有任何东西在代码中跳出错误,所以我怀疑它可能是因为另一个小'gotcha':在hook__field_schema中更改模式后( ),您必须删除该字段的所有实例,然后禁用,然后从模块中完全卸载模块 - &gt;卸载选项卡,然后重新启用该模块并重新创建所有字段。要应用更改的模式,Drupal需要从数据库中删除并重新创建表,Drupal不会这样做,除非它确定它不会破坏有价值的数据。