0

as part of the development of my CMS that I publish in a while .. I am facing a problem.

error :

[Semantical Error] The annotation "@Doctrine\ORM\Mapping\Entity" in class ScyLabs\GiftCodeBundle\Entity\GiftCode does not exist, or could not be auto-loaded.

I explain to you ,

Basically, in the project, everything is Overridable, it is already the case, with configurations in the file services.yaml.

For obvious reasons of simplicity, and an immediate need, to allow me to create a second bundle inheriting from it. I told myself that doing my "Override" or saying to the project: "Hello here I am, I am a class uses me" is very convenient with annotations (and much clearer).

So, I create a custom annotation (So far so good ..) That you find here ..

<?php
/**
 * Created by PhpStorm.
 * User: alex
 * Date: 04/11/2019
 * Time: 14:25
 */

namespace ScyLabs\NeptuneBundle\Annotation\ScyLabsNeptune;


/**
 * @Annotation
 * @Target({"CLASS"})
 * @Attributes({
 *  @Attribute("key",type="string"),
 *  @Attribute("classNameSpace",type="string"),
 * })
 */
class Override
{
    /**
     * @var string
     */
    public $key;
    /**
     * @var string
     */
    public $classNameSpace;

    public function __construct(array $opts) {

        $this->key = $opts['value'];
        $this->classNameSpace = $opts['class'];

    }
}

Well, my annotation was in place, I will now put it in an entity, .. As here

<?php
/**
 * Created by PhpStorm.
 * User: alex
 * Date: 05/11/2019
 * Time: 10:20
 */

namespace ScyLabs\GiftCodeBundle\Entity;

use ScyLabs\NeptuneBundle\Annotation\ScyLabsNeptune;
use Doctrine\ORM\Mapping as ORM;

/**
 *  @ScyLabsNeptune\Override("gift",class="ScyLabs\GiftCodeBundle\Entity\GiftCode")
 *  @ORM\Entity()
 */
class GiftCode
{

}

Why do that ? And in fact, everything is automated in the neptune, except special case, it will automatically generate all the URLs necessary for the proper functioning of an entity (ADD / EDIT / DELETE / LIST) ... And for this, it must indicate to the project that the entity exists, and that it must be part of this system.

So, until now I use a very complete configuration in services.yaml, in which I fill a table keys => value, corresponding to "key" => "Namespace"

In my case: "gift" => "ScyLabs \ GiftCodeBundle \ Entity \ GiftCode"

In short, suddenly, for override, I do a treatment in a compilation step

<?php
/**
 * Created by PhpStorm.
 * User: alex
 * Date: 01/08/2018
 * Time: 09:46
 */

namespace ScyLabs\NeptuneBundle;


class ScyLabsNeptuneBundle extends Bundle
{
    public function getContainerExtension()
    {

// Compilation de l'extension
        return new ScyLabsNeptuneExtension();
    }
}

And in this extension, I have this piece of code that makes everything

$bundles = require $projectDir.'/config/bundles.php';

        foreach ($bundles as $bundle => $env){

            if($bundle === ScyLabsNeptuneBundle::class)
                continue;
            if(method_exists(new $bundle,'getParent') && (new $bundle)->getParent() === ScyLabsNeptuneBundle::class){


                $reader = new AnnotationReader();

                $reflClass = new \ReflectionClass(GiftCode::class);

                $classAnotations = $reader->getClassAnnotation($reflClass,"Override");

                foreach ($classAnotations as $classAnotation){
                    if($classAnotation instanceof Override && class_exists($classAnotation->classNameSpace)){
                        $config['override'][$classAnotation->key] = $classAnotation->classNameSpace;                    }
                }
            }
        }

From what I suspect after a lot of research, at the compilation stage of my extension, @ORM \ Entity, and or / / Autowire, it seems not compiled yet.

The problem is that suddenly, when I get my personal annotation (Override), I can not recover @ORM \ Entity, and I can not necessarily remove it because it would not work anymore as an entity.

Why do that here? Because behind I have another step of comoilation (A CompilationPass)

$container->addCompilerPass(new ResolveDoctrineTargetEntitiesPass(),PassConfig::TYPE_BEFORE_OPTIMIZATION,1000);

Who, redefined the Entities that doctrine will call in relation to the painting that I send to him (you know, the one I defined just before).

With this I give the possibility of override entities with an identical name.

What to do ?? .. I confess that I can not do more ...

Thanks in advance friends;)

Seytu2b
  • 28
  • 4

2 Answers2

0

By default, the annotation reader does not use the same autoloader as classes. You need to tell him how to load the annotation class like that :

AnnotationRegistry::registerUniqueLoader('class_exists');

For more explanation, you can look at the doc https://www.doctrine-project.org/projects/doctrine-annotations/en/1.6/annotations.html#registering-annotations

Noémi Salaün
  • 4,866
  • 2
  • 33
  • 37
0

thanks for you response.

But it don't work and this fonction is deprecated and removed to Annotations 2.0.

BUT , when i try i found a resolution.

When i follow your link and try the code in the page , i try this function

AnnotationRegistry#registerFile($file)

For get @ORM\Entity file path , i use

new \ReflectionClass(ORM\Entity::class);

And , this work. I deleted AnnotationRegistry#registerFile($file) function , and this work.

Thanks you for help ;) You'r the best

Seytu2b
  • 28
  • 4