Magento Themes and Magento Extensions

Magento Core Class Varien_Data_Collections its application

Share

This section intends to introduce the Magento‘s Varien_Data_Collections, I Alanstorm translated (part of the translation, the reader can practice my English ability)
Varien Data Collections What is this? Haha, you read the following articles, you’ll know it in the core of Magento in the role of the.
As a PHPer, If you want some of a group of related variables together in two ways: Array and custom data structures, Varien_Object is the latter.

First of all, tell us about Varien_Object to use:
$ Thing_1 = new Varien_Object ();
$ Thing_1-> setName (‘Richard’);
$ Thing_1-> setAge (24);

$ Thing_2 = new Varien_Object ();
$ Thing_2-> setName (‘Jane’);
$ Thing_2-> setAge (12);

$ Thing_3 = new Varien_Object ();
$ Thing_3-> setName (‘Spot’);
$ Thing_3-> setLastName (‘The Dog’);
$ Thing_3-> setAge (7);

Varient_Object Magento class is the parent of all the Models category. Subclass inherits from Varient_Object getter and setter are the two magic methods (more on the magic method, please refer to:). Examples:
var_dump ($ thing_1-> getName ());
If you do not know what Varient_Object members of the property, you can getData () to print them out
var_dump ($ thing_3-> getData ());
Output as follows
array
‘Name’ => string ‘Spot’ (length = 4)
‘Last_name’ => string ‘The Dog’ (length = 7)
‘Age’ => int 7

$ Thing_1-> setLastName (‘Smith’);
We noted no ‘last_name’ more ‘_’, you can name Camel style getter and setter it.
var_dump ($ thing_3 ["last_name"]);
We have built above three Object, and then put them in the Collection of (here only Varento_Data_Collection), Collection is PHPer custom data types.
$ Collection_of_things = new Varien_Data_Collection ();
$ Collection_of_things
-> AddItem ($ thing_1)
-> AddItem ($ thing_2)
-> AddItem ($ thing_3);

Since most of the data Collections Magento is inherited from the Varient_Data_Collection, so use the above can be seen everywhere in Magento.
foreach ($ collection_of_things as $ thing)
(
var_dump ($ thing-> getData ());
)

Can also directly access a member of the first or last
var_dump ($ collection_of_things-> getFirstItem ());
var_dump ($ collection_of_things-> getLastItem () -> getData ());

Or it can be converted into XML format
var_dump ($ collection_of_things-> toXml ());
Or just extract the value of a Column (Varient_Data_Collection it its name, which corresponds to the SQL statement query results)
var_dump ($ collection_of_things-> getColumnValues (‘name’));
Even provide a filtering capability (say SQL, query and sorting capabilities both in Magento’s Varient_Data_Collection achieved)
var_dump ($ collection_of_things-> getItemsByColumnValue (‘name’, ‘Spot’));

Model Collections
So this is a very good experience, but what an important role in it? Magento as we have said above the built-in data Collections are inherited from it. This means: You can conduct a product Collection sort:
public function testAction ()
(
$ Collection_of_products = Mage:: getModel (‘catalog / product’) -> getCollection ();
var_dump ($ collection_of_products-> getFirstItem () -> getData ());
)
Most of the Magento Model objects have a name for the getCollection the method, which returns the above Collection, and the system in the Magento Model Objects default initialization and return the Collection.
Most of the other with Magento Collection as, product Collection inherited from Varient_Data_Collection_Db, so many useful ways to provide us with access to a specific select statement:
public function testAction ()
(
$ Collection_of_products = Mage:: getModel (‘catalog / product’) -> getCollection ();
var_dump ($ collection_of_products-> getSelect ()); / / might cause a segmentation fault
)

The above method will output
object (Varien_Db_Select) [94]
protected ‘_bind’ =>
array
empty
protected ‘_adapter’ =>

Haha! As the realization of the Zend framework Magento database abstraction layer, so your SQL statement is in the form of Object, such as:
public function testAction ()
(
$ Collection_of_products = Mage:: getModel (‘catalog / product’) -> getCollection ();
/ / Var_dump ($ collection_of_products-> getSelect ()); / / might cause a segmentation fault
var_dump (
(String) $ collection_of_products-> getSelect ()
);
)
The results are as follows:
‘SELECT `e` .* FROM `catalog_product_entity` AS `e`’
More often a number of more complex queries:
string ‘SELECT `e` .*, `price_index`. `price`, `price_index`. `final_price`, IF (`price_index`. `tier_price`, LEAST (`price_index`. `min_price`, `price_index`. ` tier_price `),` price_index `.` min_price `) AS` minimal_price `,` price_index `.` min_price `,` price_index `.` max_price `,` price_index `.` tier_price `FROM` catalog_product_entity `AS` e `
INNER JOIN `catalog_product_index_price` AS `price_index` ON price_index.entity_id = e.entity_id AND price_index.website_id = ’1 ‘AND price_index.customer_group_id = 0′

In addition, as part of Magento in the EAV table is designed to form, because so many can not all return column, the default return part of the column, you can return all of the following ways Column results:
$ Collection_of_products = Mage:: getModel (‘catalog / product’)
-> GetCollection ()
-> AddAttributeToSelect (‘*’); / / the asterisk is like a SQL SELECT *
Or an increase in default on the basis of a Column:
/ / Or just one
$ Collection_of_products = Mage:: getModel (‘catalog / product’)
-> GetCollection ()
-> AddAttributeToSelect (‘meta_title’);
Or increase the number of Column:
/ / Or just one
$ Collection_of_products = Mage:: getModel (‘catalog / product’)
-> GetCollection ()
-> AddAttributeToSelect (‘meta_title’)
-> AddAttributeToSelect (‘price’);

About Magento’s Lazy Loading

Since PHP supports ORM, so under normal circumstances, we write a SQL statement or initialize an object when the immediate implementation of the query statement
$ Model = new Customer ();
/ / SQL Calls being made to Populate the Object
echo ‘Done’; / / execution continues

In Magento, the use of the Lazy Loading the method, making the statement did not implement it immediately. Lazy Loading, in short only when the client-programmer to read data only when the implementation of the corresponding query. Like this child
$ Collection_of_products = Mage:: getModel (‘catalog / product’)
-> GetCollection ();
Magento has not the time actually to read the database, then you can add some attibutes to select:
$ Collection_of_products = Mage:: getModel (‘catalog / product’)
-> GetCollection ();
$ Collection_of_products-> addAttributeToSelect (‘meta_title’);

Here are some of the more filtering Database Collection methods (see the original bar)

The most important method on a database Collection is addFieldToFilter. This adds yourWHERE clauses. Consider this bit of code, run against the sample data database (substitute your own SKU is you’re using a different set of product data)

public function testAction()
{
    $collection_of_products = Mage::getModel('catalog/product')
    ->getCollection();
    $collection_of_products->addFieldToFilter('sku','n2610');

    //another neat thing about collections is you can pass them into the count      //function.  More PHP5 powered goodness
    echo "Our collection now has " . count($collection_of_products) . ' item(s)';
    var_dump($collection_of_products->getFirstItem()->getData());
}

The first parameter of addFieldToFilter is the attribute you wish to filter by. The second is the value you’re looking for. Here’s we’re adding a sku filter for the value n2610.

The second parameter can also be used to specify the type of filtering you want to do. This is where things get a little complicated, and worth going into with a little more depth.

So by default, the following

$collection_of_products->addFieldToFilter('sku','n2610');

is (essentially) equivalent to

WHERE sku = "n2610"

Take a look for yourself. Running the following

public function testAction()
{
    var_dump(
    (string)
    Mage::getModel('catalog/product')
    ->getCollection()
    ->addFieldToFilter('sku','n2610')
    ->getSelect());
}

will yield

SELECT `e`.* FROM `catalog_product_entity` AS `e` WHERE (e.sku = 'n2610')'

Keep in mind, this can get complicated fast if you’re using an EAV attribute. Add an attribute

var_dump(
(string)
Mage::getModel('catalog/product')
->getCollection()
->addAttributeToSelect('*')
->addFieldToFilter('meta_title','my title')
->getSelect()
);

and the query gets gnarly.

SELECT `e`.*, IF(_table_meta_title.value_id>0, _table_meta_title.value, _table_meta_title_default.value) AS `meta_title`
FROM `catalog_product_entity` AS `e`
INNER JOIN `catalog_product_entity_varchar` AS `_table_meta_title_default`
    ON (_table_meta_title_default.entity_id = e.entity_id) AND (_table_meta_title_default.attribute_id='103')
    AND _table_meta_title_default.store_id=0
LEFT JOIN `catalog_product_entity_varchar` AS `_table_meta_title`
    ON (_table_meta_title.entity_id = e.entity_id) AND (_table_meta_title.attribute_id='103')
    AND (_table_meta_title.store_id='1')
WHERE (IF(_table_meta_title.value_id>0, _table_meta_title.value, _table_meta_title_default.value) = 'my title')

Not to belabor the point, but try not to think too much about the SQL if you’re on deadline.

Other Comparison Operators

I’m sure you’re wondering “what if I want something other than an equals by query”? Not equal, greater than, less than, etc. The addFieldToFilter method’s second parameter has you covered there as well. It supports an alternate syntax where, instead of passing in a string, you pass in a single element Array.

The key of this array is the type of comparison you want to make. The value associated with that key is the value you want to filter by. Let’s redo the above filter, but with this explicit syntax

public function testAction()
{
    var_dump(
    (string)
    Mage::getModel('catalog/product')
    ->getCollection()
    ->addFieldToFilter('sku',array('eq'=>'n2610'))
    ->getSelect()
    );
}

Calling out our filter

addFieldToFilter('sku',array('eq'=>'n2610'))

As you can see, the second parameter is a PHP Array. Its key is eq, which stands for equals.The value for this key is n2610, which is the value we’re filtering on.

Magento has a number of these English language like filters that will bring a Tear of Remembrance (and perhaps pain) to any old perl developers in the audience.

Listed below are all the filters, along with an example of their SQL equivalents.

array("eq"=>'n2610')
WHERE (e.sku = 'n2610')

array("neq"=>'n2610')
WHERE (e.sku != 'n2610')

array("like"=>'n2610')
WHERE (e.sku like 'n2610')

array("nlike"=>'n2610')
WHERE (e.sku not like 'n2610')

array("is"=>'n2610')
WHERE (e.sku is 'n2610')

array("in"=>array('n2610'))
WHERE (e.sku in ('n2610'))

array("nin"=>array('n2610'))
WHERE (e.sku not in ('n2610'))

array("notnull"=>'n2610')
WHERE (e.sku is NOT NULL)

array("null"=>'n2610')
WHERE (e.sku is NULL)

array("gt"=>'n2610')
WHERE (e.sku > 'n2610')

array("lt"=>'n2610')
WHERE (e.sku < 'n2610')

array("gteq"=>'n2610')
WHERE (e.sku >= 'n2610')

array("moreq"=>'n2610') //a weird, second way to do greater than equal
WHERE (e.sku >= 'n2610')

array("lteq"=>'n2610')
WHERE (e.sku <= 'n2610')

array("finset"=>array('n2610'))
WHERE (find_in_set('n2610',e.sku))

array('from'=>'10','to'=>'20')
WHERE e.sku >= '10' and e.sku <= '20'

Most of these are self explanatory, but a few deserve a special callout

in, nin, find_in_set

The in and nin conditionals allow you to pass in an Array of values. That is, the value portion of your filter array is itself allowed to be an array.

array("in"=>array('n2610','ABC123')
WHERE (e.sku in ('n2610','ABC123'))

notnull, null

The keyword NULL is special in most flavors of SQL. It typically won’t play nice with the standard equality (=) operator. Specifying notnull or null as your filter type will get you the correct syntax for a NULL comparison while ignoring whatever value you pass in

array("notnull"=>'n2610')
WHERE (e.sku is NOT NULL)

from – to filter

This is another special format that breaks the standard rule. Instead of a single element array, you specify a two element array. One element has the key from, the other element has the key to. As the keys indicated, this filter allows you to construct a from / to range without having to worry about greater than and less than symbols

public function testAction
{
        var_dump(
        (string)
        Mage::getModel('catalog/product')
        ->getCollection()
        ->addFieldToFilter('price',array('from'=>'10','to'=>'20'))
        ->getSelect()
        );
}

The above yields

WHERE (_table_price.value >= '10' and _table_price.value <= '20')'

AND or OR, or is that OR and AND?

Finally, we come to the boolean operators. It’s the rare moment where we’re only filtering by one attribute. Fortunately, Magento’s Collections have us covered. You can chain together multiple calls to addFieldToFilter to get a number of “AND” queries.

function testAction()
{
        echo(
        (string)
        Mage::getModel('catalog/product')
        ->getCollection()
        ->addFieldToFilter('sku',array('like'=>'a%'))
        ->addFieldToFilter('sku',array('like'=>'b%'))
        ->getSelect()
        );
}

By chaining together multiple calls as above, we’ll produce a where clause that looks something like the the following

WHERE (e.sku like 'a%') AND (e.sku like 'b%')

To those of you that just raised your hand, yes, the above example would always return 0 records. No sku can begin with BOTH an a and a b. What we probably want here is an ORquery. This brings us to another confusing aspect of addFieldToFilter ‘s second parameter.

If you want to build an OR query, you need to pass an Array of filter Arrays in as the second parameter. I find it’s best to assign your individual filter Arrays to variables

public function testAction()
{
        $filter_a = array('like'=>'a%');
        $filter_b = array('like'=>'b%');
}

and then assign an array of all my filter variables

public function testAction()
{
        $filter_a = array('like'=>'a%');
        $filter_b = array('like'=>'b%');
        echo(
        (string)
        Mage::getModel('catalog/product')
        ->getCollection()
        ->addFieldToFilter('sku',array($filter_a,$filter_b))
        ->getSelect()
        );
}

In the interest of being explicit, here’s the aforementioned Array of filter Arrays.

array($filter_a,$filter_b)

This will gives us a WHERE clause that looks something like the following

WHERE (((e.sku like 'a%') or (e.sku like 'b%')))

Comments are closed.