Bonjour , dans le cadre du développement de mon CMS que je publierais d'ici quelques temps .. Je me trouve face à un problème de "TAILLE".



Je vous explique ,

En gros , dans le projet , tout est Overridable , c'est déjà le cas, avec des configurations dans le fichier services.yaml.

Pour une raison évidente de simplicité , et un besoin immédiat , pour me permettre de créer un 2ème bundle héritant de ce dernier . Je me suis dit que faire mon "Override" ou dire au projet : "Coucou je suis là , je suis une classe utilise moi" est bien pratique avec des annotations (et beaucoup plus clair).

Du coup , j'ai créer une annotation custom (Jusque là tout va bien .. ) Que vous trouverez ici ..

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
 
<?php
 
 
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'];
 
    }
}

Bon , mon annotation était en place , je vais maintenant la mettre dans une entité , .. Comme voici


Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
 
<?php
 
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
{
 
}
Pourquoi faire ca ? Et ben en fait , tout est automatisé dans le neptune , sauf cas particulié , il va généré automatiquement toutes les URL nécessaires au bon fonctionnement d'une entité (ADD / EDIT / DELETE / LIST ) ... Et pour cela , il faut indiquer au projet que l'entité existe , et qu'elle doit faire parti de ce système .

Du coup , jusqu'a maintenant j'utilise une configuration bien complète dans le services.yaml , dans lequel je remplis un tableau keys => value , correspondant aux "key" => "Namespace"

Dans mon cas : "gift" => "ScyLabs\GiftCodeBundle\Entity\GiftCode"



Bref , du coup , pour OVERRIDE TOUT CA, je fais un traitement dans une étape de compilation
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
 
<?php
 
 
namespace ScyLabs\NeptuneBundle;
 
 
use ScyLabs\NeptuneBundle\DependencyInjection\Compiler\OverrideAnnotationPass;
use ScyLabs\NeptuneBundle\DependencyInjection\Compiler\ResolveDoctrineTargetEntitiesPass;
use Symfony\Component\DependencyInjection\Compiler\PassConfig;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\HttpKernel\Bundle\Bundle;
use ScyLabs\NeptuneBundle\DependencyInjection\ScyLabsNeptuneExtension;
 
class ScyLabsNeptuneBundle extends Bundle
{
    public function getContainerExtension()
    {
// Compilation de l'extension
        return new ScyLabsNeptuneExtension();
    }
}
Et dans cette extension , j'ai ce bout de code qui fait tout planter


Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
 
<?php
$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;                    }
                }
            }
        }
Ca me renvoie l'erreur suivante ::
[Semantical Error] The annotation "@Doctrine\ORM\Mapping\Entity" in class ScyLabs\GiftCodeBundle\Entity\GiftCode does not exist, or could not be auto-loaded.

D'après ce que je suspecte après pas mal de recherches , à l'étape de compilation de mon extension , @ORM\Entity , et ou / Autowire , est semble-il pas encore compilé.



Le problème c'est que du coup , alors que j'arrive à récupéré mon annotation personnelle (Override) , je n'arrive pas a récupérer @ORM\Entity , et je ne peux forcément pas l'enlever car ca ne fonctionnerais plus comme une entité.



Pourquoi faire ca ici ? Car derrière j'ai une autre étape de comoilation (Un CompilationPass)
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
 
$container->addCompilerPass(new ResolveDoctrineTargetEntitiesPass(),PassConfig::TYPE_BEFORE_OPTIMIZATION,1000);
Qui , me redéfini les Entités que doctrine va appelé par rapport au tableau que je lui envoie (vous savez , celui que je défini juste avant).

Avec ca je donne la possibilité d'override des entités avec un nom identiques.



Que faire ?? .. Je vous avoue que j'en peux plus ...



Merci d'avance les amis