2011-04-15 18 views
6

Magento संग्रह सॉर्टिंग फ़ंक्शन (उदा। Mage_Eav_Model_Entity_Collection_Abstract::addAttributeToSort) एसक्यूएल चयन कथन में ORDER BY खंड जोड़कर काम करते हैं। हालांकि, ऐसे समय होते हैं जब संग्रह पहले ही लोड हो चुका है और संग्रह को सॉर्ट करना आवश्यक है।लोड मैगेंटो संग्रह लोड

toArray($fields) फ़ंक्शन और फिर PHP सरणी सॉर्टिंग फ़ंक्शंस (या तो देशी या उपयोगकर्ता परिभाषित) का उपयोग करना निश्चित रूप से संभव है, हालांकि यह थोड़ा बेकार है। इसका यह भी मतलब है कि संग्रह में वस्तुओं "गूंगा" आदि जादू getters/setters बिना मूल्यों की पंक्तियों जो/एल्गोरिदम के साथ लागू किया जाता है सकते हैं,

मैं और अधिक सुरुचिपूर्ण देखते हैं अगर/Magento- सोच रहा हूँ करने के लिए बदल रहे हैं संग्रह को सॉर्ट करने के एस्क्यू तरीके।

धन्यवाद,
जोनाथन

+0

क्या आप सोच रहे हैं, तो आप पहले से ही एक संग्रह आप विशेषताओं में से एक फिर से के अनुसार क्रमबद्ध है है तो मूल रूप से है एक और विशेषता द्वारा क्रमबद्ध करना चाहते हैं ..? –

+0

@ सुबेश पोखेल हाँ, लेकिन यह मुख्य मुद्दा नहीं है। मुख्य मुद्दा संग्रह द्वारा आंतरिक रूप से संग्रह को सॉर्ट कर रहा है संग्रह के आंतरिक $ _items पॉप्युलेट किए गए हैं (यानी SQL निष्पादन के बाद) –

+0

आप संग्रह में एक और प्रकार की क्वेरी क्यों नहीं जोड़ते हैं जिससे आप दो विशेषताओं से क्रमबद्ध हो सकते हैं और आप दो विशेषताओं के साथ आदेश संग्रह प्राप्त करें ..? या मैं पूरी बात याद कर रहा हूँ। –

उत्तर

2

एक अन्य समाधान जो काम करता है:

class Aligent_Navigation_Block_Dropdown extends Mage_Catalog_Block_Product_List { 

public function getProductsByShortDesc(){ 
    $data = $this->getLoadedProductCollection()->getItems(); //an array of objects 
    usort($data,array('Aligent_Navigation_Block_Dropdown','sortByShortDesc')); 
    return $data; 
} 

public static function sortByShortDesc($a, $b) 
{ 
    if($a->getShortDescription() == $b->getShortDescription()){ return 0 ; } 
    return ($a->getShortDescription() < $b->getShortDescription()) ? -1 : 1; 
} 
} 
+0

इस समाधान के साथ केवल समस्या यह है कि यदि आपके पास एकाधिक पेज हैं तो यह केवल इस पृष्ठ पर आइटम को सॉर्ट करेगा –

11

यह करने का कोई उचित तरीका नहीं है। लेकिन मुझे लगता है कि प्रतिबिंब का उपयोग करना संभव है। आप संग्रहण ऑब्जेक्ट की $ _items प्रॉपर्टी पुनर्प्राप्त कर सकते हैं, उन्हें सॉर्ट कर सकते हैं और इसे संग्रह में वापस सेट कर सकते हैं।

function sortCollection(Varien_Data_Collection $collection, callable $sorter) { 
    $collectionReflection = new ReflectionObject($collection); 
    $itemsPropertyReflection = $collectionReflection->getProperty('_items'); 
    $itemsPropertyReflection->setAccessible(true); // Make it accessible 

    $collectionItems = $itemsPropertyReflection->getValue($collection); 

    usort($collectionItems, $sorter); 

    $itemsPropertyReflection->setValue($collection, $collectionItems); 

    $itemsPropertyReflection->setAccessible(false); // Return restriction back 

    return $collection; 
} 
+0

दिलचस्प लग रहा है, मैं इसे देख लूंगा, धन्यवाद इवान –

+3

मैं पुष्टि करता हूं कि यह संभव है इवान, मेरा साथी बस अपने स्निपेट का सफलतापूर्वक उपयोग करें। एकमात्र चीज यह है कि '$ संग्रह-> getProperty (' _ items ') के बजाय; उसे '$ संग्रह रिफ्लेक्शन-> getProperty (' _ items ') का उपयोग करना था;', मुझे लगता है कि एक छोटा टाइपो।एक और चीज जो मुझे लगता है कि यह कहने लायक है, यह है कि, जैसा कि हम Magento के बारे में बात कर रहे हैं, और इस प्रकार कक्षाएं, '$ yourSortingCallback' को 2 तत्वों की एक सरणी होना है, पहला व्यक्ति उस वर्ग का नाम है जहां विधि परिभाषित की गई है, और दूसरा एक विधि का नाम है, यानी: 'usort ($ संग्रह Items, सरणी (' The_Class ',' The_Method ')); '। वैसे भी, हम दोनों बहुत ही आभारी हैं – OSdave

+0

@OSdave, हाँ एक प्रकार था। $ yourSortingCallback कॉल वापस भी अनाम कार्य हो सकता है। –

4

यहां एक टिप है; एक संग्रह की clear विधि इसे लोड किए गए ध्वज को अनसेट करता है, यह आपको सॉर्ट या फ़िल्टर बदलने और नई क्वेरी चलाने की अनुमति देता है।

load only configurable products का जवाब देते समय मैंने गलती से इसे खोज लिया।

+0

यह बहुत ही आसान है! –

+0

और निश्चित रूप से इसका मतलब है कि आप एट्रिब्यूट टुसेलेक्ट() भी जोड़ सकते हैं, जो कि मैं जिस तरह से संघर्ष कर रहा था, धन्यवाद :-) – benz001

0

ऊपर समाधान ठीक काम करेंगे, लेकिन यह बहुत धीमी और क्वेरी ही तरह जोड़ने से अधिक गहन है।

यदि आपके पास एक बड़ा संग्रह है तो आप बड़ी मात्रा में स्मृति का उपयोग करेंगे क्योंकि आपको प्रत्येक ऑब्जेक्ट (ऑब्जेक्ट्स) को प्रत्येक परिणाम के सामने लोड करने और उन्हें स्टोर करने की आवश्यकता होती है।

संग्रह का उपयोग Magento केवल डेटाबेस से एक समय जो ऊपर समाधान :-)

1

@Ivan Chepurnyi की विधि काम किया लेकिन एक ReflectionObject ऑब्जेक्ट की तुलना में बहुत अधिक कुशल हो जाएगा पर एक पंक्ति लोड होगा, मेरे मामले में मुझे एक Varien_Data_Collection की आवश्यकता थी।
यहाँ है कि मैं क्या बजाय किया

$collectionItems = $collection->getItems(); 
usort($collectionItems, array($this, '_sortItems')); 
$newCollection = new Varien_Data_Collection(); 

foreach ($collectionItems as $item) { 
    $newCollection->addItem($item); 
} 

var_dump($newCollection); 

और मामले में यहां की छंटाई विधि

public function _sortItems($a, $b) 
{ 
    $columnId = "your_column_that_you_need_to_sort"; 
    $dir  = "desc"; 

    $al = strtolower($a->getData($columnId)); 
    $bl = strtolower($b->getData($columnId)); 

    if ($al == $bl) { 
     return 0; 
    } 

    if ($dir == 'asc') { 
     return ($al < $bl) ? -1 : 1; 
    } else { 
     return ($al > $bl) ? -1 : 1; 
    } 
} 
संबंधित मुद्दे