Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 0 additions & 18 deletions phpstan-baseline.php
Original file line number Diff line number Diff line change
Expand Up @@ -2587,24 +2587,6 @@
'count' => 1,
'path' => __DIR__ . '/src/Event/Listener/ContentFillListener.php',
];
$ignoreErrors[] = [
'message' => '#^Parameter \\#1 \\$objectOrClass of class ReflectionClass constructor expects class\\-string\\<T of object\\>\\|T of object, string given\\.$#',
'identifier' => 'argument.type',
'count' => 1,
'path' => __DIR__ . '/src/Event/Listener/FieldDiscriminatorListener.php',
];
$ignoreErrors[] = [
'message' => '#^Property Bolt\\\\Event\\\\Listener\\\\FieldDiscriminatorListener\\:\\:\\$map type has no value type specified in iterable type array\\.$#',
'identifier' => 'missingType.iterableValue',
'count' => 1,
'path' => __DIR__ . '/src/Event/Listener/FieldDiscriminatorListener.php',
];
$ignoreErrors[] = [
'message' => '#^Property Bolt\\\\Event\\\\Listener\\\\FieldDiscriminatorListener\\:\\:\\$tempMap type has no value type specified in iterable type array\\.$#',
'identifier' => 'missingType.iterableValue',
'count' => 1,
'path' => __DIR__ . '/src/Event/Listener/FieldDiscriminatorListener.php',
];
$ignoreErrors[] = [
'message' => '#^Method Bolt\\\\Event\\\\Listener\\\\FieldFillListener\\:\\:clean\\(\\) has parameter \\$value with no type specified\\.$#',
'identifier' => 'missingType.parameter',
Expand Down
33 changes: 29 additions & 4 deletions src/Event/Listener/FieldDiscriminatorListener.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,18 @@ class FieldDiscriminatorListener
{
private readonly MappingDriver $mappingDriver;

/** The temporary map used for one run, when computing everything */
/**
* The temporary map used for one run, when computing everything
*
* @var array<class-string<FieldInterface>, string>
*/
private array $tempMap = [];

/** The cached map, this holds the results after a computation, also for other classes */
/**
* The cached map, this holds the results after a computation, also for other classes
*
* @var array<class-string<FieldInterface>, array<string, class-string<FieldInterface>>>
*/
private array $map = [];

/**
Expand All @@ -38,6 +46,7 @@ public function __construct(EntityManagerInterface $em)

public function loadClassMetadata(LoadClassMetadataEventArgs $event): void
{
/** @var class-string $className */
$className = $event->getClassMetadata()->name;
if ($this->isField($className) === false) {
return;
Expand All @@ -59,14 +68,20 @@ public function loadClassMetadata(LoadClassMetadataEventArgs $event): void
$event->getClassMetadata()->setDiscriminatorMap($this->map[$className]);
}

/**
* @param class-string $class
* @phpstan-assert-if-true class-string<FieldInterface> $class
*/
private function isField(string $class): bool
{
return is_subclass_of($class, FieldInterface::class);
}

/**
* @param class-string<FieldInterface> $class
*/
private function extractFieldType(string $class): string
{
/** @var FieldInterface $field */
$field = new $class();
$fieldType = $field->getType();
if (in_array($fieldType, $this->tempMap, true) === true) {
Expand All @@ -76,6 +91,9 @@ private function extractFieldType(string $class): string
return $fieldType;
}

/**
* @param class-string<FieldInterface> $className
*/
private function checkFamily(string $className): void
{
$this->tempMap[$className] = $this->extractFieldType($className);
Expand All @@ -84,13 +102,20 @@ private function checkFamily(string $className): void

if ($parentClass !== false) {
// Also check all the parents of our child
$this->checkFamily($parentClass->name);

/** @var class-string<FieldInterface> $parentClassName */
$parentClassName = $parentClass->name;

$this->checkFamily($parentClassName);
} else {
// Find all the children of this class
$this->checkChildren($className);
}
}

/**
* @param class-string<FieldInterface> $parentClassName
*/
private function checkChildren(string $parentClassName): void
{
foreach ($this->mappingDriver->getAllClassNames() as $className) {
Expand Down
6 changes: 5 additions & 1 deletion src/Repository/FieldRepository.php
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,6 @@ public static function factory(Collection $definition, string $name = '', string
$classname = self::getFieldClassname($type);

if ($classname && class_exists($classname)) {
/** @var Field $field */
$field = new $classname();
} else {
$field = new Field();
Expand All @@ -121,17 +120,22 @@ public static function factory(Collection $definition, string $name = '', string
return $field;
}

/**
* @return class-string<Field>|null

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
* @return class-string<Field>|null
* @return class-string<FieldInterface>|null

Wouldn't that make more sense here?

*/
public static function getFieldClassname(string $type): ?string
{
// The classname we want
$classname = ucwords($type) . 'Field';

/** @var array<class-string> $classes */
$classes = array_map(
fn (ClassMetadata $entity): string => $entity->getName(),
self::$em->getMetadataFactory()->getAllMetadata()
);

// Classnames of all fields (classes that implement Bolt\Entity\FieldInterface)
/** @var Collection<int, class-string<Field>> $allFields */

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
/** @var Collection<int, class-string<Field>> $allFields */
/** @var Collection<int, class-string<FieldInterface>> $allFields */

Same here?

$allFields = collect($classes)->filter(
fn (string $class): bool => in_array(FieldInterface::class, class_implements($class), true)
);
Expand Down
Loading