alphalabs/foundation-bundle

为Symfony2项目提供了一个有用的基础:分页集合、基于服务的存储库...

dev-master / 1.0.x-dev 2014-01-07 21:48 UTC

This package is not auto-updated.

Last update: 2024-09-23 15:13:27 UTC


README

Latest Stable Version Latest Unstable Version SensioLabsInsight

为Symfony2项目提供了一个有用的基础:分页集合、基础服务 & 存储库...

此包提供了一些在新的Symfony2项目中开始时可能有用的工具。

目前,该包提供了以下可能性

  • 集合分页:利用分页内容,归功于集成了 PagerFanta 库。
  • 基础实体/存储库具有自动分配的修改日期:提供了一个基础实体,并与其基存储库配对,该存储库管理数据的事务性持久性并在实体上自动分配创建/更新时间。还提供了一些异常,可以轻松检测在实体持久性/检索过程中发生的错误。
  • 基础服务:根据分页信息处理分页操作
  • 分页参数转换器:如果控制器需要处理分页,可以使用参数转换器来检索分页请求的信息,并将其直接注入到控制器方法参数中。
  • 集成 LiipDoctrineCacheBundle 以在项目中使用缓存系统

安装

将库添加到您的 composer.json 文件中

"require": {
    "alphalabs/foundation-bundle": "1.0@dev"
}

不要忘记使用 composer update 更新您的依赖项

将以下包声明添加到您的 AppKernel.php 文件中

public function registerBundles()
    {
        $bundles = array(
            // ...
            new WhiteOctober\PagerfantaBundle\WhiteOctoberPagerfantaBundle(),
            new Stof\DoctrineExtensionsBundle\StofDoctrineExtensionsBundle(),
            new Liip\DoctrineCacheBundle\LiipDoctrineCacheBundle(),
        );

配置

您可以在您的 config.yml 文件中配置该包

alphalabs_foundation:
    pagination:
        items_per_page: 20 # Default number of items per page in paginated collections

# Bundle used to handle automatic insertion of creation/update dates during entity persistence
stof_doctrine_extensions:
    default_locale: en_US
    orm:
        default:
            timestampable: true

有关配置缓存系统的信息,请参阅 LiipDoctrineCacheBundle 配置参考。

如果您想使用更多Doctrine扩展,请参阅 StofDoctrineExtensionBundle 配置参考。

用法

基础实体、存储库

实体

为了在您的实体中使用自动日期注入,您必须让它们继承基础实体

<?php

namespace MyBundle\Entity;

use AlphaLabs\Foundation\Entity\BaseEntity;

class MyEntity extends BaseEntity
{
}

实体中的 ìdcreatedAtupdatedAt 字段及其对应的getter/setter现在可用。

此外,这些字段已经映射到Doctrine中。您不必声明这些字段的映射。

实体接口

如果您想使用接口来表示您的实体,您可以创建您的接口以继承基础实体接口,该接口描述了新的setter/getter

<?php

namespace MyBundle\Entity;

use AlphaLabs\Foundation\Entity\BaseEntityInterface;

interface MyEntityInterface extends BaseEntityInterface
{
}

存储库

基存储库也可以用来在管理实体时获得一些有用的额外方法。只需在您的自定义存储库中扩展此类,而不是扩展Doctrine的 EntityRepository

<?php

namespace MyBundle\Repository;

use AlphaLabs\Foundation\Repository\BaseRepository;

class MyRepository extends BaseRepository
{
}

此类提供了一些处理查询/查询构建器/原生查询创建的方法,创建PagerFanta适配器,并公开 savedelete 方法以持久化和删除您的实体。

存储库接口

EntityInterface 类似,如果要在其他地方(例如您的服务中)使用它们,可以为此存储库使用接口。

您可以让您的接口继承基础存储库接口,该接口描述了添加的方法

<?php

namespace MyBundle\Repository;

use AlphaLabs\Foundation\Repository\BaseRepositoryInterface;

interface MyRepositoryInterface extends BaseRepositoryInterface
{
}

基础服务/分页

提供了一个基础服务以简化实体检索:通过ID或slug检索实体,并在检索多个实体时管理分页。

您可以从BaseService(以及接口)扩展您的自定义服务,并使用提供的方法来简化实体检索

<?php

namespace MyBundle\Service;

use AlphaLabs\FoundationBundle\Collection\PaginatedCollectionRequestInterface;
use AlphaLabs\FoundationBundle\Exception\InvalidIdentifierException;
use AlphaLabs\FoundationBundle\Exception\ObjectNotFoundException;
use AlphaLabs\FoundationBundle\Service\BaseService;
use MyBundle\Entity\MyEntityInterface;
use MyBundle\Repository\MyRepositoryInterface;

class MyService extends BaseService implements MyServiceInterface
{
    /** @var MyRepositoryInterface */
    protected $myRepository;

    /**
     * {@inheritDoc}
     */
    public function getAll(PaginatedCollectionRequestInterface $paginationInfo = null)
    {
        return $this->paginate($this->myRepository->findAllAdapter(), $paginationInfo);
    }

    /**
     * {@inheritDoc}
     */
    public function get($identifier)
    {
        switch($this->getIdentifierType($identifier)) {
            case static::IDENTIFIER_TYPE_ID:
                $entity = $this->myRepository->find(intval($identifier));
                break;
            case static::IDENTIFIER_TYPE_SLUG:
                $entity = $this->myRepository->findBySlug($identifier);
                break;
            default:
                throw new InvalidIdentifierException();
        }

        if (is_null($snippet)) {
            throw new ObjectNotFoundException();
        }

        return $entity;
    }
}

相应的接口

<?php

namespace MyBundle\Service;

use AlphaLabs\Foundation\Service\BaseServiceInterface;
use AlphaLabs\FoundationBundle\Collection\PaginatedCollectionRequestInterface;
use Pagerfanta\Pagerfanta;

interface MyServiceInterface extends BaseServiceInterface
{
    /**
     * Gets all my entities (paginated)
     *
     * @param \AlphaLabs\FoundationBundle\Collection\PaginatedCollectionRequestInterface $paginationInfo
     *
     * @return Pagerfanta
     */
    public function getAll(PaginatedCollectionRequestInterface $paginationInfo = null);

    /**
     * Gets my entity by the given identifier (slug or id)
     *
     * @param int|string $identifier
     *
     * @return MyEntity
     */
    public function get($identifier);
}

分页信息

您可以在控制器中使用分页请求。可以通过参数转换器简单地将它注入控制器的方法参数中。

如果您的控制器处理一些分页内容,只需在方法声明中添加参数即可

<?php

namespace MyBundle\Controller;

use AlphaLabs\FoundationBundle\Collection\PaginatedCollectionRequestInterface;
use AlphaLabs\FoundationBundle\Exception\InvalidRequestedPage;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;

class MyController extends Controller
{
    public function listAction(PaginatedCollectionRequestInterface $paginationInfo)
    {
        $myService = $this->get('my-service');

        try {
            $entities = $myService->getAll($paginationInfo);
        } catch (InvalidRequestedPage $e) {
            return $this->redirect($this->generateUrl('myentities_list', ['_pagination_page' => $e->getTargetPage()]));
        }

        return $this->render('MyBundle:list.html.twig', ['entities' => $entities]);
    }

$myService->getAll()方法中,将调用$this->paginate(),如果请求的页面不正确(过低或过高),则会自动抛出异常。异常对象包含最近可用的页面(如果请求的页面太低,则是1页,如果请求的页面太高,则是最后一页)。

注入的$paginationInfo基于请求属性包中的_pagination_page参数构建。为了让参数转换器正常工作,您可以在路由文件中声明此参数

<?xml version="1.0" encoding="UTF-8" ?>

<routes xmlns="https://symfony.ac.cn/schema/routing"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="https://symfony.ac.cn/schema/routing https://symfony.ac.cn/schema/routing/routing-1.0.xsd">
    <route id="snippet_list" pattern="/{_pagination_page}">
        <default key="_controller">MyBundle:MyController:list</default>
        <default key="_pagination_page">1</default>
        <requirement key="_pagination_page">\d+</requirement>
    </route>
</routes>

如果您不想使用URL来指示请求的页面,可以创建一个监听器来检测页面并将_pagination_page参数注入到请求属性中。

可以使用_pagination_items_per_page以相同的方式使用不同于默认值的每页项目数。它也会存储在由参数转换器注入的PaginatedCollectionRequestInterface中。

缓存

要在项目中使用缓存系统,您可以使用由AlphaLabsFoundationBundle安装的LiipDoctrineCacheBundle。

有关缓存系统使用的更多信息,请参阅LiipDoctrineCacheBundle文档。

待续

  • 在服务作用域级别进行事务管理(在服务方法结束时回滚/刷新所有操作)以及提供的保存/删除方法。
  • (提出您的想法)

致谢

  • Sylvain Mauduit (@Swop)

许可证

MIT