Skip to content

Commit

Permalink
Allow using attributes to configure entities for this bundle
Browse files Browse the repository at this point in the history
  • Loading branch information
mpdude committed Mar 27, 2024
1 parent fadeca2 commit 53a55ec
Show file tree
Hide file tree
Showing 17 changed files with 181 additions and 107 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/lock-symfony-version.sh
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
#!/bin/sh

sed --in-place --regexp-extended --expression='/symfony\/error-handler/b; /symfony\/phpunit-bridge/b; s/"(symfony\/.*)": ".*"/"\1": "'$VERSION'"/' composer.json
sed --in-place --regexp-extended --expression='/symfony\/deprecation-contracts/b; /symfony\/error-handler/b; /symfony\/phpunit-bridge/b; s/"(symfony\/.*)": ".*"/"\1": "'$VERSION'"/' composer.json
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,11 @@

To get the diff for a specific change, go to https://github.com/webfactory/polyglot-bundle/commit/XXX where XXX is the change hash. To get the diff between two versions, go to https://github.com/webfactory/polyglot-bundle/compare/{oldversion}...{newversion}.

## Version 3.1.0

* The annotations `\Webfactory\Bundle\PolyglotBundle\Annotation\Locale`, `\Webfactory\Bundle\PolyglotBundle\Annotation\Translatable` and `\Webfactory\Bundle\PolyglotBundle\Annotation\TranslationCollection` have been deprecated. Replace them with the corresponding PHP attributes from the `\Webfactory\Bundle\PolyglotBundle\Attribute` namespace.
* Using annotations to configure entity classes for this bundle has been deprecated. Switch to PHP 8 attributes.

## Version 3.0.0

* Dropped support for PHP versions below 8.1, and for Symfony versions before 5.4.
Expand Down
3 changes: 2 additions & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,14 @@
"php": "8.1.*|8.2.*|8.3.*",
"doctrine/annotations": "^1.12",
"doctrine/collections": "^1.0",
"doctrine/event-manager": "^1.0",
"doctrine/dbal": "^2.3|^3.0",
"doctrine/event-manager": "^1.0",
"doctrine/orm": "^2.10",
"doctrine/persistence": "^1.3.8 | ^2.1",
"psr/log": "^1.0",
"symfony/config": "^5.4|^6.4|^7.0",
"symfony/dependency-injection": "^5.4|^6.4|^7.0",
"symfony/deprecation-contracts": "^2.0|^3.0",
"symfony/event-dispatcher": "^5.4|^6.4|^7.0",
"symfony/http-kernel": "^5.4|^6.4|^7.0"
},
Expand Down
13 changes: 4 additions & 9 deletions src/Annotation/Locale.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,23 +10,18 @@
namespace Webfactory\Bundle\PolyglotBundle\Annotation;

use Doctrine\Common\Annotations\Annotation\NamedArgumentConstructor;
use Webfactory\Bundle\PolyglotBundle\Attribute\Locale as Attribute;

/**
* @Annotation
* @NamedArgumentConstructor
* @Target({"CLASS","PROPERTY"})
*/
final class Locale
final class Locale extends Attribute
{
private ?string $primary;

public function __construct(string $primary = null)
{
$this->primary = $primary;
}

public function getPrimary(): ?string
{
return $this->primary;
trigger_deprecation('webfactory/polyglot-bundle', '3.1.0', 'The %s annotation has been deprecated. Use the %s attribute instead.', self::class, parent::class);
parent::__construct($primary);
}
}
13 changes: 4 additions & 9 deletions src/Annotation/Translatable.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,22 +10,17 @@
namespace Webfactory\Bundle\PolyglotBundle\Annotation;

use Doctrine\Common\Annotations\Annotation\NamedArgumentConstructor;
use Webfactory\Bundle\PolyglotBundle\Attribute\Translatable as Attribute;

/**
* @Annotation
* @NamedArgumentConstructor
*/
final class Translatable
final class Translatable extends Attribute
{
private ?string $translationFieldname;

public function __construct(string $translationFieldname = null)
{
$this->translationFieldname = $translationFieldname;
}

public function getTranslationFieldname(): ?string
{
return $this->translationFieldname;
trigger_deprecation('webfactory/polyglot-bundle', '3.1.0', 'The %s annotation has been deprecated. Use the %s attribute instead.', self::class, parent::class);
parent::__construct($translationFieldname);
}
}
8 changes: 7 additions & 1 deletion src/Annotation/TranslationCollection.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,15 @@

namespace Webfactory\Bundle\PolyglotBundle\Annotation;

use Webfactory\Bundle\PolyglotBundle\Attribute\TranslationCollection as Attribute;

/**
* @Annotation
*/
final class TranslationCollection
final class TranslationCollection extends Attribute
{
public function __construct()
{
trigger_deprecation('webfactory/polyglot-bundle', '3.1.0', 'The %s annotation has been deprecated. Use the %s attribute instead.', self::class, parent::class);
}
}
29 changes: 29 additions & 0 deletions src/Attribute/Locale.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<?php

/*
* (c) webfactory GmbH <info@webfactory.de>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace Webfactory\Bundle\PolyglotBundle\Attribute;

use Attribute;

/** @final */
#[Attribute(Attribute::TARGET_CLASS | Attribute::TARGET_PROPERTY)]
class Locale
{
private ?string $primary;

public function __construct(string $primary = null)
{
$this->primary = $primary;
}

public function getPrimary(): ?string
{
return $this->primary;
}
}
29 changes: 29 additions & 0 deletions src/Attribute/Translatable.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<?php

/*
* (c) webfactory GmbH <info@webfactory.de>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace Webfactory\Bundle\PolyglotBundle\Attribute;

use Attribute;

/** @final */
#[Attribute]
class Translatable
{
private ?string $translationFieldname;

public function __construct(string $translationFieldname = null)
{
$this->translationFieldname = $translationFieldname;
}

public function getTranslationFieldname(): ?string
{
return $this->translationFieldname;
}
}
18 changes: 18 additions & 0 deletions src/Attribute/TranslationCollection.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<?php

/*
* (c) webfactory GmbH <info@webfactory.de>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace Webfactory\Bundle\PolyglotBundle\Attribute;

use Attribute;

/** @final */
#[Attribute]
class TranslationCollection
{
}
61 changes: 42 additions & 19 deletions src/Doctrine/TranslatableClassMetadata.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
use ReflectionProperty;
use RuntimeException;
use Webfactory\Bundle\PolyglotBundle\Annotation;
use Webfactory\Bundle\PolyglotBundle\Attribute;
use Webfactory\Bundle\PolyglotBundle\Locale\DefaultLocaleProvider;
use Webfactory\Bundle\PolyglotBundle\Translatable;

Expand Down Expand Up @@ -193,15 +194,22 @@ private function findTranslatedProperties(ClassMetadataInfo $cm, Reader $reader,
continue;
}

$foundAttributeOrAnnotation = null;
$reflectionProperty = $cm->getReflectionClass()->getProperty($fieldName);
$attributes = $reflectionProperty->getAttributes(Attribute\Translatable::class);

$annotation = $reader->getPropertyAnnotation(
$reflectionProperty,
Annotation\Translatable::class
);
if ($attributes) {
$foundAttributeOrAnnotation = $attributes[0]->newInstance();
} else {
$foundAttributeOrAnnotation = $reader->getPropertyAnnotation($reflectionProperty, Annotation\Translatable::class);

if ($foundAttributeOrAnnotation) {
trigger_deprecation('webfactory/polyglot-bundle', '3.1.0', 'Using the %s annotation on the %s::%s property is deprecated. Use the %s attribute instead.', Annotation\Translatable::class, $reflectionProperty->class, $reflectionProperty->name, Attribute\Translatable::class);
}
}

if ($annotation) {
$translationFieldname = $annotation->getTranslationFieldname() ?: $fieldName;
if ($foundAttributeOrAnnotation) {
$translationFieldname = $foundAttributeOrAnnotation->getTranslationFieldname() ?: $fieldName;
$translationFieldReflectionProperty = $translationClassMetadata->getReflectionProperty($translationFieldname);

$this->translatedProperties[$fieldName] = $reflectionProperty;
Expand All @@ -212,19 +220,24 @@ private function findTranslatedProperties(ClassMetadataInfo $cm, Reader $reader,

private function findTranslationsCollection(ClassMetadataInfo $cm, Reader $reader, ClassMetadataFactory $classMetadataFactory): void
{
$found = false;
foreach ($cm->associationMappings as $fieldName => $mapping) {
if (isset($mapping['declared'])) {
// The association is inherited from a parent class
continue;
}

$annotation = $reader->getPropertyAnnotation(
$cm->getReflectionProperty($fieldName),
Annotation\TranslationCollection::class
);
$reflectionProperty = $cm->getReflectionProperty($fieldName);

if ($annotation) {
$this->translationsCollectionProperty = $cm->getReflectionClass()->getProperty($fieldName);
if ($reflectionProperty->getAttributes(Attribute\TranslationCollection::class)) {
$found = true;
} else if ($reader->getPropertyAnnotation($reflectionProperty, Annotation\TranslationCollection::class)) {
trigger_deprecation('webfactory/polyglot-bundle', '3.1.0', 'Using the %s annotation on the %s::%s property is deprecated. Use the %s attribute instead.', Annotation\TranslationCollection::class, $reflectionProperty->class, $reflectionProperty->name, Attribute\TranslationCollection::class);
$found = true;
}

if ($found) {
$this->translationsCollectionProperty = $reflectionProperty;

$translationEntityMetadata = $classMetadataFactory->getMetadataFor($mapping['targetEntity']);
$this->translationClass = $translationEntityMetadata->getReflectionClass();
Expand All @@ -239,8 +252,17 @@ private function findTranslationsCollection(ClassMetadataInfo $cm, Reader $reade
private function findPrimaryLocale(ClassMetadataInfo $cm, Reader $reader): void
{
foreach (array_merge([$cm->name], $cm->parentClasses) as $class) {
$annotation = $reader->getClassAnnotation(new ReflectionClass($class), Annotation\Locale::class);
$reflectionClass = new ReflectionClass($class);

foreach ($reflectionClass->getAttributes(Attribute\Locale::class) as $attribute) {
$this->primaryLocale = $attribute->newInstance()->getPrimary();

return;
}

$annotation = $reader->getClassAnnotation($reflectionClass, Annotation\Locale::class);
if (null !== $annotation) {
trigger_deprecation('webfactory/polyglot-bundle', '3.1.0', 'Using the %s annotation on the %s class is deprecated. Use the %s attribute instead.', Annotation\Locale::class, $reflectionClass->name, Attribute\Locale::class);
$this->primaryLocale = $annotation->getPrimary();

return;
Expand All @@ -253,16 +275,17 @@ private function parseTranslationsEntity(Reader $reader, ClassMetadataInfo $cm):
foreach ($cm->fieldMappings as $fieldName => $mapping) {
$reflectionProperty = $cm->getReflectionProperty($fieldName);

$annotation = $reader->getPropertyAnnotation(
$reflectionProperty,
Annotation\Locale::class
);

if ($annotation) {
if ($reflectionProperty->getAttributes(Attribute\Locale::class)) {
$this->translationLocaleProperty = $reflectionProperty;

return;
}

if ($reader->getPropertyAnnotation($reflectionProperty, Annotation\Locale::class)) {
$this->translationLocaleProperty = $reflectionProperty;
trigger_deprecation('webfactory/polyglot-bundle', '3.1.0', 'Using the %s annotation on the %s::%s property is deprecated. Use the %s attribute instead.', Annotation\Locale::class, $reflectionProperty->class, $reflectionProperty->name, Attribute\Locale::class);
return;
}
}
}

Expand Down
14 changes: 5 additions & 9 deletions tests/Functional/CascadePersistTranslationsTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
use Webfactory\Bundle\PolyglotBundle\Annotation as Polyglot;
use Webfactory\Bundle\PolyglotBundle\Attribute as Polyglot;
use Webfactory\Bundle\PolyglotBundle\Translatable;
use Webfactory\Bundle\PolyglotBundle\TranslatableInterface;

Expand Down Expand Up @@ -46,9 +46,8 @@ public function adding_and_persisting_translations(): void

/**
* @ORM\Entity
*
* @Polyglot\Locale(primary="en_GB")
*/
#[Polyglot\Locale(primary: "en_GB")]
class CascadePersistTranslationsTest_Entity
{
/**
Expand All @@ -64,16 +63,14 @@ class CascadePersistTranslationsTest_Entity
* (!) There is *not* cascade="persist" configuration here.
*
* @ORM\OneToMany(targetEntity="CascadePersistTranslationsTest_Translation", mappedBy="entity")
*
* @Polyglot\TranslationCollection
*/
#[Polyglot\TranslationCollection]
protected Collection $translations;

/**
* @ORM\Column(type="string")
*
* @Polyglot\Translatable
*/
#[Polyglot\Translatable]
protected string|TranslatableInterface $text;

public function __construct()
Expand Down Expand Up @@ -104,9 +101,8 @@ class CascadePersistTranslationsTest_Translation

/**
* @ORM\Column
*
* @Polyglot\Locale
*/
#[Polyglot\Locale]
private string $locale;

/**
Expand Down
Loading

0 comments on commit 53a55ec

Please sign in to comment.