コンテンツタイプに新しいフィールドを追加した後、デフォルトフィールドですべてのノードを更新する


15

多数のノードを持つ既存のコンテンツタイプがあります。デフォルト値が「off」の新しいブールフィールドを追加しました。

ただし、各ノードを再保存するまでデフォルト値は設定されていないため、新しいフィールドがデフォルト値を使用しているノードのみを表示するビューは現在空です。

フィールドを追加する前に作成された既存のノードを更新して、そのフィールドをデフォルト値に設定するにはどうすればよいですか?


私はこの素晴らしいビデオで説明したようビューが操作とルールをBULK使用してこの問題を解決:commerceguys.com/resources/articles/217
DanH

ノードの再保存モジュールは、ノードの強制更新に役立つ場合があります。
Supriya Rajgopal

回答:


9

悲しいことに、これを行う簡単な方法はありません(VBO /ルール以外)が、新しいフィールドを追加した後に特定のノードタイプのフィールド値を事前入力する必要がある場合、カスタムモジュールインストールファイルの更新関数で使用するコードは次のとおりです(この場合、「ページ」ノード):

<?php
// Get all nodes of 'page' type, populate the field with a value of '1'.
$pages = db_query("SELECT nid, vid FROM {node} WHERE type = 'page'")->fetchAllAssoc('nid');
foreach ($pages as $nid => $values) {
  $fields = array(
    'entity_type' => 'node',
    'bundle' => 'page',
    'deleted' => 0,
    'entity_id' => $values->nid,
    'revision_id' => $values->vid,
    'language' => LANGUAGE_NONE,
    'delta' => 0,
    'field_page_new_field_value' => 1,
  );
  db_insert('field_data_field_page_new_field')
    ->fields($fields)
    ->execute();
  db_insert('field_revision_field_page_new_field')
    ->fields($fields)
    ->execute();
}
?>

この回答で言及されている別の手動の方法は、EntityFieldQueryを使用して、各ノードをロード/保存します。より多くのDrupal-yですが、パフォーマンスはあまり良くありません...(ノードごとに完全なノードのロードと保存操作が必要です!)。


それは非常に悲しいです
AlxVallejo

Field Defaultsモジュールを見ましたか?dgo.to/field_defaults
フォレスト

エンティティロードキャッシュから影響を受けるすべてのノードをフラッシュせずにこのようなコードを実行すると、バグになります。entity_get_controller('node')->resetCache($nids);そうでない場合、後続のnode_load()キャッシュが古いデータをキャッシュからロードしnode_save()、そのオブジェクトがその古いデータをデータベースに書き戻す可能性があります。
フィルス

2

最善策はMySQlに直接あります。テーブルは次のようになります。

field_data_field_newbooleanfieldname
field_revision_field_newbooleanfieldname

それらを見ると、それは非常に簡単です-クエリがどのように見えるかを始めるために私を必要としますか、ここから大丈夫ですか?


マイクに感謝します。いいえ、SQLを実際に処理できる問題ではありません。「再保存」オプションまたは一括操作として提供されるものがあるべきだと感じているのですが、実際にはこのためのVBOとルールの統合を検討するかもしれません。
DanH

わかった。私は同様の立場にあり、約30,000件の記事を別のCMSからDrupalに移行しています。SQLが迅速で汚れていたときに、別のモジュールを追加する意味がわかりませんでした。また、すべてのノードに対してnode_load()を呼び出すクイック関数を作成することもできますが、これも機能する可能性があります。
マイク

0

以下のロジックを試してください。はるかに高速で、すべてのフック実装もバイパスします。詳細は。単純な直接db_selectクエリを記述して、すべてのnidを取得し、このサンプルコードでループできます。

$node = new stdClass();
$node->nid = $val;
$node->type = 'NODETYPE';
$node-field_whatever[LANGUAGE_NONE][0]['value'] = 'VALUE';
field_attach_presave('node', $node);
field_attach_update('node', $node);

0

sqlを使用して、フィールド値が設定されていないノードは

SELECT nid,vid
 from node where type='procedure' and nid not in (select entity_id from field_data_field_pr_choix_du_document)

field_data_field_pr_choix_du_documentは、フィールドに対応するテーブルであり、ノードを参照するエンティティIDで設定された1つのエントリpar値を含む

私はSQL挿入...選択構文を使用しました

https://dev.mysql.com/doc/refman/5.5/en/insert-select.html

INSERT INTO `field_data_field_pr_choix_du_document` (`entity_type`, `bundle`, `deleted`, `entity_id`, `revision_id`, `language`, `delta`, `field_pr_choix_du_document_value`)
SELECT 'node','procedure',0,nid,vid,'und',0,'Importer un document'
from node where type='procedure' and nid not in (select entity_id from field_data_field_pr_choix_du_document)

0

Views Bulk Operationsモジュールをインストールして有効にし、ページ表示のあるビューを作成します。

追加=>一括操作:ビュー内のコンテンツ(コンテンツ)フィールド。

参照

ここに画像の説明を入力してください

デフォルト値を設定するフィールドを選択します。

ビューを保存し、作成したページに移動します。結果のページが複数ある場合は、現在のページのすべてのアイテム、すべてのページのすべてのアイテムを選択するか、個々のノードに対応するボックスを手動で選択できます。続行するには、少なくとも1つのチェックボックスをオンにする必要があります。

次に、デフォルト値を設定して保存します。


0

このモジュールを使用して、コンテンツタイプのフィールドを更新する簡単な方法を見つけました。 フィールドのデフォルト

スクリーンショットをご覧ください。既存のコンテンツをデフォルト値で更新するか、既存の値を保持できます。

D7でテストしましたが、動作します。

ここに画像の説明を入力してください

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.