CRUD控制器
编辑本页CRUD控制器
CRUD控制器为Doctrine ORM实体提供CRUD操作(创建、显示、更新、删除)。每个CRUD控制器可以关联到一个或多个仪表板。
从技术上讲,这些CRUD控制器是常规的ob娱乐下载Symfony控制器所以你可以做任何你通常在控制器中做的事情,比如注入服务和使用快捷方式$ this - >渲染()
或$ this - > isGranted ()
.
CRUD控制器必须实现EasyCorp
,确保在控制器中定义了某些方法。的接口进行扩展,而不是实现接口AbstractCrudController
类。运行命令生成CRUD控制器的基本结构。
1
$PHP bin/console make:admin:crud
CRUD控制器页面
CRUD控制器的四个主要页面是:
指数
,显示实体列表,这些实体可以分页、按列排序,并使用搜索查询和筛选器进行优化;细节
,显示给定实体的内容;新
,允许创建新的实体实例;编辑
,允许更新给定实体的任何属性。
类中具有相同名称的四个操作生成这些页面AbstractCrudController
控制器。该控制器定义了其他次要动作(例如:删除
而且自动完成
),不匹配任何页面。
中这些操作的默认行为AbstractCrudController
适用于大多数后端,但你可以用几种方式自定义它:EasyAdmin事件,自定义EasyAdmin模板等。
页面名称和常量
有些方法需要一些CRUD页面的名称作为参数。你可以使用下列任意字符串:“指数”
,“细节”
,“编辑”
而且“新”
.如果您喜欢为这些值使用常量,请使用Crud: PAGE_INDEX
,Crud: PAGE_DETAIL
,Crud: PAGE_EDIT
而且Crud: PAGE_NEW
(它们在EasyCorp
类)。
CRUD控制器配置
CRUD控制器的唯一强制配置选项是由控制器管理的Doctrine实体的FQCN。它被定义为一个公共静态方法:
12 3 4 5 6 7 8 9 10 11 12 13 14 15
名称空间应用程序\控制器\管理;使用应用程序\实体\产品;使用EasyCorp\包\EasyAdminBundle\控制器\AbstractCrudController;类ProductCrudController扩展AbstractCrudController{//它必须返回Doctrine ORM实体的FQCN(全限定类名)公共静态函数getEntityFqcn():字符串{返回产品::类;}/ /……}
属性配置其余的CRUD选项configureCrud ()
方法:
12 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
名称空间应用程序\控制器\管理;使用EasyCorp\包\EasyAdminBundle\配置\Crud;使用EasyCorp\包\EasyAdminBundle\控制器\AbstractCrudController;类ProductCrudController扩展AbstractCrudController{/ /……公共函数configureCrud(Crud$crud):Crud{返回$crud->setEntityLabelInSingular ('...')->setDateFormat ('...')/ /……;}}
设计选项
12 3 4 5 6 7 8 9 10 11 12
公共函数configureCrud(Crud$crud):Crud{返回$crud//设置此选项,如果您希望页面内容横跨整个//浏览器宽度,而不是默认设置的最大宽度->renderContentMaximized ()//设置此选项,如果您喜欢侧栏(包含主菜单)//显示为窄列,而不是默认的展开设计->renderSidebarMinimized ();}
实体的选择
12 3 4 5 6 7 8 9 10 11 12 13 14 16 17 18 19 20 21 22
公共函数configureCrud(Crud$crud):Crud{返回$crud//用于在标题、按钮等中引用该实体的标签。->setEntityLabelInSingular (“产品”)->setEntityLabelInPlural (“产品”)//除字符串外,单数和复数标签方法的参数//可以是定义两个可空参数的闭包//在'index'和'new'页面中为空)和当前页面名称->setEntityLabelInSingular(fn (?产品$产品字符串,?$pageName) = >$产品?$产品->toString ():“产品”)->setEntityLabelInPlural (函数(?类别$类别字符串,?$pageName){返回“编辑”= = =$pageName?$类别->getLabel ():“类别”;})//管理实体所ob娱乐下载需的Symfony Security权限//(默认为none,所以你可以管理实体的所有实例)->setEntityPermission (“ROLE_EDITOR”);}
标题和帮助选项
的页面标题指数
而且新
页面基于实体的选择定义的值setEntityLabelInSingular ()
而且setEntityLabelInPlural ()
方法。在细节
而且编辑
页面,EasyAdmin首先尝试将实体转换为字符串表示,否则退回到通用标题。
你可以用以下方法覆盖默认的页面标题:
12 3 4 5 6 7 8 9 10 11 12 13 14 16 17 18 19 20 21 22
公共函数configureCrud(Crud$crud):Crud{返回$crud//在页面顶部可见的标题和元素的内容 //它可以包含这些占位符:// %entity_name%, %entity_as_string%,// %entity_id%, %entity_short_id%// % entity_label_单数%,% entity_label_复数%->setPageTitle (“指数”,“% entity_label_plural %清单”)//你可以传递一个PHP闭包作为标题的值->setPageTitle (“新”, fn () =>新\ DateTime (“现在”) >新\ DateTime (今天下午的) ?“新晚餐”:“新午餐”)//在DETAIL和EDIT页中,闭包接收当前实体//作为第一个参数->setPageTitle (“细节”, fn(乘积$产品) =>(字符串)$产品)->setPageTitle (“编辑”, fn(分类$类别) => sprintf(“编辑< b > % s < / b > ',$类别->getName ()))//显示给最终用户的帮助信息(可以包含HTML标签)->setHelp (“编辑”,'...');}
日期、时间和数字格式选项
12 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
公共函数configureCrud(Crud$crud):Crud{返回$crud//参数必须是以下字符串之一:'short', 'medium', 'long', 'full', 'none'//(字符串也可以作为\EasyCorp\Bundle\EasyAdminBundle\Field\DateTimeField::FORMAT_* constants)//或有效的ICU日期时间模式(见https://unicode-org.github.io/icu/userguide/format_parse/datetime/)->setDateFormat ('...')->setTimeFormat ('...')//第一个参数=日期时间模式或日期格式;第二个可选参数=时间格式->setDateTimeFormat ('...','...')->setDateIntervalFormat ('%%y年%%m月%%d日')->setTimezone ('...')//该选项使数值用sprintf()呈现//调用,使用该值作为第一个参数。//该选项覆盖所有数值的任何格式化选项//(例如setNumDecimals(), setRoundingMode()等被忽略)// NumberField和IntegerField可以用他们的//拥有setNumberFormat()方法,以相同的方式工作->setNumberFormat (“% .2d”);;}
搜索、顺序和分页选项
12 34 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
公共函数configureCrud(Crud$crud):Crud{返回$crud//进行搜索的Doctrine实体属性的名称//(默认在所有属性中查找)->setSearchFields ([“名字”,“描述”])//使用点(例如:'seller.email')在教义关联中搜索->setSearchFields ([“名字”,“描述”,“seller.email”,“seller.address.zipCode”])//将其设置为null以禁用和隐藏搜索框->setSearchFields (零)//当加载'index'页面时,调用此方法自动聚焦搜索输入->setAutofocusSearch ()//定义应用于实体列表的初始排序//(用户稍后可以通过单击表列来更改这种排序)->setDefaultSort ([“id”= >“DESC”])->setDefaultSort ([“id”= >“DESC”,“标题”= >“ASC”,“startsAt”= >“DESC”])//您可以根据Doctrine关联进行排序,最多可分为两个级别->setDefaultSort ([“seller.name”= >“ASC”])//每个页面显示的最大实体数->setPaginatorPageSize (30.)//在当前页面的每一侧显示的页数//例如,如果num pages = 35, current page = 7 and set ->setPaginatorRangeSize(4)//分页器显示:[Previous] 1…3 4 5 6[7] 8 9 10 11…35(下)//设置这个数字为0来显示一个简单的“<上一个|下一个>”的页面->setPaginatorRangeSize (4)//这些是与Doctrine Pagination相关的高级选项//(见https://www.doctrine-project.org/projects/doctrine-orm/en/2.7/tutorials/pagination.html)->setPaginatorUseOutputWalkers (真正的)->setPaginatorFetchJoinCollection (真正的);}
对象中显示的实体列表指数
页面考虑了排序配置,可选的搜索查询,可选的过滤器还有页码。如果需要完全自定义此查询,请重写createIndexQueryBuilder ()
方法。
模板和表单选项
12 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
公共函数configureCrud(Crud$crud):Crud{返回$crud//这个方法允许使用你自己的模板来渲染某个部分//,而不是使用EasyAdmin默认模板//第一个参数是“模板名”,与// Twig路径,但没有' @EasyAdmin/ '前缀和' .html. txt '。树枝的后缀->overrideTemplate (“crud /场/ id”,“管理/字段/ my_id.html.twig”)//当呈现该实体的表单时要使用的主题//(除了EasyAdmin默认主题之外)->addFormTheme (“foo.html.twig”)//该方法覆盖所有现有的表单主题(包括//默认的EasyAdmin表单主题->setFormThemes ([“my_theme.html.twig”,“admin.html.twig”])//设置整个表单的选项(稍后,您可以设置选项//每个表单类型的相关字段的方法)//传递一个数组参数,为new和edit表单应用相同的选项->setFormOptions ([“validation_groups”= > [“默认”,“my_validation_group”]]);//传递两个数组参数,为new和edit表单应用不同的选项//(如果你想对某些表单不应用任何选项,则传递一个空数组参数)->setFormOptions ([“validation_groups”= > [“my_validation_group”]], [“validation_groups”= > [“默认”),'...'= >'...'),);;}
创建或编辑实体后自定义重定向
默认情况下,当创建或编辑实体时单击“保存”按钮时,您将被重定向到上一页。如果要更改此行为,请重写getRedirectResponseAfterSave ()
方法。
例如,如果你添加了一个自定义动作“保存并查看详细信息”,你可能更喜欢在保存更改后重定向到详细信息页面:
12 3 4 5 6 7 8 9 10 11 12 13 14 15
受保护的函数getRedirectResponseAfterSave(AdminContext$上下文、字符串$行动):RedirectResponse{$submitButtonName=$上下文->getRequest ()->请求->所有()(“ea”][“newForm中将”][“btn”];如果(“saveAndViewDetail”= = =$submitButtonName) {$url=$这->get (AdminUrlGenerator::类)->setAction(行动::细节)->setEntityId ($上下文->getEntity ()->getPrimaryKeyValue ())->generateUrl ();返回$这->重定向($url);}返回父::getRedirectResponseAfterSave ($上下文,$行动);}
不同CRUD控制器相同配置
如果您希望在所有CRUD控制器中执行相同的配置,则不需要在每个控制器中重复配置。相反,添加configureCrud ()
方法和所有控制器将继承该配置:
12 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
使用EasyCorp\包\EasyAdminBundle\配置\Crud;使用EasyCorp\包\EasyAdminBundle\配置\指示板;使用EasyCorp\包\EasyAdminBundle\控制器\AbstractDashboardController;类DashboardController扩展AbstractDashboardController{/ /……公共函数configureCrud():Crud{返回Crud::新()//定义所有CRUD控制器的分页大小//(如果需要,每个CRUD控制器都可以覆盖这个值)->setPaginatorPageSize (30.);}}
字段
字段允许显示您的Doctrine实体的内容CRUD页面.EasyAdmin提供了内置字段来显示所有常用数据类型,但您也可以这样做创建自己的字段.
如果您的CRUD控制器从AbstractCrudController
,则自动配置。在指数
在页面中,您将看到一些字段,在其余的页面中,您将看到尽可能多的字段,以显示Doctrine实体的所有属性。
读了关于田野的章节了解如何配置在每个页面上显示哪些字段,如何配置每个字段呈现的方式,等等。
定制CRUD动作
默认的CRUD动作(index ()
,详细信息()
,编辑()
,新()
而且delete ()
方法)实现应用程序中最常用的行为。
自定义它们的行为的第一种方法是在你自己的控制器中覆盖这些方法。然而,原始的操作是如此通用,以至于它们包含了相当多的代码,所以重写它们并不那么方便。
相反,您可以重写其他较小的方法,这些方法实现CRUD操作所需的某些特性。例如,index ()
操作调用名为createIndexQueryBuilder ()
创建Doctrine查询构建器,用于获取显示在索引清单上的结果。如果希望自定义该清单,最好重写createIndexQueryBuilder ()
方法,而不是整个index ()
方法。有很多这样的方法,所以您应该检查EasyCorp
类。
定制CRUD操作的另一种替代方法是使用EasyAdmin触发的事件,例如BeforeCrudActionEvent
而且AfterCrudActionEvent
.
创建、持久化和删除实体
CRUD控制器的大多数操作最终都是创建、持久化或删除实体。如果您的CRUD控制器从AbstractCrudController
,这些方法已经实现,但是您可以自定义它们覆盖方法和监听事件。
首先,您可以重写createEntity ()
,updateEntity ()
,persistEntity ()
而且deleteEntity ()
方法。的createEntity ()
方法仅执行返回new $entityFqcn()
,所以如果你的实体需要传递构造函数参数或设置它的一些属性,你需要覆盖它:
12 3 4 5 6 7 8 9 10 11 12 13 14 16 17 18 19 20 21 22
名称空间应用程序\控制器\管理;使用应用程序\实体\产品;使用EasyCorp\包\EasyAdminBundle\控制器\AbstractCrudController;类ProductCrudController扩展AbstractCrudController{公共静态函数getEntityFqcn():字符串{返回产品::类;}公共函数createEntity(字符串$entityFqcn){$产品=新产品();$产品->createdBy ($这->getUser ());返回$产品;}/ /……}
重写此行为的另一种方法是监听EasyAdmin触发的事件当创建、更新、持久化、删除实体时。
向CRUD模板传递附加变量
中实现的默认CRUD操作AbstractCrudController
不要像往常一样结束$ this - >渲染(……)
指令来呈现一个Twig模板并在Symfony中返回它的内容ob娱乐下载响应
对象。
相反,CRUD操作返回一个EasyCorp
对象,并将变量传递给呈现CRUD操作内容的模板。这KeyValueStore
object与Symfony的类似ob娱乐下载ParameterBag
对象。它就像一个面向对象的数组,具有一些有用的方法,例如get ()
,设置()
,有()
等。
在结束每个CRUD操作之前,它们的KeyValueStore
对象传递给调用的方法configureResponseParameters ()
你可以在你自己的控制器中覆盖这些模板变量来添加/删除/更改:
12 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
名称空间应用程序\控制器\管理;使用应用程序\实体\产品;使用EasyCorp\包\EasyAdminBundle\配置\Crud;使用EasyCorp\包\EasyAdminBundle\配置\KeyValueStore;使用EasyCorp\包\EasyAdminBundle\控制器\AbstractCrudController;类ProductCrudController扩展AbstractCrudController{/ /……公共函数configureResponseParameters(KeyValueStore$responseParameters):KeyValueStore{如果(Crud::PAGE_DETAIL = = =$responseParameters->get (“pageName”)) {$responseParameters->集(“foo”,'...');//键支持“点表示法”,所以你可以得到/set嵌套//用圆点分隔的值:$responseParameters->setIfNotSet (“方法”,'...');/ /这相当于:$参数['酒吧'][foo '] = '...'}返回$responseParameters;}}
您可以添加或多或少的参数KeyValueStore
对象作为您需要的。唯一的必选参数是任意一个templateName
或templatePath
分别设置作为CRUD操作结果呈现的模板的名称或路径。
模板名称和模板路径
EasyAdmin用于呈现其内容的所有模板都是可配置的。这就是为什么EasyAdmin处理“模板名称”而不是普通的Twig模板路径。
模板名称与模板路径相同,但不包含@EasyAdmin
前缀和.html.twig
后缀。例如,@EasyAdmin / layout.html.twig
其中为EasyAdmin提供的内置布局模板。然而,布局
指“在应用程序中配置为布局的任何模板”。
使用模板名称而不是路径使您可以在保留所有定制模板的同时,充分灵活地定制应用程序行为。在Twig模板中,使用ea.templatePath ()
函数获取与给定模板名关联的Twig路径:
1 2 3 4 5 6 7
<divid=“穿衣”>{{包括(ea.templatePath(“flash_messages”))}}div>{%如果Some_value为空%}{{包括(ea.templatePath(“标签/空”))}}{%endif%}
生成管理员url
作为解释在关于仪表板的文章中,给定仪表板的所有url都使用相同的路由,它们只在查询字符串参数中有所不同。不必处理这个问题,您可以使用AdminUrlGenerator
服务在PHP代码中生成url。
在生成URL时,不需要从头开始。EasyAdmin重用当前请求中存在的所有查询参数。这样做是有目的的,因为基于当前URL生成新URL是最常见的场景。使用unsetAll ()
方法删除所有现有查询参数:
12 34 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
名称空间应用程序\控制器\管理;使用EasyCorp\包\EasyAdminBundle\控制器\AbstractCrudController;使用EasyCorp\包\EasyAdminBundle\路由器\AdminUrlGenerator;类SomeCrudController扩展AbstractCrudController{私人$adminUrlGenerator;公共函数__construct(AdminUrlGenerator$adminUrlGenerator){$这->adminUrlGenerator =$adminUrlGenerator;}/ /……公共函数someMethod(){//不是在构造函数中注入AdminUrlGenerator服务,//你也可以从控制器动作中获取它,如下所示:// $adminUrlGenerator = $this->get(adminUrlGenerator::class);//现有的查询参数被维护,所以您只需//必须传递你想要更改的值。$url=$这->adminUrlGenerator->集(“页面”,2)->generateUrl ();//您可以删除现有的参数$url=$这->adminUrlGenerator->设置(“menuIndex”)->generateUrl ();$url=$这->adminUrlGenerator->unsetAll ()->集(“foo”,“someValue”)->generateUrl ();// URL生成器为最常见的参数提供快捷方式$url=$这->adminUrlGenerator->setController (SomeCrudController::类)->setAction (“theActionName”)->generateUrl ();/ /……}}
提示
方法中,如果出于任何原因需要手动处理管理url,则查询字符串参数的名称将定义为常量EA类。
在模板中也可以使用完全相同的特性ea_url ()
树枝的功能。在模板中,可以省略对generateUrl ()
方法(它将自动为您调用):
1 2 3 4 5 6 7 8 9
{#两者相等#}{%集url = ea_url({page: 2}).generateUrl() %}{%集Url = ea_url({page: 2}) %}{%集Url = ea_url()。集(“页面”,2)%}{%集url = ea_url() .setController('App\\控制器\\Admin\\SomeCrudController') .setAction('theActionName') %}
从EasyAdmin外部生成CRUD url
当从EasyAdmin外部(例如从一个常规的Symfony控制器)生成EasyAdmin页面的url时ob娱乐下载管理上下文变量不可用。这就是为什么必须始终设置与URL关联的CRUD控制器。如果你有多个仪表盘,你还必须设置仪表盘:
12 34 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42
使用应用程序\控制器\管理\DashboardController;使用应用程序\控制器\管理\ProductCrudController;使用EasyCorp\包\EasyAdminBundle\配置\行动;使用EasyCorp\包\EasyAdminBundle\路由器\AdminUrlGenerator;使用ob娱乐下载\包\FrameworkBundle\控制器\AbstractController;类Someob娱乐下载SymfonyController扩展AbstractController{私人$adminUrlGenerator;公共函数__construct(AdminUrlGenerator$adminUrlGenerator){$这->adminUrlGenerator =$adminUrlGenerator;}公共函数someMethod(){//如果你的应用程序只包含一个Dashboard,那就足够了//定义与该URL相关的控制器$url=$这->adminUrlGenerator->setController (ProductCrudController::类)->setAction(行动::指数)->generateUrl ();//在包含多个Dashboard的应用程序中,你也必须这样做//定义与URL关联的Dashboard$url=$这->adminUrlGenerator->setDashboard (DashboardController::类)->setController (ProductCrudController::类)->setAction(行动::指数)->generateUrl ();//某些操作可能需要传递额外的参数$url=$这->adminUrlGenerator->setController (ProductCrudController::类)->setAction(行动::编辑)->setEntityId ($产品->getId ())->generateUrl ();/ /……}}
这同样适用于在Twig模板中生成的url:
12 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
{#如果你的应用程序只定义了一个Dashboard #}{%集url = ea_url() .setController('App\\控制器\\Admin\\ProductCrudController') .setAction('index') %}{#如果你更喜欢PHP常量,使用这个:.setAction(constant('EasyCorp\\Bundle\\ \ adminbundle \\Config\\Action::INDEX')) #}{#如果你的应用程序定义了多个dashboard #}{%集url = ea_url() .setDashboard('应用\控制器\Admin\ DashboardController') .setController('应用\控制器\Admin\ ProductCrudController') .setAction('index') %}{#某些操作可能需要传递额外的参数#}{%集url = ea_url() .setController('App\\Controller\\Admin\\ProductCrudController') .setAction('edit') .setEntityId(product.id) %}