I have made a bunch of changes in my local folder to override core classes. But I'd like to group some of them into modules so i can turn them on and off.
I am new to the module creation process. I've copied some code from tutorials online, but one thing I have not been able to answer is whether I should rewrite the core classes (which I am effectively already doing by overriding them in the local folder), or if I should extend them.
My understanding is that in either case, you create a class in your module folder that extends the core class. But in one case you surround in in <rewrite>
tags and in the other you don't. But I don't know what the difference in effect is.
I need my module to change the behavior of
These Catalog template files in app/design/frontend/myinterface/mytheme/template/catalog/:
product/list.phtml
product/list/toolbar.phtml
product/view.phtml
These blocks in Catalog/Block/:
Product/List.php
Product/View.php
Product/List/Toolbar.php
These models in Catalog/Model/:
Layer/Filter/Attribute.php
Resource/Eav/Mysql4/Layer/Filter/Attribute.php
Resource/Eav/Mysql4/Product/Collection.php
Again, everything already works, but there is so much that is changed that I would like to package it into a module to make it easier to turn on and off and I want to make sure I go about it the right way.
EDIT:
In case anyone's wondering, the changes I've made are to group products together based on an attribute value. Some values are NULL, though, and those should not be grouped. I needed the filter functionality to display quantities that matched the visible products so that code had to be changed as well as the product list code.
Edit2:
After trying copying various online examples, one finally halfway worked, here.
Below xml attempts to load just 2 block files. The list.php
is loading, but toolbar.php
is not.
<!-- The root node for Magento module configuration -->
<config>
<!--
The module's node contains basic
information about each Magento module
-->
<modules>
<!--
This must exactly match the namespace and module's folder
names, with directory separators replaced by underscores
-->
<Mynamespace_MyModule>
<!-- The version of our module, starting at 0.0.1 -->
<version>0.0.1</version>
</Mynamespace_MyModule>
</modules>
<global>
<models />
<blocks>
<mynamespace_mymodule>
<class>Mynamespace_MyModule_Block</class>
</mynamespace_mymodule>
<catalog>
<rewrite>
<!-- THEY LOAD! --><product_list>Mynamespace_MyModule_Block_Product_List</product_list>
<product_list_toolbar>Mynamespace_MyModule_Block_Product_Toolbar</product_list_toolbar>
</rewrite>
</catalog>
</blocks>
<helpers />
</global>
</config>
I got the above XML to work after I realized that I misnamed my extension to the toolbar class.
Additional Info
Here is the function I'm overriding in the product resource class (my rewritten version).
class Mynamespace_MyModule_Model_Resource_Eav_Mysql4_Product_Collection
extends Mage_Catalog_Model_Resource_Eav_Mysql4_Product_Collection
{
/**
* Get SQL for get record count
*
* @return Varien_Db_Select
*/
public function getSelectCountSql()
{
$this->_renderFilters();
$countSelect = clone $this->getSelect();
$countSelect->reset(Zend_Db_Select::ORDER);
$countSelect->reset(Zend_Db_Select::LIMIT_COUNT);
$countSelect->reset(Zend_Db_Select::LIMIT_OFFSET);
$countSelect->reset(Zend_Db_Select::COLUMNS);
$countSelect->columns('COUNT(DISTINCT e.entity_id)');
$countSelect->resetJoinLeft();
// $countSelect->columns('COUNT(*)'); // original code
if(count($this->getSelect()->getPart(Zend_Db_Select::GROUP)) > 0) { // handles group by. from stackoverflow
$countSelect->reset(Zend_Db_Select::GROUP);
//$countSelect->distinct(true);
$group = $this->getSelect()->getPart(Zend_Db_Select::GROUP);
$countSelect->reset(Zend_Db_Select::COLUMNS);
$countSelect->columns(new Zend_Db_Expr("COUNT(DISTINCT ".implode(", ", $group).")"));
$countSelect->columns(new Zend_Db_Expr('COUNT(DISTINCT e.entity_id)'));
} else { // if no group by, handle the original way
$countSelect->columns('COUNT(*)');
}
return $countSelect;
}
}
And here's the one for the attribute resource:
/**
* Catalog Layer Attribute Filter Resource Model
*
* @category Mage
* @package Mage_Catalog
* @author Magento Core Team <[email protected]>
*/
class Mynamespace_MyModule_Model_Resource_Eav_Mysql4_Layer_Filter_Attribute extends Mage_Catalog_Model_Resource_Eav_Mysql4_Layer_Filter_Attribute
{
/**
* Retrieve array with products counts per attribute option
*
* @param Mage_Catalog_Model_Layer_Filter_Attribute $filter
* @return array
*/
public function getCount($filter)
{
// clone select from collection with filters
$select = clone $filter->getLayer()->getProductCollection()->getSelect();
// reset columns, order and limitation conditions
$select->reset(Zend_Db_Select::COLUMNS);
$select->reset(Zend_Db_Select::ORDER);
$select->reset(Zend_Db_Select::LIMIT_COUNT);
$select->reset(Zend_Db_Select::LIMIT_OFFSET);
$connection = $this->_getReadAdapter();
$attribute = $filter->getAttributeModel();
$tableAlias = $attribute->getAttributeCode() . '_idx';
$conditions = array(
"{$tableAlias}.entity_id = e.entity_id",
$connection->quoteInto("{$tableAlias}.attribute_id = ?", $attribute->getAttributeId()),
$connection->quoteInto("{$tableAlias}.store_id = ?", $filter->getStoreId()),
);
$select
->join(
array($tableAlias => $this->getMainTable()),
join(' AND ', $conditions),
array('value', 'count' => "COUNT(DISTINCT IFNULL(e.custom_grouping,e.entity_id))"))
->group("{$tableAlias}.value");
/* $select // ORIGINAL CODE
->join(
array($tableAlias => $this->getMainTable()),
join(' AND ', $conditions),
array('value', 'count' => "COUNT({$tableAlias}.entity_id)"))
->group("{$tableAlias}.value");
*/
if(isset($_GET['testing'])) { // 20140111 by Nick to see if this code is executing
$_SESSION['called'][] = 'File ' . __FILE__ . ' - Line: ' . __LINE__ . 'getcount sql: ' . (string)$select;
}
return $connection->fetchPairs($select);
}
}
Thanks.