Bir alanı programlı olarak güncelleme, hook_node_update


13

Şu anda bir düğüm her oluşturulduğunda veya güncellendiğinde bir alanı güncellemeye çalışıyor. Ancak değer düğüm içinde doldurulmuyor, bu özel kanca ile düğüm nesnesine erişim var mı? Ne eksik olabilirim?

  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');
        }

    }

Yanıtlar:


16

Varlık meta veri sarmalayıcıları

Varlık API'si, varlıklar ile kolayca ilgilenmek ve sağlanan varlık özelliği modüllerinden yararlanmak için kullanabileceğiniz bazı sarıcı sınıfları sağlar. Sarmalayıcıların yardımıyla özellik bilgilerine erişebilir, bilinen özellikler arasında geçiş yapabilir veya yalnızca açıklanan veri değerlerini alabilir / ayarlayabilirsiniz.

Bunlar README'de bulunan bazı basit kullanım örnekleridir:

Bu bilgileri (meta veriler) kullanmak için modül, değerleri almayı ve ayarlamayı kolaylaştıran bazı sarıcı sınıfları sağlar. Sarıcı, varlık özelliklerinin sarıcılarını almak için zincirleme kullanımı destekler, örneğin bir düğüm yazarının posta adresini kullanmak için:

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

Kullanıcının posta adresini güncellemek için

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

veya

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

Paketleyiciler her zaman doğrudan entity_get_property_info () üzerinden veya paketleyiciden alınabilecek özellik bilgilerinde açıklandığı gibi verileri döndürür:

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

Çıktı için sterilize edilmiş bir metin değeri almaya zorlamak için, örneğin;

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

sterilize edilmiş düğüm başlığını almak için. Bir özellik, düğüm gövdesi gibi varsayılan olarak zaten sanitize edilmiş olarak döndürüldüğünde, muhtemelen sanitize edilmemiş verileri diğer kullanım durumları için bir tarayıcıda göründüğü gibi almak ister. Bunu yapmak için, herhangi bir sterilize edilmiş veri için etiketlerin çıkarılması ve HTML öğelerinin özellik döndürülmeden önce kodunun çözülmesini sağlayan 'kod çözme' seçeneği etkinleştirilebilir:

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

Bu şekilde, veriler her zaman kullanıcıya gösterildiği gibi alınır. Bununla birlikte, sterilize edilmiş metin verileri için bile ham, işlenmemiş değeri gerçekten elde etmek istiyorsanız, bunu şu şekilde yapabilirsiniz:

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

Daha fazla örnek:

$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();

Daha fazla doküman : http://drupal.org/node/1021556


Çok teşekkür ederim. Cevabınız bana ne yapmam gerektiğine dair bir yön verdi. :) Topluluk kayalar !! \ m /
SGhosh

Bu hook_node_update üzerinde çalışır ancak değil hook_node_insert üzerinde (). Hem düğüm modülü hem de özel kodunuz aynı düğümü iki kez eklemeye çalışacağından (aynı düğüm kimliğini kullanarak) mysql'den bir birincil anahtar hatası alırsınız.
leon.nk

14

field_attach_update('node', $node)Sonunda arama hook_node_updatebenim için çalıştı. Ben varsayalım field_attach_insert('node', $node)sonunda hook_node_insertda uğratacak işler. Yani, bir örnek fonksiyon şöyle görünecektir:

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);
}

Hiçbir node_load node_saveşey aramanıza veya geri göndermenize gerek yoktur .

Bunun nedeni olduğunu düşünüyorum node_savehangi, hook_node_updateve hook_node_insertdenir, bir işlemde tüm veritabanı sorgularını sarar. (İlk satır Not node_save: $transaction = db_transaction().) Bu sorgular kadar adı değildir node_saveyüzeyler. node_saveİşleme ekleyen son sorgu çağrılır ve field_attach_updatedaha önce hook_node_update olduğu gibi $ düğüm nesnesini kullanır . Bu nedenle, field_attach_updatetekrar arayarak başka bir sorgu kuyruğa almanız gerekir . En azından, neler olduğunu anlıyorum.

Düğümün alan dışı niteliklerini değiştirme konusunda sorun yaşıyorsanız (ör. $node->log), Aramayı _node_save_revision($node, $user->uid, 'vid');da deneyin . Bu yeni bir düzeltme oluşturmaz.


2

Bir düğümdeki değerleri şu şekilde değiştirirsiniz:

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

4
undkullandıkları bu gerçekten burada mülk değil, OP zaten kodunda belirtmiştir $node->languagedil kodu için
Clive

Bu süper yararlı teşekkürler Clive ve Lance, ama düğüm kaydedildiğinde alan değerinin kaydedildiğinden emin olmak istiyorum, bu nedenle hook_node_update benim kullanımım. Bu kancada $ düğümünü döndürmek mümkün mü yoksa kesinlikle bir node_load yapmak zorunda mıyım? Gerçekten düğüm nesnesi doğrudan hook_node_update üzerinden geçirdiğini düşündüm ....
generalconsensus

Tamam, bu yüzden tavsiyenize göre kodu güncelledim - orijinal gövdede. Sorun: Sayfanın yüklenmediği ve hem mysql hem de apache'nin CPU'da% 85'lik yükün üstüne çıkmaya başladığı sonsuz döngü. Kesinlikle burada bir döngü var. Başka öneriniz var mı?
generalconsensus

Neler olduğunu söyleyemem. Ama muhtemelen bir kez düğümü yüklemek, alana bir şey girmek ve node_save () kullanarak kaydetmek için bir kez deneyin. Ya da sadece bir şey yükleyin, (bekçi köpeği veya dpm () kullanarak) yazdırın ve bunun işe
yarayıp

Sorun, düğümü kaydetmeden önce, özyinelemeli bir döngü ile sonuçlanan kaydedilmesinden kaynaklandı. Kötü kanca seçimi ve zayıf yapı
generalconsensus

1

Yukarıda yalnızca birkaç alan değeri değiştirildiğinde tüm düğümün kaydedilmesini önleyen Lance çözümünün iyileştirilmesi:

$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));

Bu, yan etkilerinden kaçınmak için de yararlı olabilir node_save().

Kaynak: Düğümün alanlarını, düğümün kendisini kaydetmeden kaydetme

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

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.