Skip to content

Commit

Permalink
Merge pull request #80 from szymach/mapping
Browse files Browse the repository at this point in the history
Translatable mapping drivers
  • Loading branch information
rn0 authored Jun 16, 2017
2 parents 2a45841 + 92ed885 commit dc0a351
Show file tree
Hide file tree
Showing 19 changed files with 803 additions and 23 deletions.
13 changes: 13 additions & 0 deletions .scrutinizer.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
---
filter:
excluded_paths: [vendor/*, tests/*, bin/*]

checks:
php:
code_rating: true
duplication: true

tools:
php_cpd: true
php_pdepend:
excluded_dirs: [vendor]
4 changes: 4 additions & 0 deletions doc/translatable.md
Original file line number Diff line number Diff line change
Expand Up @@ -608,3 +608,7 @@ example in translation entity:
*/
private $locale;
```

## XML and YAML mapping reference ##

See [here](translatable/xml.md) and [here](translatable/yaml.md), respectively.
104 changes: 104 additions & 0 deletions doc/translatable/xml.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
# Translatable - Translatable behavioral extension for Doctrine 2

## XML config example

Entity:

```php
<?php

namespace Acme\DemoBundle\Entity

class User
{
/**
* @var integer
*/
public $id;

/**
* @var string
*/
public $name;

/**
* Acme\DemoBundle\UserTranslation[]
*/
public $translations;
}
```

XML for the entity:
```xml
<?xml version="1.0" encoding="UTF-8"?>
<doctrine-mapping xmlns="http://doctrine-project.org/schemas/orm/doctrine-mapping"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://doctrine-project.org/schemas/orm/doctrine-mapping
http://www.doctrine-project.org/schemas/orm/doctrine-mapping.xsd"
xmlns:fsi="http://fsi.pl/schemas/orm/doctrine-extensions-mapping">

<entity name="Acme\DemoBundle\Entity\User"
repository-class="FSi\DoctrineExtensions\Translatable\Entity\Repository\TranslatableRepository"
>
<id name="id" type="integer" column="id">
<generator strategy="AUTO"/>
</id>
<one-to-many field="translations" target-entity="Acme\DemoBundle\Entity\UserTranslation" mapped-by="user" index-by="locale" />

<fsi:translatable-locale field="locale" /><!-- "field" is required to point at which property the mapping points -->
<fsi:translatable-field field="name" mappedBy="translations" />
</entity>

</doctrine-mapping>
```

Translation:

```php
<?php

namespace Acme\DemoBundle\Entity

class UserTranslation
{
/**
* @var integer
*/
public $id;

/**
* @var string
*/
public $name;

/**
* @var Acme\DemoBundle\User
*/
public $page;
}
```

XML for the translation:
```xml
<?xml version="1.0" encoding="UTF-8"?>
<doctrine-mapping xmlns="http://doctrine-project.org/schemas/orm/doctrine-mapping"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://doctrine-project.org/schemas/orm/doctrine-mapping
http://www.doctrine-project.org/schemas/orm/doctrine-mapping.xsd"
xmlns:fsi="http://fsi.pl/schemas/orm/doctrine-extensions-mapping">

<entity name="Acme\DemoBundle\Entity\UserTranslation">
<id name="id" type="integer" column="id">
<generator strategy="AUTO"/>
</id>

<field type="string" name="content" length="255"/>
<field type="string" name="locale" length="2">
<fsi:translatable-locale /><!-- No value needed, field name is used as locale property identifier -->
</field>

<many-to-one field="user" target-entity="cme\DemoBundle\Entity\User" inversed-by="translations" />
</entity>

</doctrine-mapping>
```
107 changes: 107 additions & 0 deletions doc/translatable/yaml.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
# Translatable - Translatable behavioral extension for Doctrine 2

## YAML config example

Translated entity:

```php
<?php

namespace Acme\DemoBundle\Entity

class User
{
/**
* @var integer
*/
public $id;

/**
* @var string
*/
public $name;

/**
* @var \Acme\DemoBundle\Entity\UserTranslation[]
*/
public $translations;
}
```

Translated entity's mapping:
```yaml
Acme\DemoBundle\Entity\User:
type: entity
id:
id:
type: integer
generator:
strategy: AUTO
fsi:
translatable:
locale:
field: locale # required, since there is no field to assign to
fields:
name:
mappedBy: translations
targetField: name
oneToMany:
translations:
targetEntity: Acme\DemoBundle\Entity\UserTranslation
mappedBy: user
cascade: ["persist", "remove"]
indexBy: locale
```
Translation entity:
```php
<?php

namespace Acme\DemoBundle\Entity

class UserTranslation
{
/**
* @var integer
*/
public $id;

/**
* @var string
*/
public $name;

/**
* @var \Acme\DemoBundle\Entity\User
*/
public $user;
}
```

Translation entity's mapping:
```yaml
Acme\DemoBundle\Entity\UserTranslation:
type: entity
id:
id:
type: integer
generator:
strategy: AUTO
fields:
locale:
type: string
length: 2
fsi:
translatable:
locale: ~ # No value is needed here, field name is assigned as locale parameter identifier
name:
type: string
length: 255
manyToOne:
user:
targetEntity: Acme\DemoBundle\Entity\User
inversedBy: translations
```
15 changes: 15 additions & 0 deletions doctrine-extensions-mapping.xsd
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,19 @@
<xs:attribute name="keyLength" type="xs:integer" use="optional"/>
<xs:attribute name="keyPattern" type="xs:string" use="optional"/>
</xs:complexType>

<xs:element name="translatable-field" type="fsi:translatable-field"/>

<xs:complexType name="translatable-field">
<xs:attribute name="mappedBy" type="xs:string" use="required"/>
<xs:attribute name="field" type="xs:string" use="required"/>
<xs:attribute name="targetField" type="xs:string" use="optional"/>
</xs:complexType>

<xs:element name="translatable-locale" type="fsi:translatable-locale"/>

<xs:complexType name="translatable-locale">
<xs:attribute name="field" type="xs:string" use="optional" default="locale"/>
</xs:complexType>

</xs:schema>
15 changes: 9 additions & 6 deletions lib/FSi/DoctrineExtensions/Mapping/Driver/AbstractXmlDriver.php
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,11 @@ protected function getFileMapping(ClassMetadataInterface $extendedClassMetadata)
$dom = new DOMDocument();
$dom->load($fileLocation);
if (!$this->validateFile($dom)) {
throw new MappingException(sprintf('There are wrong mappings in xml mapping for class "%s" in file "%s"', $extendedClassMetadata->getClassName(), $fileLocation));
throw new MappingException(sprintf(
'There are wrong mappings in XML mapping for class "%s" in file "%s"',
$extendedClassMetadata->getClassName(),
$fileLocation
));
}

$xmlElement = simplexml_load_file($fileLocation);
Expand All @@ -40,13 +44,13 @@ protected function getFileMapping(ClassMetadataInterface $extendedClassMetadata)
$className = $extendedClassMetadata->getClassName();
if (isset($xmlElement->entity)) {
foreach ($xmlElement->entity as $entityElement) {
if ($this->getAttribute($entityElement, 'name') == $className) {
if ($this->getAttribute($entityElement, 'name') === $className) {
return $entityElement;
}
}
} elseif (isset($xmlElement->{'mapped-superclass'})) {
foreach ($xmlElement->{'mapped-superclass'} as $mappedSuperClass) {
if ($this->getAttribute($mappedSuperClass, 'name') == $className) {
if ($this->getAttribute($mappedSuperClass, 'name') === $className) {
return $mappedSuperClass;
}
}
Expand All @@ -68,7 +72,7 @@ protected function getAttribute(SimpleXmlElement $node, $name)
}

/**
* Validatin xml file.
* Validating xml file.
*
* @param \DOMDocument $dom
* @return bool
Expand Down Expand Up @@ -118,8 +122,7 @@ private function validateFile(DOMDocument $dom)
EOF
;

$valid = @$dom->schemaValidateSource($source);
return $valid;
return @$dom->schemaValidateSource($source);
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@ protected function getFileMapping(ClassMetadataInterface $extendedClassMetadata)
$element = Yaml::parse(file_get_contents($this->findMappingFile($extendedClassMetadata)));
if (isset($element[$extendedClassMetadata->getClassName()])) {
return $element[$extendedClassMetadata->getClassName()];
} else {
return [];
}

return [];
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,29 +20,21 @@
final class ExtendedMetadataFactory extends MetadataFactory
{
/**
* Object manager, entity or document.
*
* @var ObjectManager
*/
private $objectManager;

/**
* Extension namespace.
*
* @var string
*/
private $extensionNamespace;

/**
* Annotation reader.
*
* @var object
*/
private $annotationReader;

/**
* Initializes extension driver.
*
* @param \Doctrine\Common\Persistence\ObjectManager $objectManager
* @param string $extensionNamespace
* @param object $annotationReader
Expand Down Expand Up @@ -111,6 +103,7 @@ private function getDriver($omDriver)
$driver->setAnnotationReader($this->annotationReader);
}
}

return $driver;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,17 @@

namespace FSi\DoctrineExtensions\ORM\Event;

use Doctrine\ORM\EntityManager;
use Doctrine\ORM\Query;
use Doctrine\Common\EventManager;
use Doctrine\ORM\EntityManagerInterface;
use Doctrine\ORM\Event\LifecycleEventArgs;
use Doctrine\ORM\Mapping\ClassMetadataFactory;
use Doctrine\ORM\Query;
use FSi\DoctrineExtensions\ORM\Events;

class PostHydrateEventDispatcher
{
/**
* @var EntityManager
* @var EntityManagerInterface
*/
private $entityManager;

Expand Down Expand Up @@ -46,12 +48,10 @@ class PostHydrateEventDispatcher
private $entities = [];

/**
* Constructs a new dispatcher instance
*
* @param EntityManager $em
* @param EntityManagerInterface $em
* @param array $hints
*/
public function __construct(EntityManager $em, array $hints = [])
public function __construct(EntityManagerInterface $em, array $hints = [])
{
$this->entityManager = $em;
$this->metadataFactory = $em->getMetadataFactory();
Expand Down
Loading

0 comments on commit dc0a351

Please sign in to comment.