2016-06-27 24 views
2

Kann mir jemand sagen, wie benutzerdefinierte Eigenschaft zu Doktrin ORM YML-Datei hinzufügen?Wie benutzerdefinierte Eigenschaft zu Symfony Doctrine YAML Mapping-Datei hinzugefügt werden

Meine Idee ist es, eine Eigenschaft wie folgt hinzuzufügen:

fields: 
    name: 
     type: string 
     localizable: true 

Dann würde Ich mag Informationen zu diesem lokalisierbaren Eigenschaft erhalten, indem

protected function getEntityMetadata($entity) 
{ 
    $factory = new DisconnectedMetadataFactory($this->getContainer()->get('doctrine')); 

    return $factory->getClassMetadata($entity)->getMetadata(); 
} 

und anschließend:

$met = $this->getEntityMetadata($bundle.'\\Entity\\'.$entity); 
    $this->metadata = $met[0]; 
    $fields = $this->metadata->fieldMappings; 

    if (isset($fields)) { 

     foreach ($fields as $field => $fieldMapping) { 
      if (isset($fieldMapping['localizable']) && $fieldMapping['localizable'] == true) { 

       // Do sth with it 
      } 
     } 
    } 

Antwort

3

Die Art und Weise Lehre geschrieben wird, macht dies umständlich. Anscheinend möchten Sie das Yaml-Mapping beibehalten, aber nur eine einzige Eigenschaft hinzufügen. Ich denke, Sie können Ihren eigenen benutzerdefinierten Treiber erstellen, der von dem bereitgestellten erweitert wird. Der Yaml-Treiber hat meistens private Methoden, daher ist es schwierig, ein wenig Funktionalität zu überschreiben, aber es ist möglich.

Ich habe einen benutzerdefinierten Treiber erstellt, der sich von der SimplifiedYamlDriver erstreckt. Die Benennung des Treibers ist wichtig, da die DocLine-Erweiterung versuchen wird, einen ihrer Treiber basierend darauf zu laden, was vor Driver kommt. Es macht auch einen Strop-Check für Simplified im Namen, also denke ich, dass die sicherste Wette ist, den ursprünglichen Namen vollständig zu behalten und dem Original einen Alias ​​zu geben.

use Doctrine\ORM\Mapping\Driver\SimplifiedYamlDriver as BaseDriver; 

class SimplifiedYamlDriver extends BaseDriver 
{ 
    public function loadMetadataForClass($className, ClassMetadata $metadata) 
    { 
     parent::loadMetadataForClass($className, $metadata); 

     $element = $this->getElement($className); 

     if (!isset($element['fields'])) { 
      return; 
     } 

     foreach ($element['fields'] as $name => $fieldMapping) { 
      if (isset($fieldMapping['localizable'])) { 
       $original = $metadata->getFieldMapping($name); 
       $additional = ['localizable' => $fieldMapping['localizable']]; 
       $newMapping = array_merge($original, $additional); 
       $metadata->fieldMappings[$newMapping['fieldName']] = $newMapping; 
      } 
     } 
    } 
} 

Dann sagte ich Symfony diesen Treiber zu verwenden, indem die Klasse innerhalb app/config/parameters.yml

parameters: 
    doctrine.orm.metadata.yml.class: MyBundle\SimplifiedYamlDriver 

zwingende Dann habe ich das Mapping wie in Ihrem Beispiel innerhalb MyBundle/Resources/config/doctrine/Foo.orm.yml

MyBundle\Entity\Foo: 
    type: entity 
    id: 
     id: 
      type: integer 
      generator: 
       strategy: IDENTITY 
    fields: 
     text: 
      type: string 
      localizable: true 

aktualisiert Und ich kann holen Diese Zuordnung, wo immer ich Zugang zu Lehre mit:

$mapping = $this 
      ->getDoctrine() 
      ->getEntityManager() 
      ->getClassMetadata(Foo::class) 
      ->getFieldMapping('text'); 

Wird mir geben:

Array 
(
    [fieldName] => text 
    [type] => string 
    [columnName] => text 
    [localizable] => 1 
) 
+0

Dies funktioniert fast. Aber das Problem ist, dass DoctrineExtensions (die wahrscheinlich ähnlich funktioniert) nicht mehr funktioniert, wenn ich das tue, was Sie geschrieben haben. Ich erweitere Doctrine \ ORM \ Mapping \ Driver \ SimplifiedYamlDriver, das standardmäßig verwendet wird, so dass es funktionieren sollte, tut es aber nicht. Irgendeine Idee warum? – Tom

+0

Hmm, diese genaue Antwort, die ich gepostet habe, hat für mich funktioniert. Vielleicht ist es ein Unterschied in den Doktrinversionen. Ich habe^2.5 in composer.json – mickadoo

+0

Ich auch. Doktrin/Orm 2.5.4 und neueste Devmaster StofDoctrineExtensions Localizable ist gezeigt, aber träge, bellable, zeitbeständig aufhören zu arbeiten. – Tom

0

Leider ist dies ohne Umschreiben nicht möglich einen bedeutenden Teil von Doctrine DBAL. Dies würde Auswirkungen auf Treiber (YAML, Annotation ...), Metadaten-Generator ...

In Ihrem Fall wäre die einfachste ich einen benutzerdefinierten Typ sagen würde sagen wir LocalizableString (ich denke höchstens, dass Sie das brauchen und vielleicht LocalizableText). Das Hinzufügen eines Typs ist relativ einfach, da Sie einen Basistyp erweitern können, so dass Sie kein SQL schreiben müssen. Sie können auf Doktrin-Dokumentation und Doktrinenbündel 1 here verweisen.

Dann können Sie einfach tun:

$met = $this->getEntityMetadata($bundle.'\\Entity\\'.$entity); 
$this->metadata = $met[0]; 
$fields = $this->metadata->fieldMappings; 

if (isset($fields)) { 

    foreach ($fields as $field => $fieldMapping) { 
     if ($this->getClassMetadata()->getTypeOfField($field) === 'localized_string') { 

      // Do sth with it 
     } 
    } 
} 
+0

Ich kann das nicht tun, weil ich diese Eigenschaft auf jede Art von Feld hinzufügen möchten. Also müsste ich für jeden Basistyp einen neuen Typ vorbereiten. Ich weiß, das ist möglich, weil DoctrineExtensions dies tut, aber ich kann nicht verstehen, wie. – Tom

+0

Soweit ich weiß, ändert DoctrineExtensions die ursprünglichen Typen nicht. Sie fügen ihre eigenen Anmerkungen hinzu und lassen beim Erstellen von Metadaten einen eigenen Mechanismus aufrufen, der "erweiterungsfähige" Entitäten nachverfolgt: https: // github.com/Atlantic18/DoctrineExtensions/Blob/Master/lib/Gedmo/Mapping/MappedEventSubscriber.php – romaricdrigon