kematjaya/base-controller-bundle
Composer 安装命令:
composer require kematjaya/base-controller-bundle
包简介
base component for traditional web application
README 文档
README
Base component for Symfony 6/7/8 applications providing reusable CRUD controllers, pagination, filtering, and custom form types.
Requirements
- PHP >= 8.1
- Symfony 6.4+ / 7.4+ / 8.0+
Installation
composer require kematjaya/base-controller-bundle
Add to config/bundles.php:
Kematjaya\BaseControllerBundle\BaseControllerBundle::class => ['all' => true]
Usage
Controller
// src/Controller/FooController.php namespace App\Controller; use App\Entity\Foo; use App\Form\FooType; use App\Filter\FooFilterType; use App\Repository\FooRepository; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\Routing\Attribute\Route; use Kematjaya\BaseControllerBundle\Controller\FilterBuilderController as BaseController; #[Route('/foo', name: 'foo_')] class FooController extends BaseController { #[Route('/', name: 'index', methods: ['GET', 'POST'])] public function index(Request $request, FooRepository $repo): Response { $form = $this->createFormFilter(FooFilterType::class); $queryBuilder = $this->buildFilter($request, $form, $repo->createQueryBuilder('this')); return $this->render('foo/index.html.twig', [ 'datas' => parent::createPaginator($queryBuilder, $request), 'filter' => $form->createView(), ]); } #[Route('/new', name: 'new', methods: ['GET', 'POST'])] public function new(Request $request): Response { $foo = new Foo(); // Ajax form processing $form = $this->createForm(FooType::class, $foo, [ 'attr' => ['id' => 'ajaxForm', 'action' => $this->generateUrl('foo_new')], ]); $result = parent::processFormAjax($request, $form); if ($result['process']) { return $this->json($result); } // Non-ajax form processing $form = $this->createForm(FooType::class, $foo, [ 'action' => $this->generateUrl('foo_new'), ]); $result = parent::processForm($request, $form); if ($result['process']) { return $this->redirectToRoute('foo_index'); } return $this->render('foo/form.html.twig', [ 'foo' => $foo, 'form' => $form->createView(), 'title' => 'new', ]); } #[Route('/{id}/show', name: 'show', methods: ['GET'])] public function show(Foo $foo): Response { return $this->render('foo/show.html.twig', [ 'foo' => $foo, ]); } #[Route('/{id}/edit', name: 'edit', methods: ['GET', 'POST'])] public function edit(Request $request, Foo $foo): Response { $form = $this->createForm(FooType::class, $foo, [ 'attr' => ['id' => 'ajaxForm', 'action' => $this->generateUrl('foo_edit', ['id' => $foo->getId()])], ]); $result = parent::processFormAjax($request, $form); if ($result['process']) { return $this->json($result); } $form = $this->createForm(FooType::class, $foo, [ 'action' => $this->generateUrl('foo_edit', ['id' => $foo->getId()]), ]); $result = parent::processForm($request, $form); if ($result['process']) { return $this->redirectToRoute('foo_index'); } return $this->render('foo/form.html.twig', [ 'foo' => $foo, 'form' => $form->createView(), 'title' => 'edit', ]); } #[Route('/{id}/delete', name: 'delete', methods: ['DELETE'])] public function delete(Request $request, Foo $foo): Response { $tokenName = 'delete'.$foo->getId(); parent::doDelete($request, $foo, $tokenName); return $this->redirectToRoute('foo_index'); } }
Form Type
// src/Form/FooType.php namespace App\Form; use Symfony\Component\Form\AbstractType; use Symfony\Component\Form\FormBuilderInterface; use Kematjaya\BaseControllerBundle\Type\PhoneNumberType; use Kematjaya\BaseControllerBundle\Type\DateRangeType; class FooType extends AbstractType { public function buildForm(FormBuilderInterface $builder, array $options): void { $builder->add('phone', PhoneNumberType::class, [ 'label' => 'phone', ]); $builder->add('dateRange', DateRangeType::class, [ 'label' => 'date range', 'from_options' => ['widget' => 'single_text'], 'to_options' => ['widget' => 'single_text'], ]); } }
Add to config/packages/twig.yaml:
twig: form_themes: - '@BaseController/phone_number_layout.html.twig'
Filter
Filter form based on SpiriitLabs FormFilterBundle (fork of LexikFormFilterBundle).
// src/Filter/FooFilterType.php namespace App\Filter; use Symfony\Component\Form\FormBuilderInterface; use Kematjaya\BaseControllerBundle\Filter\AbstractFilterType; class FooFilterType extends AbstractFilterType { public function buildForm(FormBuilderInterface $builder, array $options): void { $builder->add('roles', Filter\ChoiceFilterType::class, [ 'choices' => [], 'apply_filter' => $this->JSONQuery(), ]); } }
Available query helper methods (from FilterFunctionTrait):
JSONQuery()— query JSON columns with LIKEdateRangeQuery()— filter by date rangefloatRangeQuery()— filter by numeric range
Development
composer test # run PHPUnit tests composer phpstan # run static analysis (level 6) composer cs:check # check coding standards (dry-run) composer cs:fix # auto-fix coding standards
kematjaya/base-controller-bundle 适用场景与选型建议
kematjaya/base-controller-bundle 是一款 基于 PHP 开发的 Composer 扩展包,目前已累计 2.29k 次下载、GitHub Stars 达 3, 最近一次更新时间为 2020 年 11 月 20 日, 在 PHP 生态内属于活跃度较高的组件。
我们在过去多个企业项目中使用过 kematjaya/base-controller-bundle 或与其功能相近的方案,如果你在选型或落地过程中遇到问题,例如 版本兼容、二次改造、私有化封装、与内部系统对接、生产 BUG 排查,欢迎联系我们协助评估。
基于 kematjaya/base-controller-bundle 在你已有业务上做功能扩展、字段裁剪、UI 适配、与内部账号 / 权限 / 日志系统的深度对接。
线上偶发问题、内存泄漏、慢查询、并发异常等排查修复;针对高流量场景做缓存、队列、索引层面的调优。
承接完整的项目从需求 → 设计 → 开发 → 上线 → 长期运维;也可按月提供技术保姆服务。
统计信息
- 总下载量: 2.29k
- 月度下载量: 0
- 日度下载量: 0
- 收藏数: 3
- 点击次数: 4
- 依赖项目数: 1
- 推荐数: 0
其他信息
- 授权协议: MIT
- 更新时间: 2020-11-20