*/ public array $joinTableColumns = []; /** @var array */ public array $relationToSourceKeyColumns = []; /** @var array */ public array $relationToTargetKeyColumns = []; /** @return array */ public function toArray(): array { $array = parent::toArray(); $array['joinTable'] = $this->joinTable->toArray(); return $array; } /** * @param mixed[] $mappingArray * @psalm-param array{ * fieldName: string, * sourceEntity: class-string, * targetEntity: class-string, * cascade?: list<'persist'|'remove'|'detach'|'refresh'|'all'>, * fetch?: ClassMetadata::FETCH_*|null, * inherited?: class-string|null, * declared?: class-string|null, * cache?: array|null, * id?: bool|null, * isOnDeleteCascade?: bool|null, * originalClass?: class-string|null, * originalField?: string|null, * orphanRemoval?: bool, * unique?: bool|null, * joinTable?: mixed[]|null, * type?: int, * isOwningSide: bool, * } $mappingArray */ public static function fromMappingArrayAndNamingStrategy(array $mappingArray, NamingStrategy $namingStrategy): self { if (isset($mappingArray['joinTable']['joinColumns'])) { foreach ($mappingArray['joinTable']['joinColumns'] as $key => $joinColumn) { if (empty($joinColumn['name'])) { $mappingArray['joinTable']['joinColumns'][$key]['name'] = $namingStrategy->joinKeyColumnName( $mappingArray['sourceEntity'], $joinColumn['referencedColumnName'] ?? null, ); } } } if (isset($mappingArray['joinTable']['inverseJoinColumns'])) { foreach ($mappingArray['joinTable']['inverseJoinColumns'] as $key => $joinColumn) { if (empty($joinColumn['name'])) { $mappingArray['joinTable']['inverseJoinColumns'][$key]['name'] = $namingStrategy->joinKeyColumnName( $mappingArray['targetEntity'], $joinColumn['referencedColumnName'] ?? null, ); } } } // owning side MUST have a join table if (! isset($mappingArray['joinTable']) || ! isset($mappingArray['joinTable']['name'])) { $mappingArray['joinTable']['name'] = $namingStrategy->joinTableName( $mappingArray['sourceEntity'], $mappingArray['targetEntity'], $mappingArray['fieldName'], ); } $mapping = parent::fromMappingArray($mappingArray); $selfReferencingEntityWithoutJoinColumns = $mapping->sourceEntity === $mapping->targetEntity && $mapping->joinTable->joinColumns === [] && $mapping->joinTable->inverseJoinColumns === []; if ($mapping->joinTable->joinColumns === []) { $mapping->joinTable->joinColumns = [ JoinColumnMapping::fromMappingArray([ 'name' => $namingStrategy->joinKeyColumnName($mapping->sourceEntity, $selfReferencingEntityWithoutJoinColumns ? 'source' : null), 'referencedColumnName' => $namingStrategy->referenceColumnName(), 'onDelete' => 'CASCADE', ]), ]; } if ($mapping->joinTable->inverseJoinColumns === []) { $mapping->joinTable->inverseJoinColumns = [ JoinColumnMapping::fromMappingArray([ 'name' => $namingStrategy->joinKeyColumnName($mapping->targetEntity, $selfReferencingEntityWithoutJoinColumns ? 'target' : null), 'referencedColumnName' => $namingStrategy->referenceColumnName(), 'onDelete' => 'CASCADE', ]), ]; } $mapping->joinTableColumns = []; foreach ($mapping->joinTable->joinColumns as $joinColumn) { if (empty($joinColumn->referencedColumnName)) { $joinColumn->referencedColumnName = $namingStrategy->referenceColumnName(); } if ($joinColumn->name[0] === '`') { $joinColumn->name = trim($joinColumn->name, '`'); $joinColumn->quoted = true; } if ($joinColumn->referencedColumnName[0] === '`') { $joinColumn->referencedColumnName = trim($joinColumn->referencedColumnName, '`'); $joinColumn->quoted = true; } if (isset($joinColumn->onDelete) && strtolower($joinColumn->onDelete) === 'cascade') { $mapping->isOnDeleteCascade = true; } $mapping->relationToSourceKeyColumns[$joinColumn->name] = $joinColumn->referencedColumnName; $mapping->joinTableColumns[] = $joinColumn->name; } foreach ($mapping->joinTable->inverseJoinColumns as $inverseJoinColumn) { if (empty($inverseJoinColumn->referencedColumnName)) { $inverseJoinColumn->referencedColumnName = $namingStrategy->referenceColumnName(); } if ($inverseJoinColumn->name[0] === '`') { $inverseJoinColumn->name = trim($inverseJoinColumn->name, '`'); $inverseJoinColumn->quoted = true; } if ($inverseJoinColumn->referencedColumnName[0] === '`') { $inverseJoinColumn->referencedColumnName = trim($inverseJoinColumn->referencedColumnName, '`'); $inverseJoinColumn->quoted = true; } if (isset($inverseJoinColumn->onDelete) && strtolower($inverseJoinColumn->onDelete) === 'cascade') { $mapping->isOnDeleteCascade = true; } $mapping->relationToTargetKeyColumns[$inverseJoinColumn->name] = $inverseJoinColumn->referencedColumnName; $mapping->joinTableColumns[] = $inverseJoinColumn->name; } return $mapping; } /** @return list */ public function __sleep(): array { $serialized = parent::__sleep(); $serialized[] = 'joinTable'; $serialized[] = 'joinTableColumns'; foreach (['relationToSourceKeyColumns', 'relationToTargetKeyColumns'] as $arrayKey) { if ($this->$arrayKey !== null) { $serialized[] = $arrayKey; } } return $serialized; } }