Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/64.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Silverstripe 4-通过getCMSFields添加FormAction_Silverstripe_Silverstripe 4 - Fatal编程技术网

Silverstripe 4-通过getCMSFields添加FormAction

Silverstripe 4-通过getCMSFields添加FormAction,silverstripe,silverstripe-4,Silverstripe,Silverstripe 4,目标: 我有一个叫做“事件”的数据对象。这是在“EventsAdmin”(扩展ModelAdmin)的托管_模型中。编辑事件时,我希望记录上有一个名为“审核”的选项卡,该选项卡有几个字段和两个按钮:“批准”和“拒绝”。这两个按钮分别调用执行相关操作的操作 事件扩展数据对象 public function getCMSFields() { $fields = parent::getCMSFields(); $eventStatus = $fields->dataFieldB

目标:

我有一个叫做“事件”的数据对象。这是在“EventsAdmin”(扩展ModelAdmin)的托管_模型中。编辑事件时,我希望记录上有一个名为“审核”的选项卡,该选项卡有几个字段和两个按钮:“批准”和“拒绝”。这两个按钮分别调用执行相关操作的操作

事件扩展数据对象

public function getCMSFields() {
    $fields = parent::getCMSFields();

    $eventStatus = $fields->dataFieldByName("EventStatus")
        ->setTitle('Current Status')
        ->setDisabled(true);

    $approveButton = FormAction::create('doApproveEvent', _t('SiteBlockAdmin.Approve', 'Approve'))
        ->setUseButtonTag(true)
        ->addExtraClass('btn-outline-success font-icon-check-mark-circle');

    $rejectButton = FormAction::create('doRejectEvent', _t('SiteBlockAdmin.Reject', 'Reject'))
        ->setUseButtonTag(true)
        ->addExtraClass('btn-outline-danger font-icon-cancel-circled');

    $fields->addFieldsToTab('Root.Moderation', [
        $eventStatus,
        $approveButton,
        $rejectButton
    ]);

    return $fields;
}
这显示的按钮很好。但他们什么也不做。因此,我试图找出它们如何插入到操作方法doApproveEvent和doRejectEvent中(以及它们应该放在哪里)

我确实找到了一些文档,这些文档引导我通过updateFormActions()将按钮添加到CMS页面底部的操作栏中。但这不是我想要的,因为我在按钮上方添加的其他字段是批准/拒绝流程的一部分。下面是此方法的代码。除非按钮不在我试图创建的流程的逻辑位置,否则这可以正常工作

class CMSActionButtonExtension extends DataExtension
{
    public function updateFormActions(FieldList $actions)
    {
        $record = $this->owner->getRecord();

        if (!$record instanceof Event || !$record->exists()) {
            return;
        }

        $approveButton = FormAction::create('doApproveEvent', _t('SiteBlockAdmin.Approve', 'Approve'))
            ->setUseButtonTag(true)
            ->addExtraClass('btn-outline-success font-icon-check-mark-circle');

        $rejectButton = FormAction::create('doRejectEvent', _t('SiteBlockAdmin.Reject', 'Reject'))
            ->setUseButtonTag(true)
            ->addExtraClass('btn-outline-danger font-icon-cancel-circled');

        $actions->push($approveButton);
        $actions->push($rejectButton);

    }

    public function doApproveEvent($data, $form) {
        $record = $this->owner->getRecord();

        // Approve logic
    }

    public function doRejectEvent($data, $form) {
        $record = $this->owner->getRecord();

        // Reject logic
    }

}
上述扩展名附加到GridFieldDetailForm_ItemRequest

扩展名.yml

SilverStripe\Forms\GridField\GridFieldDetailForm_ItemRequest:
  extensions:
    - My\Namespace\CMSActionButtonExtension
有趣的是,如果我在页面上同时有两组按钮,updateFormActions选项可以工作,而我想要的选项仍然不能工作。尽管按钮具有相同的标记,并且位于完全相同的表单标记中。我假设这与Silverstripe如何加载主内容面板和DOM有关


有没有想过要达到这个目标?有人看到我可以查看的模块中添加到CMS主面板的按钮吗?我找到了5年前的帖子,但它是针对SS3的,答案对我不适用。

简短回答:
您必须通过控制表单(或表单本身)的控制器上的扩展添加自定义表单

长答案

关于SilverStripe是如何生成表单的一些背景信息:

一般来说,表单总是通过控制器/请求处理程序提供(它们需要在某些路由上可访问,通常这是控制器上的一个操作,通常命名为Form、EditForm、ItemEditoForm等等)

  • 字段
    在CMS内部,您很少需要创建自己的表单,这是由CMS为管理区域内置的控制器/请求处理程序完成的(
    GridFieldDetailForm\u ItemRequest

    基本上(此处为伪代码),这些控制器所做的是:

    public function EditForm() {
       $fields = $myCurrentlyEditingDataObject->getCMSFields();
       $actions = ...;
       $validator = ...;
       $this->updateFormActions(&$actions);
       $form = new Form('ItemRequestForm', $fields, $actions, $validator);
       $this->updateItemEditForm(&$form); // or $this->updateEditForm()
       return $form;
    }
    
    因此,
    getCMSFields()
    以及在某些情况下
    getCMSActions()
    /
    getCMSValidator()
    (不确定这两个字段是否仍在SilverStripe 4.x中使用),您可以向表单添加内容,而不必查看表单对象

    同样,“代码”> GETCMsFieldSDS()/Case>将始终放入窗体的“``”部分,这就是为什么您的按钮位于中间的所有字段而不是其他动作。

  • 提交
    提交表单时(例如提交到
    /admin/pages/edit/EditForm/265/field/NameOfMyGridField/item/542/ItemEditForm
    ),它将调用操作
    GridFieldDetailForm\u ItemRequest->ItemEditForm()
    ,该操作返回
    表单
    对象,随后
    表单请求处理程序->httpSubmission()调用
    。然后查看提交的数据,找出单击了什么操作(例如
    $\u REQUEST['action\u doapprovevent']
    ),并尝试查找该操作。
    它试图找到它的方法是检查它本身是否有一个名为
    doapprovevent
    的方法,如果失败,它将尝试
    Form->getController()->doapprovevent()
    或类似的东西。在
    GridField
    的情况下,该控制器是
    GridFieldDetailForm\u ItemRequest
    ,这意味着它将尝试调用
    GridFieldDetailForm\u ItemRequest->doApproveEvent()


  • 因此,这意味着
    DataObject->getCMSFields()
    可以让您轻松地将FormFields(和FormActions)添加到表单体中。
    但它没有提供一种添加方法来处理提交的方法

    这就是为什么,对于自定义操作,您需要修改控制器(
    GridFieldDetailForm\u ItemRequest,在本例中为
    )。
    为此,您可以创建一个
    扩展名
    ,并将其附加到
    GridFieldDetailForm\u ItemRequest
    扩展中的任何方法都会添加到它所附加的对象中,因此如果添加一个名为
    updateFormActions
    的方法,它将有点像
    GridFieldDetailForm\u ItemRequest->updateFormActions()

    如果您回忆起前面的内容,则在创建表单期间,控制器将调用
    $this->updateFormActions()

    此外,正如我前面所解释的,当一个FormAction被命名为
    doapprovevent
    时,它将查找
    GridFieldDetailForm\u ItemRequest->doapprovevent()
    ,它现在存在,因为您通过该
    扩展添加了它

    总之,您必须通过控制表单(或表单本身)的控制器上的扩展添加自定义表单


    附言:来自中国的旧帖子
    您链接到的bummzack在3.x中工作,因为他示例中创建表单的控制器是
    LeftAndMain

    的一个实例,我假设CMSActionButtonExtension连接到表单或gridfield组件?您还可以包括用于该操作的config.yml吗please@Zauberfisch是的,没错。GridFieldDetailForm\u ItemR确切地说,我已经用配置更新了我的帖子。