प्रोग्रामेटिक रूप से एक इकाई पर एक फ़ील्ड से एक प्रविष्टि हटाएं


13

किसी विशिष्ट इकाई से बहु-प्रविष्टि क्षेत्र के लिए एक विशिष्ट फ़ील्ड प्रविष्टि को प्रोग्रामेटिक रूप से हटाने का उचित तरीका क्या है? (यह विशिष्ट फ़ील्ड्स और विशिष्ट इकाइयाँ हैं, फ़ील्ड प्रकार या इंस्टेंस और एंटिटी प्रकार नहीं)

यहाँ कुछ संभावनाएँ हैं जिन पर मैंने काम किया है:

  • entity_load()फ़ील्ड प्रविष्टि को = null या = array () में सेट करने के साथ , फिर से लोड करके इकाई को लोड करें field_attach_update()। यह मेरे निकटतम पाया गया है, लेकिन यह डेटाबेस में एक ज़ोंबी अशक्त क्षेत्र प्रविष्टि छोड़ता है जो प्रपत्र को सहेजने तक रिक्त पंक्ति के रूप में दिखाता है और hook_field_is_empty()किक कर सकता है ( hook_field_is_empty()ऐसे कॉन्फ़िगर किया गया है कि = null या = array) जितना खाली)।
  • इकाई को लोड करना entity_load(), कुंजी द्वारा फ़ील्ड प्रविष्टि को परेशान करना, फिर बचत करना field_attach_update()। यह कुछ भी नहीं करने के लिए लगता है - ऐसा लगता है कि ड्रुपल प्रविष्टि की व्याख्या करता है कि इसे संशोधित नहीं करने के संकेत के रूप में नहीं है। (अजीब तरह से मुझे भी कभी-कभी इस दृष्टिकोण की कोशिश करते समय अधिकतम क्वेरी समय समाप्ति समय समाप्ति मिलती है)
  • field_attach_delete() - यह बहुत अधिक कुंद है: यह इकाई के लिए सभी क्षेत्रों को मारता है
  • field_purge_data() - बेहतर, लेकिन फिर भी बहुत कुंद: यह क्षेत्र की सभी प्रविष्टियों को मारता है, विशिष्ट प्रविष्टियों को नहीं

तो स्पष्ट करने के लिए, मुझे एक कोड मिला है जो एक इकाई को ढूंढता है (और लोड करता है) जिसमें एक फ़ील्ड होती है जिसमें कई प्रविष्टियाँ होती हैं, और उस फ़ील्ड पर एक विशिष्ट प्रविष्टि पाता है जिसे निकालने की आवश्यकता होती है। मैं उस प्रविष्टि को पूरी तरह से हटा देना चाहता हूं, इकाई पर किसी भी अन्य प्रविष्टियों या किसी भी अन्य क्षेत्रों को छूने के बिना।

जवाबों:


24

यदि आप इकाई API मॉड्यूल पर भरोसा करने में सक्षम हैं, तो आपको निम्नलिखित के समान कोड का उपयोग करने में सक्षम होना चाहिए:

// Load some entity.
$entity = entity_load_single($entity_type, $id);

// Remove the field value.
unset($entity->field_FIELD_NAME[LANGUAGE_NONE][$index]);

// Reset the array to zero-based sequential keys.
$entity->field_FIELD_NAME[LANGUAGE_NONE] = array_values($entity->field_FIELD_NAME[LANGUAGE_NONE]);

// Save the entity.
entity_save($entity_type, $entity);

2
यह काम किया! धन्यवाद, मेरी ज़ोंबी समस्या अब समाप्त हो गई है। कुछ नोट्स जो दूसरों के समय को बचा सकते हैं: मुझे RC2 के लिए एप्पी को अपडेट करने की आवश्यकता है; चूँकि मैं एक डायनामिक फ़ील्ड के नाम का उपयोग कर रहा था, इसलिए unset लाइन की आवश्यकता होती है जैसे unset ($ निकाय -> {$ field_name} [LANGUAGE_NONE] [$ index]); और एक चेतावनी से बचने के लिए मुझे array_values ​​() को (यदि (खाली!)) {}
user56reinstatemonica8

यह भी काम करता है अगर आप पूरे क्षेत्र को खाली करना चाहते हैं, और खूंखार "अखंडता के उल्लंघन से बचते हैं: 1048 कॉलम 'field_duty_user_target_id' शून्य नहीं हो सकता"
डैरेल

आपका बहुत बहुत धन्यवाद! नोड मान के माध्यम से फ़ील्ड मान बदलने की कोशिश की गई, लेकिन यह काम नहीं किया। तो इस तरह काम करने के लिए इकाई क्षेत्र मूल्य बदलना निश्चित रूप से काम करता है!
Артем Ильин

1

मैं एक Drupal8 प्रवास सफाई के हिस्से के रूप में यह करने की जरूरत है।

कुछ प्रयोग के बाद, मैंने पाया कि पुनरावृत्ति और फिर डेल्टा पर अनसेट () का उपयोग करके इसे मार सकते हैं। मेरा उदाहरण एक टैग को हटा रहा था (इसलिए मैं 'target_id' खोजता हूं, 'value' नहीं, जैसा कि आप अक्सर अन्य क्षेत्रों के लिए करते हैं।

/**
 * Removes a term from a field.
 *
 * @return bool
 *   success
 */
private function removeTerm(\Drupal\node\NodeInterface $object, \Drupal\taxonomy\TermInterface $term, $field_name) {
  // Check if tag value exists already.
  // Remember they may be multiples.
  /** @var @var \Drupal\Core\Field\FieldItemList $field_values */
  $field_values = $object->get($field_name);
  foreach ($field_values as $delta => $field_value) {
    if ($field_value->getValue()['target_id'] == $term->id()) {
      unset($field_values[$delta]);
      return TRUE;
    }
  }
  return FALSE;
}

और बाद में, अगर सफलता, तो $object->save();


0

Drupal 8 के लिए, इकाई से फ़ील्ड हटाने के लिए:

$entity = Node::load($nid);
unset($entity->field_name);

यह जादू विधि को __unset () ContentEntityBase से बुलाएगा:

public function __unset($name) {
    // Unsetting a field means emptying it.
    if ($this->hasField($name)) {
        $this->get($name)->setValue([]);
    }
    // For non-field properties, unset the internal value.
    else {
        unset($this->values[$name]);
    }
}

अपने परिवर्तनों को जारी रखने के लिए, आपको कॉल करने की आवश्यकता नहीं है

$entity->save();

आपके द्वारा अपने सभी परिवर्तनों को करने के बाद।


-1

यह बेहतर तरीका है:

> $user = user_load($user->uid); 
> $user_wrp = entity_metadata_wrapper('user', $user);
> $user_wrp->{'field_data_multiple'} = array();

-2

वर्तमान पसंदीदा तरीका एंफ़ॉर्म_मेटडाटा_वैपेर को नियोजित करेगा

$node_wrapped = entity_metadata_wrapper('node', node_load($nid));

unset($node_wrapped->$field_name[$index];

यह EMW पर सबसे अच्छा ट्यूटोरियल है जो मैंने देखा है http://deeson-online.co.uk/labs/programatically-access-field-data-use-entitymetadatawrapper-drupal


यह काम नहीं किया। मैंने भी इसे इस तरह आज़माया था, जैसे कोई किस्मत नहीं; $ आवरण = संस्था_मेटडाटा_वापर ('नोड', $ शुल्क); unset ($ आवरण-> field_duty_user); $ wrapper-> सहेजें (); node_save ($ कर्तव्य);
डेरेल डुआने

1
सही तरीक़ा $ नोड होगा- फंस-> फ़ील्ड_नाम-> सेट (""); उसके बाद $ रैपर-> सेव ()
चैडपेपर्स
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.