覆盖KNP DoctrineBehaviors" under-the-hood"

时间:2016-06-13 14:36:28

标签: php symfony override bundle

我正在写一个SEO包,主要由两部分组成:

  • 一个表单扩展名(用于在表单中添加slug / title / desc字段)
  • 一个特性Seoable包含实体方面的字段

除此之外,我想使用缓慢的特性爬上KNP DoctrineBehaviors的肩膀。

我的问题:在我的架构中,Sluggable特性将由我的Seoable特性使用,而不是由最终的类。在DoctrineBehaviors'胆量,我发现特征检查由ClassAnalyzer类完成,使用此方法:

/**
     * Return TRUE if the given object use the given trait, FALSE if not
     * @param ReflectionClass $class
     * @param string $traitName
     * @param boolean $isRecursive
     */
    public function hasTrait(\ReflectionClass $class, $traitName, $isRecursive = false)
    {
        if (in_array($traitName, $class->getTraitNames())) {
            return true;
        }

        $parentClass = $class->getParentClass();

        if ((false === $isRecursive) || (false === $parentClass) || (null === $parentClass)) {
            return false;
        }

        return $this->hasTrait($parentClass, $traitName, $isRecursive);
    }

递归部分检查所有祖先类,但不检查特征中包含的特征。

我头顶的2个解决方案:

  • 提交KNP DoctrineBehaviors的拉取请求,将此递归模式扩展到特征(我最终会做)
  • 覆盖此部分

DoctrineBehaviors不是"常规" bundle,意思是未在AppKernel中注册。我该如何扩展这部分?

感谢您的回复,

尼古拉斯

1 个答案:

答案 0 :(得分:0)

感谢this part of cookbook更加细心的阅读,我查看了DoctrineBehaviors配置文件(vendor / knplabs / doctrine-behavior / config / orm-services.yml)。

KNP在此提供DoctrineBehaviors包中使用的侦听器和类的所有参数,例如:

parameters:
    knp.doctrine_behaviors.reflection.class_analyzer.class: Knp\DoctrineBehaviors\Reflection\ClassAnalyzer
    knp.doctrine_behaviors.reflection.is_recursive: true
    knp.doctrine_behaviors.translatable_subscriber.class: Knp\DoctrineBehaviors\ORM\Translatable\TranslatableSubscriber
# next...

所以,我刚刚在参数config.yml部分中覆盖了第一个使用我自己的ClassAnalyser实例的参数。 对于记录,具有祖先特征的递归循环检查:

     /**
     * Return TRUE if the given object use the given trait, FALSE if not
     * Extends from ClassAnalyzer::hasTrait to check in ancestors traits as well
     * @param \ReflectionClass $class
     * @param string $traitName
     * @param boolean $isRecursive
     */
    public function hasTrait(\ReflectionClass $class, $traitName, $isRecursive = false)
    {
        $classTraits = $class->getTraitNames();

        // Trait directly present in final class
        if (in_array($traitName, $classTraits)) {
            return true;
        }

        // Check in parents traits
        foreach($classTraits as $classTrait) {
            $traitObject = new \ReflectionClass($classTrait);

            if($this->hasTrait($traitObject, $traitName, $isRecursive)) {
                return true;
            }
        }

        // Check in parents classes
        $parentClass = $class->getParentClass();

        if ((false === $isRecursive) || (false === $parentClass) || (null === $parentClass)) {
            return false;
        }

        return $this->hasTrait($parentClass, $traitName, $isRecursive);
    }