Пытаюсь написать модуль под Друпал, и столкнулся с проблемой:
в ноде отображаеться рейтинг новости который виден всем и selectBox для выставления рейтинга администратором от 1..5.
проблема в следующем что в 7й строке '#value' => drupal_get_form('form_votex',$node) передаеться аргумент $node->nid в форму с selectBox, но он всегда равен 1 и во всех тизерах обновляеться рейтинг только для 1й ноды.
global $user;
switch($op){
case 'view':
if($user->uid == 1){
$node->content['voteX'] = array(
'#value' => drupal_get_form('form_votex',$node->nid),
'#weight' => 10
);
}
$result = db_query("SELECT vote FROM {votex} WHERE nid = %d",$node->nid);
$raiting = db_result($result);
$node->content['raiting'] = array(
'#value' => '<p><strong>Рейтинг:</strong> '.$raiting.'</p>',
'#weight' => -1
);
break;
}
}
function form_votex($node){
$form['voteX'] = array(
'#type' => 'select',
'#title' => t('VoteX'),
'#default_value' => variable_get('voteX',1),
'#description' => t('Votex provide vote for your page'),
'#options' => array(
'1' => '1',
'2' => '2',
'3' => '3',
'4' => '4',
'5' => '5'
)
);
$form['hidden'] = array(
'#type' => 'value',
'#value' => $node->nid
);
$form['submit'] = array(
'#type' => 'submit',
'#value' => 'update'
);
return $form;
}
function form_votex_submit($form_id,$formstate){
$vote = $formstate['values']['voteX'];
$nid = $formstate['values']['hidden'];
$result = db_query("UPDATE votex SET vote = %d WHERE nid = %d",$vote,$nid);
if($result){
drupal_set_message("Saved");
}else{
drupal_set_message("Dont Saved");
}
}
Комментарии
Я не могу точно сказать, в чем проблема, но есть несколько замечаний.
1.Друпал передает функции form_votex не один, а два аргумента.
Первый –это массив параметров (он тебе не нужен), а второй - это и есть nid;
2.В строке 7 ты передаешь функции не объект ноды, а только ее id ($node->nid) и в строке 37 ты обращаешься к переменной уже как к объекту.
В функцию form_votex_submit должны приходить две переменные непосредственно форма $form и &$form_state именно так как и написано, прежде чем писать всегда внимательно проверяйте свой код.
И уж если окончательно придираться, то если вы назвали свою первую функцию votex_nodeapi то почему вторую и последующие не называть votex_form, votex_form_submit и т.д. есть правила и стандарты кодирования, и когда в коде порядок то и ошибки искать гораздо проще.
1.$formstate или $form_state – это ничего не меняет.
2.Амперсанд здесь не нужен, поскольку $formstate не будет манятся.
3.“…то почему вторую и последующие не называть votex_form…” потому что это хук, который используется для редактирования нод (http://api.drupal.ru/api/function/hook_form/6).
1. Есть API на которое вы ссылаетесь и если там $form_state то и писать надо аналогично, никто не запрещает Вам подходить творчески к решению тех или иных задач но есть и правила.
2. Завтра вам будет необходимо написать к этой форме валидацию и т.д. и т.п. значит переменная начнет меняться т.е. нужно будет ставить амперсанд я не думаю что это займет много времени но почему его сразу не написать? он что сожрет много памяти или Вашей энергии?
3. http://api.drupal.org/api/function/hook_form/6 посмотрите внимательно и найдите несколько различий с тем что прислали мне вы (чтоб было проще сравните инфу с вашей ссылки вот с этим http://api.drupal.org/api/function/hook_form/4.6) время движется вперед вместе с версиями друпала, это по поводу хука. По поводу того что если назвать функцию более понятно я могу и ошибаться (или может не правильно делаю, мы все не безгрешны) но я написал уже не один модуль в котором свои формы я называл именно "имя модуля"_form и никаких проблем никогда не возникало (может просто не попадался в такие ситуации). Пользовался инструкциями отсюда http://api.drupal.org/api/file/developer/topics/forms_api.html/6
Просто я говорю про то что переменные и функции по нормальному надо называть так, чтоб человек который придет после Вас обслуживать этот проект мог быстро разобраться в Ваших творениях а не убивать на это время за которое он бы прекрасно мог что-то другое сделать (Вам просто наверное не попадались на доработку или дописку работы "мастеров").
спасибо и вправду нужно было передавать 2 аргумента, сделал все работает. хотя в документации об этом не говориться.
еще не совсем понятно что именно передавать первым аргументом?! я передаю 2 объекта $node хотя это наверное не совсем верно, хотелось бы узнать что должно быть по стандартам?!
http://api.drupal.org/api/file/developer/topics/forms_api.html
сразу после примера
«Note that the form builder function always takes $form_state as its first argument, though for basic usage (as here) it is not used.»
<?php drupal_get_form('form_votex',$node) ?>
http://api.drupal.org/api/function/drupal_get_form/6