web-dev-qa-db-ja.com

プログラムでノードからフィールドを削除する方法は?

プログラムでノードからフィールドを削除するにはどうすればよいですか? hook_update_Nは、フィールドの内容をカスタムテーブルに移動します。その移行後、同じ機能のフィールドを削除します。

フィールドの削除に対応するフィールドAPIはありますか?

編集、解決策:回答に実際のコードが不足しているため、$ usersから自分のレコードにフィールドを移動し、その後データベースからフィールドを削除するために、次のことを行いました。

function my_module_update_7005(&$sandbox) {
  $slice = 100;
  //Fetch users from database;
  if (!isset($sandbox['progress'])) {
    $sandbox['progress'] = 0;
    $sandbox['current_uid'] = 0;
    // We'll -1 to disregard the uid 0...
    $sandbox['max'] = db_query('SELECT COUNT(DISTINCT uid) FROM {users}')->fetchField() - 1;
  }
  if (empty($users)) {
    $sandbox["current_uid"] += $slice;
  }
  $users = db_select('users', 'u')
    ->fields('u', array('uid', 'name'))
    ->condition('uid', $sandbox['current_uid'], '>')
    ->range(0, $slice)
    ->orderBy('uid', 'ASC')
    ->execute();
  //Loop trough users;
  foreach ($users as $user) {
    $foo = new Foo();
    // Warning: drupal's fields return mixed values; e.g. NULL versus an int.
    $foo->debits = (int) $user->user()->field_credits["und"][0]["value"];
    $foo->save();

    $sandbox['progress']++;
    $sandbox['current_uid'] = $user->uid;
  }

  $sandbox['#finished'] = empty($sandbox['max']) ? 1 : ($sandbox['progress'] / $sandbox['max']);

  // Remove the field.
  field_delete_field("field_credits"); //note that the name for Foo is field_foo
  field_purge_batch($sandbox['max']+1);//Drupal seems to have an offbyone problem.
}
16
berkes

field_delete_field($field_name) は、次回のcron実行時に削除するために_$field_name_をマークします。

Cronの実行時に削除したくない場合は、 _field_purge_batch_ を使用して削除できます。

EDIT:field_delete_field()は、他のバンドルからもフィールドを削除する必要がある場合に使用する必要があります。特定のバンドルからフィールドを削除するだけの場合は、@ Cliveで言及されているように field_delete_instance() を使用する必要があります。

29
AjitS

特定のバンドルからフィールドを削除するには、 field_delete_instance() を使用できます

フィールドインスタンスとそのデータに削除のマークを付けます。

例:

_function my_module_update_7001() {
  if ($instance = field_info_instance('node', 'field_name', 'page'))  {
    field_delete_instance($instance, TRUE);
    field_purge_batch(1);
  }
}
_

システムからフィールドを完全に削除するには、 field_delete_field() を使用できます

フィールドとそのインスタンスおよびデータに削除のマークを付けます。

例:

_function my_module_update_7001() {
  field_delete_field('field_name');
  field_purge_batch(1);
}
_

フィールド/インスタンスは削除用にのみマークされ、データはその後のcron実行中に実際に消去されます。手動で削除するには、次のコマンドを実行します。

_field_purge_batch(1);
_
24
Clive

@berkesの質問に答えるには:

field_delete_field()は、フィールドに削除のマークを付け、次回のcronの実行時にパージされるようにします。ただし、そうするドロップされたフィールドに関するデータを_field_config_instance_に残します。 cronまたはfield_purge_batch()を実行しても、フィールドの削除された列が_field_config_instance_に設定されていても、このデータは_1_テーブルから削除されません。

私の場合、パージされたフィールドごとにfield_delete_instance()に続けてfield_purge_batch()を使用すると、データベースから両方のフィールドが即座に削除され(cronは不要)、_field_config_instance_もパージされます。 (削除されたフィールドの)フィールドデータのテーブル。

これが解決策です:

_/**
 * Implements hook_uninstall().
 */
function hook_uninstall() {
  // Delete all fields for all xyz entity bundles.

  // Retrieve all bundles for an entity.
  $bundles = field_info_bundles('XYZ'); // The name of your entity type, for example, 'node'.
  foreach ($bundles as $bundle => $properties) {

    // Retrieve all the fields for a given bundle.
    $instances = field_info_instances('XYZ', $bundle);
    foreach ($instances as $instance) {
      field_delete_instance($instance, TRUE);
      field_purge_batch(1);
    }
  }
}
_

フィールドAPIがクリーンアップ操作を実行する必要があることを示しているため、field_delete_instance()TRUEに注意してください。

5
amateur barista