Prevent Doctrine from using ArrayCollection for relations

Is there a way to prevent Doctrine from using array collections when fetching relations ? The goal is to ban ORM code (includes) from the entities (Domain layer), so layers are independant, I’m playing with the clean architecture.

I have this class

class User extends AbstractModel implements UserInterface
{
    // some other fields

    /**
     * @var array|RoleInterface[]
     */
    private array $roles = [];

    /**
     * @return RoleInterface[]
     */
    final public function getRoles(): array
    {
        return (array) $this->roles;
    }

    public function hasRole(RoleInterface $role): bool
    {
        return in_array($role, $this->roles);
    }

    /**
     * @param RoleInterface[]
     * 
     * @return self
     */
    final public function setRoles(array $roles): self
    {
        $this->roles = $roles;

        return $this;
    }

    final public function addRole(RoleInterface $role): self
    {
        if (! $this->hasRole($role)) {
            $this->setRoles([...$this->roles, $role]);
        }

        return $this;
    }


    final public function removeRole(RoleInterface $role): self
    {
        if ($this->hasRole($role)) {
            $this->setRoles(array_filter(
                $this->roles, 
                fn (Role $current) => $current === $role
            ));
        }

        return $this;
    }
}

And maping is done with XML

<doctrine-mapping xmlns="https://doctrine-project.org/schemas/orm/doctrine-mapping"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://doctrine-project.org/schemas/orm/doctrine-mapping
    https://raw.github.com/doctrine/doctrine2/master/doctrine-mapping.xsd">

    <entity name="AppDomainModelUserUser">

        <!-- some other fields -->

        <many-to-many field="roles" target-entity="AppDomainModelRoleRole">
            <join-table name="user_role">
                <join-columns>
                    <join-column name="user_id" referenced-column-name="id" nullable="false" unique="false" />
                </join-columns>
                <inverse-join-columns>
                    <join-column name="role_id" referenced-column-name="id" nullable="false" unique="false" />
                </inverse-join-columns>
            </join-table>
        </many-to-many>
        
    </entity>

</doctrine-mapping>

The problem is when fetching an User, Doctrine tries to put an ArrayCollection in the user, which leads to en error 500.
I’m aware I can remove the typing and just do $collection->toArray(), however it would mean my model complies to the ORM, and it should be the opposite.

Is there a way to configure Doctrine in such a way that it returns a native array for relations ? YML, XML or PHP will do.

Source: Symfony Questions

Was this helpful?

0 / 0

Leave a Reply 0

Your email address will not be published. Required fields are marked *