找不到自定义后端FormAction处理程序


Custom backend FormAction handler not found

我的目标是在ModelAdmin中的DataObjects EditForm中添加一个自定义FormAction,紧邻"保存"answers"删除"操作。

设置:

使用updateCMSActions,我可以添加该按钮。

class MyActionEventExtension extends DataExtension {
    public function updateCMSActions(FieldList $actions) {
        if($this->owner->canEdit(Member::currentUser())) {
          $actions->push(FormAction::create('doMyAction', 'Action'));
        }
        return $actions;
    }
}

这个工作很好。

在stackoverflow上回答这个问题后,我为动作处理程序创建了一个LeftAndMainExtension

class MyActionLeftAndMainExtension extends LeftAndMainExtension {
    private static $allowed_actions = array(
        'doMyAction'
    );
    public function doMyAction($data, $form) {
        // Do stuff.
        // ... I never get here.

        // Return stuff
        $this->owner->response->addHeader(
            'X-Status',
            rawurlencode('Success message!') 
        );
        return $this->owner->getResponseNegotiator()
               ->respond($this->owner->request);
    }
}

对应的config.yml文件如下所示:

LeftAndMain:
  extensions:
    - MyActionLeftAndMainExtension
TheDataObject:
  extensions:
    - MyActionEventExtension

问题:

当我点击按钮时,响应给我"404 Not Found"。

请求的URL总是相同的:

http://localhost/admin/model-admin-url-slug/TheDataObject/EditForm/field/TheDataObject/item/878/ItemEditForm

我发现了其他一些解决方案,建议扩展ModelAdmins GridField。遗憾的是,这不是一个选项,因为我需要操作的数据对象有很多关系,这意味着,它的EditForm也出现在其他数据对象的EditForms(嵌套)中。

我真的没主意了。我是否错过了ModelAdmin中的某些内容?我创建的那个只实现了基本的静态变量,所以我没有把它贴在这里。

任何帮助将是伟大的!

更新:

我最后在我的ModelAdmin上提供了一个getEditForm方法。

public function getEditForm($id = null, $fields = null) {
    $form = parent::getEditForm($id, $fields);
    $listField = $form->Fields()->fieldByName($this->modelClass);
    if ($gridField = $listField->getConfig()->getComponentByType('GridFieldDetailForm')) {
        $gridField->setItemRequestClass('MyAdminForm_ItemRequest');
    }
    return $form;
}

和扩展GridFieldDetailForm_ItemRequest:

class MyAdminForm_ItemRequest extends GridFieldDetailForm_ItemRequest {
    private static $allowed_actions = array (
        'edit',
        'view',
        'ItemEditForm'
    );
    public function ItemEditForm() {
        $form = parent::ItemEditForm();
        $formActions = $form->Actions();
        // Adds all FormActions provided by the model's `getCMSActions` callback
        if ($actions = $this->record->getCMSActions()) {
            foreach ($actions as $action) {
                $formActions->push($action);
            }
        }
        return $form;
    }
    public function doAction($data, $form) {
        // do stuff here
    }
}

遗憾的是,这并没有在has_many或many_many关系网格上添加操作。正因为如此,我将保留这个问题的开放性和未解之谜。也许有一天会有更好的解决方案…:)

这个问题的一个非常简单的答案(如果它对你来说是一个选项)是使用Better Buttons模块:https://github.com/unclecheese/silverstripe-gridfield-betterbuttons#creating-a-custom-action

它允许您定义模型上的操作,从体系结构的角度来看,这有点可疑,但在Silverstripe和ModelAdmin的上下文中也工作得很好。