Override code-behind for a block in Magento - magento

I am writing a module to extend the Core/Catalog/Product/View/Media.php class so I can expose new methods in my template. I followed a number of guides online, including Alan Storms excellent series, but have had little success. ( http://alanstorm.com/magento_config )
I posted my code on Github: https://github.com/razialx/Magento-Overwrite-Block
I am not getting any errors in the logs, it just isn't loading my class. Very perplexed.
One thought I had was that I may only be able to rewrite classes that are explicitly defined. I know the Mage_Catalog_Block_Product_View_Media class is never defined in a config file, though I assume it is referenced by the layout xml file catalog.xml
<block type="catalog/product_view_media" name="product.info.media" as="media" template="catalog/product/view/media.phtml"/>

Your config.xml is slightly off. Give the following a try.
<config>
<modules>
<Test_Catalog>
<version>1.0.0.0.0</version>
</Test_Catalog>
</modules>
<global>
<blocks>
<catalog>
<rewrite>
<product_view_media>Test_Catalog_Block_Product_View_Media</product_view_media>
</rewrite>
</catalog>
</blocks>
</global>
</config>
Your <blocks> node needs to be enclosed in a <global> node.

Related

How to remove tabs from customer edit page in Magento backend?

In magento, by default 11 tabs are displayed in the customer edit page in the back end. How can I remove tabs from the default list of tabs. What I have done so far:
Created a class to override Mage_Adminhtml_Block_Customer_Edit_Tabs class and then overrode the _beforeToHtml() method.
tried to remove the tabs using
$this->removeTab('addresses');
Removing Customer tabs
a) You have to override Mage_Adminhtml_Block_Customer_Edit_Tabs because the Magento guys did a small typo there: they are adding tabs in _beforeToHtml() method instead of _prepareLayout(). So first you have to modify your config.xml and add:
<global>
<blocks>
<adminhtml>
<rewrite>
<customer_edit_tabs>Yourmodule_Customer_Block_Edit_Tabs</customer_edit_tabs>
</rewrite>
</adminhtml>
</blocks>
</global>
In Yourmodule_Customer_Block_Edit_Tabs just copy and paste the Mage_Adminhtml_Block_Customer_Edit_Tabs contents (don’t forget to change the class name!), and rename _beforeToHtml() method to _prepareLayout()
b) Add the removeTab action into your layout xml (default: customer.xml):
<adminhtml_customer_edit>
<reference name="left">
<block type="adminhtml/customer_edit_tabs" name="customer_edit_tabs">
<action method="removeTab">
<name>NAME_OF_TAB</name>
</action>
</block>
</reference>
</adminhtml_customer_edit>
You can find out the NAME_OF_TAB, by inspecting the tab’s anchor () and looking for the “name” attribute.

Magento: Editing top navigation sub nav structure

I need to do a bit of major editing to the sub navigation displayed from the standard Magento top level navigation.
I've gone into top.phtml and found that it calls a function in the core Mage code, Is it possible to have a file in my theme run before this is called or do I have to create a totally custom navigation/use a extension?
You're always more than welcome to simply replace the design/frontend/[package]/[theme]/catalog/navigation/top.phtml template with your own markup which you can then iterate over as you please.
The Block class already provides some basic methods that can be used to build your nav menu how you like it, such as getStoreCategories(), isCategoryActive(), getCurrenetChildCategories(), etc.
Alternatively, as mentioned by Peter, you can rewrite the Block class to change specific methods or include your own methods which are then accessible from the template file.
To override Mage_Catalog_Block_Navigation:
in app/etc/modules/Yourmodule_Catalog.xml:
<?xml version="1.0"?>
<config>
<modules>
<Yourmodule_Catalog>
<active>true</active>
<codePool>local</codePool>
<depends />
</Yourmodule_Catalog>
</modules>
</config>
in app/code/local/Yourmodule/Catalog/etc/config.xml:
<?xml version="1.0"?>
<config>
<modules>
<Yourmodule_Catalog>
<version>0.1.0</version>
</Yourmodule_Catalog>
</modules>
<global>
<blocks>
<catalog>
<rewrite>
<navigation>Yourmodule_Catalog_Block_Navigation</navigation>
</rewrite>
</catalog>
</blocks>
</global>
in app/code/local/Yourmodule/Catalog/Block/Navigation.php:
<?php
class Yourmodule_Catalog_Block_Navigation extends Mage_Catalog_Block_Navigation
{
.... the methods you want to override...
}
And that's it.

How to override Magento model classes with as little copy-paste as possible?

I want to change a single line of code in a single method in e.g. the class Mage_Reports_Model_Resource_Product_Collection. The easiest way seems to be to copy the entire class file to app/code/local/..., but then I have replaced the original class, not overridden a method.
How can I create a new class that inherits from e.g. Mage_Reports_Model_Resource_Product_Collection and only override one method? And still tell Magento to use my new class instead of the original.
Here's the working code to rewrite product collection:
<global>
<models>
<reports_resource>
<rewrite>
<product_collection>Company_ModelName_Model_Resource_Product_Collection</product_collection>
</rewrite>
</reports_resource>
</models>
</global>
It should work for Mage::getResourceModel('reports/product_collection') call.
Yeah and I haven't included the <config> tag, I think you should already have even <global> one, so I felt it wasn't necessary.
Theoretically the rewriting of the model would be...
<config>
<global>
<models>
<reports>
<rewrite>
<resource_product_collection>Namespace_Extension_Model_Resource_Product_Collection</resource_product_collection>
</rewrite>
</reports>
</models>
</global>
</config>
I've never personally rewritten a resource model though, so I can't swear it will work. It will very much depend on how the collection is getting loaded.

How to scale image in cms Magento

When the admin adds an image to a cms page in Magento, and then resize the image:
then the image at the frontend retains its original size, but scaled.
Is there any solution to save the image in smaller size when the page is saved?
There's no way this will happen with any default magento. However, you could put together a module that will observe your cms page saved data. Take for instance this event:
cms_page_prepare_save
with parameters:
array(’page’ ⇒ $model, ‘request’ ⇒ $this→getRequest())
You can create the module starting with only 3 files:
/app/etc/Electricjesus_Cms.xml:
<?xml version="1.0" encoding="UTF-8"?>
<config>
<modules>
<Electricjesus_Cms>
<active>true</active>
<codePool>local</codePool>
</Electricjesus_Cms>
</modules>
</config>
/app/code/local/Electricjesus/Cms/etc/config.xml:
<?xml version="1.0"?>
<config>
<modules>
<Electricjesus_Cms>
<version>0.1.0</version>
</Electricjesus_Cms>
</modules>
<global>
<models>
<cms>
<class>Electricjesus_Cms_Model</class>
</cms>
</models>
<events>
<cms_page_prepare_save>
<observers>
<prepareSave>
<class>cms/observer</class>
<method>prepareSave</method>
</prepareSave>
</observers>
</cms_page_prepare_save>
</events>
</global>
</config>
/app/code/local/Electricjesus/Cms/Model/Observer.php:
<?php
class Electricjesus_Cms_Model_Observer {
function prepareSave ( $observer ) {
$request = $observer->getRequest();
$params = $request->getParams();
// scan the request and params for stuff related with the images..
// find out scaling and pass into a good resizer like TimThumb or
// Zend_Filter_ImageSize etc.
}
}
While the above answer is not complete, this is a good place to start. I'll try and develop a complete solution whenever I have more time on it.
Alternative method:
Since I mentioned TimThumb above, you can also deploy that at your magento root and start adding your images via HTML editor instead of the usual WYSIWYG editor. If installing thumb.php on your website root directory, you can use it like so:
<img src="/thumb.php?src=images/image.jpg&w=100&h=50" alt="Hey" />
Good luck!

Magento: Several custom blocks all outputting the same code!

I have a custom module, which has several blocks. If I include these blocks in a CMS page after each other, they work as expected. If I include them through the layout XML files, they all display the source code of the last one called in the XML. A minimum test case (that for me is exhibiting this behavior) follows, along with expected and actual results.
Code
/app/etc/modules/Test_Tester.xml
<?xml version="1.0"?>
<config>
<modules>
<Test_Tester>
<active>true</active>
<codePool>local</codePool>
</Test_Tester>
</modules>
</config>
/app/code/local/Test/Tester/etc/config.xml
<?xml version="1.0"?>
<config>
<modules>
<Test_Tester>
<version>0.1.0</version>
</Test_Tester>
</modules>
<global>
<blocks>
<test_tester>
<class>Test_Tester_Block</class>
</test_tester>
</blocks>
</global>
</config>
/app/code/local/Test/Tester/Block/One.php
<?php
class Test_Tester_Block_One extends Mage_Catalog_Block_Product_List_Upsell
{
protected function _prepareData()
{
echo 'One.php';
//...MORE code here, it's not really relevant though
}
}
/app/code/local/Test/Tester/Block/Two.php
<?php
class Test_Tester_Block_Two extends Mage_Catalog_Block_Product_List_Upsell
{
protected function _prepareData()
{
echo 'Two.php';
//...MORE code here, it's not really relevant though
}
}
/app/design/frontend/INTERFACE/TEMPLATE/layout/page.xml (under
..
<block type="core/text_list" name="testa" as="testa" />
<block type="core/text_list" name="testb" as="testb" />
..
/app/design/frontend/INTERFACE/TEMPLATE/layout/cms.xml (under
<reference name="testa">
<block type="test_tester/one" template="tester/one.phtml"/>
</reference>
<reference name="testb">
<block type="test_tester/two" template="tester/two.phtml"/>
</reference>
/app/design/frontend/INTERFACE/TEMPLATE/template/page/home_template.phtml
<?php echo $this->getChildHtml('testa'); ?>
<?php echo $this->getChildHtml('testb'); ?>
/app/design/frontend/INTERFACE/TEMPLATE/tester/one.phtml
one.phtml
/app/design/frontend/INTERFACE/TEMPLATE/tester/two.phtml
two.phtml
Expected
This should print out (on the homepage, where the blocks are being included):
One.php
one.phtml
Two.php
two.phtml
Actual Output
If I include the blocks within the Homepage CMS page, like so:
{{block type="test_tester/one" template="tester/one.phtml"}}
{{block type="test_tester/two" template="tester/two.phtml"}}
...I get the expected output. However, using the layout as above in the code sample, I get:
Two.php
two.phtml
Two.php
two.phtml
I think I've gone insane - I can't see the bit I'm mucking up.
Try giving your blocks names in the homepage CMS page. Similar errors I've received have been resolved this way. I see that you're trying to wrap the blocks in text lists, but from what I see you never actually identify the blocks from within the CMS page. Try something to this effect instead:
{{block type="test_tester/one" template="tester/one.phtml" name="testa"}}
{{block type="test_tester/two" template="tester/two.phtml" name="testb"}}
If you cannot get away from the parent blocks as containers, you may have to rethink part of your layout. If that doesn't do it either way, let me know and we'll try something else. Hope that helps.
Thanks,
Joe

Resources