При добавлении поля в редактор ноды, она не сохраняется

Главные вкладки

Аватар пользователя yojik yojik 18 июня 2012 в 15:28

Здраствуйте. Пытаюсь создать модуль для добавления поля в редактор ноды. Делал по вот этому руководству (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;  
   } 
}
?>

Комментарии

Аватар пользователя graker graker 19 июня 2012 в 12:27

inza wrote:
hook_field_schema в Друпал 7 (по аналогии с Друпал 6) может только декларировать структуру поля в схеме БД, но не добавлять его в БД.
Зачем ты вводишь людей в заблуждение?

Аватар пользователя yojik yojik 19 июня 2012 в 12:09

Как я понямаю, в Д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 как видно:))
Толко в базе таблица пустая

Аватар пользователя graker graker 19 июня 2012 в 12:43

yojik wrote:
Например я добавил поле в тип материала с названием qp_area. В базе появились 2 таблицы (не знаю зачем 2. Для всех полей их 2)
В одной хранятся данные поля, другая нужна в случае если вы пользуетесь ревизиями.

По теме: не смотрел еще ваше решение внимательно, но возможно ли, что проблема в том, что ваше поле везде называется qp_area, а в форму ноды вы добавляете некое qp_point? Если Дру сохраняет содержимое автоматически - ему хорошо бы было знать, под каким именем это делать.

upd: а нет, посмотрел, у вас соответствующий столбец есть в таблице. А если die() из валидации убрать, в базу потом вообще ничего не попадает?
Но на глаз от мануала интернетдевелов отличается только название qp_area/qp_point. Попробуйте все же назвать и поле, и столбец, qp_area - что будет?

Аватар пользователя yojik yojik 19 июня 2012 в 13:27

Спасибо! Действительно получилось. К сожалению надо чтобы название поля было отличным от qp_area.
В конечном итоге задача состоит в том чтобы создать виджет для сохранения 2-х полей. (извините если я в терминах ошибаюсь)
То есть должно быть 2 поля в базе и 2 поля при редактировании node. Естественно не назовешь же их одним именем. В node_reference поле называется nid (отлично от названия модуля). Может подскажите куда копать?

Аватар пользователя graker graker 19 июня 2012 в 13:36

yojik wrote:
Спасибо! Действительно получилось. К сожалению надо чтобы название поля было отличным от qp_area.
В конечном итоге задача состоит в том чтобы создать виджет для сохранения 2-х полей. (извините если я в терминах ошибаюсь)
То есть должно быть 2 поля в базе и 2 поля при редактировании node. Естественно не назовешь же их одним именем. В node_reference поле называется nid (отлично от названия модуля). Может подскажите куда копать?

Ну во-первых попробуйте скопировать определение поля с nodereference.
Во-вторых, на странице с описанием хука hook_field_widget_form в комментах писали люди, что и три поля сохраняли.

Аватар пользователя yojik yojik 19 июня 2012 в 16:53

Не знаю что сделал, но все заработало. Обидно так вот получается: мучился мучился, а оно взяло и заработало.
На самом деле заменил опять qp_area на qp_point где надо было. Может сначала не везде где надо проставил.

Аватар пользователя graker graker 20 июня 2012 в 14:20

inza wrote:
2. Мой ответ - предположение, но не утверждение. В моем ответе слово "может" многое значит, для умеющих читать.

Ты написал:
Quote:
hook_field_schema в Друпал 7 (по аналогии с Друпал 6) может только декларировать структуру поля в схеме БД, но не добавлять его в БД.

Для понимающих русский язык, фраза "может только декларировать структуру поля в схеме БД, но не добавлять его в БД" - означает, что хук может только декларировать, а добавлять не может. И нечего тут кривляться.

Quote:
Я никого не вводил в заблуждение, и надеюсь, что моя информация была полезной. Д7 хуже документирована, чем Д6, и вопросов по работе системных хуков будет еще немало. Кроме самих разрботчиков API D7 не так уж много людей, знающих как все они работают.

Как работают хуки по добавлению полей - написано прямо в описании хуков.

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

Вот потому тебя тут и гоняют, что толком еще ничего не знаешь, доки нормально прочитать не можешь - а уже лезешь с рассказами.

Аватар пользователя graker graker 20 июня 2012 в 14:19

inza wrote:
"yojik" wrote:
Не знаю что сделал, но все заработало.

Причину желательно все-таки выяснить. Попробуй подключить модуль Schema - увидишь и узнаешь много интересного.

Да не увидит он там ничего интересного - он увидит, что его поле прекрасно существует и в БД, и в схеме. А причина простая - в какой-то из частей исходного кода автор недовставил название столбца БД, отличающееся от названия поля. Что он сам, кстати, и предположил.

Аватар пользователя graker graker 20 июня 2012 в 14:35

inza wrote:
Это и есть самое интересное, чтобы его поле было и в БД и в схеме, а не только в БД.

Оно там есть.

Quote:
А еще интересно, чтобы его модуль не конфликтовал с ядром и другими модулями
Чтобы модуль не конфликтовал с другими модулями, достаточно задать для него уникальное название (нарушение этого правила очевидно сразу) и не лезть в системные таблицы.

Quote:
для разработчика модуля, который еще не знает наизусть всю схему БД Друпла (включая схемы таблиц подключенных модулей)
Я тебе страшное скажу - разработчику достаточно соблюдать неймспейс, и схему БД друпала можно вообще не знать. Но для этого, понятно, нужно знать, что такое неймспейс.

Аватар пользователя graker graker 20 июня 2012 в 14:38

inza wrote:
Исключительно для graker-а
Если тебе так нравится разводить флейм с моим участием - то ты же знаешь, где это делается: http://www.drupal.ru/node/83363
А здесь, из уважения к автору темы, по нетехническим вопросам я с тобой препираться не буду.

Мне не нужно "разводить флейм с твоим участием", мне нужно чтобы ты прекратил писать херню о том, о чем понятия не имеешь. Если бы это был первый раз - никто бы не заметил, тут каждый день глупости пишут, но ты уже две недели не унимаешься.
А обсуждение тебя в теме "где это делается" - никому не интересно. Как и лично ты сам.

Аватар пользователя graker graker 20 июня 2012 в 15:02

inza wrote:
Ты постоянно доказываешь обратное. Ты ж без меня жить не можешь. И в этой теме ты появился только потому, что увидел мой ответ автору. А если бы моего ответа не было - эта тема так и висела бы безответной годика 2-3, пока не померла бы естетвенной смертью в забвении.
Да-да, и только ты спас тему от забвения своим безграмотным ответом! Молодец!

Quote:
Вдобавок ко всему автор полез в системную таблицу node, а этого здесь очень не любят.
Вот опять - ни хера не знаешь, но лезешь. Автор не полез в таблицу node, чтобы программно добавить новое поле, работающее с нодами, не нужно лезть в системные таблицы, в том числе и в таблицу node.

Quote:
"graker" wrote:
Чтобы модуль не конфликтовал с другими модулями, достаточно задать для него уникальное название (нарушение этого правила очевидно сразу) и не лезть в системные таблицы.

Не всякий разработчик сайтов на Друпле мальчик, который собирает домик из готовых кубиков. Есть разработчики, которые ставят перед собой цель знать системные таблицы и уметь грамотно с ними работать, и, при необходимости, уметь их модифицировать.

И эти разработчики - если они разработчики, а не пустобрехи, как ты - прекрасно знают и что такое неймспейс, и что в большинстве случаев никакие модификации системных таблиц не нужны.

Аватар пользователя graker graker 20 июня 2012 в 15:36

inza wrote:
В большинстве случаев, на Друпале, никакие разработчики не нужны.
Лично у меня, например, ни один проект без программного вмешательства не обходится, если это не визитка. Хотя я и для визиток кое-где вмешиваюсь.

Quote:
Ты сам-то зачем влез в системную часть и так подробно ее изучил? Это ведь совсем не нужно в большинстве случаев.
Если бы ты был способен читать, что тебе пишут, давно бы уже понял, что речь почти никогда не идет о "влезании в системную часть". Речь идет о программировании своих модулей, которые в "системную часть" не лезут, а дополняют ее снаружи. Либо о модификации темплейтов - каковая вообще не относится к "системной части".

Quote:
А если в Друпале есть своя система имен для модулей и прочих сущностей, то ежику понятно, что ее надо учитывать.
В том-то и дело, что чтобы ее учитывать - никуда лезть не надо, достаточно посмотреть на список модулей и - в случае возникновения характерных ошибок - на список таблиц в БД. И всё - никаких конфликтов.

Аватар пользователя graker graker 20 июня 2012 в 15:48

inza wrote:
Ну это ты загнул. Только список модулей и список таблиц знать недостаточно, чтобы не было ниаких конфликтов. Чтобы модули никогда не конфликтовали друг с другом надо знать больше.
А можно мне будет лучше знать?
Если ты не модифицируешь функционал других модулей (через всевозможные _alter-ы) - больше не нужно знать ничего. Если модифицируешь - нужно знать ту область, в которой работает данный конкретный _alter (например, form api) и содержимое конкретной таблицы, если ты взаимодействуешь с ней (что, кстати, не самый лучший вариант). Посмотреть структуру таблицы в БД - дело 2 минут.

Аватар пользователя graker graker 20 июня 2012 в 16:38

inza wrote:
Если разработчику необходимо, по каким-либо причинам, проделать какую-либо похожую модификацию, но из своего модуля, он что, не должен этого делать?
Если разработчику необходимо проделать модификации системной таблицы, он их проделает без труда, тем более такую ерунду как ты привел сделать - 10 минут. Но в 99.(9)% случаев разработчику не нужно проделывать таких модификаций.

Quote:
Время идет, и очень быстро. И дожидаться пока системные разработчики ядра учтут все твои пожелания - далеко не у всех есть время.
Абстрактные примеры в вакууме? Smile Я понимаю, если бы ты свои примеры привел - того что действительно нужно и на что нет времени, а так - пустой треп.

Quote:
А того что ты написал для разработки модулей, которые гарантированно не будут конфликтовать с системой и другими модулями - все равно недостаточно.
Дорогой друг, я модулей разработал не один десяток - и никаких конфликтов. Можно я буду лучше знать, что нужно для разработки модулей, чем ты, не разработавший пока ни одного?

Аватар пользователя graker graker 20 июня 2012 в 18:05

inza wrote:
С модулем Schema это дело 15 секунд.
Получить результат работы модуля schema, и зайти на страницу phpmyadmin - это примерно одно и то же.
Не ну то есть я понимаю, ты как ребенок - сам нашел модуль, воспользовался, это первое важное впечатление для тебя, наверно мне не стоит мир детских иллюзий разрушать.

Quote:
Или ты считешь, что модуль Schema разрабочику модулей никаких удобств не дает и он вообше не нужен?
В принципе - не нужен. Точнее нужен - тем, кто не может самостоятельно схему написать в module.install.

Quote:
Я понимаю что синсеи никогда не ошибаются.
Все ошибаются. Но по делу ошибаться - это одно, и совсем другое - городить херню на ровном месте. Ты занят именно херней.

Quote:
Но со своим "Вандюком" ты сильно подорвал доверие в собственную непогрешимость.

Дорогой друг. Ты со своим вандюком уже всех задрал. Тебе объяснили пятьдесят раз - и правила русского языка, и какие предпосылки для выбора (кем бы он там ни был выбран) именно такого варианта, и что всем плевать, что ты думаешь о его правильности. Сколько ты будешь еще усираться-то на эту тему?

Аватар пользователя graker graker 20 июня 2012 в 19:34

inza wrote:
"graker" wrote:
Сколько ты будешь еще усираться-то на эту тему?

До тех пор, пока ты и другие неучи и шарлатаны не начнут писать правильно: Джон ван Дюк.
Ну усирайся, усирайся, раз мозгов нет. Тебе сразу сказали, что писать "Вандюк" тоже правильно, и объяснили почему, вся остальная твоя истерика - всем по-барабану.

Quote:
Ну да. Ты считаешь себя умнее разработчиков модуля Schema, на мой взгляд, весьма удобного и полезного. Именно для разработчиков.
Ну до тебя-то мне далеко: ты вон сходу решил что умнее всего сообщества и, не разобравшись, полез системные модули править, а потом - сходу рассказывать нам, что всё, оказывается, "не так" устроено.

Quote:
Во всяком случае для тех, кто не считает нужным помнить наизусть всю схему БД и схемы таблиц всех модулей, с которыми приходится иметь дело разработчику.
Omg. Если б ты понимал, что такое схема и осознавал область ее применения - ты давно бы уже забил носиться с ней как с писаной торбой.

Quote:
В phpmyadmin ты увидишь все, что есть в БД, включая таблицы отключенных модулей, которых нет в схеме БД.

Omg. У тебя больше одной фразы в памяти не сохраняется? Речь шла о том, чтобы таблицу посмотреть - одну. Я ее прекрасно посмотрю и в phpmyadmin. Смотреть все таблицы нужды при разработке нет практически никогда. Кроме того, я не имею привычки держать в БД таблицы отключенных модулей - я отключенные модули удаляю и таблицы (сюрприз!) немедленно исчезают.

Quote:
И ты взял себе за правило публично поливать дерьмом тех, кто исключительно с твоей личной точки зрения (ошибочной) ошибается "не по делу".

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

Quote:
Сам же ты не ошибаешься никогда и никогда не признаешь своих ошибок.
Когда я ошибаюсь - я всегда это признаю. Только ошибка должна существовать не в фантазиях мудаков вроде тебя, а на самом деле.

Аватар пользователя graker graker 20 июня 2012 в 20:20

inza wrote:
Ты в очередной раз наглядно продемонстрировал кто ты есть и чего ты стоишь.
Спасибо, услышать это от безграмотного мудака вроде тебя - для меня очень ценно и важно.