Files
Chamilo/vendor/sonata-project/doctrine-extensions/src/Mapper/ORM/DoctrineORMMapper.php
T
Xes 73154ae174
Behat tests 1.11.x 🐞 / PHP 7.4 Test on ubuntu-latest (push) Canceled after 0s
PHP-CS-Fixer / composer_install (7.4) (push) Canceled after 0s
Chamilo 1.11.40 (ZIP oficial v1.11.40)
Fuente: https://github.com/chamilo/chamilo-lms/releases/download/v1.11.40/chamilo-1.11.40.zip
sha256: 1cf4bf2cc7bae1ef1a1eff643235db1d552f78ddf4b6dd1e2d2dac9868679439
Snapshot independiente (rama huerfana); diffable vs 1.11.38. vendor incluido.
2026-08-06 17:59:45 +02:00

390 lines
12 KiB
PHP

<?php
declare(strict_types=1);
/*
* This file is part of the Sonata Project package.
*
* (c) Thomas Rabaix <thomas.rabaix@sonata-project.org>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Sonata\Doctrine\Mapper\ORM;
use Doctrine\Common\EventSubscriber;
use Doctrine\ORM\EntityManagerInterface;
use Doctrine\ORM\Mapping\ClassMetadata as ORMClassMetadata;
use Doctrine\Persistence\Event\LoadClassMetadataEventArgs;
use Doctrine\Persistence\Mapping\ClassMetadata;
final class DoctrineORMMapper implements EventSubscriber
{
/**
* @var array<class-string, array<string, array<array<string, mixed>>>>
*/
private array $associations = [];
/**
* @var array<class-string, array<string, class-string>>
*/
private array $discriminators = [];
/**
* @var array<class-string, array<string, mixed>>
*/
private array $discriminatorColumns = [];
/**
* @var array<class-string, int>
* @phpstan-var array<class-string, ORMClassMetadata::INHERITANCE_TYPE_*>
*/
private array $inheritanceTypes = [];
/**
* @var array<class-string, array<string, array<string>>>
*/
private array $indexes = [];
/**
* @var array<class-string, array<string, array<string>>>
*/
private array $uniques = [];
/**
* @var array<class-string, array<string, array<array<string, mixed>>>>
*/
private array $overrides = [];
public function getSubscribedEvents(): array
{
return [
'loadClassMetadata',
];
}
/**
* @param array<array<string, mixed>> $options
*
* @phpstan-param class-string $class
*/
public function addAssociation(string $class, string $type, $options): void
{
// NEXT_MAJOR: Move array check to method signature
if (!\is_array($options)) {
@trigger_error(sprintf(
'Passing other type than array as argument 3 for method %s() is deprecated since sonata-project/doctrine-extensions 1.8. It will accept only array in version 2.0.',
__METHOD__
), \E_USER_DEPRECATED);
}
if (!isset($this->associations[$class])) {
$this->associations[$class] = [];
}
$this->associations[$class][$type] = $options;
}
/**
* Add a discriminator to a class.
*
* @param string $key Key is the database value and values are the classes
*
* @phpstan-param class-string $class
* @phpstan-param class-string $discriminatorClass
*/
public function addDiscriminator(string $class, string $key, string $discriminatorClass): void
{
if (!isset($this->discriminators[$class])) {
$this->discriminators[$class] = [];
}
if (!isset($this->discriminators[$class][$key])) {
$this->discriminators[$class][$key] = $discriminatorClass;
}
}
/**
* @param array<string, mixed> $columnDef
*
* @phpstan-param class-string $class
*/
public function addDiscriminatorColumn(string $class, $columnDef): void
{
// NEXT_MAJOR: Move array check to method signature
if (!\is_array($columnDef)) {
@trigger_error(sprintf(
'Passing other type than array as argument 2 for method %s() is deprecated since sonata-project/doctrine-extensions 1.8. It will accept only array in version 2.0.',
__METHOD__
), \E_USER_DEPRECATED);
}
if (!isset($this->discriminatorColumns[$class])) {
$this->discriminatorColumns[$class] = $columnDef;
}
}
/**
* @phpstan-param class-string $class
* @phpstan-param ORMClassMetadata::INHERITANCE_TYPE_* $type
*
* @see ClassMetadata for supported types
*/
public function addInheritanceType(string $class, int $type): void
{
if (!isset($this->inheritanceTypes[$class])) {
$this->inheritanceTypes[$class] = $type;
}
}
/**
* @param string[] $columns
*
* @phpstan-param class-string $class
*/
public function addIndex(string $class, string $name, array $columns): void
{
$this->verifyColumnNames($columns);
if (!isset($this->indexes[$class])) {
$this->indexes[$class] = [];
}
if (isset($this->indexes[$class][$name])) {
return;
}
$this->indexes[$class][$name] = $columns;
}
/**
* @param string[] $columns
*
* @phpstan-param class-string $class
*/
public function addUnique(string $class, string $name, array $columns): void
{
$this->verifyColumnNames($columns);
if (!isset($this->uniques[$class])) {
$this->uniques[$class] = [];
}
if (isset($this->uniques[$class][$name])) {
return;
}
$this->uniques[$class][$name] = $columns;
}
/**
* @param array<array<string, mixed>> $options
*
* @phpstan-param class-string $class
*/
public function addOverride(string $class, string $type, $options): void
{
// NEXT_MAJOR: Move array check to method signature
if (!\is_array($options)) {
@trigger_error(sprintf(
'Passing other type than array as argument 3 for method %s() is deprecated since sonata-project/doctrine-extensions 1.8. It will accept only array in version 2.0.',
__METHOD__
), \E_USER_DEPRECATED);
}
if (!isset($this->overrides[$class])) {
$this->overrides[$class] = [];
}
$this->overrides[$class][$type] = $options;
}
/**
* @param LoadClassMetadataEventArgs<ClassMetadata<object>, EntityManagerInterface> $eventArgs
*/
public function loadClassMetadata(LoadClassMetadataEventArgs $eventArgs): void
{
$metadata = $eventArgs->getClassMetadata();
$this->loadAssociations($metadata);
$this->loadIndexes($metadata);
$this->loadUniques($metadata);
$this->loadDiscriminatorColumns($metadata);
$this->loadDiscriminators($metadata);
$this->loadInheritanceTypes($metadata);
$this->loadOverrides($metadata);
}
/**
* @param ClassMetadata<object> $metadata
*
* @throws \RuntimeException
*/
private function loadAssociations(ClassMetadata $metadata): void
{
if (!\array_key_exists($metadata->getName(), $this->associations)) {
return;
}
try {
foreach ($this->associations[$metadata->getName()] as $type => $mappings) {
foreach ($mappings as $mapping) {
// the association is already set, skip the native one
if ($metadata->hasAssociation($mapping['fieldName'])) {
continue;
}
// @phpstan-ignore-next-line https://github.com/phpstan/phpstan/issues/1105
\call_user_func([$metadata, $type], $mapping);
}
}
} catch (\ReflectionException $e) {
throw new \RuntimeException(sprintf('Error with class %s : %s', $metadata->getName(), $e->getMessage()), 404, $e);
}
}
/**
* @param ClassMetadata<object> $metadata
*
* @throws \RuntimeException
*/
private function loadDiscriminatorColumns(ClassMetadata $metadata): void
{
if (!\array_key_exists($metadata->getName(), $this->discriminatorColumns)) {
return;
}
\assert($metadata instanceof ORMClassMetadata);
try {
if (isset($this->discriminatorColumns[$metadata->getName()])) {
$arrayDiscriminatorColumns = $this->discriminatorColumns[$metadata->getName()];
if (isset($metadata->discriminatorColumn)) {
$arrayDiscriminatorColumns = array_merge($metadata->discriminatorColumn, $this->discriminatorColumns[$metadata->getName()]);
}
$metadata->setDiscriminatorColumn($arrayDiscriminatorColumns);
}
} catch (\ReflectionException $e) {
throw new \RuntimeException(sprintf('Error with class %s : %s', $metadata->getName(), $e->getMessage()), 404, $e);
}
}
/**
* @param ClassMetadata<object> $metadata
*
* @throws \RuntimeException
*/
private function loadInheritanceTypes(ClassMetadata $metadata): void
{
if (!\array_key_exists($metadata->getName(), $this->inheritanceTypes)) {
return;
}
\assert($metadata instanceof ORMClassMetadata);
try {
if (isset($this->inheritanceTypes[$metadata->getName()])) {
$metadata->setInheritanceType($this->inheritanceTypes[$metadata->getName()]);
}
} catch (\ReflectionException $e) {
throw new \RuntimeException(sprintf('Error with class %s : %s', $metadata->getName(), $e->getMessage()), 404, $e);
}
}
/**
* @param ClassMetadata<object> $metadata
*
* @throws \RuntimeException
*/
private function loadDiscriminators(ClassMetadata $metadata): void
{
if (!\array_key_exists($metadata->getName(), $this->discriminators)) {
return;
}
\assert($metadata instanceof ORMClassMetadata);
try {
foreach ($this->discriminators[$metadata->getName()] as $key => $class) {
if (\in_array($key, $metadata->discriminatorMap, true)) {
continue;
}
$metadata->setDiscriminatorMap([$key => $class]);
}
} catch (\ReflectionException $e) {
throw new \RuntimeException(sprintf('Error with class %s : %s', $metadata->getName(), $e->getMessage()), 404, $e);
}
}
/**
* @param ClassMetadata<object> $metadata
*/
private function loadIndexes(ClassMetadata $metadata): void
{
if (!\array_key_exists($metadata->getName(), $this->indexes)) {
return;
}
\assert($metadata instanceof ORMClassMetadata);
foreach ($this->indexes[$metadata->getName()] as $name => $columns) {
$metadata->table['indexes'][$name] = ['columns' => $columns];
}
}
/**
* @param ClassMetadata<object> $metadata
*/
private function loadUniques(ClassMetadata $metadata): void
{
if (!\array_key_exists($metadata->getName(), $this->uniques)) {
return;
}
\assert($metadata instanceof ORMClassMetadata);
foreach ($this->uniques[$metadata->getName()] as $name => $columns) {
$metadata->table['uniqueConstraints'][$name] = ['columns' => $columns];
}
}
/**
* @param ClassMetadata<object> $metadata
*/
private function loadOverrides(ClassMetadata $metadata): void
{
if (!\array_key_exists($metadata->getName(), $this->overrides)) {
return;
}
try {
foreach ($this->overrides[$metadata->getName()] as $type => $overrides) {
foreach ($overrides as $override) {
// @phpstan-ignore-next-line https://github.com/phpstan/phpstan/issues/1105
\call_user_func([$metadata, $type], $override['fieldName'], $override);
}
}
} catch (\ReflectionException $e) {
throw new \RuntimeException(
sprintf('Error with class %s : %s', $metadata->getName(), $e->getMessage()),
404,
$e
);
}
}
/**
* @param string[] $columns
*/
private function verifyColumnNames(array $columns): void
{
foreach ($columns as $column) {
if (!\is_string($column)) {
throw new \InvalidArgumentException(sprintf('The column is not a valid string, %s given', \gettype($column)));
}
}
}
}