いくつかのフィールドを挿入するためにhook_form_alter()
を実装しました。フィールドデータを保存するhook_node_insert()
、hook_node_load()
、およびhook_node_view()
を実装しました。
すべて正常に動作しますが、ノードを編集すると、編集フォームがデータなしで表示されます。
どうすれば修正できますか?
function mymodule_form_ABC_node_form_alter(&$form, &$form_state, $form_id) {
$options_first = _mymodule_get_first_dropdown_options();
$selected = isset($form_state['values']['filed_1']) ? $form_state['values']['field_1'] : key($options_first);
$form['field_1'] = array(
// …
);
$form['field_2'] = array(
// …
);
return $form;
}
/**
* Implements hook_node_insert().
*/
function mymodule_node_insert($node) {
db_insert('my_custom_table')
->fields(array('nid' => $node->nid, 'field_1' => $node->field_1, 'field_2' => $node->field_2,))
->execute();
}
/**
* Implements hook_node_load().
*/
function mymodule_node_load($nodes, $types) {
foreach ($nodes as $node) {
$nids[] = $node->nid;
}
$result = db_select('custom_table', 'e')
->fields('e', array('nid', 'filed_1', 'field_2'))
->where('e.nid IN (:nids)', array(':nids' => $nids))
->execute();
foreach ($result as $record) {
$nodes[$record->nid]->field_1 = $record->field_1;
$nodes[$record->nid]->field_2 = $record->field_2;
}
}
/**
* Implements hook_node_update().
*/
function mymodule_node_update($node) {
if ($node->type == 'abc') {
// Delete the existing values.
db_delete('custom_table')
->condition('nid', $node->nid)
->execute();
db_insert('custom_table')
->fields(array('nid' => $node->nid, 'field_1' => $node->field_1, 'field_2' => $node->field_2,))
->execute();
}
}
コードが行うことは、Bookモジュールが book_form_node_form_alter() 、 book_node_load() 、および book_node_insert() を使用して行うことと似ています。
あなたのコードの何が間違っているのですか?
mymodule_form_ABC_node_form_alter()
では、mymodule_node_load()
でロードした値からフォームフィールドを初期化しません。つまり、使用しているフォームフィールドは常に空の文字列に設定されます。 Bookモジュールは_$form_state['values']['book']
_を使用して_$node->book
_を初期化しますが、 _ book_add_form_elements() に関するコメントは、その理由を説明しています。
_// If the form is being processed during the Ajax callback of our book bid
// dropdown, then $form_state will hold the value that was selected.
if (isset($form_state['values']['book'])) {
$node->book = $form_state['values']['book'];
}
_
hook_node_insert() を実装しますが、 hook_node_update() は実装しません。つまり、使用しているノードプロパティの値は、ノードの更新時ではなく、ノードの作成時に保存されます。
Bookモジュールは hook_node_prepare() ( book_node_prepare() )を実装していることは事実ですが、その目的は、処理するノードプロパティのデフォルト値を設定することだけであり、これは便利ですノードがユーザーインターフェイスを介して作成されていない場合。
コンテンツタイプがabcのときにこれらのノードプロパティを保存することに関心があるので、次のようにコードを実装します。
_function mymodule_form_abc_node_form_alter(&$form, &$form_state, $form_id) {
$node = $form['#node'];
$options_first = _mymodule_get_first_dropdown_options();
$selected = !empty($node->field_1) ? $node->field_1 : key($options_first);
$form['field_1'] = array(
// …
);
$form['field_2'] = array(
// …
);
return $form;
}
function mymodule_node_prepare($node) {
if ($node->type == 'abc') {
$node->field_1 = '';
$node->field_2 = '';
}
}
function mymodule_node_load($nodes, $types) {
$nids = array();
foreach ($nodes as $nid => $node) {
if ($node->type == 'abc') {
$nids[] = $nid;
}
}
if (!empty($nids)) {
db_query('SELECT e.nid, e.field_1, e.field_2 FROM {custom_table} e WHERE e.nid IN :nids'), array(':nids' => $nids), array('fetch' => PDO::FETCH_ASSOC));
foreach ($result as $record) {
$nodes[$record['nid']]->field_1 = $record['field_1'];
$nodes[$record['nid']]->field_2 = $record['field_2'];
}
}
}
/**
* Implements hook_node_insert().
*/
function mymodule_node_insert($node) {
// hook_node_insert() is called for any node.
// Check the content type of the node is the one for which the form fields have been added.
if ($node->type == 'abc') {
$values['field_1'] = !empty($node->field_1) ? $node->field_1 : '';
$values['field_2'] = !empty($node->field_2) ? $node->field_2 : '';
db_insert('my_custom_table')
->fields(array('nid' => $node->nid, 'field_1' => $values['field_1'], 'field_2' => $values['field_2']))
->execute();
}
}
/**
* Implements hook_node_update().
*/
function mymodule_node_update($node) {
if ($node->type == 'abc') {
db_update('custom_table')
->condition('nid' => $node->nid)
->fields(array('field_1' => $node->field_1, 'field_2' => $node->field_2))
->execute();
}
}
_
動的クエリは、別のモジュールが変更するなど、厳密に必要な場合に使用する必要があります。動的クエリを使用する必要がある場合は、次のように書き直します。
_$result = db_select('custom_table', 'e')
->fields('e', array('nid', 'filed_1', 'field_2'))
->condition('nid', $nids, 'IN')
->execute();
_
データベースの値を更新するには、 db_update() を使用する必要があります。データベースにすでに存在する値は削除せず、新しい値を挿入します。 db_update()
は、$query->condition()
で表される条件に一致するデータベース行を探し、$query->fields()
で指定されたフィールドを新しい値で更新します。
補足として、すでにインストールされて有効になっているモジュールを編集している場合は、無効にしてから再度有効にする必要があります。そうしないと、Drupalはコードが変更されたことに気付かず、新しいモジュールを実装しますフック。 Drupalは、有効なモジュールから実装されたフックのリストをキャッシュに保持します。モジュールを無効にして再度有効にすると、Drupalがそのキャッシュを強制的に更新します。
hook_node_prepare を実装する必要があります。このフックは、ノードオブジェクトが追加/編集フォームに表示される前に追加データをロードするために使用されます。