diff --git a/.coveralls.yml b/.coveralls.yml deleted file mode 100644 index 5b6d7ce..0000000 --- a/.coveralls.yml +++ /dev/null @@ -1,3 +0,0 @@ -service_name: travis-ci -src_dir: . -coverage_clover: build/logs/clover.xml \ No newline at end of file diff --git a/.github/workflows/dependencies.yml b/.github/workflows/dependencies.yml new file mode 100644 index 0000000..c936d61 --- /dev/null +++ b/.github/workflows/dependencies.yml @@ -0,0 +1,36 @@ +name: Dependencies + +on: + push: + branches: + - master + pull_request: + +env: + PHP_VERSION: 7.2 + +jobs: + composer-require-checker: + name: Check missing composer requirements + runs-on: ubuntu-18.04 + steps: + - uses: actions/checkout@v2 + - name: Konfiguriere PHP-Version und -Einstellungen im Worker-Node + uses: shivammathur/setup-php@v2 + with: + php-version: ${{ env.PHP_VERSION }} + tools: composer:v2 + ini-values: variables_order=EGPCS + - name: Cache Composer Dependencies + uses: actions/cache@v1 + with: + path: vendor/ + key: composer-${{ env.PHP_VERSION }}-${{ hashFiles('composer.*') }} + restore-keys: | + composer-${{ env.PHP_VERSION }}-${{ github.ref }} + composer-${{ env.PHP_VERSION }}- + - run: | + composer install --no-interaction --no-scripts --no-progress --no-suggest + composer show + - name: ComposerRequireChecker + uses: docker://webfactory/composer-require-checker:2.1.0 diff --git a/.github/workflows/fix-cs-php.yml b/.github/workflows/fix-cs-php.yml new file mode 100644 index 0000000..755da70 --- /dev/null +++ b/.github/workflows/fix-cs-php.yml @@ -0,0 +1,50 @@ +# Update this by running +# curl https://gist.githubusercontent.com/mpdude/ca93a185bcbf56eb7e341632ad4f8263/raw/fix-cs-php.yml > .github/workflows/fix-cs-php.yml + +on: + push: + branches: + - master + pull_request: + +name: Coding Standards + +jobs: + open-pr-for-cs-violations: + name: PHP-CS-Fixer + runs-on: ubuntu-18.04 + steps: + + - name: Checkout code + uses: actions/checkout@v2 + with: + ref: ${{ github.head_ref }} + + - name: Run PHP-CS-Fixer + uses: docker://oskarstark/php-cs-fixer-ga:2.16.7 + + - name: Create PR for CS fixups + uses: peter-evans/create-pull-request@c7f493a8000b8aeb17a1332e326ba76b57cb83eb + id: create-pull-request + with: + token: ${{ secrets.GITHUB_TOKEN }} + title: Fix coding standards in ${{ github.ref }} + branch: php-cs-fixer/${{ github.ref }} + assignees: ${{ github.actor }} + labels: php-cs-fixer + body: Please merge these changes into the ${{ github.ref }} branch to fix coding standard violations. + commit-message: Apply php-cs-fixer changes as of ${{ github.sha }} + + - name: Leave a notice in the discussion when fixing code in a Pull Request + uses: docker://mpdude/comment-on-pr:v1.2.0 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + if: steps.create-pull-request.outputs.pr_number # only if PR was created in the previous step + continue-on-error: true # continue on failure - necessary when the current branch does not have a pending PR + with: + msg: | + @${{ github.actor }} please apply the coding standard fixes from #${{ steps.create-pull-request.outputs.pr_number }} + + - name: Fail the workflow when necessary CS fixes were detected + run: echo "Failing workflow run because CS violations were detected." && exit 1 + if: steps.create-pull-request.outputs.pr_number diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml new file mode 100644 index 0000000..fb30658 --- /dev/null +++ b/.github/workflows/tests.yml @@ -0,0 +1,35 @@ +name: Tests + +on: + push: + branches: + - master + pull_request: + +env: + PHP_VERSION: 7.2 + +jobs: + PHPUnit: + name: PHPUnit + runs-on: ubuntu-18.04 + steps: + - uses: actions/checkout@v2 + - name: Konfiguriere PHP-Version und -Einstellungen im Worker-Node + uses: shivammathur/setup-php@v2 + with: + php-version: ${{ env.PHP_VERSION }} + tools: composer:v2 + ini-values: variables_order=EGPCS + - name: Cache Composer Dependencies + uses: actions/cache@v1 + with: + path: vendor/ + key: composer-${{ env.PHP_VERSION }}-${{ hashFiles('composer.*') }} + restore-keys: | + composer-${{ env.PHP_VERSION }}-${{ github.ref }} + composer-${{ env.PHP_VERSION }}- + - run: | + composer install --no-interaction --no-scripts --no-progress --no-suggest + composer show + - run: vendor/bin/phpunit diff --git a/.gitignore b/.gitignore index f7015c3..b01b535 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ vendor/ -.idea/ composer.lock +phpunit.xml$ +.php_cs.cache diff --git a/.php_cs.dist b/.php_cs.dist new file mode 100644 index 0000000..e1d792e --- /dev/null +++ b/.php_cs.dist @@ -0,0 +1,19 @@ +setRules([ + '@Symfony' => true, + '@Symfony:risky' => true, + 'array_syntax' => array('syntax' => 'short'), + 'no_unreachable_default_argument_value' => false, + 'braces' => array('allow_single_line_closure' => true), + 'heredoc_to_nowdoc' => false, + 'phpdoc_annotation_without_dot' => false, + ]) + ->setRiskyAllowed(true) + ->setFinder( + PhpCsFixer\Finder::create() + ->in(__DIR__) + ->notPath('vendor/') + ) +; diff --git a/.scrutinizer.yml b/.scrutinizer.yml deleted file mode 100644 index fc0c727..0000000 --- a/.scrutinizer.yml +++ /dev/null @@ -1,17 +0,0 @@ -build: - environment: - php: '7.2' - timezone: 'Europe/Berlin' - postgresql: false - node: false - redis: false - variables: - COMPOSER_MEMORY_LIMIT: "-1" - - tests: - override: - - - command: 'vendor/bin/phpunit --coverage-clover=clover.xml' - coverage: - file: 'clover.xml' - format: 'clover' diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 425c217..0000000 --- a/.travis.yml +++ /dev/null @@ -1,30 +0,0 @@ -language: php - -sudo: false - -cache: - directories: - - $HOME/.composer/cache - -php: - - '7.2' - -env: - global: - - DEPS=no - - SYMFONY_VERSION=no - matrix: - - SYMFONY_VERSION="2.8.*" - - SYMFONY_VERSION="3.4.*" - - DEPS=no - -before_script: - - composer self-update - - if [[ $SYMFONY_VERSION != no ]]; then composer require --no-update symfony/symfony:${SYMFONY_VERSION}; fi - - if [[ $DEPS = low ]]; then composer update --no-interaction --prefer-lowest; fi - - composer install --no-interaction - - mkdir -p build/logs - -script: - - composer validate --strict - - vendor/bin/phpunit --coverage-clover build/logs/clover.xml diff --git a/README.md b/README.md index db909d1..095faf8 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,7 @@ # ![webfactory Logo](https://www.webfactory.de/bundles/webfactorytwiglayout/img/logo.png) WebfactoryPolyglotBundle -[![Build Status](https://scrutinizer-ci.com/g/webfactory/WebfactoryPolyglotBundle/badges/build.png?b=master)](https://scrutinizer-ci.com/g/webfactory/WebfactoryPolyglotBundle/build-status/master) -[![Code Coverage](https://scrutinizer-ci.com/g/webfactory/WebfactoryPolyglotBundle/badges/coverage.png?b=master)](https://scrutinizer-ci.com/g/webfactory/WebfactoryPolyglotBundle/?branch=master) -[![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/webfactory/WebfactoryPolyglotBundle/badges/quality-score.png?b=master)](https://scrutinizer-ci.com/g/webfactory/WebfactoryPolyglotBundle/?branch=master) +![Tests](https://github.com/webfactory/WebfactoryPolyglotBundle/workflows/Tests/badge.svg) +![Dependencies](https://github.com/webfactory/WebfactoryPolyglotBundle/workflows/Dependencies/badge.svg) A bundle to simplify translations for Doctrine entities. @@ -263,7 +262,7 @@ this information in an attribute. This would allow each record to have its own p ## Credits, Copyright and License -Copyright 2012-2017 webfactory GmbH, Bonn. Code released under [the MIT license](LICENSE). +This Bundle was written by webfactory GmbH, Bonn, Germany. We're a software development agency with a focus on PHP (mostly [Symfony](http://github.com/symfony/symfony)). If you're a developer looking for new challenges, we'd like to hear from you! - - diff --git a/composer.json b/composer.json index b84291d..419f694 100644 --- a/composer.json +++ b/composer.json @@ -13,12 +13,19 @@ ], "autoload": { - "psr-0": { "Webfactory\\Bundle\\PolyglotBundle": "src" } + "psr-4": { "Webfactory\\Bundle\\PolyglotBundle\\": "src" } + }, + "autoload-dev": { + "psr-4": { "Webfactory\\Bundle\\PolyglotBundle\\Tests\\": "tests" } }, "require": { + "php": "^7.2", + "doctrine/annotations": "^1.11", + "doctrine/collections": "^1.0", + "doctrine/persistence": "^1.3.8", "doctrine/orm": "~2.2", - "php": "^5.5|^7.0", + "psr/log": "^1.0", "symfony/config": "^2.0|^3.0|^4.0", "symfony/dependency-injection": "^2.0|^3.0|^4.0", "symfony/event-dispatcher": "^2.0|^3.0|^4.0", @@ -27,9 +34,9 @@ "require-dev": { "phpunit/phpunit": "^5.7", - "symfony/debug": "^2.8|^3.0|^4.0", - "symfony/phpunit-bridge": "dev-master", - "webfactory/doctrine-orm-test-infrastructure": "~1.0" + "symfony/error-handler": "^4.4", + "symfony/phpunit-bridge": "*", + "webfactory/doctrine-orm-test-infrastructure": "^1.9" }, "config": { diff --git a/phpunit.xml.dist b/phpunit.xml.dist index 70441df..7873ca0 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -1,24 +1,21 @@ - src/Webfactory/Bundle/PolyglotBundle/Tests + tests - src/ + src - src/*/*Bundle/Resources - src/*/*Bundle/Tests - src/*/Bundle/*Bundle/Resources - src/*/Bundle/*Bundle/Tests + src/Resources diff --git a/src/Webfactory/Bundle/PolyglotBundle/Annotation/Locale.php b/src/Annotation/Locale.php similarity index 100% rename from src/Webfactory/Bundle/PolyglotBundle/Annotation/Locale.php rename to src/Annotation/Locale.php diff --git a/src/Webfactory/Bundle/PolyglotBundle/Annotation/Translatable.php b/src/Annotation/Translatable.php similarity index 100% rename from src/Webfactory/Bundle/PolyglotBundle/Annotation/Translatable.php rename to src/Annotation/Translatable.php diff --git a/src/Webfactory/Bundle/PolyglotBundle/Annotation/TranslationCollection.php b/src/Annotation/TranslationCollection.php similarity index 100% rename from src/Webfactory/Bundle/PolyglotBundle/Annotation/TranslationCollection.php rename to src/Annotation/TranslationCollection.php diff --git a/src/Webfactory/Bundle/PolyglotBundle/DependencyInjection/WebfactoryPolyglotExtension.php b/src/DependencyInjection/WebfactoryPolyglotExtension.php similarity index 91% rename from src/Webfactory/Bundle/PolyglotBundle/DependencyInjection/WebfactoryPolyglotExtension.php rename to src/DependencyInjection/WebfactoryPolyglotExtension.php index 6fa99f6..11ef275 100644 --- a/src/Webfactory/Bundle/PolyglotBundle/DependencyInjection/WebfactoryPolyglotExtension.php +++ b/src/DependencyInjection/WebfactoryPolyglotExtension.php @@ -9,19 +9,19 @@ namespace Webfactory\Bundle\PolyglotBundle\DependencyInjection; -use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\Config\FileLocator; -use Symfony\Component\HttpKernel\DependencyInjection\Extension; +use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\DependencyInjection\Loader\XmlFileLoader; +use Symfony\Component\HttpKernel\DependencyInjection\Extension; class WebfactoryPolyglotExtension extends Extension { public function load(array $configs, ContainerBuilder $container) { - $loader = new XmlFileLoader($container, new FileLocator(__DIR__ . '/../Resources/config')); + $loader = new XmlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config')); $loader->load('services.xml'); - $m = array("defaultLocale" => "de_DE"); + $m = ['defaultLocale' => 'de_DE']; foreach ($configs as $c) { $m = array_merge($m, $c); } diff --git a/src/Webfactory/Bundle/PolyglotBundle/Doctrine/PersistentTranslatable.php b/src/Doctrine/PersistentTranslatable.php similarity index 78% rename from src/Webfactory/Bundle/PolyglotBundle/Doctrine/PersistentTranslatable.php rename to src/Doctrine/PersistentTranslatable.php index 2aa4cc3..a015646 100644 --- a/src/Webfactory/Bundle/PolyglotBundle/Doctrine/PersistentTranslatable.php +++ b/src/Doctrine/PersistentTranslatable.php @@ -9,15 +9,14 @@ namespace Webfactory\Bundle\PolyglotBundle\Doctrine; -use \Doctrine\Common\Collections\Criteria; +use Doctrine\Common\Collections\Criteria; use Psr\Log\LoggerInterface; use Psr\Log\NullLogger; -use \ReflectionProperty; -use \ReflectionClass; +use ReflectionClass; +use ReflectionProperty; use Webfactory\Bundle\PolyglotBundle\Exception\TranslationException; -use Webfactory\Bundle\PolyglotBundle\Translatable; -use Webfactory\Bundle\PolyglotBundle\TranslatableInterface; use Webfactory\Bundle\PolyglotBundle\Locale\DefaultLocaleProvider; +use Webfactory\Bundle\PolyglotBundle\TranslatableInterface; /** * Eine TranslationProxy-Implementierung für eine Entität, die @@ -26,19 +25,22 @@ class PersistentTranslatable implements TranslatableInterface { /** - * @var array> Cache für die Übersetzungen, indiziert nach Entity-OID und Locale. - * Ist static, damit ihn sich verschiedene Proxies (für die gleiche Entität, aber - * unterschiedliche Felder) teilen können. + * Cache für die Übersetzungen, indiziert nach Entity-OID und Locale. Ist static, damit ihn sich verschiedene Proxies (für die gleiche Entität, aber unterschiedliche Felder) teilen können. + * + * @var array> */ - static protected $_translations = array(); + protected static $_translations = []; /** - * @var object Die Entität, in der sich dieser Proxy befindet (für die er Übersetzungen verwaltet). + * Die Entität, in der sich dieser Proxy befindet (für die er Übersetzungen verwaltet). + * + * @var object */ protected $entity; /** * Der einzigartige Hash für die verwaltete Entität. + * * @var string */ protected $oid; @@ -54,35 +56,44 @@ class PersistentTranslatable implements TranslatableInterface protected $primaryValue = null; /** - * @var DefaultLocaleProvider Provider, über den der Proxy die Locale erhält, in der Werte zurückgeben soll, wenn - * keine andere Locale explizit gewünscht wird + * Provider, über den der Proxy die Locale erhält, in der Werte zurückgeben soll, wenn keine andere Locale explizit gewünscht wird. + * + * @var DefaultLocaleProvider */ protected $defaultLocaleProvider; /** - * @var ReflectionProperty ReflectionProperty für die Eigenschaft der Translation-Klasse, die den übersetzten Wert - * hält + * ReflectionProperty für die Eigenschaft der Translation-Klasse, die den übersetzten Wert hält. + * + * @var ReflectionProperty */ protected $translatedProperty; /** - * @var ReflectionProperty ReflectionProperty für die Eigenschaft der Haupt-Klasse, in der die Übersetzungen als - * Doctrine Collection abgelegt sind. + * ReflectionProperty für die Eigenschaft der Haupt-Klasse, in der die Übersetzungen als Doctrine Collection abgelegt sind. + * + * @var ReflectionProperty */ protected $translationCollection; /** - * @var ReflectionClass ReflectionClass für die Klasse, die die Übersetzungen aufnimmt. + * ReflectionClass für die Klasse, die die Übersetzungen aufnimmt. + * + * @var ReflectionClass */ protected $translationClass; /** - * @var ReflectionProperty Das Feld in der Übersetzungs-Klasse, in dem die Locale einer Übersetzung abgelegt ist. + * Das Feld in der Übersetzungs-Klasse, in dem die Locale einer Übersetzung abgelegt ist. + * + * @var ReflectionProperty */ protected $localeField; /** - * @var ReflectionProperty Das Feld in der Übersetzungs-Klasse, in Many-to-one-Beziehung zur Entität abgelegt ist. + * Das Feld in der Übersetzungs-Klasse, in Many-to-one-Beziehung zur Entität abgelegt ist. + * + * @var ReflectionProperty */ protected $translationMapping; @@ -98,19 +109,11 @@ class PersistentTranslatable implements TranslatableInterface private $addedTranslations = []; /** - * @param object $entity - * @param string $primaryLocale - * @param DefaultLocaleProvider $defaultLocaleProvider - * @param ReflectionProperty $translatedProperty - * @param ReflectionProperty $translationCollection - * @param ReflectionClass $translationClass - * @param ReflectionProperty $localeField - * @param ReflectionProperty $translationMapping * @param LoggerInterface $logger */ public function __construct( - $entity, - $primaryLocale, + object $entity, + string $primaryLocale, DefaultLocaleProvider $defaultLocaleProvider, ReflectionProperty $translatedProperty, ReflectionProperty $translationCollection, @@ -118,8 +121,7 @@ public function __construct( ReflectionProperty $localeField, ReflectionProperty $translationMapping, LoggerInterface $logger = null - ) - { + ) { $this->entity = $entity; $this->oid = spl_object_hash($entity); $this->primaryLocale = $primaryLocale; @@ -129,7 +131,7 @@ public function __construct( $this->translationClass = $translationClass; $this->localeField = $localeField; $this->translationMapping = $translationMapping; - $this->logger = ($logger == null) ? new NullLogger() : $logger; + $this->logger = (null == $logger) ? new NullLogger() : $logger; } public function setPrimaryValue($value) @@ -144,11 +146,12 @@ public function getPrimaryValue() /** * @param string $locale + * * @return object|null */ protected function getTranslationEntity($locale) { - if ($this->isTranslationCached($locale) === false) { + if (false === $this->isTranslationCached($locale)) { $this->cacheTranslation($locale); } @@ -157,6 +160,7 @@ protected function getTranslationEntity($locale) /** * @param string $locale + * * @return object */ protected function createTranslationEntity($locale) @@ -176,7 +180,7 @@ protected function createTranslationEntity($locale) } /** - * @param string $value + * @param string $value * @param string|null $locale */ public function setTranslation($value, $locale = null) @@ -195,7 +199,9 @@ public function setTranslation($value, $locale = null) /** * @param string|null $locale + * * @return mixed|string + * * @throws TranslationException */ public function translate($locale = null) @@ -212,11 +218,12 @@ public function translate($locale = null) return $translated; } } + return $this->primaryValue; } catch (\Exception $e) { $message = sprintf( 'Cannot translate property %s::%s into locale %s', - get_class($this->entity), + \get_class($this->entity), $this->translatedProperty->getName(), $locale ); @@ -231,7 +238,8 @@ public function isTranslatedInto($locale) } $entity = $this->getTranslationEntity($locale); - return $entity && $this->translatedProperty->getValue($entity) !== null; + + return $entity && null !== $this->translatedProperty->getValue($entity); } /** @@ -240,9 +248,10 @@ public function isTranslatedInto($locale) public function __toString() { try { - return (string)$this->translate(); + return (string) $this->translate(); } catch (\Exception $e) { $this->logger->error($this->stringifyException($e)); + return ''; } } @@ -270,6 +279,7 @@ protected function getDefaultLocale() /** * @param string $locale + * * @return bool */ protected function isTranslationCached($locale) @@ -298,6 +308,7 @@ protected function cacheTranslation($locale) /** * @param $locale + * * @return Criteria */ protected function createLocaleCriteria($locale) @@ -310,6 +321,7 @@ protected function createLocaleCriteria($locale) /** * @param string $locale + * * @return object|null */ protected function getCachedTranslation($locale) @@ -318,19 +330,18 @@ protected function getCachedTranslation($locale) } /** - * @param \Exception $e * @return string */ private function stringifyException(\Exception $e) { $exceptionAsString = ''; - while ($e !== null) { + while (null !== $e) { if (!empty($exceptionAsString)) { - $exceptionAsString .= PHP_EOL . 'Previous exception: ' . PHP_EOL; + $exceptionAsString .= PHP_EOL.'Previous exception: '.PHP_EOL; } $exceptionAsString .= sprintf( "Exception '%s' with message '%s' in %s:%d\n%s", - get_class($e), + \get_class($e), $e->getMessage(), $e->getFile(), $e->getLine(), @@ -338,6 +349,7 @@ private function stringifyException(\Exception $e) ); $e = $e->getPrevious(); } + return $exceptionAsString; } } diff --git a/src/Webfactory/Bundle/PolyglotBundle/Doctrine/PolyglotListener.php b/src/Doctrine/PolyglotListener.php similarity index 88% rename from src/Webfactory/Bundle/PolyglotBundle/Doctrine/PolyglotListener.php rename to src/Doctrine/PolyglotListener.php index b301180..bd9be92 100644 --- a/src/Webfactory/Bundle/PolyglotBundle/Doctrine/PolyglotListener.php +++ b/src/Doctrine/PolyglotListener.php @@ -9,11 +9,11 @@ namespace Webfactory\Bundle\PolyglotBundle\Doctrine; -use Doctrine\ORM\Event\LifecycleEventArgs; -use Doctrine\ORM\Event\PreFlushEventArgs; -use Doctrine\ORM\Event\PostFlushEventArgs; use Doctrine\Common\Annotations\Reader; use Doctrine\ORM\EntityManager; +use Doctrine\ORM\Event\LifecycleEventArgs; +use Doctrine\ORM\Event\PostFlushEventArgs; +use Doctrine\ORM\Event\PreFlushEventArgs; use Doctrine\ORM\Mapping\ClassMetadataInfo; use Psr\Log\LoggerInterface; use Webfactory\Bundle\PolyglotBundle\Locale\DefaultLocaleProvider; @@ -23,30 +23,26 @@ class PolyglotListener const CACHE_SALT = '$WebfactoryPolyglot'; protected $reader; - protected $translatedClasses = array(); - protected $_proxiesStripped = array(); + protected $translatedClasses = []; + protected $_proxiesStripped = []; protected $defaultLocaleProvider; /** @var \SplObjectStorage */ private $entitiesWithTranslations; /** - * @var null|LoggerInterface + * @var LoggerInterface|null */ protected $logger; /** * PolyglotListener constructor. - * @param Reader $annotationReader - * @param DefaultLocaleProvider $defaultLocaleProvider - * @param LoggerInterface|null $logger */ public function __construct( Reader $annotationReader, DefaultLocaleProvider $defaultLocaleProvider, LoggerInterface $logger = null - ) - { + ) { $this->reader = $annotationReader; $this->defaultLocaleProvider = $defaultLocaleProvider; $this->logger = $logger; @@ -101,7 +97,7 @@ protected function getTranslationMetadataForLifecycleEvent(LifecycleEventArgs $e $entity = $event->getEntity(); $em = $event->getEntityManager(); - $className = get_class($entity); + $className = \get_class($entity); return $this->getTranslationMetadata($className, $em); } @@ -119,11 +115,10 @@ protected function getTranslationMetadata($className, EntityManager $em) // Cache driver available and in cache if ($cacheDriver) { - - if (($cached = $cacheDriver->fetch($className . self::CACHE_SALT)) !== false) { + if (($cached = $cacheDriver->fetch($className.self::CACHE_SALT)) !== false) { $this->translatedClasses[$className] = $cached; if ($cached) { // evtl. ist im Cache gespeichert, das die Klasse *nicht* übersetzt ist - /** @var $cached TranslatableClassMetadata */ + /* @var $cached TranslatableClassMetadata */ $cached->wakeupReflection($reflectionService); $cached->setLogger($this->logger); } @@ -136,14 +131,14 @@ protected function getTranslationMetadata($className, EntityManager $em) /* @var $metadataInfo ClassMetadataInfo */ $metadataInfo = $metadataFactory->getMetadataFor($className); $meta = TranslatableClassMetadata::parseFromClassMetadata($metadataInfo, $this->reader); - if ($meta !== null) { + if (null !== $meta) { $meta->setLogger($this->logger); $this->translatedClasses[$className] = $meta; } // Save if cache driver available if ($cacheDriver) { - $cacheDriver->save($className . self::CACHE_SALT, $meta); + $cacheDriver->save($className.self::CACHE_SALT, $meta ? $meta->prepareSleepInstance() : null); } return $meta; diff --git a/src/Webfactory/Bundle/PolyglotBundle/Doctrine/TranslatableClassMetadata.php b/src/Doctrine/TranslatableClassMetadata.php similarity index 59% rename from src/Webfactory/Bundle/PolyglotBundle/Doctrine/TranslatableClassMetadata.php rename to src/Doctrine/TranslatableClassMetadata.php index b4f2dea..36092b6 100644 --- a/src/Webfactory/Bundle/PolyglotBundle/Doctrine/TranslatableClassMetadata.php +++ b/src/Doctrine/TranslatableClassMetadata.php @@ -10,11 +10,13 @@ namespace Webfactory\Bundle\PolyglotBundle\Doctrine; use Doctrine\Common\Annotations\Reader; -use Doctrine\Common\Persistence\Mapping\ClassMetadata; -use Doctrine\Common\Persistence\Mapping\ReflectionService; +use Doctrine\Common\Collections\Collection; use Doctrine\ORM\EntityManager; use Doctrine\ORM\Mapping\ClassMetadataInfo; +use Doctrine\Persistence\Mapping\ClassMetadata; +use Doctrine\Persistence\Mapping\ReflectionService; use Psr\Log\LoggerInterface; +use Webfactory\Bundle\PolyglotBundle\Annotation as Annotation; use Webfactory\Bundle\PolyglotBundle\Locale\DefaultLocaleProvider; use Webfactory\Bundle\PolyglotBundle\Translatable; @@ -27,30 +29,38 @@ class TranslatableClassMetadata { /** - * @var \ReflectionProperty[] Ein Mapping von Feldnamen in der Hauptklasse auf die Felder in der + * Ein Mapping von Feldnamen in der Hauptklasse auf die Felder in der * Übersetzungs-Klasse, in denen die jeweilige Übersetzung liegt. + * + * @var \ReflectionProperty[] */ - protected $translationFieldMapping = array(); + protected $translationFieldMapping = []; /** - * @var \ReflectionProperty[] Die Eigenschaften der Haupt-Klasse, die übersetzbar sind; indiziert nach Feldnamen. + * Die Eigenschaften der Haupt-Klasse, die übersetzbar sind; indiziert nach Feldnamen. + * + * @var \ReflectionProperty[] */ - protected $translatedProperties = array(); + protected $translatedProperties = []; /** - * @var \ReflectionProperty Die Eigenschaft der Haupt-Klasse, die die Collection der Übersetzungen hält. + * Die Eigenschaft der Haupt-Klasse, die die Collection der Übersetzungen hält. + * + * @var \ReflectionProperty */ protected $translationsCollectionProperty; /** - * @var \ReflectionProperty Die Eigenschaft der Übersetzungs-Klasse, die als many-to-one auf die Haupt-Klasse - * verweist. + * Die Eigenschaft der Übersetzungs-Klasse, die als many-to-one auf die Haupt-Klasse verweist. + * + * @var \ReflectionProperty */ protected $translationMappingProperty; /** - * @var \ReflectionProperty Die Eigenschaft in der Übersetzungs-Klasse, die die Sprache einer Übersetzungsinstanz - * enhtält. + * Die Eigenschaft in der Übersetzungs-Klasse, die die Sprache einer Übersetzungsinstanz enhtält. + * + * @var \ReflectionProperty */ protected $translationLocaleProperty; @@ -69,10 +79,8 @@ class TranslatableClassMetadata */ protected $logger = null; - - public static function parseFromClassMetadata(ClassMetadataInfo $cm, Reader $reader) + public static function parseFromClassMetadata(ClassMetadataInfo $cm, Reader $reader): ?self { - /* @var $tm TranslatableClassMetadata */ $tm = new static(); $tm->findPrimaryLocale($reader, $cm); $tm->findTranslationsCollection($reader, $cm); @@ -86,87 +94,72 @@ public static function parseFromClassMetadata(ClassMetadataInfo $cm, Reader $rea return $tm; } - /** - * @param LoggerInterface|null $logger - */ - public function setLogger(LoggerInterface $logger = null) + public function setLogger(LoggerInterface $logger = null): void { $this->logger = $logger; } - /** - * serialize() checks if your class has a function with the magic name __sleep. - * If so, that function is executed prior to any serialization. - * It can clean up the object and is supposed to return an array with the names of all variables of that object that should be serialized. - * If the method doesn't return anything then NULL is serialized and E_NOTICE is issued. - * The intended use of __sleep is to commit pending data or perform similar cleanup tasks. - * Also, the function is useful if you have very large objects which do not need to be saved completely. - * - * @return array|NULL - * @link http://php.net/manual/en/language.oop5.magic.php#language.oop5.magic.sleep - */ - function __sleep() + public function prepareSleepInstance(): self { - $properties = array_keys(get_object_vars($this)); - $notSerializableProperties = array('logger'); - return array_diff($properties, $notSerializableProperties); - } + $sleep = clone $this; + $sleep->logger = null; + $sleep->translationClass = $this->translationClass->name; - protected function resurrect(\ReflectionProperty $property, ReflectionService $reflectionService) - { - return $reflectionService->getAccessibleProperty($property->class, $property->name); + foreach ($sleep->translationFieldMapping as $fieldname => $property) { + $sleep->translationFieldMapping[$fieldname] = [$property->class, $property->name]; + } + + foreach ($sleep->translatedProperties as $fieldname => $property) { + $sleep->translatedProperties[$fieldname] = [$property->class, $property->name]; + } + + $sleep->translationLocaleProperty = [$sleep->translationLocaleProperty->class, $sleep->translationLocaleProperty->name]; + $sleep->translationsCollectionProperty = [$sleep->translationsCollectionProperty->class, $sleep->translationsCollectionProperty->name]; + $sleep->translationMappingProperty = [$sleep->translationMappingProperty->class, $sleep->translationMappingProperty->name]; + + return $sleep; } public function wakeupReflection(ReflectionService $reflectionService) { + $this->translationClass = $reflectionService->getClass($this->translationClass); + foreach ($this->translationFieldMapping as $fieldname => $property) { - $this->translationFieldMapping[$fieldname] = $this->resurrect($property, $reflectionService); + $this->translationFieldMapping[$fieldname] = \call_user_func_array([$reflectionService, 'getAccessibleProperty'], $property); } foreach ($this->translatedProperties as $fieldname => $property) { - $this->translatedProperties[$fieldname] = $this->resurrect($property, $reflectionService); + $this->translatedProperties[$fieldname] = \call_user_func_array([$reflectionService, 'getAccessibleProperty'], $property); } - $this->translationsCollectionProperty = $this->resurrect( - $this->translationsCollectionProperty, - $reflectionService - ); - $this->translationMappingProperty = $this->resurrect($this->translationMappingProperty, $reflectionService); - $this->translationLocaleProperty = $this->resurrect($this->translationLocaleProperty, $reflectionService); + $this->translationsCollectionProperty = \call_user_func_array([$reflectionService, 'getAccessibleProperty'], $this->translationsCollectionProperty); + $this->translationMappingProperty = \call_user_func_array([$reflectionService, 'getAccessibleProperty'], $this->translationMappingProperty); + $this->translationLocaleProperty = \call_user_func_array([$reflectionService, 'getAccessibleProperty'], $this->translationLocaleProperty); } protected function assertNoAnnotationsArePresent() { - return $this->translationClass === null - && $this->translationLocaleProperty === null - && $this->translationMappingProperty === null - && count($this->translatedProperties) === 0; + return null === $this->translationClass + && null === $this->translationLocaleProperty + && null === $this->translationMappingProperty + && 0 === \count($this->translatedProperties); } protected function assertAnnotationsAreComplete() { - if ($this->translationClass === null) { - throw new \RuntimeException( - 'The annotation with the translation class name is missing or incorrect, e.g. ' - . '@ORM\OneToMany(targetEntity="TestEntityTranslation", ...)' - ); + if (null === $this->translationClass) { + throw new \RuntimeException('The annotation with the translation class name is missing or incorrect, e.g. '.'@ORM\OneToMany(targetEntity="TestEntityTranslation", ...)'); } - if ($this->translationLocaleProperty === null) { - throw new \RuntimeException( - 'The @Polyglot\Locale annotation at the language property of the translation class is missing or ' - . 'incorrect' - ); + if (null === $this->translationLocaleProperty) { + throw new \RuntimeException('The @Polyglot\Locale annotation at the language property of the translation class is missing or '.'incorrect'); } - if ($this->translationMappingProperty === null) { - throw new \RuntimeException( - 'The attribute referenced in the mappedBy-Attribute of the @ORM\OneToMany(..., mappedBy="...") is ' - . 'missing or incorrect' - ); + if (null === $this->translationMappingProperty) { + throw new \RuntimeException('The attribute referenced in the mappedBy-Attribute of the @ORM\OneToMany(..., mappedBy="...") is '.'missing or incorrect'); } - if (count($this->translatedProperties) === 0) { + if (0 === \count($this->translatedProperties)) { throw new \RuntimeException('No translatable attributes annotated with @Polyglot\Translatable were found'); } } @@ -177,15 +170,15 @@ protected function findTranslatedProperties(Reader $reader, ClassMetadata $class foreach ($classMetadata->getReflectionClass()->getProperties() as $property) { $annotation = $reader->getPropertyAnnotation( $property, - 'Webfactory\Bundle\PolyglotBundle\Annotation\Translatable' + Annotation\Translatable::class ); - if ($annotation !== null) { + if (null !== $annotation) { $fieldname = $property->getName(); $property->setAccessible(true); $this->translatedProperties[$fieldname] = $property; - $translationFieldname = $annotation->getTranslationFieldname() ? : $fieldname; + $translationFieldname = $annotation->getTranslationFieldname() ?: $fieldname; $translationField = $this->translationClass->getProperty($translationFieldname); $translationField->setAccessible(true); $this->translationFieldMapping[$fieldname] = $translationField; @@ -199,9 +192,9 @@ protected function findTranslationsCollection(Reader $reader, ClassMetadataInfo foreach ($classMetadata->getReflectionClass()->getProperties() as $property) { $annotation = $reader->getPropertyAnnotation( $property, - 'Webfactory\Bundle\PolyglotBundle\Annotation\TranslationCollection' + Annotation\TranslationCollection::class ); - if ($annotation !== null) { + if (null !== $annotation) { $property->setAccessible(true); $this->translationsCollectionProperty = $property; $am = $classMetadata->getAssociationMapping($property->getName()); @@ -219,9 +212,9 @@ protected function findPrimaryLocale(Reader $reader, ClassMetadata $classMetadat { $annotation = $reader->getClassAnnotation( $classMetadata->getReflectionClass(), - 'Webfactory\Bundle\PolyglotBundle\Annotation\Locale' + Annotation\Locale::class ); - if ($annotation !== null) { + if (null !== $annotation) { $this->primaryLocale = $annotation->getPrimary(); } } @@ -233,9 +226,9 @@ protected function parseTranslationsEntity(Reader $reader, $class) foreach ($this->translationClass->getProperties() as $property) { $annotation = $reader->getPropertyAnnotation( $property, - 'Webfactory\Bundle\PolyglotBundle\Annotation\Locale' + Annotation\Locale::class ); - if ($annotation !== null) { + if (null !== $annotation) { $property->setAccessible(true); $this->translationLocaleProperty = $property; } @@ -268,11 +261,8 @@ public function injectProxies($entity, DefaultLocaleProvider $defaultLocaleProvi /** * For a given entity, find all @Translatable fields that contain new (not yet persisted) * Translatable objects and replace those with PersistentTranslatable. - * - * @param object $entity - * @param DefaultLocaleProvider $defaultLocaleProvider */ - public function manageTranslations($entity, DefaultLocaleProvider $defaultLocaleProvider) + public function manageTranslations(object $entity, DefaultLocaleProvider $defaultLocaleProvider) { foreach ($this->translatedProperties as $fieldname => $property) { $translatableValue = $property->getValue($entity); @@ -285,13 +275,12 @@ public function manageTranslations($entity, DefaultLocaleProvider $defaultLocale } } - public function getTranslations($entity) + public function getTranslations($entity): Collection { - $translations = $this->translationsCollectionProperty->getValue($entity); - return $translations; + return $this->translationsCollectionProperty->getValue($entity); } - protected function createProxy($entity, $fieldname, DefaultLocaleProvider $defaultLocaleProvider) + protected function createProxy($entity, $fieldname, DefaultLocaleProvider $defaultLocaleProvider): PersistentTranslatable { return new PersistentTranslatable( $entity, diff --git a/src/Webfactory/Bundle/PolyglotBundle/Entity/BaseTranslation.php b/src/Entity/BaseTranslation.php similarity index 100% rename from src/Webfactory/Bundle/PolyglotBundle/Entity/BaseTranslation.php rename to src/Entity/BaseTranslation.php index 6675df9..a4764ee 100644 --- a/src/Webfactory/Bundle/PolyglotBundle/Entity/BaseTranslation.php +++ b/src/Entity/BaseTranslation.php @@ -9,8 +9,8 @@ namespace Webfactory\Bundle\PolyglotBundle\Entity; -use Webfactory\Bundle\PolyglotBundle\Annotation as Polyglot; use Doctrine\ORM\Mapping as ORM; +use Webfactory\Bundle\PolyglotBundle\Annotation as Polyglot; /** * @ORM\MappedSuperclass diff --git a/src/Webfactory/Bundle/PolyglotBundle/EventListener/LocaleListener.php b/src/EventListener/LocaleListener.php similarity index 92% rename from src/Webfactory/Bundle/PolyglotBundle/EventListener/LocaleListener.php rename to src/EventListener/LocaleListener.php index 6c74b95..f4e87f2 100644 --- a/src/Webfactory/Bundle/PolyglotBundle/EventListener/LocaleListener.php +++ b/src/EventListener/LocaleListener.php @@ -33,8 +33,6 @@ public function __construct(DefaultLocaleProvider $defaultLocaleProvider) * Set the translation listener locale from the request. * * This method should be attached to the kernel.request event. - * - * @param \Symfony\Component\HttpKernel\Event\GetResponseEvent $event */ public function onKernelRequest(GetResponseEvent $event) { @@ -43,8 +41,8 @@ public function onKernelRequest(GetResponseEvent $event) public static function getSubscribedEvents() { - return array( + return [ KernelEvents::REQUEST => 'onKernelRequest', - ); + ]; } } diff --git a/src/Webfactory/Bundle/PolyglotBundle/Exception/TranslationException.php b/src/Exception/TranslationException.php similarity index 89% rename from src/Webfactory/Bundle/PolyglotBundle/Exception/TranslationException.php rename to src/Exception/TranslationException.php index 777bfc7..840f300 100644 --- a/src/Webfactory/Bundle/PolyglotBundle/Exception/TranslationException.php +++ b/src/Exception/TranslationException.php @@ -2,16 +2,15 @@ namespace Webfactory\Bundle\PolyglotBundle\Exception; - class TranslationException extends \Exception { /** * TranslationException constructor. + * * @param string $message - * @param \Exception $previous */ public function __construct($message, \Exception $previous) { parent::__construct($message, 0, $previous); } -} \ No newline at end of file +} diff --git a/src/Webfactory/Bundle/PolyglotBundle/Locale/DefaultLocaleProvider.php b/src/Locale/DefaultLocaleProvider.php similarity index 100% rename from src/Webfactory/Bundle/PolyglotBundle/Locale/DefaultLocaleProvider.php rename to src/Locale/DefaultLocaleProvider.php diff --git a/src/Webfactory/Bundle/PolyglotBundle/Resources/config/services.xml b/src/Resources/config/services.xml similarity index 100% rename from src/Webfactory/Bundle/PolyglotBundle/Resources/config/services.xml rename to src/Resources/config/services.xml diff --git a/src/Webfactory/Bundle/PolyglotBundle/Translatable.php b/src/Translatable.php similarity index 87% rename from src/Webfactory/Bundle/PolyglotBundle/Translatable.php rename to src/Translatable.php index b6ce0a1..2eb56c5 100644 --- a/src/Webfactory/Bundle/PolyglotBundle/Translatable.php +++ b/src/Translatable.php @@ -8,6 +8,7 @@ */ namespace Webfactory\Bundle\PolyglotBundle; + use Webfactory\Bundle\PolyglotBundle\Locale\DefaultLocaleProvider; /** @@ -48,15 +49,15 @@ class Translatable implements TranslatableInterface * * @var array */ - protected $translations = array(); + protected $translations = []; /** - * @param string|null $value + * @param string|null $value * @param string|DefaultLocaleProvider|null $defaultLocale */ public function __construct($value = null, $defaultLocale = null) { - if ($defaultLocale !== null && !is_string($defaultLocale) && !$defaultLocale instanceof DefaultLocaleProvider) { + if (null !== $defaultLocale && !\is_string($defaultLocale) && !$defaultLocale instanceof DefaultLocaleProvider) { throw new \InvalidArgumentException('When provided, the $defaultLocale argument must either be a string or an instance of DefaultLocaleProvider'); } @@ -73,7 +74,7 @@ public function setDefaultLocale($locale) $this->defaultLocale = $locale; $newLocale = $this->getDefaultLocale(); - if ($oldLocale == '' && $newLocale != '') { + if ('' == $oldLocale && '' != $newLocale) { $this->translations[$newLocale] = $this->translations[$oldLocale]; unset($this->translations[$oldLocale]); } @@ -82,11 +83,12 @@ public function setDefaultLocale($locale) /** * @param string|null $locale + * * @return string|null */ public function translate($locale = null) { - $locale = $locale ? : $this->getDefaultLocale(); + $locale = $locale ?: $this->getDefaultLocale(); if (isset($this->translations[$locale])) { return $this->translations[$locale]; @@ -96,12 +98,12 @@ public function translate($locale = null) } /** - * @param string $value + * @param string $value * @param string|null $locale */ public function setTranslation($value, $locale = null) { - $locale = $locale ? : $this->getDefaultLocale(); + $locale = $locale ?: $this->getDefaultLocale(); $this->translations[$locale] = $value; } @@ -121,13 +123,11 @@ public function __toString() /** * Copies translations from this object into the given one. - * - * @param TranslatableInterface $p */ public function copy(TranslatableInterface $p) { foreach ($this->translations as $locale => $value) { - $p->setTranslation($value, ($locale == '' ? null : $locale)); + $p->setTranslation($value, ('' == $locale ? null : $locale)); } } diff --git a/src/Webfactory/Bundle/PolyglotBundle/TranslatableInterface.php b/src/TranslatableInterface.php similarity index 96% rename from src/Webfactory/Bundle/PolyglotBundle/TranslatableInterface.php rename to src/TranslatableInterface.php index 8055d25..be06368 100644 --- a/src/Webfactory/Bundle/PolyglotBundle/TranslatableInterface.php +++ b/src/TranslatableInterface.php @@ -18,6 +18,7 @@ interface TranslatableInterface * Returns the translation for the given locale. * * @param string|null $locale The target locale or null for the current locale. + * * @return string|null The translation or null if not available. */ public function translate($locale = null); @@ -25,7 +26,7 @@ public function translate($locale = null); /** * Overwrites the translation for the given locale. * - * @param string $value + * @param string $value * @param string|null $locale The target locale or null for the current locale. */ public function setTranslation($value, $locale = null); @@ -34,6 +35,7 @@ public function setTranslation($value, $locale = null); * Returns wether the text is translated into the target locale. * * @param string $locale The target locale. + * * @return bool */ public function isTranslatedInto($locale); diff --git a/src/Webfactory/Bundle/PolyglotBundle/WebfactoryPolyglotBundle.php b/src/WebfactoryPolyglotBundle.php similarity index 100% rename from src/Webfactory/Bundle/PolyglotBundle/WebfactoryPolyglotBundle.php rename to src/WebfactoryPolyglotBundle.php diff --git a/src/Webfactory/Bundle/PolyglotBundle/Tests/Doctrine/PersistentTranslatableTest.php b/tests/Doctrine/PersistentTranslatableTest.php similarity index 93% rename from src/Webfactory/Bundle/PolyglotBundle/Tests/Doctrine/PersistentTranslatableTest.php rename to tests/Doctrine/PersistentTranslatableTest.php index cbae90c..18e87be 100644 --- a/src/Webfactory/Bundle/PolyglotBundle/Tests/Doctrine/PersistentTranslatableTest.php +++ b/tests/Doctrine/PersistentTranslatableTest.php @@ -4,14 +4,13 @@ use Psr\Log\LoggerInterface; use Psr\Log\NullLogger; -use Symfony\Component\Debug\BufferingLogger; +use Symfony\Component\ErrorHandler\BufferingLogger; use Webfactory\Bundle\PolyglotBundle\Doctrine\PersistentTranslatable; use Webfactory\Bundle\PolyglotBundle\Locale\DefaultLocaleProvider; use Webfactory\Bundle\PolyglotBundle\Tests\TestEntity; class PersistentTranslatableTest extends \PHPUnit_Framework_TestCase { - public function testToStringReturnsTranslatedMessage() { $entity = new TestEntity('foo'); @@ -21,7 +20,7 @@ public function testToStringReturnsTranslatedMessage() $proxy->setTranslation('bar', 'de'); $proxy->setTranslation('bar in en', 'en'); - $translation = (string)$proxy; + $translation = (string) $proxy; $this->assertEquals('bar', $translation); } @@ -31,7 +30,7 @@ public function testToStringReturnsStringIfExceptionOccurredAndNoLoggerIsAvailab $entity = new TestEntity('foo'); $proxy = $this->createProxy($entity); $this->breakEntity($entity); - $translation = (string)$proxy; + $translation = (string) $proxy; $this->assertInternalType('string', $translation); } @@ -41,7 +40,7 @@ public function testToStringReturnsStringIfExceptionOccurredAndLoggerIsAvailable $entity = new TestEntity('foo'); $proxy = $this->createProxy($entity, new NullLogger()); $this->breakEntity($entity); - $translation = (string)$proxy; + $translation = (string) $proxy; $this->assertInternalType('string', $translation); } @@ -56,7 +55,7 @@ public function testToStringLogsExceptionIfLoggerIsAvailable() $proxy->__toString(); - $this->assertGreaterThan(0, count($logger->cleanLogs()), 'Expected at least one log message'); + $this->assertGreaterThan(0, \count($logger->cleanLogs()), 'Expected at least one log message'); } public function testLoggedMessageContainsInformationAboutTranslatedProperty() @@ -143,9 +142,6 @@ public function isTranslatedInto_returns_false_if_translation_is_not_set() } /** - * @param TestEntity $entity - * @param LoggerInterface|null $logger - * * @return PersistentTranslatable */ private function createProxy(TestEntity $entity, LoggerInterface $logger = null) @@ -166,12 +162,10 @@ private function createProxy(TestEntity $entity, LoggerInterface $logger = null) $this->makeAccessible(new \ReflectionProperty($translationClass, 'entity')), $logger ); + return $proxy; } - /** - * @param TestEntity $entity - */ private function breakEntity(TestEntity $entity) { $brokenCollection = $this->getMockBuilder('Doctrine\Common\Collections\ArrayCollection')->getMock(); @@ -184,12 +178,12 @@ private function breakEntity(TestEntity $entity) } /** - * @param \ReflectionProperty $property * @return \ReflectionProperty */ private function makeAccessible(\ReflectionProperty $property) { $property->setAccessible(true); + return $property; } } diff --git a/src/Webfactory/Bundle/PolyglotBundle/Tests/Doctrine/TranslatableClassMetadataTest.php b/tests/Doctrine/TranslatableClassMetadataTest.php similarity index 50% rename from src/Webfactory/Bundle/PolyglotBundle/Tests/Doctrine/TranslatableClassMetadataTest.php rename to tests/Doctrine/TranslatableClassMetadataTest.php index 951a20d..325166f 100644 --- a/src/Webfactory/Bundle/PolyglotBundle/Tests/Doctrine/TranslatableClassMetadataTest.php +++ b/tests/Doctrine/TranslatableClassMetadataTest.php @@ -3,8 +3,8 @@ namespace Webfactory\Bundle\PolyglotBundle\Tests\Doctrine; use Doctrine\Common\Annotations\AnnotationReader; +use Doctrine\Persistence\Mapping\RuntimeReflectionService; use Psr\Log\LoggerInterface; -use Symfony\Component\Debug\BufferingLogger; use Webfactory\Bundle\PolyglotBundle\Doctrine\TranslatableClassMetadata; use Webfactory\Bundle\PolyglotBundle\Tests\TestEntity; use Webfactory\Bundle\PolyglotBundle\Tests\TestEntityTranslation; @@ -12,39 +12,20 @@ class TranslatableClassMetadataTest extends \PHPUnit_Framework_TestCase { - public function testIsSerializableWithoutLogger() + /** + * @test + */ + public function can_be_serialized_and_retrieved() { $metadata = $this->createMetadata(); - $serialized = serialize($metadata); - $unserialized = unserialize($serialized); - - $this->assertInstanceOf(TranslatableClassMetadata::class, $unserialized); - } - - public function testIsSerializableEvenIfInjectedLoggerIsNotSerializable() - { - $notSerializableLogger = $this->getMockBuilder(BufferingLogger::class)->setMethods(['__sleep'])->getMock(); - $notSerializableLogger->expects($this->any()) - ->method('__sleep') - ->will($this->throwException(new \RuntimeException('You cannot serialize me!'))); - - $metadata = $this->createMetadata($notSerializableLogger); - - $serialized = serialize($metadata); - $unserialized = unserialize($serialized); + $unserialized = unserialize(serialize($metadata->prepareSleepInstance())); + $unserialized->wakeupReflection(new RuntimeReflectionService()); - $this->assertInstanceOf(TranslatableClassMetadata::class, $unserialized); + $this->assertEquals($metadata, $unserialized); } - /** - * Creates metadata for testing. - * - * @param LoggerInterface|null $logger - * - * @return TranslatableClassMetadataTest - */ - private function createMetadata(LoggerInterface $logger = null) + private function createMetadata(LoggerInterface $logger = null): TranslatableClassMetadata { $reader = new AnnotationReader(); $infrastructure = new ORMInfrastructure( @@ -55,7 +36,7 @@ private function createMetadata(LoggerInterface $logger = null) ); $metadata = $infrastructure->getEntityManager()->getClassMetadata(TestEntity::class); $metadata = TranslatableClassMetadata::parseFromClassMetadata($metadata, $reader); - if ($logger !== null) { + if (null !== $logger) { $metadata->setLogger($logger); } diff --git a/src/Webfactory/Bundle/PolyglotBundle/Tests/IntegrationTest.php b/tests/IntegrationTest.php similarity index 98% rename from src/Webfactory/Bundle/PolyglotBundle/Tests/IntegrationTest.php rename to tests/IntegrationTest.php index df46b11..5e290f6 100644 --- a/src/Webfactory/Bundle/PolyglotBundle/Tests/IntegrationTest.php +++ b/tests/IntegrationTest.php @@ -102,7 +102,7 @@ public function testEntityConsideredCleanWhenNoTranslationWasChanged() { $entity = $this->createAndFetchTestEntity(); - $queryCount = count($this->getQueries()); + $queryCount = \count($this->getQueries()); /* Nothing was changed here, so the flush() should not need to write anything @@ -113,7 +113,7 @@ public function testEntityConsideredCleanWhenNoTranslationWasChanged() $this->infrastructure->getEntityManager()->flush(); $queries = $this->getQueries(); - $this->assertEquals($queryCount, count($queries)); + $this->assertEquals($queryCount, \count($queries)); $this->assertInstanceOf(TranslatableInterface::class, $entity->getText()); } diff --git a/src/Webfactory/Bundle/PolyglotBundle/Tests/TestEntity.php b/tests/TestEntity.php similarity index 95% rename from src/Webfactory/Bundle/PolyglotBundle/Tests/TestEntity.php rename to tests/TestEntity.php index 894e891..1c466a2 100644 --- a/src/Webfactory/Bundle/PolyglotBundle/Tests/TestEntity.php +++ b/tests/TestEntity.php @@ -12,7 +12,6 @@ use Doctrine\Common\Collections\ArrayCollection; use Doctrine\ORM\Mapping as ORM; use Webfactory\Bundle\PolyglotBundle\Annotation as Polyglot; -use Webfactory\Bundle\PolyglotBundle\Translatable; use Webfactory\Bundle\PolyglotBundle\TranslatableInterface; /** @@ -27,7 +26,8 @@ class TestEntity * @ORM\Id * @ORM\Column(type="integer", name="id") * @ORM\GeneratedValue - * @var integer|null + * + * @var int|null */ private $id; @@ -37,6 +37,7 @@ class TestEntity * * @ORM\Column(type="string") * @Polyglot\Translatable + * * @var TranslatableInterface|string|null */ protected $text = null; diff --git a/src/Webfactory/Bundle/PolyglotBundle/Tests/TestEntityTranslation.php b/tests/TestEntityTranslation.php similarity index 92% rename from src/Webfactory/Bundle/PolyglotBundle/Tests/TestEntityTranslation.php rename to tests/TestEntityTranslation.php index dfb2fb4..b7347e0 100644 --- a/src/Webfactory/Bundle/PolyglotBundle/Tests/TestEntityTranslation.php +++ b/tests/TestEntityTranslation.php @@ -10,7 +10,6 @@ namespace Webfactory\Bundle\PolyglotBundle\Tests; use Doctrine\ORM\Mapping as ORM; -use Webfactory\Bundle\PolyglotBundle\Annotation as Polyglot; use Webfactory\Bundle\PolyglotBundle\Entity\BaseTranslation; /** @@ -22,6 +21,7 @@ class TestEntityTranslation extends BaseTranslation { /** * @ORM\ManyToOne(targetEntity="TestEntity", inversedBy="translations") + * * @var TestEntity */ protected $entity; @@ -32,6 +32,7 @@ class TestEntityTranslation extends BaseTranslation * Must be protected to be usable when this class is used as base for a mock. * * @ORM\Column(type="string") + * * @var string */ protected $text; @@ -39,7 +40,6 @@ class TestEntityTranslation extends BaseTranslation /** * @param string|null $locale, e.g. 'de_DE' * @param string|null $text - * @param TestEntity|null $entity */ public function __construct($locale = null, $text = null, TestEntity $entity = null) { diff --git a/src/Webfactory/Bundle/PolyglotBundle/Tests/TranslatableTest.php b/tests/TranslatableTest.php similarity index 95% rename from src/Webfactory/Bundle/PolyglotBundle/Tests/TranslatableTest.php rename to tests/TranslatableTest.php index 41d6d5d..6389de1 100644 --- a/src/Webfactory/Bundle/PolyglotBundle/Tests/TranslatableTest.php +++ b/tests/TranslatableTest.php @@ -61,7 +61,7 @@ public function testCopyTranslations() public function testReturnsDefaultValueWhenCastToString() { $t = new Translatable('text locale_A', 'locale_A'); - $this->assertEquals('text locale_A', (string)$t); + $this->assertEquals('text locale_A', (string) $t); } public function testDefaultLocaleProviderCanProvideDefaultLocale() @@ -71,11 +71,11 @@ public function testDefaultLocaleProviderCanProvideDefaultLocale() $t = new Translatable('text locale_A', $defaultLocaleProvider); $t->setTranslation('text locale_B', 'locale_B'); - $this->assertEquals('text locale_A', (string)$t); + $this->assertEquals('text locale_A', (string) $t); $this->assertEquals('text locale_A', $t->translate()); $defaultLocaleProvider->setDefaultLocale('locale_B'); - $this->assertEquals('text locale_B', (string)$t); + $this->assertEquals('text locale_B', (string) $t); $this->assertEquals('text locale_B', $t->translate()); }