I am trying to extend Mage_Catalog_Block_Product_View I have it setup in my version of it in my local directory and everything works fine, but I wasn’t getting the results that I wanted. I then saw that another class extended that class as well. Which seemed to reset whatever got set from my class. I know that my class is working fine and executing. Its just that there is another class that is a child of the same class I am extending and calling parent::method to the same method I am overriding, that class gets executed after my class and when it does that, it is running the original method that I am overriding and not mine
This is the function
class Mage_Review_Block_Product_View extends Mage_Catalog_Block_Product_View
protected function _prepareLayout()
{
$this->getLayout()->createBlock('catalog/breadcrumbs');
$headBlock = $this->getLayout()->getBlock('head');
if ($headBlock) {
$title = $this->getProduct()->getMetaTitle();
if ($title) {
$headBlock->setTitle($title);
}
$keyword = $this->getProduct()->getMetaKeyword();
$currentCategory = Mage::registry('current_category');
if ($keyword) {
$headBlock->setKeywords($keyword);
} elseif($currentCategory) {
$headBlock->setKeywords($this->getProduct()->getName());
}
$description = $this->getProduct()->getMetaDescription();
if ($description) {
$headBlock->setDescription( ($description) );
} else {
$headBlock->setDescription( $this->getProduct()->getDescription() );
}
}
return parent::_prepareLayout();
}
I am trying to modify it just a bit with the following, keep in mind I know there is a title prefix and suffix but I needed it only for the product page and also I needed to add text to the description.
class MyCompany_Catalog_Block_Product_View extends Mage_Catalog_Block_Product_View
protected function _prepareLayout()
{
$storeId = Mage::app()->getStore()->getId();
$this->getLayout()->createBlock('catalog/breadcrumbs');
$headBlock = $this->getLayout()->getBlock('head');
if ($headBlock) {
$title = $this->getProduct()->getMetaTitle();
if ($title) {
if($storeId == 2){
$title = "Pool Supplies Fast - " .$title;
$headBlock->setTitle($title);
}
$headBlock->setTitle($title);
}else{
$path = Mage::helper('catalog')->getBreadcrumbPath();
foreach ($path as $name => $breadcrumb) {
$title[] = $breadcrumb['label'];
}
$newTitle = "Pool Supplies Fast - " . join($this->getTitleSeparator(), array_reverse($title));
$headBlock->setTitle($newTitle);
}
$keyword = $this->getProduct()->getMetaKeyword();
$currentCategory = Mage::registry('current_category');
if ($keyword) {
$headBlock->setKeywords($keyword);
} elseif($currentCategory) {
$headBlock->setKeywords($this->getProduct()->getName());
}
$description = $this->getProduct()->getMetaDescription();
if ($description) {
if($storeId == 2){
$description = "Pool Supplies Fast - ". $this->getProduct()->getName() . " - " . $description;
$headBlock->setDescription( ($description) );
}else{
$headBlock->setDescription( ($description) );
}
} else {
if($storeId == 2){
$description = "Pool Supplies Fast: ". $this->getProduct()->getName() . " - " . $this->getProduct()->getDescription();
$headBlock->setDescription( ($description) );
}else{
$headBlock->setDescription( $this->getProduct()->getDescription() );
}
}
}
return Mage_Catalog_Block_Product_Abstract::_prepareLayout();
}
This executs fine but then I notice that the following class Mage_Review_Block_Product_View_List extends which extends Mage_Review_Block_Product_View and that extends Mage_Catalog_Block_Product_View as well. Inside this class they call the _prepareLayout as well and call the parent with parent::_prepareLayout()
class Mage_Review_Block_Product_View_List extends Mage_Review_Block_Product_View
protected function _prepareLayout()
{
parent::_prepareLayout();
if ($toolbar = $this->getLayout()->getBlock('product_review_list.toolbar')) {
$toolbar->setCollection($this->getReviewsCollection());
$this->setChild('toolbar', $toolbar);
}
return $this;
}
So obviously this just calls the same class I am extending and runs the function I am overiding but it doesn’t get to my class because it is not in my class hierarchy and since it gets called after my class all the stuff in the parent class override what I have set.
I’m not sure about the best way to extend this type of class and method, there has to be a good way to do this, I keep finding I am running into issues when trying to overide these prepare methods that are derived from the abstract classes, there seems to be so many classes overriding them and calling parent::method.
What is the best way to override these functions?
Your post is a little unclear, but I think you’re running into the Magento limitation of only being able to override classes that are at the bottom of the inheritance chain.
Here’s how Magento’s override system works. I’m going to use models as an example, but it applies to helpers and blocks as well.
When Magento needs to instantiate an overridable class, it doesn’t use the new keyword.
instead, a static factory method is called on global Mage object.
What
getModeldoes is turn the string “foo/bar” into an actual class name. It does this based on a series of rules, one of which is to check all module configuration for any overrides. Once the class name is determined, an object is instantiated.This works decently, but it means you may only override the instantiation of a class. There’s no way to override methods on parent classes, as those methods are inherited via the normal PHP mechanism.
Clarification: So, let’s say you have a class Foo which extends Bar
and you override
class Barwith something likeWhen someone instantiates a
Fooobject and calls the example method,parentwill resolves to class Bar, even though you’ve overridden class Bar in the Magento config.