2010-04-22 69 views
0

我想扩展Mage_Catalog_Block_Product_View我已经在我的本地版本中设置了它,并且一切工作正常,但我没有得到我想要的结果。然后,我看到另一个班级也扩展了这个班级。这似乎重置了我班的任何设置。我知道我的班级工作正常并正在执行。它只是有另一个类是我正在扩展的同一个类的子类,并调用parent ::方法为我重写的同一个方法,该类在我的类之后执行,当它执行时,它正在运行原始方法,我重写,与我无关你如何覆盖由父类::方法调用另一个类的类

这是函数

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(); 
} 

我想有以下修改它只是有点,记住我知道有一个标题前缀和后缀,但我只需要它的产品页面,我也需要添加文字的描述。

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(); 
} 

这executs很好,但后来我发现下面的类Mage_Review_Block_Product_View_List扩展延伸Mage_Review_Block_Product_View和延伸Mage_Catalog_Block_Product_View为好。这个类中,他们称之为_prepareLayout以及和调用父类与父母:: _ 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; 
} 

所以,很显然这只是叫我延伸的同一类和运行我overiding的功能,但它不去我的课,因为它不在我的类层次结构中,并且因为它在我的课程后被调用,所以父类中的所有东西都会覆盖我所设置的内容。

我不确定扩展这种类型和方法的最佳方式,必须有一个很好的方法来做到这一点,我试图覆盖这些准备方法时遇到问题派生自抽象类,似乎有这么多的类覆盖它们并调用parent ::方法。

覆盖这些功能的最佳方法是什么?

回答

3

您的文章是有点不清楚,但我认为你正在运行到仅能够覆盖是在继承的底部类的Magento的限制链。

下面是Magento的覆盖系统的工作原理。我将使用模型作为示例,但它也适用于助手和块。

当Magento需要实例化一个可重写的类时,它不使用new关键字。

$foo = new FooBar(); 

改为在全局Mage对象上调用静态工厂方法。

$foo = Mage::getModel('foo/bar'); 

getModel做什么是转字符串“富/酒吧”为实际的类名。它基于一系列规则来做到这一点,其中之一是检查所有模块配置是否有任何覆盖。一旦类名被确定,一个对象就被实例化了。

这样做的效果很好,但这意味着你可能只有重写一个类的实例化。没有办法覆盖父类的方法,因为这些方法是通过普通的PHP机制继承的。

澄清:那么,让我们说你有延伸酒吧

class Bar 
{ 
    public function example() 
    { 
    } 
} 

class Foo extends Bar 
{ 
    public function example() 
    { 
     return parent::example(); 
    } 
} 

类Foo和重写class Bar喜欢的东西

//magento configured ot use Baz in place of Bar 
class Baz 
{ 
} 

当有人实例化一个Foo对象,并调用示例方法,parent将解析为类Bar,即使您已覆盖cla在Magento配置中的ss酒吧。

+0

谢谢艾伦,我明白你必须重写在链的底部的子类,所以我想这意味着,而不是扩展Mage_Catalog_Block_Product_View我会扩展Mage_Review_Block_Product_View_List它似乎很奇怪,因为它是在评论。是否有一种简单的方法来查看应该扩展的类是什么类? 当你说“但它意味着你可能只能覆盖类的实例化”,你只是指最后一个调用该类的类。顺便说一句,我从你的文章中学到了我的Magento开发的大部分内容 – 2010-04-22 14:12:21

+0

更新了我正在驾驶的内容,这可能会也可能不会解决你之后的问题。很高兴你喜欢这些有用的文章! – 2010-04-22 14:53:34

+0

ahh是啊,那就是我认为你的意思,所以我想唯一的选择是扩展Foo,即使它没有意义 – 2010-04-22 17:15:25

1

你确定你已经正确覆盖了类吗? (我的意思是把你的模块的config.xml中<重写>标签,让Magento的知道你要重写这个类) 如果是,请更清晰言传要扩展什么,你认为什么是不工作

+0

是的一切都设置正确,因为我知道它击中我的课,我已经调试它,并看到它的工作。它只是在另一个类的后面运行并调用parent :: _ prepareLayout(),这当然会调用Mage_Catalog_Block_Product_View而不是我的类。 – 2010-04-22 11:56:44

+0

是的,这很正常,因为该类具有Mage_Catalog_Block_Product_View,因为它是父级。我认为我现在明白你在说什么,但我不认为你可以做任何事情,因为类扩展机制很简单(你说类X扩展了Mage_Catalog_Block_Product_View,不是这样的:class X extends Mage :: getBlock( 'catalog/product_review') - 所以你可以重写)。唯一的解决方案是重写调用它的父类,并修改它的_prepareLayout太 – matei 2010-04-22 12:06:47

+0

是的,我扩展了这一点,但不知道该怎么做,我想把我的_prepareLayout中的所有东西都放在那个中?因为我不能调用MyClass :: _ prepareLayout(),因为它不是静态函数,也不是我的类层次结构中的其他类。我不得不认为人们已经以某种方式扩展了这个类的扩展,但我想他们可能不得不修改它们。 – 2010-04-22 12:21:28

1

有三个选项的位置:

  1. 覆盖所有子类为好,使他们正确地从你的类下降(或者至少打电话给你以某种方式类)。

  2. 将父类放到app/code/local/文件夹中,以便Magento找到它而不是默认的文件夹。所以你要创建目录app/code/local/Mage/Catalog/Block/Product/并将View.php复制到它。这对于升级来说是一个问题,但是,因为你必须合并Varien对班级所做的任何改变。

  3. 放弃重写并将其更改为模板。这可能是所有的最佳选择,因为您不必担心_prepareLayout方法的更改。

希望帮助, 乔

+0

1.是的,这似乎有点像我想要做的简单事情,所以我觉得必须有更好的方法。 2.我可能只是在这样做后永远这样做。 3。我只是不确定如何在模板中进行更改,因为我试图只更改产品页面的元标题和说明,对于描述我必须获取产品名称。 – 2010-04-22 12:24:15