In a previous post, I shew how to create an Array attribute in Varien Object Class on Magento. Now it’s time to use your object in a Varien_Data_Collection.
When your create a Varien Data Collection, filters functions and others are defines, but contain nothing. They just return themselves. Here is a part of my code with some of these functions, it’s not complete, but you can check some of the functions :
INFO : This code is under construction, I have to create other filters and renderLimits !
Here is a function you have to put in your object class :
class MiniMax_MyModule_Model_MyObject extends Varien_Object{ /* ... */ public function getGeneric($field){return $this->{$field}; } /* ... */ }
If you find another solution to avoid this function, talk about it on the comments !
Now we create our custom collection inherit Varien_Data_Collection !
<?php class MiniMax_MyModule_Model_Collection_MyCollection extends Varien_Data_Collection{ public function load($printQuery = false, $logQuery = false){ // We add the renders $this->_renderFilters()->_renderOrders()->_renderLimit(); parent::load($printQuery,$logQuery); } // This function is called by Magento when you type a text on a search field in a grid // $field : field we want to filter // $condition : Array ( [like] => Zend_Db_Expr Object ( [_expression:protected] => '%USER STRING%' ) ) // It's the most classical type of condition, a string with a LIKE search like SQL, you can modify and // complete the code to implements other filters, if you do this, tell me on comments! public function addFieldToFilter($field, $condition = null) { $keyFilter = key($condition); $valueFilter = $condition[$keyFilter]->__toString(); $this->addFilter($field,$valueFilter,'and'); return $this; } protected function _renderFilters() { // If elements are already filtered, return this if ($this->_isFiltersRendered) { return $this; } foreach($this->_filters AS $filter){ $keyFilter = $filter->getData()['field']; $valueFilter = substr($filter->getData()['value'],2,-2); // Delete '% AND %' of the string $condFilter = $filter->getData()['type']; // not used in this example // Loop you're item collection foreach($this->_items AS $key => $item){ // NOTE : $item->getGeneric is a function in your object, i gave you the code at the top //of the article // If it's not an array, we use the search term to compare with the value of our item if(!is_array($item->getGeneric($keyFilter))){ if(!(strpos(strtolower($item->getGeneric($keyFilter)),strtolower($valueFilter)) !== FALSE)){ unset($this->_items[$key]); // If search term not founded, unset the item to //not display it! } } else { // If it's an array $founded = false; foreach($item->getGeneric($keyFilter) AS $valeur){ if(strpos(strtolower($valeur),strtolower($valueFilter)) !== FALSE){ $founded = true; } } if(!$founded) unset($this->_items[$key]); // Not founded in the array, so unset the item } } } $this->_isFiltersRendered = true; return $this; } protected function _renderOrders() { $keySort = key($this->_orders); $keyDirection = $this->_orders[$keySort]; // We sort our items tab with a custom function AT THE BOTTOM OF THIS CODE usort($this->_items, $this->_build_sorter($keySort,$keyDirection)); return $this; } protected function _renderLimit() { /* I'm coding this part, COMING SOON ; ) */ return $this; } protected function _build_sorter($key,$direction) { return function ($a, $b) use ($key,$direction) { if ($direction == self::SORT_ORDER_ASC) return strnatcmp($a[$key], $b[$key]); // Natural comparaison of string else return -1 * strnatcmp($a[$key], $b[$key]); // reverse the result if sort order desc ! }; } }
If you have some questions, or suggestions, comment the post, I am sure this code can be better 🙂
Use a Varien Data Collection with filters, sorts (orders) and limits
Hi,
your code helped me very much! Thank you!
Here is a simple renderLimit method I implemented:
protected function _renderLimit()
{
$this->_totalRecords = sizeof($this->_items);
if($this->_pageSize){
$this->_items = array_slice($this->_items, ($this->getCurPage()-1) * $this->_pageSize, $this->_pageSize);
}
return $this;
}
Greets
Hi,
when I use the function (_renderLimit()), I get the following error:
Fatal error: Maximum function nesting level of ‘256’ reached, aborting!
I don’t find where the problem.
Thanks
Did you try to increase the value of xdebug.max_nesting_level in your php.ini ? http://xdebug.org/docs/all_settings#max_nesting_level
J’avais quelques problemes avec les limites et le filtre dropdown. J’ai finis par modifier ce que t’avais fais et ca donne ca si ca t’intéresse: http://magento.stackexchange.com/questions/124171/magento-1-filtering-paging-sorting-with-varien-data-collection/124324#124324
Pingback: Magento 1 : Filtering / Paging / Sorting with Varien_Data_Collection - gomagento2