Форма Drupal FAPI вызывает обратный вызов дважды

Первый пост о переполнении стека... так что будь осторожен со мной!

Кажется, не существует подходящего решения проблемы множественного обратного вызова Drupal FAPI для простых отправлений форм.

ПРОБЛЕМА. Моя форма при отправке добавляет две записи в соответствующую таблицу базы данных. Учитывая, что есть только один вызов, чтобы добавить его в базу данных, я уверен, что можно предположить, что запрос выполняется дважды (отсюда и двойные записи).

Следующий код может помочь обеспечить основу для решения. О, это тоже Drupal 7, так что документация все еще в значительной степени ориентирована на D6.

function mymodule_sidebar_form_add_submit(&$form, &$form_state) {

  $form_values = $form_state['values'];

  $se_title = check_plain(trim($form_values['title']));
  $se_link = url(trim($form_values['link']));
  $se_content = check_plain(trim($form_values['content']));
  $se_image = isset($form_values['image']) ? $form_values['image'] : '';

  // The multi-line part below is actually a single line the real code
  $query = sprintf("INSERT INTO sidebar_element(title, image_url, content) 
      VALUES ('%s', '%s', '%s');", $se_title, $se_image, $se_content);

  db_query($query);
  drupal_set_message(t('Sidebar Element has been added successfully.'));
}

... и моя функция формы содержит кнопку отправки:

  $form['submit'] = array(
      '#value' => t('Add Sidebar'),
      '#type' => 'submit',
      '#title' => t('Add Sidebar'),
      '#submit' => array('mymodule_sidebar_form_add_submit'),
      );

Я предполагаю, что мне нужно ответить на следующие вопросы:

  1. Почему двойной вызов в первую очередь?
  2. Есть ли способ идентифицировать первый обратный звонок?

Заранее всем спасибо.

3 ответа

  $form['submit'] = array(
      '#type' => 'submit',
      '#value' => t('Save')
  );
  $form['#submit'] = array('my_form_submit');

И заменить

// The multi-line part below is actually a single line the real code
  $query = sprintf("INSERT INTO sidebar_element(title, image_url, content) 
      VALUES ('%s', '%s', '%s');", $se_title, $se_image, $se_content);

  db_query($query);

с

// The multi-line part below is actually a single line the real code
  $query = "INSERT INTO {sidebar_element} (title, image_url, content) 
      VALUES ('%s', '%s', '%s')";

  db_query($query, $se_title, $se_image, $se_content);

Для Drupal 7

// Add the buttons.
  $form['actions'] = array('#type' => 'actions');

  $form['actions']['submit'] = array(
    '#type' => 'submit', 
    '#access' => my_func(), 
    '#value' => t('Save'), 
    '#weight' => 100, 
    '#submit' => array('my_form_submit'),
  );

В качестве примера прочитайте код node_form()

Чтобы выяснить, откуда поступает второй вызов, проще всего установить devel.module и использовать ddebug_backtrace() в обратном вызове submit. Возможно, вам придется отключить перенаправление HTTP, чтобы увидеть его тоже (exit()).

Но что более важно, используйте API, Люк!

<?php
db_insert('sidebar_element')
  ->fields(array(
    'title' => $se_title,
    'image_url' => $se_image,
    'content' => $se_content,
  ))
  ->execute():
?>

Вот как должен выглядеть ваш запрос на вставку, то, что вы делаете, небезопасно!

А для SELECT используйте db_query() с именованными заполнителями:

<?php
$result = db_query('SELECT * FROM {sidebar_element} WHERE title = :title', array(':title' => $something));
?>
Другие вопросы по тегам