jurjean/spray-persistence-bundle

关于此包的最新版本(2.1.1)没有可用的许可证信息。

2.1.1 2013-10-22 09:14 UTC

README

一个增强Doctrine2仓库功能的Symfony2包。

Build Status Scrutinizer Quality Score Code Coverage

简介

此包提供了一种以抽象方式查询对象的方法

    $articles->filter('currentlyPublished');
    $articles->filter('writtenBy', new Author('Buster'));
    $articles->filter('ascending');

它有一个通用的API

    $articleCount = count($articles);
    foreach ($articles as $article) {
          
    }

允许轻松分页

    foreach ($articles->paginate(1) as $article) {
          
    }

并且可以独立使用!您不需要symfony,可以将它集成到任何选择的框架中(但是Doctrine是必需的)。

安装

在您的composer.json中要求"jurjean/spray-persistence-bundle"

    {
        "require": {
            "jurjean/spray-persistence-bundle": "2.2.*@dev"
        }
    }

在您的AppKernel中注册SprayPersistenceBundle

    class AppKernel extends Kernel
    {
        public function registerBundles()
        {
            $bundles = array(
                // ...
                new Spray\PersistenceBundle\SprayPersistenceBundle(),
            );
            return $bundles;
        }
    }

问题

Doctrine2提供了一个很好的API,允许您通过仓库查询实体。然而,仓库模式并不非常DRY。

如果您想要进行上述描述的查询,您可能会得到一个类似的仓库

    class ArticleRepository extends Repository
    {
        public function findCurrentlyPublished($order)
        {
            
        }
        
        public function findCurrentlyPublishedAndWrittenBy(Author $author, $order)
        {
            
        }
    }

如您所想象的,添加更多条件的唯一方法是通过复制。这就是RepositoryFilter的作用所在。

实体过滤器

优先级实体过滤器

您可能希望某个过滤器具有优先级。为了做到这一点,您必须实现PrioritizedFilterInterface

    use Doctrine\ORM\QueryBuilder;
    use Spray\PersistenceBundle\EntityFilter\EntityFilterInterface;
    use Spray\PersistenceBundle\EntityFilter\PrioritizedFilterInterface;

    class First implements EntityFilterInterface, PrioritizedFilterInterface
    {
        public function filter(QueryBuilder $queryBuilder, $options = array())
        {
            
        }

        public function getName()
        {
            return 'first';
        }

        public function getPriority()
        {
            return 100;
        }
    }

    class Last implements EntityFilterInterface, PrioritizedFilterInterface
    {
        public function filter(QueryBuilder $queryBuilder, $options = array())
        {
            
        }

        public function getName()
        {
            return 'last';
        }

        public function getPriority()
        {
            return -100;
        }
    }

无论您以何种顺序添加这些过滤器,执行顺序仍然是第一个然后是最后一个。

    $repository->filter('last'); // Added at priority level -100
    $repository->filter('first'); // Added at priority level 100, before 'last'

冲突的实体过滤器

如果您有可能会相互冲突的过滤器(例如,如果它们在相同的列上添加了WHERE语句),您可以实现ConflictingFilterInterface

    use Doctrine\ORM\QueryBuilder;
    use Spray\PersistenceBundle\EntityFilter\ConflictingFilterInterface;

    class ArticlesConflictingWith implements ConflictingFilterInterface
    {
        public function filter(QueryBuilder $queryBuilder, $options = array())
        {
            
        }

        public function getName()
        {
            return 'conflictingWith';
        }

        public function getConflictingFilters()
        {
            return array('another');
        }
    }

如果'repository filter'作用域中存在'another',则在添加ArticlesConflictingWith时将删除它。

    $articles->filter('another');
    $articles->filter('conflictingWith'); // This is now the only filter

过滤器注册表

过滤器注册表用于向仓库过滤器提供可用的实体过滤器。您可以通过编程方式构建它们,或者创建自己的注册表类。之后,您需要将注册表注入到仓库过滤器中。

    class ArticleFilters extends FilterRegistry
    {
        public function __construct()
        {
            $this->add(new ArticlesPublishedSince());
            $this->add(new ArticlesWrittenBy());
        }
    }

    $articles = new RepositoryFilter($entityManager->getRepository('Article'));
    $articles->setFilterLocator(new ArticleFilters());

    $articles->filter('publishedSince');
    $articles->filter('writtenBy', new Author('Buster'));

Symfony集成

您可以通过扩展父级di容器定义spray_persistence.repository_filter并为其提供一个实体名称作为参数,轻松配置您的仓库过滤器。

    <container>
        <services>
            <service id="bundle.articles"
                     parent="spray_persistence.repository_filter">
                <argument>Bundle\Entity\Article</argument>
            </service>
        </services>
    </container>

通过将它们标记为具有名称spray_persistence.entity_filter来添加过滤器。您可以将它们设置为全局(对于所有仓库)或局部(对于单个仓库)。您通过添加repository作为标记选项来使它们局部。

    <container>
        <services>
            <service id="bundle.articles"
                     parent="spray_persistence.repository_filter">
                <argument>Bundle\Entity\Article</argument>
            </service>
            <service id="bundle.filter.global"
                     class="Bundle\EntityFilter\Global">
                <tag name="spray_persistence.entity_filter" />
            </service>
            <service id="bundle.filter.local"
                     class="Bundle\EntityFilter\Local">
                <tag name="spray_persistence.entity_filter" repository="bundle.articles" />
            </service>
        </services>
    </container>

示例

有关更多示例,请参阅此项目的集成测试