web-dev-qa-db-ja.com

データベースのプログラムで用語のvid列を変更することはできますか?

翻訳、エイリアス、ノード参照などのすべてのデータを保持することで、用語をある用語から別の用語に移動する必要があります。

データベースでvid列の値を直接変更することはできますか?用語には、処理する必要がある階層関係がありません。

8
Molfar

データベース

Drupalでは、Drupalまたは外部からSQLクエリを実行するだけで、多くのことを行うことができます。通常、このアプローチを採用することは決してありません。うまく動作する場合もありますが、ほとんどの場合、このようにする理由はありません。

API

Drupalには豊富なAPIがあり、これはDrupal 6、7、8の場合に当てはまります。これらは常にDrupalの重要な機能でした。具体的な例では taxonomy_term_load および taxonomy_term_save 用語の更新を容易にします。このようにすると、vidを含むすべてのデータパーツを編集できます。 APIの実行forbiddenでそれを実行したからといって、自動的に機能するだけでなく、正常に機能する可能性が大幅に向上します。

この具体的な例では、APIは必ずしも必要なことを何もしません。これは、用語にいくつかの内部データを設定し、フック文字モジュールを呼び出して、更新されたことを認識します。

変更したい用語が階層の一部である場合、状況が崩れる可能性があることに注意してください。フィールドが新しい語彙の用語を参照することを許可されていない場合、その用語を参照するノードで物事が壊れることもあります。

マイグレーション

データの移行は防弾ソリューションであり、巨大なデータセットがない限り、非常に簡単に開発および実行できます。新しい用語を作成し、移行するコンテンツを移行してから、古い用語を削除するという考え方です。更新フックとして、サンプルコードは次のようになります。

/**
 * Put in modules .install file, replace xxxx with 7000 or higher
 */
function MODULE_NAME_update_XXXX(&$sandbox) {
  $term = taxonomy_term_load(CONSTANT_WITH_TID);
  $new_term = clone $term;
  unset($new_term->tid);
  unset($new_term->tid);
  $new_term->vid = CONSTANT_WITH_VID;
  taxonomy_term_save($term);
  // Find all nodes we want to update and update them.
  // If there is a lot of nodes, can use $sandbox to make this a batch job.
  $query = new EntityFieldQuery();
  $query->entityCondition('entity_type', 'node')
    ->fieldCondition('field_which_is_term_reference', 'tid', $term->tid);
  $result = $query->execute();
  foreach (node_load_multiple(array_keys($result['node'])) as $node) {
    $node->field_which_is_term_reference[LANGUAGE_NONE][0]['tid'] = $term->tid;
    node_save($node);
  }
  // Migration all done - delete the old term.
  taxonomy_term_delete($term->tid);
}

上記のコードは純粋にサンプルコードであり、暗記されていることに注意してください。構文エラーまたはその他のエラーが発生する可能性があり、多くの仮定を行います。これは単にアイデアを説明し、移行は大したことではないかもしれないことを示すためです。

11
googletorp

Drupalで作業するときにデータベースを直接変更することは非推奨です。しかし、はい、影響を受ける可能性のある場所がすべてわかっていて、それに応じて必要な変更を行う場合、[〜#〜] ok [〜#〜]でデータベースを直接変更できます。この場合、これはUIからは実行できないためです。 注:用語に関連付けられているノードがある場合、それも手動で処理する必要があります。

Drupal 7で用語語彙を変更する方法を説明するこのリンクを確認してください: Drupal 7を使用して分類用語の語彙を変更しますデータベース

4
Yogesh

あなたの質問であなたがそれを説明した方法でその用語を変更することはお勧めしません。代わりに、別のアプローチを使用して(指定された順序で)同様の結果を達成します。

手順1-今後のノードの更新で新しい用語の使用を開始する

新しい分類用語フィールドを作成して、今後のノードの更新(または作成される新しいノード)がその新しいフィールドを使用するようにします。これらの用語はノードに使用されていると思います(ユーザーなど、他のエンティティタイプに使用する場合)。これらのエンティティにも同じアプローチを使用できます。

Rules モジュールを使用して、次のようなルールを作成します。

  • ルールイベント:before saving content
  • ルール条件:
    • entity has field、フィールド=古いフィールド。
    • AND NOT(entity has field、with field =新しいフィールド)。
  • ルールアクション:set Drupal message。これには、古いフィールドを空白にする必要があるという指示が含まれており、新しいフィールドには適切な値が含まれている必要があります。

ステップ2-ルールを使用してプロセスを高速化する

明らかに、ステップ1のアプローチは、これを手動で、一度に1ノードずつ行う必要がある場合、「ある程度」時間がかかります。しかし Views (更新する同様のノードのリストを作成する)と [〜#〜] vbo [〜#〜] (このようなリストを一括更新する)を使用すると、 (すべきです!)このプロセスをかなり高速化できます。

特に、 Rules を使用して、このようなVBOビューのカスタムバルク操作を作成する場合、「 ルールを使用してVBOビューのカスタムバルク操作を作成する方法? "。このようなカスタム一括操作の実装に役立つはずのルールコンポーネントのプロトタイプを次に示します(ルールエクスポート形式)。

{ "rules_replace_a_term_field_by_another_term_field" : {
    "LABEL" : "Replace a term field by another term field",
    "PLUGIN" : "rule",
    "OWNER" : "rules",
    "REQUIRES" : [ "rules" ],
    "USES VARIABLES" : { "node" : { "label" : "Node", "type" : "node" } },
    "IF" : [
      { "entity_has_field" : { "entity" : [ "node" ], "field" : "field_sample_tags" } },
      { "entity_has_field" : { "entity" : [ "node" ], "field" : "field_demo_tags" } },
      { "data_is" : { "data" : [ "node:field-demo-tags" ], "value" : "1" } }
    ],
    "DO" : [
      { "data_set" : { "data" : [ "node:field-sample-tags" ], "value" : "31" } },
      { "drupal_message" : { "message" : "Term updated in node with id = [node:nid]" } }
    ]
  }
}

上記のプロトタイプを説明するいくつかの詳細:

  • ノードをパラメーターとして使用します。
  • これらはルール条件です:

    • エンティティ(=ノード)にフィールドfield_sample_tagsがあるかどうかを確認します。
    • エンティティ(=ノード)にフィールドfield_demo_tagsがあるかどうかを確認します。
    • フィールドfield_demo_tagsの値が、置換する用語に対応しているかどうかを確認します(この例では、用語にはid = 1があります)。この条件が満たされない場合、ルールアクションは実行されないことに注意してください。
  • ルールアクションは次のとおりです。

    • フィールドfield_sample_tagsの値を、用語id = 31の用語に等しく設定します(これは、置き換えられる語彙の用語と一致する、新しく作成された語彙の用語です)。
    • サイトにTerm updated in node with id = 72のようなメッセージを表示しますが、72は更新されたノードのノードIDです。

必要に応じて、上記のプロトタイプのフィールド名のマシン名と使用されている用語IDを適合させます。次に、(ルールUIを使用して)自分のサイトにインポートし、インポートしたルールコンポーネントの右側にある「実行」リンクを使用してQAテストします(そして、「直接入力」に切り替えた後、ノードIDを入力してテストしますモード」でノードIDを指定できるようにします)。テスト中にそのようなTerm updated in node ...メッセージが表示されない場合、選択したノードがルールの条件で指定された用語の値を使用していないことが原因であると考えられます。

ステップ3-VBOを最後の仕上げとして使用する

手順2のこのルールコンポーネントのQAテストが完了したら、処理するノードのVBOビューを作成します。このビューでは、上記のルールプロトタイプ(またはニーズに合わせてそのバリエーション)を参照します。

このアプローチの利点

このアプローチを使用すると、カスタムデータベースを一切使用せずに(データベースを直接更新する場合と比較して)データの不整合を招くリスクを最小限に抑えることができます(ビューUIとルールUIのみを使用します)。

4
Pierre.Vriens

私はあなたがプログラムで言うことを知っていますが、モジュールを使用したい場合は Taxonomy Manager を使用できます

このモジュールは、分類法を管理するための強力なインターフェースを提供します。語彙は動的ツリービューに表示され、親用語を展開してネストされた子用語を一覧表示したり、折りたたんだりできます。

Taxonomy Managerには、次の操作と主な機能があります。

  • 動的ツリービュー
  • 一括削除
  • 新しい用語の大量追加
  • 階層内の用語の移動用語のマージ(7.xの用語マージモジュールを使用)
  • 上矢印と下矢印を使用した高速の体重変更(およびAJAX保存))
  • AJAXを利用した用語編集フォーム
  • シンプルな検索インターフェース
  • 用語のCSVエクスポート
  • 多言語語彙のi18nサポート(言語ごと)
  • 階層内の用語の移動、新しい翻訳の追加、異なる語彙間の用語の切り替えのためのダブルツリーインターフェイス
2