Dans un article précédent, je vous ai expliqué comment créer un attribut de type array dans un Varien_Object. Pourquoi pas utiliser notre objet dans une Varien_Data_Collection? On peut faire plein d’opérations dessus, notamment les afficher en grid (oui oui ça viendra bientôt cette partie !).

Le soucis, c’est que la Varien Data Collection contient bien les fonctions de filtres etc… mais ne font que retourner l’élément lui même, donc rien ne lui est appliqué! Je vous propose donc mon code, commenté en anglais par soucis de référencement, qui n’est pas encore terminé à 100% mais peu déjà vous être utile 😉

INFO : Ce code est encore en construction, il reste les filtres différents de LIKE à gérer, ainsi que les renderLimits !

Avant de commencer, voici une fonction à insérer dans la classe de votre type d’objet :

class MiniMax_MonModule_Model_MonObjet extends Varien_Object{
	/*
	...
	*/

	public function getGeneric($field){return $this->{$field}; }

	/*
	...
	*/
}

Si vous trouvez une solution dans le code qui suit pour éviter de devoir utiliser cette fonction, je suis preneur 😉

Passons donc aux choses sérieux avec notre Collection perso qui va hériter de Varien_Data_Collection !

<?php 
class MiniMax_MonModule_Model_Collection_MaCollection 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 !
		};
	}

}

Si vous avez des questions ou des ajouts à faire sur ce code, n’hésitez pas 😉 Je suis sûr qu’il peut être amélioré 🙂

Utiliser une Varien Data Collection avec des filtres, des tris et des limites
Taggé sur :                

2 thoughts on “Utiliser une Varien Data Collection avec des filtres, des tris et des limites

  • 25/04/2013 à 19:38
    Permalink

    Salut,
    Ce code m’a bien été utile pour créer un grid avec des données ne provenant pas de la base de données (mais venant d’une API). J’ai terminé (je pense) la fin de ce code à savoir le filtre sur les « from » / « to » pour les tris de quantité/prix et la gestion des pages. Si vous souhaitez ce code, je peux vous le fournir. Ce code peut servir pour un éventuel tutoriel sur la création de grid en utilisant des données qui ne proviennent pas d’une base de données. Johnny

    Répondre
  • 27/11/2013 à 16:56
    Permalink

    Bien joué, ca fait un moment que je cherche comment filtrer ces Varien_Data_Collection et je tombe la dessus avec en bonus, le filtre LIKE que je cherchais.

    Merci

    Répondre

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *

Nous utilisons des cookies afin de nous assurer de vous proposer la meilleure expérience sur ce site.
Ok