strontium / specification-bundle
Doctrine 和 Symfony 2 框架中的规范模式
dev-master / 0.1.x-dev
2015-07-31 16:18 UTC
Requires
- php: >=5.4
- happyr/doctrine-specification: ^0.6@stable
- sylius/registry: ^0.14
- symfony/expression-language: ^2.5
- symfony/form: ^2.5
- symfony/framework-bundle: ^2.3
Requires (Dev)
- phpspec/phpspec: ~2.2
This package is auto-updated.
Last update: 2024-09-26 21:36:34 UTC
README
将 Happyr/Doctrine-Specification 集成到 Symfony 2 框架。
安装
添加 composer 依赖 composer require strontium/doctrine-specification-bundle
。在您的 Kernel 中注册包
<?php // app/AppKernel.php public function registerBundles() { $bundles = array( // ... new \Strontium\SpecificationBundle\SpecificationBundle(), ); // ... }
使用方法
创建您的规范构建器
use Strontium\SpecificationBundle\Builder\SpecificationBuilderInterface; class OwnedByCurrentUser implements SpecificationBuilderInterface { protected $tokenStorage; public function setContextManager(TokenStorageInterface $tokenStorage) { $this->tokenStorage = $tokenStorage; return $this; } public function buildSpecification(SpecificationFactory $spec, array $options) { return $spec->eq([ 'field' => $options['field'], 'value' => $this->tokenStorage->getToken()->getUser(), 'dql_alias' => $options['dql_alias'] ]); } public function configureOptions(OptionsResolver $resolver) { $resolver ->setDefined(['field']) ->setDefaults([ 'field' => 'user', ]); } }
通过添加标签 specification
注册构建器
# services.yml my_app.specification.owned_by_current_user: class: MyApp\MyBundle\Specification\OwnedByCurrentUser arguments: - @security.token_storage tags: - { name: specification, alias: ownedByCurrentUser }
在您的应用程序的某处使用它
class CommentController extends Controller { public function indexAction(Request $request) { $spec = $this->get('specification.factory')->ownedByCurrentUser(); $comments = $this->getRepository()->match($spec); return [ 'comments' => $comments ]; } }
或创建其他依赖于它的规范构建器
class NewCommentsOwnedByCurrentUser extends AbstractSpecificationBuilder { public function buildSpecification(SpecificationFactory $spec, array $options) { return $spec->andX( $spec->ownedByCurrentUser(), $spec->gte('createdAt', new \DateTime('-5 days')) ); } }
您可以在控制器中使用 Specification 过滤表单。首先创建 FormType
class AppointmentChainFilterType extends AbstractType { public function buildForm(FormBuilderInterface $builder, array $options) { $builder ->add('text', 'text', [ 'specification' => function (SpecificationFactory $spec, $value) { return $spec->like([ 'field' => 'text', 'value' => $value ]); }, ]) ->add('status', 'choice', [ 'choices' => ['draft', 'posted', 'deleted'], 'specification' => 'in' 'specification_options' => [ 'field' => 'status' ], ]) ->addEventListener(FormEvents::POST_SUBMIT, function (FormEvent $event) { $form = $event->getForm(); $text = $form->get('text')->getNormData(); if ($text && strlen($text) < 3) { $form['text']->addError( new FormError("Search text should contains at least 3 symbols.") ); } }) ; } public function configureOptions(OptionsResolver $resolver) { $resolver->setDefaults([ 'specification' => 'andX', ]); } public function getName() { return 'posts_filter'; } public function getParent() { return 'resource_filter'; } }
通过此表单处理请求,获取 Specification 实例!
class PostController { public function indexAction(Request $request) { $specFactory = $this->get('specification.factory'); $specification = $specFactory->ownedByCurrentUser(); $filterForm = $this->createForm('posts_filter'); $filterForm->handleRequest($request); if ($filterForm->isValid() && $filterSpecification = $filterForm->getData()) { $specification = $specFactory->andX($filterSpecification, $specification); } $comments = $this->getRepository()->match($specification); // .... } }
通过一些扩展,可以使用 Sylius/ResoucreBundle 与规范一起使用。资源路由配置看起来像这样
sylius_product_index: path: /products/{tag} methods: [GET] defaults: _controller: sylius.controller.product:indexAction _sylius: specification: name: haveTag options: tag: $tag paginate: $limit