व्यू व्यू फील्ड कैसे बदलें और कस्टम व्यू हैंडलर द्वारा छँटाई करें?


11

कुछ दृश्यों के प्रदर्शन के मुद्दों और सर्वोत्तम प्रथाओं का सम्मान करने के लिए, मैं कुछ ऐसे दृश्यों को बदलना चाहूंगा जिन्हें मैंने कुछ समय पहले अपने स्वयं के कस्टम हैंडलर द्वारा कॉन्फ़िगर किया था ।

उदाहरण के लिए, मुझे एक दृश्य PHP फ़ील्ड मिला है , जो उस सेटअप के साथ प्रदर्शन से बाहर रखा गया है :

मूल्य कोड:

if( $row->sticky ==1 ) {
  return 100;
} else {

  if ( isset($row->product_id) && $row->product_id != ""  ){

    $query = "SELECT COUNT(statut.entity_id) FROM field_data_field_statut_depart statut"
    . " INNER JOIN  field_data_field_product product ON statut.entity_id= product.field_product_product_id"
    . " INNER JOIN  field_data_field_date_depart depart ON statut.entity_id = depart.entity_id"
    . " WHERE product.entity_id = ". $row->nid." AND field_statut_depart_value IN (2,3) AND field_date_depart_value > NOW(); ";

    $select = db_query($query);
    $count = $select->fetchField();

    return $count; 
  }
  else {
    return -1;
  }
}

आउटपुट कोड :

<?php print $value ; ?>`

फिर मैं उस क्षेत्र को पहले प्रकार के मानदंड ( आरोही ) के रूप में उपयोग करता हूं , ग्लोबल PHP सॉर्ट मानदंड में:

if ($row1->php> $row2->php) return -1; else return 1;

यदि आप मुझे सही तरीके से लगा सकते हैं, तो मैं वास्तव में शुक्रगुज़ार होऊंगा: डेटाबेस में PHP के साथ समाप्त करने के लिए मैं उसी फ़ंक्शन को किस फ़ंक्शन में बनाऊंगा?

सारांश :

खोज और प्रगति के बाद, प्लस @ रेनरह मदद, अधिकांश कार्यान्वयन ठीक लगता है, नीचे विस्तृत है। लेकिन मैं अभी भी एक बिंदु के साथ लड़ रहा हूं : मैंने मूल्य की गणना करने के लिए एक कस्टम फ़ील्ड हैंडलर जोड़ा, लेकिन मैं उस हैंडलर द्वारा कैसे ऑर्डर कर सकता हूं?

संपादन:

मैंने अब तक क्या किया:

.info फ़ाइल

files[] = views_handler_vts_products_sort.inc
files[] = includes/views_handler_vts_count_depconf_field.inc

मॉड्यूल फ़ाइल

/**
 * Implements hook_views_data().
 */
function vts_views_handler_views_data() {
  $data['custom']['table']['group'] = t('Custom');
  $data['custom']['table']['join'] = array(
    // #global is a special flag which let's a table appear all the time.
    '#global' => array(),
  );

  $data['custom']['custom_handler'] = array(
    'title' => t('Vts custom Sort Handler'),
    'help' => 'Sorts products by sticky first then by custom statut field',
    'sort' => array(
      'handler' => 'views_handler_vts_products_sort',
    ),
  );

  $data['custom']['count_depconf_field'] = array(
    'title' => t('Sum of products with status confirmed '),
    'help' => t('Calculate Sum of products with status confirmed, to order lists".'),
    'field' => array(
      'handler' => 'views_handler_vts_count_depconf_field',
      'click sortable'=> TRUE,
    ),
    /*'sort' => array(
      'handler' => 'views_handler_sort',
    ), */
  );  
  return $data;
}

function vts_views_handler_views_api() {
    return array(
    'api' => 3,
    'path' => drupal_get_path('module', 'vts_views_handler'),
  );
}

views_handler_vts_products_sort फ़ाइल

/**
 * Base sort handler that has no options and performs a simple sort.
 *
 * @ingroup views_sort_handlers
 */
class views_handler_vts_products_sort extends views_handler_sort {

  function query() {
    $this->ensure_my_table();
    // Add the field.
    $this->query->add_orderby('node', 'sticky', 'DESC');
  }
}

views_handler_vts_count_depconf_field फ़ाइल

/*
 * A simple field to calculate the value I wish to order by.
 */
class views_handler_vts_count_depconf_field extends views_handler_field {

  function query() {
    //do nothing
  }

  function render($values) {
    $count = 0;

    $product_id = isset($values-> commerce_product_field_data_field_product_product_id)? $values-> commerce_product_field_data_field_product_product_id: NULL;
    if(!is_null($product_id)){

      $query = "SELECT COUNT(statut.entity_id) FROM field_data_field_statut_depart statut"
      . " INNER JOIN  field_data_field_product product ON statut.entity_id= product.field_product_product_id"
      . " INNER JOIN  field_data_field_date_depart depart ON statut.entity_id = depart.entity_id"
      . " WHERE product.entity_id = " . $values->nid . " AND field_statut_depart_value IN (2,3) AND field_date_depart_value > NOW(); ";

      $select = db_query($query);
      $count = $select->fetchField();
    }
    return $count;
  }
}

शेष प्रश्न:

  • कस्टम फ़ील्ड हैंडलर द्वारा ऑर्डर कैसे करें? मैंने 'click sortable'=> TRUE,OR 'sort' => array('handler' => 'views_handler_sort',),OR $this->query->add_orderby('custom', 'count_depconf_field', 'DESC');को कस्टम सॉर्ट हैंडलर में जोड़ने की कोशिश की । कोई भी काम नहीं करता है लेकिन 'ऑर्डर क्लॉज' में अज्ञात कॉलम लौटाता है

  • किया : मैं कैसे $row->product_idऔर $row->nidअंदर मिल सकता है query()? मुझे इसकी जरूरत है कि उपकुंजी का निर्माण किया जाए। : एक दृश्य हैंडलर फ़ील्ड जोड़ा गया और रेंडर ($ मान) में पंक्ति मान मिला ...

  • संपन्न : उदाहरण हैंडलर का कौन सा हिस्सा मुझे संपादित करना है? केवल क्वेरी फ़ंक्शन? क्या मुझे पूरे उदाहरण कोड या बस कस्टम भागों को रखने की आवश्यकता है?

धन्यवाद

जवाबों:


7

आपको किसी तरह के हैंडलर का उपयोग करने की आवश्यकता है: https://api.drupal.org/api/views/handlers/views_handler_sort.inc/group/views_sort_handlers/7.x-3.x

प्रदर्शन कारणों से आप अपने परिणामों को क्रमबद्ध करने के लिए PHP का उपयोग नहीं कर सकते। यदि आप संपूर्ण तालिका परिणाम लाते हैं, तो PHP का उपयोग केवल परिणामों को सॉर्ट करने के लिए किया जा सकता है, और यह एक विकल्प नहीं है।

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

इस सभी कोड को आपके ऑब्जेक्ट के "क्वेरी ()" विधि में निवास करना है। आपको इस तरह एक क्वेरी प्राप्त करने की आवश्यकता है:

SELECT table_x.field_y, ...
FROM  ...
...
...
ORDER BY row.sticky, (SELECT COUNT(statut.entity_id) 
FROM field_data_field_statut_depart statut
INNER JOIN field_data_field_product product
INNER JOIN field_data_field_date_depart depart
WHERE product.entity_id = table_x.field_y
AND field_statut_depart_value IN (2,3) 
AND field_date_depart_value > NOW())

फ़ंक्शन का उपयोग करके https://api.drupal.org/api/views/plugins%21views_plugin_query_default.inc/function/views_plugin_query_default%3A%Aadd_orderby/7.x-3.x और एक उपश्रेणी।

उपश्रेणी को 3 या अधिक जोड़ों और कुछ ऐसी स्थितियों में अनुकूलित किया जा सकता है जहां शायद स्थिति हो लेकिन मैं पूरी क्वेरी के बिना नहीं बता सकता।

संपादित करें

आप "views_handler" ऑब्जेक्ट से फैली हुई हैं, लेकिन आपको सीधे "view_handler_sort" से फैलना चाहिए ताकि आप मुख्य डिफ़ॉल्ट कोड का अधिकतम उपयोग कर सकें:

class views_handler_vts_products_sort extends views_handler_sort {
  /**
   * Called to add the sort to a query.
   */
  function query() {
    $this->ensure_my_table();
    // Add the field.
    $this->query->add_orderby($this->table_alias, $this->real_field, $this->options['order']);
  }
}

जैसा कि आप ऊपर देख सकते हैं, आपके मामले में केवल "क्वेरी" विधि की आवश्यकता है क्योंकि आपको UI आदि में किसी विशिष्ट कॉन्फ़िगरेशन की आवश्यकता नहीं है।

अपने "क्वेरी ()" विधि के अंदर product_id या nid प्राप्त करने के लिए , आपको उन मौजूदा फ़ील्ड्स का उपयोग करना होगा, जिन्हें व्यू फ़ील्ड हैंडलर्स द्वारा क्वेरी में जोड़ा गया था (और आपके विचार UI में परिभाषित)।

यह फ़ाइल इस बात का सही उदाहरण है कि आप क्या हासिल करना चाहते हैं (आप इसे दृश्य प्रलेखन में पा सकते हैं, यह एक मौजूदा है लेकिन मुझे लिंक सेट करने की अनुमति नहीं है क्योंकि मेरी प्रतिष्ठा बहुत कम है):

class views_handler_sort_node_version_count extends views_handler_sort {
  function query() {
    $this->ensure_my_table();

    $this->query->add_orderby(NULL, '(SELECT COUNT(vid) FROM {node_revision} WHERE nid = {' . $this->table_alias . '}.nid)', $this->options['order'], 'sort_node_version_count');
  }
}

देखें कि क्या आप इस कोड को अपनी आवश्यकता के अनुसार ढाल सकते हैं और मुझे अंतिम परिणाम देखकर खुशी होगी :)


मैंने अपने प्रश्न को प्रगति के साथ संपादित किया। यदि आप अपना उत्तर पूरा करना चाहते हैं? बहुत बहुत धन्यवाद
कोजो

1
हो गया, कृपया इसे देखें और मुझे बताएं कि क्या आप अपनी तरह से काम करने में कामयाब रहे :)
Renrff

मेरा बुरा, मुझे एहसास हुआ कि चूंकि विचार छाँटने के लिए डीबी क्वेरी पर निर्भर करते हैं, ऐसा लगता है कि मैं एक डमी फ़ील्ड के साथ हैंडलर द्वारा बनाई गई तरह के विचारों को कभी प्राप्त नहीं करूँगा! इसलिए मुझे निश्चय ही पराधीनता पर काम करना है!
कोजो

1
पहले प्रतिक्रिया न करने के लिए क्षमा करें! मुझे उम्मीद है कि मेरा उत्तर उपयोगी था, लेकिन आपने खुद ही सारा काम किया था, मैं उपकुमारी उर्फ ​​चीज के बारे में नहीं जानता था, आपके विस्तृत समाधान के लिए धन्यवाद, यह बहुत से लोगों की मदद करेगा।
रेनफ्रैफ

4

मैं पूर्ण कार्यान्वयन के बारे में नीचे साझा करता हूं कि मैंने एक कस्टम व्यू हैंडलर द्वारा व्यूज PHP सॉर्टिंग को बदलने के लिए कैसे किया ।

.info फ़ाइल

files[] = includes/views_handler_my_custom_sort.inc

मॉड्यूल फ़ाइल

/**
 * Implements hook_views_data().
 */
function MODULE_NAME_views_data() {
  $data['custom']['table']['group'] = t('Custom');
  $data['custom']['table']['join'] = array(
    '#global' => array(),
  );

  $data['custom']['custom_handler'] = array(
    'title' => t('My custom Sort Handler'),
    'help' => 'Sorts products by sticky first then by custom statut field',
    'sort' => array(
      'handler' => 'views_handler_vts_products_sort',
    ),
  );

  return $data;
}

function MODULE_NAME_views_api() {
    return array(
    'api' => 3,
    'path' => drupal_get_path('module', 'MODULE_NAME'),
  );
}

views_handler_my_custom_sort.inc फ़ाइल

/**
 * Base sort handler that has no options and performs a simple sort.
 *
 * @ingroup views_sort_handlers
 */
class views_handler_my_custom_sort extends views_handler_sort {

  function query() {
    $this->ensure_my_table();

    $sub_query = "(SELECT COUNT(p.field_product_product_id) "
      . "FROM field_data_field_product p "
      . "LEFT JOIN field_data_field_statut_depart statut ON statut.entity_id = p.field_product_product_id "
      . "LEFT JOIN field_data_field_date_depart depart ON depart.entity_id = p.field_product_product_id  "
      . "LEFT JOIN node nod ON nod.nid = p.entity_id "
      . "WHERE nod.nid = node.nid "//This is a the obligatory condition mapping the subquery with the outer query
      . "AND field_statut_depart_value IN (2,3) "
      . "AND field_date_depart_value > NOW())";

    /* I'm timeless to write the query with the object syntax, here was a beginning
    $sub_query = db_select('field_data_field_product', 'p');
    $sub_query->addField('p', 'field_product_product_id');
    $sub_query->leftJoin('node', 'nod', 'nod.nid = p.entity_id');
    $sub_query->where("nod.nid = node.nid");
    $sub_query->countQuery(); */  

    $this->query->add_orderby('node', 'sticky', 'DESC');
    $this->query->add_orderby(NULL, $sub_query, 'DESC', 'subquery');

  }
}

थोडा स्पष्टीकरण: व्यू हैंडलर्स को लागू करने के तरीके को समझने के बाद, मैं सबक्वीरी में उलझ गया:

  • एक गतिशील "पंक्ति द्वारा" परिणाम प्राप्त करने के लिए बाहरी क्वेरी के साथ मैप करें: एक ही तालिका और स्तंभ लेकिन अलग-अलग उपनाम: WHERE nod.nid = node.nid
  • में उपनाम सेट add_orderby: $this->query->add_orderby(NULL, $sub_query, 'DESC', 'subquery');काम करता है, लेकिन $this->query->add_orderby(NULL, $sub_query, 'DESC');नहीं करता है

यह अंतिम बिंदु आश्चर्यजनक था क्योंकि SELECT TITLE FROM node ORDER BY (SELECT COUNT(field_product_product_id) FROM field_data_field_product p LEFT JOIN node nod ON nod.nid = p.entity_id WHERE nod.nid = node.nid )SQL प्रत्यक्ष इनपुट में काम करते समय , यह वर्तमान सेटअप के पार नहीं है।

आपको उपकथा उपनाम को निर्दिष्ट करने की आवश्यकता है और अंतिम क्वेरी कुछ इस तरह होगी SELECT TITLE, (SELECT COUNT(field_product_product_id) FROM field_data_field_product p LEFT JOIN node nod ON nod.nid = p.entity_id WHERE nod.nid = node.nid ) as subquery FROM node ORDER BY subquery

कस्टम हैंडलर फ़ील्ड में परिणाम को सॉर्ट करने के लिए मानों की गणना करने का प्रयास करता है, इसलिए काम नहीं किया क्योंकि व्यू सॉर्टिंग एक DB आधार पर किया जाता है और कस्टम फ़ील्ड हैंडलर डमी फ़ील्ड की तरह है ... कम से कम यह मेरा निष्कर्ष था।

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