首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何使用parent::method重写由另一个类调用的类

如何使用parent::method重写由另一个类调用的类
EN

Stack Overflow用户
提问于 2010-04-22 19:27:22
回答 3查看 3.2K关注 0票数 0

我正在尝试扩展Mage_Catalog_Block_Product_View,我已经将它设置在我本地目录中的版本中,一切正常,但我没有得到我想要的结果。然后我看到另一个类也扩展了那个类。这似乎重置了我的课上设置的所有内容。我知道我的类工作得很好,并且正在执行。只是有另一个类是我正在扩展的同一个类的子类,并将parent::method调用到我要重写的同一个方法,这个类在我的类之后执行,当它执行时,它运行的是我重写的原始方法,而不是我的方法

这就是函数

代码语言:javascript
运行
复制
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();
}

我正在尝试修改它只有一点与以下,请记住,我知道有一个标题前缀和后缀,但我需要它只为产品页面,我还需要添加文字的描述。

代码语言:javascript
运行
复制
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();
}

这可以很好地执行,但是我注意到下面的Mage_Review_Block_Product_View_List扩展类,它扩展了Mage_Review_Block_Product_View,也扩展了Mage_Catalog_Block_Product_View。在这个类内部,它们也调用_prepareLayout,并用parent::_prepareLayout()调用父类

代码语言:javascript
运行
复制
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;
}

显然,这只是调用了我正在扩展的同一个类,并运行了我重写的函数,但它没有到达我的类,因为它不在我的类层次结构中,而且由于它是在我的类之后调用的,所以父类中的所有内容都覆盖了我设置的内容。

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

覆盖这些函数的最佳方式是什么?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2010-04-22 21:31:43

你的帖子有点不清楚,但我认为你遇到了Magento的限制,只能覆盖位于继承链底部的类。

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

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

代码语言:javascript
运行
复制
$foo = new FooBar();

取而代之的是,在全局Mage对象上调用静态工厂方法。

代码语言:javascript
运行
复制
$foo = Mage::getModel('foo/bar');

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

这可以很好地工作,但这意味着您只能覆盖类的实例化。没有办法覆盖父类上的方法,因为这些方法是通过正常的PHP机制继承的。

假设你有一个扩展了Clarification:的类

代码语言:javascript
运行
复制
class Bar
{
    public function example()
    {
    }
} 

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

你可以用类似这样的东西来覆盖class Bar

代码语言:javascript
运行
复制
//magento configured ot use Baz in place of Bar
class Baz
{
}

当有人实例化Foo对象并调用example方法时,parent将解析为类Bar,,即使已经覆盖了Magento配置中的类Bar。

票数 3
EN

Stack Overflow用户

发布于 2010-04-22 19:35:23

你确定你已经正确地覆盖了这个类吗?(我的意思是将标签放在模块的config.xml中,让magento知道你正在覆盖这个类)如果是,请用更清晰的语言解释你正在扩展的是什么,以及你认为什么是不起作用的

票数 1
EN

Stack Overflow用户

发布于 2010-04-22 20:20:27

这里有三个选项:

  1. 还会覆盖所有的子类,以便它们正确地从您的类中继承下来(或者至少以某种方式调用您的类)。
  2. 将父类放在app/code/local/文件夹中,以便Magento找到它而不是默认的父类。因此,您需要创建目录app/code/local/Mage/Catalog/Block/Product/并将View.php复制到其中。然而,这对于升级来说是个问题,因为你必须合并Varien对类所做的任何更改。
  3. 放弃重写,并在模板中进行更改。这可能是最好的选择,因为您不必担心_prepareLayout方法的更改。

希望这会有帮助,乔

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/2690311

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档