From 05e38eadbeb3de19e5b26003c2b401e00bb71df4 Mon Sep 17 00:00:00 2001 From: polo Date: Sun, 18 Oct 2026 00:08:23 +0200 Subject: =?UTF-8?q?sortie=20de=20vendor=20du=20d=C3=A9p=C3=B4t,=20oubli=20?= =?UTF-8?q?dans=20config-template.ini?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- vendor/doctrine/orm/src/PersistentCollection.php | 652 ----------------------- 1 file changed, 652 deletions(-) delete mode 100644 vendor/doctrine/orm/src/PersistentCollection.php (limited to 'vendor/doctrine/orm/src/PersistentCollection.php') diff --git a/vendor/doctrine/orm/src/PersistentCollection.php b/vendor/doctrine/orm/src/PersistentCollection.php deleted file mode 100644 index d54d3d1..0000000 --- a/vendor/doctrine/orm/src/PersistentCollection.php +++ /dev/null @@ -1,652 +0,0 @@ - - * @template-implements Selectable - */ -final class PersistentCollection extends AbstractLazyCollection implements Selectable -{ - /** - * A snapshot of the collection at the moment it was fetched from the database. - * This is used to create a diff of the collection at commit time. - * - * @psalm-var array - */ - private array $snapshot = []; - - /** - * The entity that owns this collection. - */ - private object|null $owner = null; - - /** - * The association mapping the collection belongs to. - * This is currently either a OneToManyMapping or a ManyToManyMapping. - * - * @var (AssociationMapping&ToManyAssociationMapping)|null - */ - private AssociationMapping|null $association = null; - - /** - * The name of the field on the target entities that points to the owner - * of the collection. This is only set if the association is bi-directional. - */ - private string|null $backRefFieldName = null; - - /** - * Whether the collection is dirty and needs to be synchronized with the database - * when the UnitOfWork that manages its persistent state commits. - */ - private bool $isDirty = false; - - /** - * Creates a new persistent collection. - * - * @param EntityManagerInterface $em The EntityManager the collection will be associated with. - * @param ClassMetadata $typeClass The class descriptor of the entity type of this collection. - * @psalm-param Collection&Selectable $collection The collection elements. - */ - public function __construct( - private EntityManagerInterface|null $em, - private readonly ClassMetadata|null $typeClass, - Collection $collection, - ) { - $this->collection = $collection; - $this->initialized = true; - } - - /** - * INTERNAL: - * Sets the collection's owning entity together with the AssociationMapping that - * describes the association between the owner and the elements of the collection. - */ - public function setOwner(object $entity, AssociationMapping&ToManyAssociationMapping $assoc): void - { - $this->owner = $entity; - $this->association = $assoc; - $this->backRefFieldName = $assoc->isOwningSide() ? $assoc->inversedBy : $assoc->mappedBy; - } - - /** - * INTERNAL: - * Gets the collection owner. - */ - public function getOwner(): object|null - { - return $this->owner; - } - - public function getTypeClass(): ClassMetadata - { - assert($this->typeClass !== null); - - return $this->typeClass; - } - - private function getUnitOfWork(): UnitOfWork - { - assert($this->em !== null); - - return $this->em->getUnitOfWork(); - } - - /** - * INTERNAL: - * Adds an element to a collection during hydration. This will automatically - * complete bidirectional associations in the case of a one-to-many association. - */ - public function hydrateAdd(mixed $element): void - { - $this->unwrap()->add($element); - - // If _backRefFieldName is set and its a one-to-many association, - // we need to set the back reference. - if ($this->backRefFieldName && $this->getMapping()->isOneToMany()) { - assert($this->typeClass !== null); - // Set back reference to owner - $this->typeClass->reflFields[$this->backRefFieldName]->setValue( - $element, - $this->owner, - ); - - $this->getUnitOfWork()->setOriginalEntityProperty( - spl_object_id($element), - $this->backRefFieldName, - $this->owner, - ); - } - } - - /** - * INTERNAL: - * Sets a keyed element in the collection during hydration. - */ - public function hydrateSet(mixed $key, mixed $element): void - { - $this->unwrap()->set($key, $element); - - // If _backRefFieldName is set, then the association is bidirectional - // and we need to set the back reference. - if ($this->backRefFieldName && $this->getMapping()->isOneToMany()) { - assert($this->typeClass !== null); - // Set back reference to owner - $this->typeClass->reflFields[$this->backRefFieldName]->setValue( - $element, - $this->owner, - ); - } - } - - /** - * Initializes the collection by loading its contents from the database - * if the collection is not yet initialized. - */ - public function initialize(): void - { - if ($this->initialized || ! $this->association) { - return; - } - - $this->doInitialize(); - - $this->initialized = true; - } - - /** - * INTERNAL: - * Tells this collection to take a snapshot of its current state. - */ - public function takeSnapshot(): void - { - $this->snapshot = $this->unwrap()->toArray(); - $this->isDirty = false; - } - - /** - * INTERNAL: - * Returns the last snapshot of the elements in the collection. - * - * @psalm-return array The last snapshot of the elements. - */ - public function getSnapshot(): array - { - return $this->snapshot; - } - - /** - * INTERNAL: - * getDeleteDiff - * - * @return mixed[] - */ - public function getDeleteDiff(): array - { - $collectionItems = $this->unwrap()->toArray(); - - return array_values(array_diff_key( - array_combine(array_map('spl_object_id', $this->snapshot), $this->snapshot), - array_combine(array_map('spl_object_id', $collectionItems), $collectionItems), - )); - } - - /** - * INTERNAL: - * getInsertDiff - * - * @return mixed[] - */ - public function getInsertDiff(): array - { - $collectionItems = $this->unwrap()->toArray(); - - return array_values(array_diff_key( - array_combine(array_map('spl_object_id', $collectionItems), $collectionItems), - array_combine(array_map('spl_object_id', $this->snapshot), $this->snapshot), - )); - } - - /** INTERNAL: Gets the association mapping of the collection. */ - public function getMapping(): AssociationMapping&ToManyAssociationMapping - { - if ($this->association === null) { - throw new UnexpectedValueException('The underlying association mapping is null although it should not be'); - } - - return $this->association; - } - - /** - * Marks this collection as changed/dirty. - */ - private function changed(): void - { - if ($this->isDirty) { - return; - } - - $this->isDirty = true; - } - - /** - * Gets a boolean flag indicating whether this collection is dirty which means - * its state needs to be synchronized with the database. - */ - public function isDirty(): bool - { - return $this->isDirty; - } - - /** - * Sets a boolean flag, indicating whether this collection is dirty. - */ - public function setDirty(bool $dirty): void - { - $this->isDirty = $dirty; - } - - /** - * Sets the initialized flag of the collection, forcing it into that state. - */ - public function setInitialized(bool $bool): void - { - $this->initialized = $bool; - } - - public function remove(string|int $key): mixed - { - // TODO: If the keys are persistent as well (not yet implemented) - // and the collection is not initialized and orphanRemoval is - // not used we can issue a straight SQL delete/update on the - // association (table). Without initializing the collection. - $removed = parent::remove($key); - - if (! $removed) { - return $removed; - } - - $this->changed(); - - if ( - $this->association !== null && - $this->association->isToMany() && - $this->owner && - $this->getMapping()->orphanRemoval - ) { - $this->getUnitOfWork()->scheduleOrphanRemoval($removed); - } - - return $removed; - } - - public function removeElement(mixed $element): bool - { - $removed = parent::removeElement($element); - - if (! $removed) { - return $removed; - } - - $this->changed(); - - if ( - $this->association !== null && - $this->association->isToMany() && - $this->owner && - $this->getMapping()->orphanRemoval - ) { - $this->getUnitOfWork()->scheduleOrphanRemoval($element); - } - - return $removed; - } - - public function containsKey(mixed $key): bool - { - if ( - ! $this->initialized && $this->getMapping()->fetch === ClassMetadata::FETCH_EXTRA_LAZY - && isset($this->getMapping()->indexBy) - ) { - $persister = $this->getUnitOfWork()->getCollectionPersister($this->getMapping()); - - return $this->unwrap()->containsKey($key) || $persister->containsKey($this, $key); - } - - return parent::containsKey($key); - } - - public function contains(mixed $element): bool - { - if (! $this->initialized && $this->getMapping()->fetch === ClassMetadata::FETCH_EXTRA_LAZY) { - $persister = $this->getUnitOfWork()->getCollectionPersister($this->getMapping()); - - return $this->unwrap()->contains($element) || $persister->contains($this, $element); - } - - return parent::contains($element); - } - - public function get(string|int $key): mixed - { - if ( - ! $this->initialized - && $this->getMapping()->fetch === ClassMetadata::FETCH_EXTRA_LAZY - && isset($this->getMapping()->indexBy) - ) { - assert($this->em !== null); - assert($this->typeClass !== null); - if (! $this->typeClass->isIdentifierComposite && $this->typeClass->isIdentifier($this->getMapping()->indexBy)) { - return $this->em->find($this->typeClass->name, $key); - } - - return $this->getUnitOfWork()->getCollectionPersister($this->getMapping())->get($this, $key); - } - - return parent::get($key); - } - - public function count(): int - { - if (! $this->initialized && $this->association !== null && $this->getMapping()->fetch === ClassMetadata::FETCH_EXTRA_LAZY) { - $persister = $this->getUnitOfWork()->getCollectionPersister($this->association); - - return $persister->count($this) + ($this->isDirty ? $this->unwrap()->count() : 0); - } - - return parent::count(); - } - - public function set(string|int $key, mixed $value): void - { - parent::set($key, $value); - - $this->changed(); - - if (is_object($value) && $this->em) { - $this->getUnitOfWork()->cancelOrphanRemoval($value); - } - } - - public function add(mixed $value): bool - { - $this->unwrap()->add($value); - - $this->changed(); - - if (is_object($value) && $this->em) { - $this->getUnitOfWork()->cancelOrphanRemoval($value); - } - - return true; - } - - public function offsetExists(mixed $offset): bool - { - return $this->containsKey($offset); - } - - public function offsetGet(mixed $offset): mixed - { - return $this->get($offset); - } - - public function offsetSet(mixed $offset, mixed $value): void - { - if (! isset($offset)) { - $this->add($value); - - return; - } - - $this->set($offset, $value); - } - - public function offsetUnset(mixed $offset): void - { - $this->remove($offset); - } - - public function isEmpty(): bool - { - return $this->unwrap()->isEmpty() && $this->count() === 0; - } - - public function clear(): void - { - if ($this->initialized && $this->isEmpty()) { - $this->unwrap()->clear(); - - return; - } - - $uow = $this->getUnitOfWork(); - $association = $this->getMapping(); - - if ( - $association->isToMany() && - $association->orphanRemoval && - $this->owner - ) { - // we need to initialize here, as orphan removal acts like implicit cascadeRemove, - // hence for event listeners we need the objects in memory. - $this->initialize(); - - foreach ($this->unwrap() as $element) { - $uow->scheduleOrphanRemoval($element); - } - } - - $this->unwrap()->clear(); - - $this->initialized = true; // direct call, {@link initialize()} is too expensive - - if ($association->isOwningSide() && $this->owner) { - $this->changed(); - - $uow->scheduleCollectionDeletion($this); - - $this->takeSnapshot(); - } - } - - /** - * Called by PHP when this collection is serialized. Ensures that only the - * elements are properly serialized. - * - * Internal note: Tried to implement Serializable first but that did not work well - * with circular references. This solution seems simpler and works well. - * - * @return string[] - * @psalm-return array{0: string, 1: string} - */ - public function __sleep(): array - { - return ['collection', 'initialized']; - } - - public function __wakeup(): void - { - $this->em = null; - } - - /** - * Extracts a slice of $length elements starting at position $offset from the Collection. - * - * If $length is null it returns all elements from $offset to the end of the Collection. - * Keys have to be preserved by this method. Calling this method will only return the - * selected slice and NOT change the elements contained in the collection slice is called on. - * - * @return mixed[] - * @psalm-return array - */ - public function slice(int $offset, int|null $length = null): array - { - if (! $this->initialized && ! $this->isDirty && $this->getMapping()->fetch === ClassMetadata::FETCH_EXTRA_LAZY) { - $persister = $this->getUnitOfWork()->getCollectionPersister($this->getMapping()); - - return $persister->slice($this, $offset, $length); - } - - return parent::slice($offset, $length); - } - - /** - * Cleans up internal state of cloned persistent collection. - * - * The following problems have to be prevented: - * 1. Added entities are added to old PC - * 2. New collection is not dirty, if reused on other entity nothing - * changes. - * 3. Snapshot leads to invalid diffs being generated. - * 4. Lazy loading grabs entities from old owner object. - * 5. New collection is connected to old owner and leads to duplicate keys. - */ - public function __clone() - { - if (is_object($this->collection)) { - $this->collection = clone $this->collection; - } - - $this->initialize(); - - $this->owner = null; - $this->snapshot = []; - - $this->changed(); - } - - /** - * Selects all elements from a selectable that match the expression and - * return a new collection containing these elements. - * - * @psalm-return Collection - * - * @throws RuntimeException - */ - public function matching(Criteria $criteria): Collection - { - if ($this->isDirty) { - $this->initialize(); - } - - if ($this->initialized) { - return $this->unwrap()->matching($criteria); - } - - $association = $this->getMapping(); - if ($association->isManyToMany()) { - $persister = $this->getUnitOfWork()->getCollectionPersister($association); - - return new ArrayCollection($persister->loadCriteria($this, $criteria)); - } - - $builder = Criteria::expr(); - $ownerExpression = $builder->eq($this->backRefFieldName, $this->owner); - $expression = $criteria->getWhereExpression(); - $expression = $expression ? $builder->andX($expression, $ownerExpression) : $ownerExpression; - - $criteria = clone $criteria; - $criteria->where($expression); - $criteria->orderBy( - $criteria->orderings() ?: array_map( - static fn (string $order): Order => Order::from(strtoupper($order)), - $association->orderBy(), - ), - ); - - $persister = $this->getUnitOfWork()->getEntityPersister($association->targetEntity); - - return $association->fetch === ClassMetadata::FETCH_EXTRA_LAZY - ? new LazyCriteriaCollection($persister, $criteria) - : new ArrayCollection($persister->loadCriteria($criteria)); - } - - /** - * Retrieves the wrapped Collection instance. - * - * @return Collection&Selectable - */ - public function unwrap(): Selectable&Collection - { - assert($this->collection instanceof Collection); - assert($this->collection instanceof Selectable); - - return $this->collection; - } - - protected function doInitialize(): void - { - // Has NEW objects added through add(). Remember them. - $newlyAddedDirtyObjects = []; - - if ($this->isDirty) { - $newlyAddedDirtyObjects = $this->unwrap()->toArray(); - } - - $this->unwrap()->clear(); - $this->getUnitOfWork()->loadCollection($this); - $this->takeSnapshot(); - - if ($newlyAddedDirtyObjects) { - $this->restoreNewObjectsInDirtyCollection($newlyAddedDirtyObjects); - } - } - - /** - * @param object[] $newObjects - * - * Note: the only reason why this entire looping/complexity is performed via `spl_object_id` - * is because we want to prevent using `array_udiff()`, which is likely to cause very - * high overhead (complexity of O(n^2)). `array_diff_key()` performs the operation in - * core, which is faster than using a callback for comparisons - */ - private function restoreNewObjectsInDirtyCollection(array $newObjects): void - { - $loadedObjects = $this->unwrap()->toArray(); - $newObjectsByOid = array_combine(array_map('spl_object_id', $newObjects), $newObjects); - $loadedObjectsByOid = array_combine(array_map('spl_object_id', $loadedObjects), $loadedObjects); - $newObjectsThatWereNotLoaded = array_diff_key($newObjectsByOid, $loadedObjectsByOid); - - if ($newObjectsThatWereNotLoaded) { - // Reattach NEW objects added through add(), if any. - array_walk($newObjectsThatWereNotLoaded, [$this->unwrap(), 'add']); - - $this->isDirty = true; - } - } -} -- cgit v1.2.3