مبدأ Symfony: إضافة مساحات جديدة لأسماء التعليقات التوضيحية إلى القارئ الحالي

0

لقد قمت بتطبيق بلدي Doctrine\Common\EventSubscriber التي تشترك في أحداث "onFlush" وتقارن EntityChangeSet بقائمة مشفرة من خصائص الفئة (مثل User->Name و Event->Date ) ويسجل التغيير إذا لزم الأمر.

نظرًا لأن أسماء خصائص الفئات الأخرى قد تتغير ، فإنني أفضل بدلاً من ذلك إضافة تعليق توضيحي لهذه الخصائص باستخدام مخصص @Loggable .

وأضاف لقد بنيت فئة التعليق "Loggable" use MyNamespace\Annotations\Loggable; إلى User و Event الطبقات ولها طريقة في EventSubscriber بلدي الذي يخلق Doctrine\Common\Annotations\AnnotationReader ويستخدم لها getPropertyAnnotation($property, 'Loggable') للتحقق من وجود قيمة غير فارغة.

الآن على المشكلة

كما يمكن للمرء أن يتوقع (أو لا) ، يلقي هذا القارئ بالذات

[Semantical Error] The annotation "@Id" in property MyNamespace\Entities\User::$id was never imported.

وليس على علم بأي تعليقات توضيحية أخرى لـ ORM يستخدمها القارئ في EntityManager يعرف عن.

هل علي أن أضيف فعلا use Doctrine\ORM\Mapping as ORM; لكل فئة من الكيانات ويبدأ كل تعليق ORM مع ORM\ فقط لإرضاء هذا القارئ الذي تم إنشاؤه حديثًا أو هل هناك طريقة لإعادة استخدام القارئ في EntityManagerDoctrine\Common\Annotations\SimpleAnnotationReader بشكل افتراضي ، إذا فهمت بشكل صحيح؟)

لقد أجريت بحثي وقرأت معظم الإجابات المتعلقة بالعقيدة والتعليقات التوضيحية ، ولكن يبدو أنني افتقدت بعض الفهم المفاهيمي. ربما شخص ما يمكن أن يشير لي في الاتجاه الصحيح؟

2 الاجابة

1
افضل جواب

بشكل أساسي ، تستخدم فئة AnnotationReader getClassAnnotations و getClassAnnotation (التي تستخدم getClassAnnotations في الواقع).

getClassAnnotations:

public function getClassAnnotations(ReflectionClass $class)
{
    $this->parser->setTarget(Target::TARGET_CLASS);
    $this->parser->setImports($this->getClassImports($class));
    $this->parser->setIgnoredAnnotationNames($this->getIgnoredAnnotationNames($class));
    $this->parser->setIgnoredAnnotationNamespaces(self::$globalIgnoredNamespaces);

    return $this->parser->parse($class->getDocComment(), 'class ' . $class->getName());
}

getClassAnnotation:

public function getClassAnnotation(ReflectionClass $class, $annotationName)
{
    $annotations = $this->getClassAnnotations($class);

    foreach ($annotations as $annotation) {
        if ($annotation instanceof $annotationName) {
            return $annotation;
        }
    }

    return null;
}

ما عليك سوى إلقاء نظرة على هذا الخط:

$this->parser->setImports($this->getClassImports($class));

يقوم قارئ التعليقات التوضيحية بجمع بيانات الاستخدام للكشف عن أي تعليقات توضيحية أخرى تستخدمها. لذا ، حول سؤالك

Do I actually have to add use Doctrine\ORM\Mapping as ORM; to every Entity class and prefix every ORM-annotation with ORM\ [...]?

يجب أن أجيب: نعم ، أنت تفعل.

:مؤلف
0

بفضل تفسيراتFrank Gamess ، تمكنت أخيرًا من الخوض في غابة قاعدة التعليمات البرمجية لـ Doctrine والعثور على حل فوضوي ، ولكنه حل عملي ، لا يتضمن مساحات أسماء واضحة لكل ملف.

بدلا من استخدام أبسط Setup::createAnnotationMetadataConfiguration() عند إنشاء EntityManager الخاص بي ، قمت بمزيد من الكلام المطوّل وأداء معظم خطوات التكوين بنفسي:

// preloading all of Doctrine's Annotation classes
$rc = new \ReflectionClass(Configuration::class);
$dir = dirname($rc->getFileName());

AnnotationRegistry::registerFile($dir . '/Mapping/Driver/DoctrineAnnotations.php');

// preloading my own classes
$dir = $dir ?? self::BASE_DIR . '/src/Annotations';  // BASE_DIR is my project root directory
// CustomAnnotations.php is built the same way as DoctrineAnnotations.php;
AnnotationRegistry::registerFile($dir . '/CustomAnnotations.php');

$reader = new SimpleAnnotationReader();
$reader->addNamespace('Doctrine\ORM\Mapping');
$reader->addNamespace('MyProject\Annotations');

$mapping_driver = new AnnotationDriver($reader, [self::BASE_DIR . '/src/Entities']);

$config = Setup::createConfiguration();
$config->setMetadataDriverImpl($mapping_driver);
$config->setAutoGenerateProxyClasses(true);

$EM = EntityManager::create($db_params, $config, new EventManager());

// adding the objects to my ORM-objects for later use
$this->annotation_reader = $reader;
$this->EM = $EM;

يمكنني الآن استخدام التعليقات التوضيحية الخاصة بي دون أي بيانات استخدام أو FQCN. ربما ليس أنظف ولكن أقل تكرارًا.

مع نجاح هذا ، قد أكون قادرًا على الانتقال إلى أشياء أكثر إلحاحًا ، ولكن إذا كان بإمكان أي شخص أن يشير إلى إمكانيات إعادة الهيكلة ، فأنا كله آذان!

:مؤلف

أسئلة ذات صلة

فوق
قائمة طعام