Здраствуйте. Пытаюсь создать модуль для добавления поля в редактор ноды. Делал по вот этому руководству (http://internetdevels.ru/blog/sozdanie-prostogo-modulya-field-api-v-drup...). Но что-то он не хочет сохранять данные из моего поля в базу.
Начал думать почему так происходит. Добавил в форму validate для своего поля (я только начал изучать drupal и не нашёл другой функции, которая вызвалась бы при отправке формы). Распечатал там массив $_POST. В нем моё поле есть, как и его значение, а вот в массиве $form как и в $form_state пустовато, не там значения из $_POST. Подскажите что я делаю не так? Вроде все как в мануале. Только тип поля другой (int), но я вроде и число ввожу.
Ко всему вот код модуля
файл qp_area.info
<?php
name = Point Field
description = Номер точки
package = Fields
core = 7.x
files
[] = qp_area.module
files[] = qp_area.install
stylesheets[all][] = qp_area.css
?>
файл qp_area.install
<?php
// hook_field_schema
function qp_area_field_schema($field) {
$columns = array(
'qp_point' => array(
'type' => 'int',
'unsigned' => TRUE,
'not null' => FALSE,
),
);
return array(
'columns' => $columns,
'indexes' => array('qp_point' => array('qp_point')),
);
}
?>
файл qp_area.module
<?php
// хук для отображения типа поля
// hook_field_info
function qp_area_field_info() {
return array(
'qp_area' => array(
'label' => t('Поле'),
'description' => t('Поле'),
'default_widget' => 'qp_area',
'default_formatter' => 'qp_area_formatter',
'property_type' => 'node',
),
);
}
//хук для отображеня и настройки виджета
// hook_field_widget_info
function qp_area_field_widget_info() {
return array(
'qp_area' => array(
'label' => t('Поле'),
'field types' => array('qp_area'),
),
);
}
// хук для отображения формата для нашего поля
// hook_field_formatter_info
function qp_area_field_formatter_info() {
return array(
'qp_area_formatter' => array(
'label' => t('Поле'),
'field types' => array('qp_area'),
),
);
}
// hook_field_widget_form
function qp_area_field_widget_form(&$form, &$form_state, $field, $instance, $langcode, $items, $delta, $element) {
switch ($instance['widget']['type']) {
case 'qp_area':
$element['qp_point'] = array(
'#type' => 'textfield',
'#title' => $element['#title'],
'#description' => $element['#description'],
'#default_value' => isset($items[$delta]['qp_point']) ? $items[$delta]['qp_point'] : NULL,
'#required' => $element['#required'],
'#weight' => 0,
'#delta' => $delta,
'#element_validate' => array('qp_point_autocomplete_validate'),
);
break;
}
return $element;
}
function
qp_point_autocomplete_validate($element, &$form_state, $form){
printarr($_POST);
printarr($form_state);
die();
}
// hook_field_formatter_view
function qp_area_field_formatter_view($entity_type, $entity, $field, $instance, $langcode, $items, $display) {
$element = array();
switch ($display['type']) {
case 'qp_area_formatter':
foreach ($items as $delta => $item) {
if ($item['qp_point']) {
$formattedText = $item['qp_point'];
$element[$delta]['#markup'] = '<h1><b>' . $formattedText .'</b></h1>';
}
}
break;
}
return $element;
}
// hook_field_is_empty
function qp_area_field_is_empty($item, $field) {
if (empty($item['qp_area'])) {
return true;
}
}?>
Комментарии
Как я понямаю, в Д7 при использовании hook_field_schema мы определяем поле, которое используем ПОТОМ для добавления в базу.
То есть подключая модуль мы определяем что будет такое поле. Затем добавляем поел в тип материала со своим виджетом. В базе появляется таблица с нашим полем.
Например я добавил поле в тип материала с названием qp_area. В базе появились 2 таблицы (не знаю зачем 2. Для всех полей их 2) - field_data_field_qp_area и field_revision_field_qp_area. А в них добавилось наше поле qp_point.
Вот это то что есть в базе.
Когда делал смотрел ещё на модуль node_reference. Там функия node_reference_field_schema находится в node_reference.module. Но сути это не меняет как я понял, потому что попробовав сделать так же ничечго не изменилось.
Могу выложить результат сабмита. Он просто много места занимает. Тут нельзя делать скрытые комменты?
Дело в том что там есть вот такие строки (при распечатке $form)
<?php
[qp_point] => Array
(
[#type] => textfield
[#title] => qp_area
[#description] =>
[#default_value] => 1
[#required] =>
[#weight] => 0
[#delta] => 0
[#element_validate] => Array
(
[0] => qp_point_autocomplete_validate
)
[
#input] => 1[#size] => 60
[#maxlength] => 128
[#autocomplete_path] =>
[#process] => Array
(
[0] => ajax_process_form
)
[
#theme] => textfield[#theme_wrappers] => Array
(
[0] => form_element
)
[
#pre_render] => Array(
[0] => ctools_dependent_pre_render
)
[
#defaults_loaded] => 1[#tree] => 1
[#parents] => Array
(
[0] => field_qp_area
[1] => und
[2] => 0
[3] => qp_point
)
[
#array_parents] => Array(
[0] => field_qp_area
[1] => und
[2] => 0
[3] => qp_point
)
[
#processed] => 1[#attributes] => Array
(
)
[
#title_display] => before[#id] => edit-field-qp-area-und-0-qp-point
[#name] => field_qp_area[und][0][qp_point]
[#value] => 5
[#needs_validation] => 1
[#ajax_processed] =>
[#sorted] => 1
)
?>
То есть введенное число в поле куда то сохранилось (вводил 5 как видно:))
Толко в базе таблица пустая
По теме: не смотрел еще ваше решение внимательно, но возможно ли, что проблема в том, что ваше поле везде называется qp_area, а в форму ноды вы добавляете некое qp_point? Если Дру сохраняет содержимое автоматически - ему хорошо бы было знать, под каким именем это делать.
upd: а нет, посмотрел, у вас соответствующий столбец есть в таблице. А если die() из валидации убрать, в базу потом вообще ничего не попадает?
Но на глаз от мануала интернетдевелов отличается только название qp_area/qp_point. Попробуйте все же назвать и поле, и столбец, qp_area - что будет?
Спасибо! Действительно получилось. К сожалению надо чтобы название поля было отличным от qp_area.
В конечном итоге задача состоит в том чтобы создать виджет для сохранения 2-х полей. (извините если я в терминах ошибаюсь)
То есть должно быть 2 поля в базе и 2 поля при редактировании node. Естественно не назовешь же их одним именем. В node_reference поле называется nid (отлично от названия модуля). Может подскажите куда копать?
Ну во-первых попробуйте скопировать определение поля с nodereference.
Во-вторых, на странице с описанием хука hook_field_widget_form в комментах писали люди, что и три поля сохраняли.
Не знаю что сделал, но все заработало. Обидно так вот получается: мучился мучился, а оно взяло и заработало.
На самом деле заменил опять qp_area на qp_point где надо было. Может сначала не везде где надо проставил.
Ты написал:
Для понимающих русский язык, фраза "может только декларировать структуру поля в схеме БД, но не добавлять его в БД" - означает, что хук может только декларировать, а добавлять не может. И нечего тут кривляться.
Как работают хуки по добавлению полей - написано прямо в описании хуков.
А то что ты пишешь - означает "я ничего не знаю, доков не читал, но возможно автору стоит потратить свое время на то что я пишу, хотя это ничем не подтверждается, а просто мне так кажется". Тогда так и пиши - ничего не знаю, с друпалом работаю две недели, но хочу всем давать советы.
Вот потому тебя тут и гоняют, что толком еще ничего не знаешь, доки нормально прочитать не можешь - а уже лезешь с рассказами.
Да не увидит он там ничего интересного - он увидит, что его поле прекрасно существует и в БД, и в схеме. А причина простая - в какой-то из частей исходного кода автор недовставил название столбца БД, отличающееся от названия поля. Что он сам, кстати, и предположил.
Оно там есть. Чтобы модуль не конфликтовал с другими модулями, достаточно задать для него уникальное название (нарушение этого правила очевидно сразу) и не лезть в системные таблицы. Я тебе страшное скажу - разработчику достаточно соблюдать неймспейс, и схему БД друпала можно вообще не знать. Но для этого, понятно, нужно знать, что такое неймспейс.
Мне не нужно "разводить флейм с твоим участием", мне нужно чтобы ты прекратил писать херню о том, о чем понятия не имеешь. Если бы это был первый раз - никто бы не заметил, тут каждый день глупости пишут, но ты уже две недели не унимаешься.
А обсуждение тебя в теме "где это делается" - никому не интересно. Как и лично ты сам.
И эти разработчики - если они разработчики, а не пустобрехи, как ты - прекрасно знают и что такое неймспейс, и что в большинстве случаев никакие модификации системных таблиц не нужны.
Если ты не модифицируешь функционал других модулей (через всевозможные _alter-ы) - больше не нужно знать ничего. Если модифицируешь - нужно знать ту область, в которой работает данный конкретный _alter (например, form api) и содержимое конкретной таблицы, если ты взаимодействуешь с ней (что, кстати, не самый лучший вариант). Посмотреть структуру таблицы в БД - дело 2 минут.
Не ну то есть я понимаю, ты как ребенок - сам нашел модуль, воспользовался, это первое важное впечатление для тебя, наверно мне не стоит мир детских иллюзий разрушать. В принципе - не нужен. Точнее нужен - тем, кто не может самостоятельно схему написать в module.install. Все ошибаются. Но по делу ошибаться - это одно, и совсем другое - городить херню на ровном месте. Ты занят именно херней.
Дорогой друг. Ты со своим вандюком уже всех задрал. Тебе объяснили пятьдесят раз - и правила русского языка, и какие предпосылки для выбора (кем бы он там ни был выбран) именно такого варианта, и что всем плевать, что ты думаешь о его правильности. Сколько ты будешь еще усираться-то на эту тему?
Omg. У тебя больше одной фразы в памяти не сохраняется? Речь шла о том, чтобы таблицу посмотреть - одну. Я ее прекрасно посмотрю и в phpmyadmin. Смотреть все таблицы нужды при разработке нет практически никогда. Кроме того, я не имею привычки держать в БД таблицы отключенных модулей - я отключенные модули удаляю и таблицы (сюрприз!) немедленно исчезают.
Я взял за правило гонять ссаными тряпками мудаков вроде тебя, которые в ответ на нормальное обращение начинают гнать пургу и, следовательно, нормального обращения не заслуживают. Когда я ошибаюсь - я всегда это признаю. Только ошибка должна существовать не в фантазиях мудаков вроде тебя, а на самом деле.