Php 在保存到编辑表单之前获取相关类实例的健壮方法

Php 在保存到编辑表单之前获取相关类实例的健壮方法,php,silverstripe,Php,Silverstripe,将标准ModelAdmin与两个具有简单关系的对象一起使用具有一个关系。我希望在编辑MyDataObject时单击“添加HasManyDataObject”后访问相关对象。包括是一个真正的黑客,我不高兴,但工作。另一个黑客是从URL中删除ID。两者都不好 我希望能有这样的事情发生 $myDataObject = $this->MyDataObject(); ……但不是 令人沮丧的是,它确实在编辑表单中将对象指示为只读字段,因此它必须以某种方式可用 非常感谢所有的答案。我一次又一次地遇到这

将标准ModelAdmin与两个具有简单关系的对象一起使用具有一个关系。我希望在编辑MyDataObject时单击“添加HasManyDataObject”后访问相关对象。包括是一个真正的黑客,我不高兴,但工作。另一个黑客是从URL中删除ID。两者都不好

我希望能有这样的事情发生

$myDataObject = $this->MyDataObject();
……但不是

令人沮丧的是,它确实在编辑表单中将对象指示为只读字段,因此它必须以某种方式可用


非常感谢所有的答案。

我一次又一次地遇到这个问题。如您所知,无法访问主模型对象的原因是,在保存次模型之前,这些模型的每个DB表之间都没有关系。因此,如果模型的实例尚未保存,SilverStripe将无法为您提供该实例,以便它从中创建
DataObject
子类实例

正如您所发现的,解决方法是“刮取”主模型ID的URL,并将该状态保存在某个位置,例如会话或HTML5本地存储。通过使用
getURL()
查询当前控制器的
SS_-HTTPRequest
实例,有一些稍微不那么老练的方法可以提取该ID。您还可以从
params()
中获得一些里程-将其转储以查看您有权访问的内容。让框架帮助您解决问题:-)


祝你好运。

这里有一个古老的论坛帖子,用不同的解决方案处理相同的问题:


一些通过
GridFieldEditForm
注入
ParentID
,一些从当前的
控制器
参数获取它。

添加并使用以下函数返回“parent”对象

public static function GetParentObject($class) {
    $obj = null;

    $controller = Controller::curr();
    if ($controller->request->Param('ModelClass') == $class)
        $obj = $class::get()->ByID($controller->request->Param('ID'));

    if ($obj)
        return $obj;

    $url = $_SERVER['REQUEST_URI'];
    $start = $class.'/item/';
    $end = '/';
    $startpos = strpos($url,$start);
    $id = null;
    if ($startpos != false) {
        $startpos += strlen($start);
        $endpos = strpos($url,$end,$startpos);
        $id = substr($url,$startpos,$endpos - $startpos);
    }

    return $class::get()->ByID($id);
}

难道没有一个gridfield组件来创建一个新的has\u many组件吗?如果将现有项目添加为$has_one,则有hey@wmk如果有-然后回答,我将接受:)谢谢你的回答,不过它说的是“没有关系”,你能解释一下SS是如何链接对象的吗。。。如果没有可靠的方法来确定“父”对象。。。当然,SS必须使用另一种更健壮的方法?这似乎是一种比使用会话或抓取URL更好的方法,我接受你的回答,不过请你以一种清晰可用的方式(根据SO指南)添加论坛上的代码,我想我会这样做。。。因为这一定是SS在里面做的
public static function GetParentObject($class) {
    $obj = null;

    $controller = Controller::curr();
    if ($controller->request->Param('ModelClass') == $class)
        $obj = $class::get()->ByID($controller->request->Param('ID'));

    if ($obj)
        return $obj;

    $url = $_SERVER['REQUEST_URI'];
    $start = $class.'/item/';
    $end = '/';
    $startpos = strpos($url,$start);
    $id = null;
    if ($startpos != false) {
        $startpos += strlen($start);
        $endpos = strpos($url,$end,$startpos);
        $id = substr($url,$startpos,$endpos - $startpos);
    }

    return $class::get()->ByID($id);
}