프로그래밍 방식으로 필드 업데이트, hook_node_update


13

현재 노드를 만들거나 업데이트 할 때마다 필드를 업데이트하려고합니다. 그러나 값이 노드 내에 채워지지 않습니다.이 특정 후크를 사용하여 노드 개체에 액세스 할 수 있습니까? 무엇을 놓칠 수 있습니까?

  function vbtoken_node_update($node) {


      entity_get_controller('node')->resetCache(array($node->nid));


      $types = node_type_get_types(); //What are the current Node Content Types?
      $yes = ($types['volunteer_project']->type);

      if($node->type === $yes){


        $hash = md5($node->title . $node->nid . $node->nid);
        $hashed = substr($hash, 0, 6);
        $node = node_load($node->nid);
        $node->tcode[$node->language][0]['value'] = $hashed;
        node_save($node);

        watchdog('vbtoken', 'Added a new Token code to %nid', array('%nid' => $node->nid));

        }
        else 
        {
          dpm('not working dude');
        }

    }

답변:


16

엔티티 메타 데이터 랩퍼

엔티티 API는 엔티티를 쉽게 처리하고 제공된 엔티티 특성 정보 모듈을 활용하는 데 사용할 수있는 일부 랩퍼 클래스를 제공합니다. 래퍼를 사용하면 속성 정보에 액세스하거나 알려진 속성을 반복하거나 설명 된 데이터 값을 가져 오거나 설정할 수 있습니다.

다음은 README에서 볼 수있는 간단한 사용법 예입니다.

이 정보 (메타 데이터)를 사용하기 위해 모듈은 값을 쉽게 가져오고 설정할 수있는 래퍼 클래스를 제공합니다. 래퍼는 엔티티 속성의 래퍼를 검색하기위한 체인 사용을 지원합니다 (예 : 노드 작성자의 메일 주소를 얻기 위해).

$wrapper = entity_metadata_wrapper('node', $node);
$wrapper->author->mail->value();

사용자의 메일 주소를 업데이트하려면

$wrapper->author->mail->set('sepp@example.com');

또는

$wrapper->author->mail = 'sepp@example.com';

래퍼는 항상 속성 정보에 설명 된대로 데이터를 반환합니다.이 정보는 entity_get_property_info () 또는 래퍼에서 직접 검색 할 수 있습니다.

$mail_info = $wrapper->author->mail->info();

출력을 위해 텍스트 값을 위생 처리하기 위해 다음을 사용할 수 있습니다.

$wrapper->title->value(array('sanitize' => TRUE));

삭제 된 노드 제목을 가져옵니다. 노드 본문과 같이 속성이 기본적으로 위생 상태로 반환되면 다른 유스 케이스의 브라우저에 표시되는 것처럼 위생되지 않은 데이터를 가져 오려고 할 수 있습니다. 이를 위해 'decode'옵션을 활성화하면 위생 처리 된 데이터에 대해 태그가 제거되고 속성이 반환되기 전에 HTML 엔터티가 디코딩됩니다.

$wrapper->body->value->value(array('decode' => TRUE));

그렇게하면 항상 사용자에게 표시된대로 데이터를 얻습니다. 그러나 위생 처리 된 텍스트 데이터의 경우에도 처리되지 않은 원시 값을 얻으려면 다음을 통해 수행 할 수 있습니다.

$wrapper->body->value->raw();

더 많은 예 :

$wrapper->body->set(array('value' => "content"));
$wrapper->field_text[0] = 'the text';
$wrapper->field_text[0]->set(array('value' => "content"));
$wrapper->field_text2->summary = 'the summary';
$wrapper->field_text2->value = 'the text';

$wrapper->save();
$wrapper->delete();

더 많은 문서 : http://drupal.org/node/1021556


정말 고맙습니다. 당신의 대답은 제가해야 할 일에 대한 지침을주었습니다. :) 커뮤니티 락 !! \ m /
SGhosh

이것은 hook_node_update에서는 작동하지만 hook_node_insert () 에서는 작동 하지 않습니다 . 노드 모듈과 사용자 정의 코드 모두 동일한 노드 ID를 사용하여 동일한 노드를 두 번 삽입하려고하므로 mysql에서 중복 기본 키 오류가 발생합니다.
leon.nk

14

field_attach_update('node', $node)마지막에 전화 하면 hook_node_update나를 위해 일했습니다. 나는 field_attach_insert('node', $node)끝날에도 효과 hook_node_insert가 있다고 가정합니다 . 따라서 샘플 함수는 다음과 같습니다.

function mymodule_node_update($node) {
  $new_value = // ...do some stuff to compute a new value for the field.
  $node->field_my_field[LANGUAGE_NONE][0]['value'] = $new_value;
  field_attach_update('node', $node);
}

전화를 걸 node_load node_save거나 아무것도 반환 할 필요가 없습니다 .

나는 그 이유가 있다고 생각 node_save되는, hook_node_updatehook_node_insert호출, 트랜잭션의 모든 데이터베이스 쿼리를 래핑합니다. ( node_save: 의 첫 번째 줄 참고 $transaction = db_transaction()) 이러한 쿼리는 node_save완료 될 때까지 호출되지 않습니다 . node_save트랜잭션에 추가하는 마지막 쿼리 는에서 호출되며 field_attach_update$ node 오브젝트를 이전 과 같이 사용합니다 hook_node_update. 따라서 field_attach_update다시 호출하여 다른 쿼리를 대기열에 추가해야 합니다. 적어도, 그것은 무슨 일이 일어나고 있는지에 대한 나의 이해입니다.

노드의 필드가 아닌 속성 (예 :)을 변경하는 데 문제가 있으면 $node->log전화를 걸어보십시오 _node_save_revision($node, $user->uid, 'vid');. 새 개정은 작성되지 않습니다.


2

노드에서 값을 변경하는 방법은 다음과 같습니다.

$node = node_load($nodeID);
$node->field_fieldname['und'][0]['value'] = $val;
node_save($node);

4
undOP는 이미 코드 $node->language에서 언어 코드로 사용한다고 명시했습니다
Clive

Clive와 Lance 덕분에 매우 도움이되지만 노드가 저장 될 때마다 필드 값이 저장되도록하므로 hook_node_update를 사용하고 싶습니다. 이 후크에서 $ node를 반환 할 수 있습니까 아니면 절대 node_load를 수행해야합니까? 정말 .... 내가 노드 객체가 hook_node_update를 통해 직접 전달 알았는데
generalconsensus

좋아, 권장 사항에 따라 코드를 업데이트했습니다. 원본에 있습니다. 문제 : 페이지가로드되지 않고 mysql과 apache가 CPU에서 85 % 이상으로로드되기 시작하는 무한 루프. 분명히 여기에 약간의 반복이 있습니다. 다른 제안?
일반 합의

무슨 일인지 말할 수 없습니다. 그러나 아마도 한 번만 노드를로드하고 필드에 무언가를 입력하고 node_save ()를 사용하여 저장하려고 시도합니다. 또는 그냥로드하고, 무언가를 인쇄하고 (watchdog 또는 dpm () 사용) 다시 저장하여 이것이 작동하는지 확인하십시오
Lance

이 문제는 노드를 저장하기 전에 저장 한 결과 재귀 루프로 인해 발생했습니다. 열악한 갈고리 선택과 열악한 빌드
일반 합의

1

Lance의 솔루션을 개선하여 몇 가지 필드 값만 수정하면 전체 노드를 절약 할 수 있습니다.

$node = node_load($nodeID);
// for each field whose value remains unchanged
unset($node->field_<field-name>); 
// for each field whose value changes
$node->field_<field-name>[LANGUAGE_NONE][0]['value'] = <new-value>;
field_attach_update('node', $node);
entity_get_controller('node')->resetCache(array($node->nid));

또한의 부작용을 피하는 데 유용 할 수 있습니다 node_save().

출처 : 노드 자체를 저장하지 않고 노드 필드 저장

https://www.urbaninsight.com/2011/10/24/saving-nodes-fields-without-saving-node-itself

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