값에 대한 데이터가있는 선택 필드의 허용 된 값 목록에서 항목을 제거하려면 어떻게해야합니까?


16

목록 / 선택 옵션 필드가있는 컨텐츠 유형을 작성했으며 선택 목록이 작동하는 데 필요한 키 | 값 쌍을 입력했습니다.

데이터가 입력되었으며 특정 용어가 더 이상 적용되지 않으며 삭제되어야한다고 결정되었습니다.

그러나 해당 용어를 제거하려고 할 때 다음 오류가 발생합니다.

Allowed values list: some values are being removed while currently in use.

분명히 프로젝트 기간 동안 가치는 변할 것입니다. 노드가 나열된 용어와 연결되면 항목을 제거하는 실용적인 방법은 무엇입니까?

이것은 내가 찾을 수있는 가장 가까운 것에 관한 것입니다.

https://drupal.org/node/1653012

그것은 d6 플러그인과 내가 선호하지 않는 패치 트릭을 참조합니다. 해당 필드에서 유효성 검사를 제거하기 위해 패치를 사용하는 데 궁극적으로 의지해야한다면, 해당 항목이 연결된 노드에서 고립 된 상태로 두는 데 해가 있습니까?

업데이트, 나는 Drupal 사이트를 보유한 지난 7 년 동안 50 개의 주와 테리토리가 선정 된 목록에있는 정부 고객과 함께이 문제에 다시 직면하게되었습니다. 이제 정책이 변경되었으며 지역을 더 이상 포함 할 필요가 없었습니다. 선택 목록에서 항목을 제거 할 수있는 것이 중요하므로 현상금을 제공하고 있습니다.

선택 목록에서 항목을 제거 할 수있는 안전한 솔루션을 찾고 있습니다. 내가 모르는 것은 노드의 총 콘텐츠와 관련하여 필드 값이 어떻게 저장되는지 잘 모르기 때문에 솔루션이 노드를 업데이트 해야하는지입니다.

MySQL에서 실행되는 순수한 SQL 솔루션에 만족합니다. 또는 모듈을 찾고 있습니다.


3
분명히 프로젝트 기간 동안 가치는 변할 것입니다. 정적 선택 목록의 값은 프로젝트 시작시 정의되어야한다고 논쟁합니다. 융통성이 있어야하는 경우 정적 목록 대신 용어 참조를 사용해야합니다. 정적 목록은 성 (남성 / 여성)과 같은 것들을위한 것이며, 심각한 변화가 없다면 조만간 변경되지 않을 것입니다. 그리고 그렇다면 추가 되지 않고 추가 됩니다 . 내가이 '실수'를 할 때마다 항상 철회하는 가장 좋은 방법은 데이터에 대해 수동 쿼리를 실행하는 것입니다.
Clive

1
이 목록을 동적으로 만드시겠습니까? 생성 및 삭제에 역동적입니다.
M ama D

1
그래, 나는 그것이 단지 의견에 달려 있다고 생각한다.-자동차 제조업체는 내가 구축하려는 모든 사이트에 대해 항상 노드 유형 또는 어휘가 될 것입니다. 제조업체는 자동차의 카테고리 (또는 누군가 수리하는 자동차의 카테고리)이므로 콘텐츠 유형이 아니라 분류 체계로 가장 적합합니다. 하지만 그하지 도움 ... 난 DB에 고아 데이터를 떠나 조심 것이다 않습니다 알고, 당신의 사이트에 설치 정확히 무엇과 구성 어떻게 모르고있을 수있는 어떤 영향을 말을하는 것은 매우 어렵다
클라이브

1
views_bulk_operations의 문제점은 무엇입니까?
donquixote

1
heh,이 답변들 중 어느 것도 아직
찬성 투표를

답변:


7

최근에 다음과 같은 접근 방식으로 이와 같은 작업을 수행했습니다.

  1. 새로운 허용 값을 추가하십시오.
  2. "활성"값을 구성하기위한 설정을 추가하십시오.
  3. 양식에 표시되는 "비활성"값을 필터링하십시오.

예 :

/**
 * Admin settings form
 */
function MODULE_admin_settings(){

  $form = array();

  // Select active preferences for display
  $field = field_info_field('field_preferences');
  $preferences = list_allowed_values($field);
  $form['field_preferences_active'] = array(
    '#type' => 'checkboxes',
    '#title' => t('Active preferences'),
    '#options' => $preferences,
    '#description' => t('Select the preferences available for user selection.'),
    '#default_value' => variable_get('field_preferences_active', array()),
  );

  return system_settings_form($form);

}

/**
 * Implements hook_field_attach_form
 */
function MODULE_field_attach_form($entity_type, $entity, &$form, &$form_state, $langcode) {

  // Filter out inactive preferences
  if(isset($form['field_preferences'])){
    $preferences = variable_get('field_preferences_active', array());
    foreach($preferences as $key => $preference){
      // If this preference isn't checked, but is set in the field values, unset it.
      if(empty($preference) && isset($form['field_preferences'][LANGUAGE_NONE]['#options'][$key])){
        unset($form['field_preferences'][LANGUAGE_NONE]['#options'][$key]);
      }
    }
  }

}

이렇게하면 레거시 데이터가 참조 용으로 유지되고 양식이 검증되며 데이터 무결성이 그대로 유지됩니다.


1
이 옵션은 본질적으로 비파괴 적이며 (즉, 삭제보다는 숨기는 것), 오래된 옵션이있는 엔티티를 처리하는 방법에 대한 최상의 조치를 결정할 때까지 가장 좋은 출발점이 될 것입니다.
mpdonadio

3

아시다시피 모든 필드 데이터는 field_data_field_FIELDNAME 및 field_revision_field_FIELDNAME의 두 테이블에 저장됩니다. 그리고 내 생각을 확인했습니다 : https : //.com/a/7773117/1300562

따라서 불필요한 필드 값을 제거하려면 위에서 언급 한 테이블에서이 값을 삭제 한 다음 허용 된 값 목록에서 제거해야합니다.

1 단계.

$values_to_remove = array('value1', 'value2'); // an array of unnecessary values
$fieldname = 'FIELDNAME'; // name of your field. For example,
                          // 'territory' for field with machine name 'field_territory'
$entity_type = 'node'; // it's 'node' in your case, but it can be 'taxonomy_term' or something else

db_delete('field_data_field_' . $fieldname)
  ->condition('entity_type', $entity_type)
  ->condition('field_' . $fieldname . '_value', $values_to_remove)
  ->execute();

db_delete('field_revision_field_' . $fieldname)
  ->condition('entity_type', $entity_type)
  ->condition('field_' . $fieldname . '_value', $values_to_remove)
  ->execute();

2 단계.
필드 설정 페이지에서 불필요한 키 쌍을 제거하고 변경 사항을 저장하는 양식을 제출하십시오.
그 후에 캐시가 자동으로 지워 져야하지만 노드 페이지에서 여전히 제거 된 필드 값이 표시되면 캐시를 수동으로 지우십시오.

추신 : 최근 비슷한 문제에 직면하여 이제 텍스트 값 목록 대신 "Term reference"또는 "enter reference"유형의 필드를 사용하는 것을 선호합니다. 참조 필드를 사용할 때 각 필드에 대해 별도의 어휘를 작성하고 언제든지 용어를 작성 / 편집 / 삭제할 수 있습니다.


필드가 반복되는 경우 해당 쿼리는 나머지 데이터의 델타를 조정하지 않습니다.
mpdonadio

1

먼저 필드에 허용 된 값이 지정되어 있는지 확인하십시오. 그렇게하면 다른 옵션의 유효성이 검사되지 않습니다. 따라서 먼저 필드 설정 탭에서 값을 제거하십시오.

또는 두 가지 옵션이 있습니다.


1.

사용자 계정에서 사용중인 허용 된 값 목록에 입력 한 모든 값을 제거하십시오. 예를 들어 SQL 쿼리를 실행하여 다음을 찾을 수 있습니다.

SELECT * FROM field_data_field_MYFIELDNAME WHERE entity_type = 'user' and value = 'MY VALUE'

또는 허용 된 값 목록에서 제거하려는 값을 가진 사용자 계정을 표시하는 사용자보기를 작성하십시오.


2.

필드에서 값을 제거하지 않으려면 해킹을 통해이를 수행 할 수 있습니다.

경고, 이것은 생산을위한 제안 된 솔루션이 아니며 현재하고있는 일을 알아야합니다!

  1. 모듈 / 필드 / 필드 찾기 및 편집
  2. field_has_data () 함수를 찾아서 return TRUE;첫 번째 함수 행에 추가하십시오 .

    function field_has_data($field) {
      return FALSE; // HACK !!!
      $query = new EntityFieldQuery();
  3. 원하는 값으로 필드를 다시 저장하십시오.
  4. 그렇게하는 즉시 해킹을 제거하십시오.

0

실제로 Views Bulk Operations 모듈 을 사용 하여이 작업을 수행 할 수 있다고 생각합니다 .

  1. 해당 필드에 바꾸려는 새 옵션을 추가하십시오. 예를 들면 다음과 같습니다. na | NA
  2. 해당 필드에 포함 할 노드를 나열하는보기를 작성하십시오.
  3. 해당 뷰에 "대량 작업 : 내용"필드 추가
  4. "항목 값 수정"및 "사용 가능한 토큰 표시"를 확인하십시오 (표시 값에서 모두 선택).
  5. 필터 기준에서 변경하려는 필드를 추가하고 해당 필터를 "노출"
  6. 해당보기에서 URL 경로를 설정하십시오.
  7. 해당 뷰 페이지로 이동하여 변경
  8. 이제 노출 및 조작 기능을 사용하여 필드 옵션을 변경하십시오.
  9. 끝난

0

다음은 HL 답변에 대한 개선 사항입니다.

요약하면 선택 필드에 "이전"값이 할당 된 컨텐츠에 새 값을 지정해야합니다.

Views Bulk Operations 외에도 Administration Views 모듈 을 설치하고 활성화해야 합니다. 이 모듈을 사용하면 벌크 작업이 활성화 된 즉시 사용 가능한보기가 있습니다 (한 번 활성화 된 관리자 / 컨텐츠 참조). 그때:

1) "관리 : 노드"보기 편집으로 관리 / 구조 /보기로 이동

2) 상단의 "추가-> 페이지"버튼을 사용하여보기에 대한 새 페이지 표시를 추가하십시오.

3) 새 디스플레이의 경로를 지정하십시오. 예 admin / content / custom

4) 선택 필드에 새 필터를 추가하십시오. 연산자 "이 중 하나입니다"를 선택한 다음 삭제할 모든 옵션을 선택하십시오.

5)보기를 저장하십시오

6) 관리자 / 콘텐츠 / 사용자 정의로 이동 이제 일괄 편집해야하는 모든 콘텐츠가 표시됩니다 (선택 필드의 값 변경).

7) 표 왼쪽의 첫 번째 확인란을 클릭하여 모든 행을 선택하십시오 (한 페이지가 여러 개인 경우 "이보기에서 모든 X 행 선택"이라는 단추를 선택하십시오).

8) "값 변경"작업을 선택하고 "실행"을 누릅니다.

9) 선택 필드에서 새 값을 선택하여 삭제하려는 값을 덮어 씁니다.

10) 해당 선택 필드의 확인란을 선택하십시오

11) 다음을 클릭하면 완료


0

Drupal 문제는 더 깊은 데이터 문제를 기반으로하는 것처럼 들립니다. 현재 감가 상각 된 목록 값을 사용하는 엔터티는 어떻게됩니까? 이 질문은 Drupal이 보낸 오류 메시지의 근본입니다.

주 / 지역의 예를 자세히 살펴 보겠습니다. 고객은 수년간 같은 방식으로 주와 준주를 취급하는 시스템을 사용하고 있으며 주와 준주를 모두 포함하는 거대한 노드 그룹을 구축했습니다. 그러던 어느 날, 영토를 다르게 처리해야하고 지역 할당을위한 드롭 다운에 영토가 더 이상 포함되지 않아야한다고 결정하는 권한이 있습니다. 큰. 표준 필터를 사용하여 모든 지역 노드의 목록을 렌더링하는 뷰를 만들고 뷰 대량 작업을 사용하여 모든 지역 값을 다음과 같이 변경하면됩니다. 영토의 운명은 매우 심각한 질문입니다. 솔루션에는 영역 상태를 유지하거나 재배치하는 방법이 포함되어 있어야합니다. '테리토리'라는 새 목록 필드를 만들어야 할 수도 있습니다.

이러한 변경을 수행하려면 View Bulk Operations 와 함께 규칙 을 사용해야 합니다. 규칙에 대해 잘 모르는 경우 규칙이 어떻게 작동하는지 시간을 내십시오. 규칙은 트리거, 조건 및 작업을 기반으로 정보를 조작 할 수있는 기능을 제공합니다. 규칙에 대해 배운 후에는 찾고있는 답변이 직관적으로 나타납니다. 기본적으로 대량 작업에 의해 트리거되는 규칙을 작성해야합니다.이 작업은 모든 영토를 대상으로하고 기본 정보 본문에서 규칙을 제거, 재 할당, 이름 바꾸기 또는 분리합니다. 규칙은 어떤 방식 으로든 영토 상태를 저장할 수 있어야하며 상태 드롭 다운을 '기타'또는 'N / A'상태로 설정하십시오. 이것이 필요한 전부일 수 있습니다. 그렇지 않으면...

재 할당이 완료되면 원래 목록 필드를 변경하고 지역 이름을 제거하는 간단한 작업이어야합니다. 그러나 시스템에서 여전히 목록을 변경할 수없는 경우 새 목록 필드를 작성한 다음 대량 작업 및 규칙보기를 사용하여 모든 현재 상태 값을 검토하고 새 목록에 다시 지정하십시오. 규칙은 Views Bulk Operations와 함께 작동하여 모든 관련 노드를 대상으로하고 필드 값을 기반으로 조치를 수행 할 수 있습니다. 규칙을 사용하면 노드 그룹의 기존 목록 필드 값을 기반으로 새 목록 필드 값을 쉽게 설정할 수 있습니다.

또한 Drupal이 작업에 문제가 있으면 어려운 대안을 고려하기 전에 항상 캐시를 플러시하십시오.


0

고객이 기존 콘텐츠를 원래 값으로 유지하기를 원한다고 가정합니다. 즉, 선택 목록을 변경하면 이전 데이터가 효과적으로 파괴됩니다. 그것이 관심사가 아니라면 다른 대답이 효과가있을 것입니다. 그러나 데이터 히스토리를 잃지 않고 선택 목록을 실제로 변경할 수는 없습니다. 사이트를 조금 더 미래에 대비하는 동시에 기록 데이터를 허용하기 위해 훨씬 간단한 경로를 사용할 수 있습니다. 필드 권한을 사용하는 것이 좋습니다.

정적 데이터 대신 분류 체계를 사용하여 해당 선택 목록에 대한 새 필드를 설정하십시오.

* 기존 선택 목록에 대한 필드 권한을 VIEW로 설정하지만 관리자 이외의 사람은 편집 할 수 없습니다.

이를 통해 기존 필드는 계속 볼 수 있고 검색 가능해야하며 (레거시로만 반영하는 새 제목 추가) 편집 할 수 없습니다. 물론 이것은 조정이 필요한 사용자 정의 검색,보기 등에 크게 좌우됩니다.

나는 데이터를 제거하고 기록을 제거하며 장기적으로 치명적일 수 있기 때문에 (소리가 들리면 지저분한) 제안합니다. css를 사용하여 편집 노드에서 이전 필드를 숨기고 값을 설정하지 않은 새 컨텐츠를 위해 숨길 수있는 후크도 있습니다. 이러한 방식으로 해당 레거시 컨텐츠에만 표시됩니다.

물론 사용자 지정 일회용 모듈을 사용하여 이전 선택 목록에서 새 분류 체계로 데이터를 복사 할 수 있습니다.


0

구조에 간단한 drush 스크립트! 필드 설정을 수동으로 변경하기 전에 필드 데이터 및 필드 개정 테이블을 업데이트하고 이전 값을 새 값으로 바꿉니다.

현재 필드 설정에서 이와 같은 것이 있다면 :

&date=today|today
&date=last2days|last2days

다음과 같이 바꾸십시오.

date=today|today
date=last2days|last2days

먼저 drush 스크립트를 실행 한 다음 관리자 UI에서 필드 설정을 변경합니다.

참고 : 이 코드는 시스템 이름이있는 필드 용입니다 field_foo_bar.

    $field_name = 'foo_bar';

    print "for {$field_name}...\n";

    replace_field("&date=today", "date=today", $field_name);

    replace_field("&date=last2days", "date=last2days", $field_name);

    function replace_field($old_value, $new_value, $field_name, $entity_type='node') {
      print "Replacing {$old_value} with {$new_value}...\n";
      $data_count = replace_options_data_field($field_name, $entity_type, $old_value, $new_value);
      $revision_count = replace_options_revision_field($field_name, $entity_type, $old_value, $new_value);
      print $data_count + $revision_count . " entries replaced.\n";
    }

    function replace_options_data_field($field_name, $entity_type, $old_value, $new_value) {
      $num_updated = db_update('field_data_field_' . $field_name)
        ->fields(array(
                   'field_' . $field_name . '_value' => $new_value,
                 ))
        ->condition('entity_type', $entity_type)
        ->condition('field_' . $field_name . '_value', $old_value)
        ->execute();
      return $num_updated;
    }

function replace_options_revision_field($field_name, $entity_type, $old_value, $new_value) {
  $num_updated = db_update('field_revision_field_' . $field_name)
    ->fields(array(
               'field_' . $field_name . '_value' => $new_value,
             ))
    ->condition('entity_type', $entity_type)
    ->condition('field_' . $field_name . '_value', $old_value)
    ->execute();
  return $num_updated;
}

0

나는 kenorb의 두 번째 제안을 사용했으며 Drupal 7.52, Profile2 7.x-1.3 필드의 값 목록을 업데이트했습니다. 따라서 drupal 경고가 표시되는 경우 : "허용 된 값 목록 : 현재 사용중인 일부 값이 제거되고 있습니다."다음으로 데이터베이스에서 값을 제거하거나 바꾸지 않고 (profile2) 필드에서 값을 제거 할 수있었습니다.

Drupal 코어의 루트 디렉토리에는 모듈이라는 폴더가 있으며 편집 할 파일은 modules / field / field.module에 있습니다. 이 파일은 핵심 파일이므로 값 업데이트가 완료되면 변경 사항을 완전히 되돌려 야합니다. 사이트를 오프라인으로 전환하고 (drupal root) /modules/field/field.module에서 다음 코드 블록을 임시로 교체했습니다.

function field_has_data($field) {
  $query = new EntityFieldQuery();
  $query = $query->fieldCondition($field)
    ->range(0, 1)
    ->count()
    // Neutralize the 'entity_field_access' query tag added by
    // field_sql_storage_field_storage_query(). The result cannot depend on the
    // access grants of the current user.
    ->addTag('DANGEROUS_ACCESS_CHECK_OPT_OUT');

  return (bool) $query
    ->execute() || (bool) $query
    ->age(FIELD_LOAD_REVISION)
    ->execute();
}

정확하게

function field_has_data($field) { 
    return FALSE; // hack 
    $query = new EntityFieldQuery();
}

드루팔은 불평을 멈추고 목록을 바꿀 수있었습니다. (제 경우에는 대학을 떠난 가치 목록의 교수진이지만 여전히 고문, 멘토 등의 학생 기록과 관련이 있습니다.)

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.