프로그래밍 방식으로 노드에서 필드를 제거하는 방법은 무엇입니까?


16

프로그래밍 방식으로 노드에서 필드를 어떻게 제거합니까? 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.
}

답변:


29

field_delete_field($field_name)$field_name다음 cron 실행에서 삭제를 표시합니다 .

field_purge_batchcron 실행에서 삭제하지 않으려면 삭제를 수행하는 데 사용할 수 있습니다 .

편집 : field_delete_field() 다른 번들에서 필드를 삭제해야 할 때 사용해야합니다. 특정 번들에서만 필드를 삭제하려면 field_delete_instance()@Clive에서 언급 한대로 사용해야합니다.


4
또한에 :) 좋은 부착 할 수있는 다른 번들에서 필드를 제거 것,주의 정도 알고 field_purge_batch있지만
클라이브

@Clive : 맞습니다. 모든 번들에서 필드를 삭제합니다. 수정 해 주셔서 감사합니다 :) 나는 답변을 편집했습니다.
AjitS

모든 번들에서 필드를 완전히 제거하고 싶었습니다. 그러나 경고는 좋습니다. 감사.
berkes

1
field_delete_instance ()가 방법입니다.
Ryan McVeigh

field_purge_batch ()는 실제로 전달 된 배치 크기만큼 많은 필드 항목 만 삭제합니다. 필드에 항목이 거의없는 경우 도움이 될 수 있으므로 필드 인스턴스를 완전히 제거하기 위해 cron이 정리할 때까지 기다릴 필요가 없습니다. 필드에 많은 값이있는 경우 배치 크기를 너무 크게 늘리려 고하지 마십시오 (이름의 "배치"는 배치 자체를 수행하는 것이 아니라 단일 배치를 수행한다는 의미입니다) 요청한 항목 수만큼) PHP 메모리 또는 시간 제한이 발생할 수 있습니다.
Eelke Blok

24

특정 번들에서 필드를 제거하려면 다음을 사용할 수 있습니다. 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);
}

필드 / 인스턴스는 삭제 표시 만되며, 후속 크론 실행 중에 데이터가 실제로 제거됩니다. 수동으로 제거하려면 다음을 수행하십시오.

field_purge_batch(1);

1
호출하는 동안 field_delete_field()field_purge_batch()작품, 그것은 레코드를 유지 field_config_instance하고 field_config. 왜 그런 겁니까?
berkes

1의 값으로 field_purge_batch를 호출하면 모든 필드 데이터가 제거되는 이유를 알 수 없습니다. 코드를 올바르게 이해하면 $ batchsize 엔터티에 대한 필드 데이터를 가져 와서 그대로 둡니다 (즉, 재귀 적으로 함수를 호출하지 않습니다). 모든 데이터가 사라 졌는지 확인하고 그렇지 않은 경우 함수를 계속 호출하는 것은 호출자에게 달려 있습니다. 그러나 나는 근본적으로 무언가를 오해하고 있습니다.
Eelke Blok

실제로, field_ui.admin.inc의이 주석은 이것을 설명하는 데 먼 길을 가고 있습니다. // 필드는 cron에서 제거됩니다. 그러나 필드 모듈은 제공된 필드 유형이 완전히 제거 될 때까지 // 필드 유형을 사용하는 경우 모듈 비활성화를 방지합니다. 필드에 컨텐츠가 최소이거나없는 경우, field_purge_batch ()를 한 번 호출하면 시스템에서 해당 필드가 제거됩니다. //이 기준을 충족하는 인스턴스를 제거 할 때 관리자가 cron 실행을 기다려야하는 것을 방지하려면 // 배치 제한을 낮추어 호출하십시오.
Eelke Blok

@Clive, 나는 당신이 거의 암시 적으로 조언이라고 믿지만 if 조건에서 선언을하는 것이 얼마나 이상하게 보이는지 극복 할 수 없습니다. 의도적인가요? 을 참조하고 $instance = field_info_instance('node', 'field_name', 'page')있습니다. 대신 $instance = field_info_instance('node', 'field_contact', 'job');if 문을 삭제 해서는 안 됩니까?
cdmo

1
@ cdmo 그것은 "조건의 할당"이라고 불리며, 그래도 문제가 있습니다 . 그러나 Drupal 코어는 최신 버전에서도 자유로이 사용하기 때문에 최소한 우선합니다. 솔직히 말해서 5 년 전이었고 지금은 더 현명합니다. 사용하지 않거나 어떤 이유로 든 과제를 마무리합니다 (예 : if ( ($foo = $bar) ) {의도가 분명하고 잠재력이 있음) field_delete_instancenull을 검사하지 않기 때문에 if 문 자체가 필요합니다
Clive

5

@berkes 질문에 대답하려면 :

field_delete_field()필드를 삭제 표시하여 다음 cron 실행시 제거되도록합니다. 그러나 삭제 된 필드 에 관한 데이터 남습니다 field_config_instance. 삭제 된 열이 필드 에 대해 설정되어 있어도 cron을 실행하거나 테이블 field_purge_batch()에서이 데이터를 제거하지 않습니다 .field_config_instance1

내가 제거 된 각 필드에 대해 field_delete_instance()그다음 에을 사용 field_purge_batch()하여 데이터베이스에서 필드를 즉시 제거 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);
    }
  }
}

메모 마십시오 TRUE에를 field_delete_instance()가 필드 API가 정리 작업을 수행해야 함을 나타냅니다으로.


이 코드를 사용하는 방법? 컨텐츠 유형에서 제목 필드를 삭제하고 싶습니다
Umair
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.