Как использовать пользовательскую коллекцию в Symfony 4 - PullRequest
0 голосов
/ 25 февраля 2019

Я хочу использовать пользовательский класс коллекции для моего приложения Symfony 4.Следующий сценарий является примером того, чего я пытаюсь достичь:

У меня есть класс сбора записей, в котором есть некоторая утилита для фильтрации и сопоставления данных.

class PostArrayCollection extends ArrayCollection implements PostCollectionInterface
{
    public function mapTitles()
    {
        return $this->map(function (Post $post) {
            return $post->getTitle();
        });
    }

    public function filterPublishedAfterDate(DateTime $from)
    {
        return $this->filter(function (Post $post) use ($from) {
            return $post->publishedDate() > $from;
        });
    }
}

Также пользовательский класс, которыйявляется сущностью Doctrine.

class User
{
    /**
     * @ORM\OneToMany(targetEntity="App\Entity\Post", mappedBy="post", cascade={"persist"})
     */
    private $posts;

    public function __construct()
    {
        $this->posts = new PostArrayCollection();
    }

    public function getPosts(): PostCollectionInterface
    {
        return $this->posts;
    }
}

Затем в помощнике или контроллере есть метод, который будет обращаться к данным пользователя, как показано ниже:

public function showPublishedPostTitlesForUser(User $user)
{
    $publishedPostTitles = $user->getPosts()
        ->filterPublishedAfterDate(new DateTime())
        ->mapTitles();

    // Render the titles...
}

При создании нового работаетобъект вручную, например, в модульном тесте.Но он не будет работать при загрузке сущности из репозитория, потому что тогда коллекции будут заполнены Doctrine\ORM\PersistentCollection объектами.

Теперь у меня вопрос, как мне настроить приложение, чтобы я мог использовать пользовательский персистентныйколлекция (например PersistentPostCollection) при загрузке сущностей?

Я нашел эту страницу https://www.doctrine -project.org / projects / doctrine-collection / en / latest / lazy-collection.html #lazy-collection , но я не могу найти, как интегрировать это в Symfony 4.

Примечание. Вышеприведенный сценарий - простой пример, чтобы этот вопрос был коротким и простым для понимания.,Я знаю, что всей этой проблемы можно избежать при использовании репозитория для получения правильных данных.Но это не то, что я ищу здесь.Этот вопрос касается понимания того, что возможно с коллекциями Doctrine в Symfony 4.

Ответы [ 2 ]

0 голосов
/ 05 апреля 2019

Ваша пользовательская коллекция должна выступать в качестве декоратора и проверить в вашем методе getPosts(), является ли она вашей пользовательской коллекцией.

PostArrayCollection будет выглядеть следующим образом

class PostArrayCollection implements Collection, Selectable, PostCollectionInterface
{
    /**
     * @var ArrayCollection|PersistentCollection
     */
    private $collection;

    public static function fromItems(Post ...$elements)
    {
        return new self(new ArrayCollection($elements));
    }

    public static function fromDoctrine(PersistentCollection $collection)
    {
        return new self($collection);
    }

    private function __construct(Collection $collection)
    {
        $this->collection = $collection;
    }

    public function mapTitles()
    {
        return $this->collection->map(function (Post $post) {
            return $post->getTitle();
        });
    }

    public function filterPublishedAfterDate(DateTime $from)
    {
        return $this->collection->filter(function (Post $post) use ($from) {
            return $post->publishedDate() > $from;
        });
    }

    // TODO implement all other methods and delegate it to $this->collection
}

User класс будет выглядеть так.

class User
{
    /**
     * @ORM\OneToMany(targetEntity="App\Entity\Post", mappedBy="post", cascade={"persist"})
     */
    private $posts;

    public function __construct()
    {
        $this->posts = PostArrayCollection::fromItems();
    }

    public function getPosts(): PostCollectionInterface
    {
        if ($this->posts instanceof PersistentCollection) {
            $this->posts = PostArrayCollection::fromDoctrine($this->posts);
        }
        return $this->posts;
    }
}
0 голосов
/ 25 февраля 2019

То, что вы нашли, - это документ для пакета коллекций Doctrine.

Doctrine ORM использует пакет коллекций Doctrine, но они являются отдельными пакетами друг от друга.Поэтому тот факт, что вы можете создать собственную коллекцию, не означает, что ORM будет уважать это.

То, что вы хотите сделать, сейчас невозможно с Doctrine ORM.

Функция пользовательских коллекций запланировано на следующую основную версию Doctrine ORM .

...