प्रोग्राम को नोड से फ़ील्ड कैसे निकालें?


16

प्रोग्राम को नोड से फ़ील्ड को कैसे हटाया जा सकता है? मेरे पास एक माइग्रेशन है hook_update_Nजो एक फ़ील्ड से सामग्री को एक कस्टम टेबल में ले जाती है। उस माइग्रेशन के बाद, मैं उसी फंक्शन में फील्ड को हटाना चाहता हूं।

क्या कोई फ़ील्ड API है जो फ़ील्ड्स निकालना है?

संपादित करें, समाधान : क्योंकि उत्तरों में वास्तविक कोड का अभाव है, यहां मैंने $ उपयोगकर्ताओं से फ़ील्ड को अपने रिकॉर्ड में स्थानांतरित करने के लिए किया और बाद में डेटाबेस से फ़ील्ड को हटा दिया;

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अगले क्रोन रन पर विलोपन के लिए चिह्नित करेगा ।

आप field_purge_batchविलोपन करने के लिए उपयोग कर सकते हैं , यदि आप इसे क्रोन रन पर नहीं करना चाहते हैं।

EDIT: field_delete_field() का उपयोग तब किया जाना चाहिए जब आपको फ़ील्ड को अन्य बंडलों से भी हटाने की आवश्यकता हो। यदि आप केवल किसी विशेष बंडल से फ़ील्ड को हटाना चाहते हैं, तो आपको field_delete_instance()@Clive द्वारा बताए अनुसार उपयोग करना चाहिए ।


4
सावधान, वह भी किसी अन्य बंडलों इसे करने के लिए :) अच्छा संलग्न किया जा सकता है से क्षेत्र निकाल देंगे पता करने के लिए के बारे में field_purge_batchहालांकि
क्लाइव

@ क्लीव: सही है, यह फ़ील्ड फॉर्म को सभी बंडलों को हटा देगा। सही करने के लिए धन्यवाद :) मैंने उत्तर संपादित किया है।
अजीत

मैं मैदान को पूरी तरह से हटाना चाहता था, यानी सभी बंडलों से। लेकिन चेतावनी अच्छी है। धन्यवाद।
Berkes

1
field_delete_instance () जाने का रास्ता है।
रयान मैकवीघ

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

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_ui.admin.inc में यह टिप्पणी यह ​​समझाने में एक लंबा रास्ता तय करती है: // फ़ील्ड क्रोन पर शुद्ध किए जाते हैं। हालाँकि फ़ील्ड मॉड्यूल, मॉड्यूल को अक्षम करने से रोकता है // जब फ़ील्ड प्रकार वे प्रदान किए जाते हैं, तब तक इसका उपयोग फ़ील्ड में किया जाता है जब तक कि यह पूरी तरह से // शुद्ध न हो। इस मामले में कि किसी क्षेत्र में न्यूनतम या कोई सामग्री नहीं है, एक एकल कॉल // से field_purge_batch () तक इसे सिस्टम से हटा देगा। व्यवस्थापकों से बचने के लिए // कम बैच सीमा के साथ इसे कॉल करें जब इस मापदंड को पूरा करने वाले उदाहरणों को हटाने के लिए क्रोन रन का इंतजार करना पड़े।
इलके ब्लोक

@ क्लिक करें, मुझे विश्वास है कि आप बहुत स्पष्ट रूप से सलाह दे रहे हैं, लेकिन मैं यह नहीं पा सकता हूं कि अगर मुझे एक शर्त में घोषणा करने में कितना अजीब लगता है। क्या यह उद्देश्य पर है? मैं जिक्र कर रहा हूं $instance = field_info_instance('node', 'field_name', 'page')। इसके बजाय यह नहीं होना चाहिए $instance = field_info_instance('node', 'field_contact', 'job');और अगर बयान को छोड़ दें?
cdmo

1
@cdmo इसे "कंडीशन में असाइनमेंट" कहा जाता है, और हाँ इसमें समस्याएं हैं । लेकिन ड्रुपल कोर इसे नवीनतम संस्करण में भी उदारतापूर्वक उपयोग करता है, इसलिए इसमें कम से कम मिसाल है। सच कहूं तो यह 5 साल पहले की बात है और अब मैं थोड़ा समझदार हो गया हूं, या तो मैं इसका इस्तेमाल नहीं करता हूं, या यदि किसी कारण से मैं जा रहा हूं, तो मैं असाइनमेंट को लपेटता हूं (जैसे if ( ($foo = $bar) ) {कि इरादा स्पष्ट और संभावित है त्रुटि के लिए सीमित है। यदि कथन स्वयं आवश्यक है क्योंकि field_delete_instanceअशक्त के लिए जाँच नहीं करता है
क्लाइव

5

@Berkes सवाल का जवाब देने के लिए:

field_delete_field()विलोपन के लिए क्षेत्र को चिह्नित करता है, जिससे यह अगले क्रोन रन पर शुद्ध हो जाता है। हालांकि यहfield_config_instance गिराए गए क्षेत्र के बारे में डेटा छोड़ता है । रनिंग क्रॉन field_purge_batch()इस डेटा को field_config_instanceटेबल से नहीं हटाएगा , भले ही हटाए गए कॉलम को 1फ़ील्ड के लिए सेट किया गया हो।

मेरे लिए प्रत्येक शुद्ध किए गए क्षेत्र के लिए 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(), क्योंकि यह इंगित करता है कि फील्ड एपीआई को सफाई संचालन करना चाहिए।


इस कोड का उपयोग कैसे करें? मैं एक सामग्री प्रकार से शीर्षक क्षेत्र को हटाना चाहता हूं
उमैर
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.