Skip to content

Commit 7421699

Browse files
committed
chore: pass PHPStan at level 9
1 parent 5b47ed3 commit 7421699

15 files changed

+210
-61
lines changed

composer.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
"require-dev": {
3838
"doctrine/common": "^2.0|^3.1",
3939
"doctrine/doctrine-bundle": "^2.0",
40+
"phpstan/phpstan": "^1.12",
4041
"phpunit/phpunit": "^9.6.18",
4142
"symfony/error-handler": "^6.4|^7.0",
4243
"symfony/framework-bundle": "^5.4|^6.4|^7.0",

phpstan.neon.dist

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
parameters:
2+
level: 9
3+
paths:
4+
- src

src/DependencyInjection/RegisterDoctrineTypePass.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ public function process(ContainerBuilder $container): void
1515
throw new RuntimeException('This bundle expects DoctrineBundle to be registered, it should provide the doctrine.dbal.connection_factory.types container parameter');
1616
}
1717

18+
/** @var array<string, mixed> $types */
1819
$types = $container->getParameter('doctrine.dbal.connection_factory.types');
1920
$types[TranslatableStringType::NAME] = ['class' => TranslatableStringType::class];
2021

src/DependencyInjection/WebfactoryPolyglotExtension.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,9 @@
1616

1717
final class WebfactoryPolyglotExtension extends Extension
1818
{
19+
/**
20+
* @param list<array{defaultLocale: string}> $configs
21+
*/
1922
public function load(array $configs, ContainerBuilder $container): void
2023
{
2124
$loader = new XmlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config'));

src/Doctrine/PersistentTranslatable.php

Lines changed: 24 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99

1010
namespace Webfactory\Bundle\PolyglotBundle\Doctrine;
1111

12+
use Doctrine\Common\Collections\Collection;
1213
use Doctrine\Common\Collections\Criteria;
1314
use Doctrine\Common\Collections\Selectable;
1415
use Doctrine\ORM\UnitOfWork;
@@ -25,6 +26,9 @@
2526
use Webfactory\Bundle\PolyglotBundle\TranslatableInterface;
2627

2728
/**
29+
* @template T
30+
* @implements TranslatableInterface<T>
31+
*
2832
* This class implements `TranslatableInterface` for entities that are managed by
2933
* the entity manager. PolyglotListener will replace `Translatable` instances with
3034
* instances of this class as soon as a new entity is passed to EntityManager::persist().
@@ -61,17 +65,17 @@ final class PersistentTranslatable implements TranslatableInterface
6165
private LoggerInterface $logger;
6266

6367
/**
64-
* @param UnitOfWork $unitOfWork The UoW managing the entity that contains this PersistentTranslatable
65-
* @param class-string $class The class of the entity containing this PersistentTranslatable instance
66-
* @param object $entity The entity containing this PersistentTranslatable instance
67-
* @param string $primaryLocale The locale for which the translated value will be persisted in the "main" entity
68-
* @param DefaultLocaleProvider $defaultLocaleProvider DefaultLocaleProvider that provides the locale to use when no explicit locale is passed to e. g. translate()
69-
* @param ReflectionProperty $translationProperty ReflectionProperty pointing to the field in the translations class that holds the translated value to use
70-
* @param ReflectionProperty $translationCollection ReflectionProperty pointing to the collection in the main class that holds translation instances
71-
* @param ReflectionClass $translationClass ReflectionClass for the class holding translated values
72-
* @param ReflectionProperty $localeField ReflectionProperty pointing to the field in the translations class that holds a translation's locale
73-
* @param ReflectionProperty $translationMapping ReflectionProperty pointing to the field in the translations class that refers back to the main entity (the owning side of the one-to-many translations collection).
74-
* @param ReflectionProperty $translatedProperty ReflectionProperty pointing to the field in the main entity where this PersistentTranslatable instance will be used
68+
* @param UnitOfWork $unitOfWork The UoW managing the entity that contains this PersistentTranslatable
69+
* @param class-string $class The class of the entity containing this PersistentTranslatable instance
70+
* @param object $entity The entity containing this PersistentTranslatable instance
71+
* @param string $primaryLocale The locale for which the translated value will be persisted in the "main" entity
72+
* @param DefaultLocaleProvider $defaultLocaleProvider DefaultLocaleProvider that provides the locale to use when no explicit locale is passed to e. g. translate()
73+
* @param ReflectionProperty $translationProperty ReflectionProperty pointing to the field in the translations class that holds the translated value to use
74+
* @param ReflectionProperty $translationCollection ReflectionProperty pointing to the collection in the main class that holds translation instances
75+
* @param ReflectionClass<object> $translationClass ReflectionClass for the class holding translated values
76+
* @param ReflectionProperty $localeField ReflectionProperty pointing to the field in the translations class that holds a translation's locale
77+
* @param ReflectionProperty $translationMapping ReflectionProperty pointing to the field in the translations class that refers back to the main entity (the owning side of the one-to-many translations collection).
78+
* @param ReflectionProperty $translatedProperty ReflectionProperty pointing to the field in the main entity where this PersistentTranslatable instance will be used
7579
*/
7680
public function __construct(
7781
private readonly UnitOfWork $unitOfWork,
@@ -150,7 +154,10 @@ private function createTranslationEntity(string $locale): object
150154
$this->localeField->setValue($entity, $locale);
151155

152156
$this->translationMapping->setValue($entity, $this->entity);
153-
$this->translationCollection->getValue($this->entity)->add($entity);
157+
158+
/** @var Collection<array-key, object> $collection */
159+
$collection = $this->translationCollection->getValue($this->entity);
160+
$collection->add($entity);
154161

155162
self::$_translations[$this->class][$this->oid][$locale] = $entity;
156163
$this->unitOfWork->persist($entity);
@@ -241,13 +248,17 @@ private function isTranslationCached(string $locale): bool
241248
*/
242249
private function cacheTranslation(string $locale): void
243250
{
244-
/** @var $translationsInAllLanguages Selectable */
251+
/** @var Selectable<array-key, object> $translationsInAllLanguages */
245252
$translationsInAllLanguages = $this->translationCollection->getValue($this->entity);
246253
$criteria = $this->createLocaleCriteria($locale);
247254
$translationsFilteredByLocale = $translationsInAllLanguages->matching($criteria);
248255

249256
$translationInLocale = ($translationsFilteredByLocale->count() > 0) ? $translationsFilteredByLocale->first() : null;
250257

258+
if (is_bool($translationInLocale)) {
259+
return;
260+
}
261+
251262
self::$_translations[$this->class][$this->oid][$locale] = $translationInLocale;
252263
}
253264

src/Doctrine/PolyglotListener.php

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,12 @@
1010
namespace Webfactory\Bundle\PolyglotBundle\Doctrine;
1111

1212
use Doctrine\ORM\EntityManager;
13+
use Doctrine\ORM\EntityManagerInterface;
1314
use Doctrine\ORM\Event\PostFlushEventArgs;
1415
use Doctrine\ORM\Event\PreFlushEventArgs;
1516
use Doctrine\Persistence\Event\LifecycleEventArgs;
1617
use Doctrine\Persistence\Mapping\RuntimeReflectionService;
18+
use Doctrine\Persistence\ObjectManager;
1719
use Psr\Log\LoggerInterface;
1820
use Psr\Log\NullLogger;
1921
use WeakReference;
@@ -39,28 +41,34 @@ final class PolyglotListener
3941
private array $translatedClasses = [];
4042

4143
/**
42-
* @var array<WeakReference>
44+
* @var array<WeakReference<object>>
4345
*/
4446
private array $entitiesWithTranslatables = [];
4547

4648
/**
47-
* @var list<PersistentTranslatable>
49+
* @var list<PersistentTranslatable<mixed>>
4850
*/
4951
private array $ejectedTranslatables = [];
5052

5153
public function __construct(
5254
private readonly DefaultLocaleProvider $defaultLocaleProvider,
53-
private readonly LoggerInterface $logger = null ?? new NullLogger(),
55+
private readonly LoggerInterface $logger = new NullLogger(),
5456
private readonly RuntimeReflectionService $reflectionService = new RuntimeReflectionService(),
5557
) {
5658
}
5759

60+
/**
61+
* @param LifecycleEventArgs<EntityManager> $event
62+
*/
5863
public function postLoad(LifecycleEventArgs $event): void
5964
{
6065
// Called when the entity has been hydrated
6166
$this->injectPersistentTranslatables($event->getObjectManager(), $event->getObject());
6267
}
6368

69+
/**
70+
* @param LifecycleEventArgs<EntityManager> $event
71+
*/
6472
public function prePersist(LifecycleEventArgs $event): void
6573
{
6674
// Called when a new entity is passed to persist() for the first time
@@ -109,7 +117,7 @@ public function postFlush(PostFlushEventArgs $event): void
109117
/**
110118
* @return list<TranslatableClassMetadata>
111119
*/
112-
private function getTranslationMetadatas(object $entity, EntityManager $em): array
120+
private function getTranslationMetadatas(object $entity, EntityManagerInterface $em): array
113121
{
114122
$class = $entity::class;
115123

@@ -127,7 +135,10 @@ private function getTranslationMetadatas(object $entity, EntityManager $em): arr
127135
return $this->translatableClassMetadatasByClass[$class];
128136
}
129137

130-
private function loadTranslationMetadataForClass($className, EntityManager $em): ?TranslatableClassMetadata
138+
/**
139+
* @param class-string<object> $className
140+
*/
141+
private function loadTranslationMetadataForClass(string $className, EntityManagerInterface $em): ?TranslatableClassMetadata
131142
{
132143
// In memory cache
133144
if (isset($this->translatedClasses[$className])) {
@@ -140,6 +151,7 @@ private function loadTranslationMetadataForClass($className, EntityManager $em):
140151

141152
if ($cache?->hasItem($cacheKey)) {
142153
$item = $cache->getItem($cacheKey);
154+
/** @var SerializedTranslatableClassMetadata|null $data */
143155
$data = $item->get();
144156
if (null === $data) {
145157
$this->translatedClasses[$className] = null;

src/Doctrine/SerializedTranslatableClassMetadata.php

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -11,33 +11,40 @@
1111

1212
final class SerializedTranslatableClassMetadata
1313
{
14+
/**
15+
* @var class-string<object>
16+
*/
1417
public string $class;
18+
19+
/**
20+
* @var class-string<object>
21+
*/
1522
public string $translationClass;
1623

1724
/**
18-
* @var array<string, array{0: string, 1: string}>
25+
* @var array<string, array{0: class-string<object>, 1: string}>
1926
*/
20-
public array $translationFieldMapping = [];
27+
public array $translationFieldMapping;
2128

2229
/**
23-
* @var array<string, array{0: string, 1: string}>
30+
* @var array<string, array{0: class-string<object>, 1: string}>
2431
*/
25-
public array $translatedProperties = [];
32+
public array $translatedProperties;
2633

2734
/**
28-
* @var array{0: string, 1: string}
35+
* @var array{0: class-string<object>, 1: string}
2936
*/
30-
public array $translationLocaleProperty = [];
37+
public array $translationLocaleProperty;
3138

3239
/**
33-
* @var array{0: string, 1: string}
40+
* @var array{0: class-string<object>, 1: string}
3441
*/
35-
public array $translationsCollectionProperty = [];
42+
public array $translationsCollectionProperty;
3643

3744
/**
38-
* @var array{0: string, 1: string}
45+
* @var array{0: class-string<object>, 1: string}
3946
*/
40-
public array $translationMappingProperty = [];
47+
public array $translationMappingProperty;
4148

4249
public string $primaryLocale;
4350
}

0 commit comments

Comments
 (0)