在保存在编辑表单之前获取相关类实例的强大方法

时间:2016-05-30 12:17:03

标签: php silverstripe

使用标准ModelAdmin和两个具有简单has_one关系的对象。我希望在点击" Add HasManyDataObject"之后访问相关对象。在编辑MyDataObject时。包括一个真正的黑客,我不满意,但工作。另一个黑客是将ID从URL中删除。两个都不好

class MyModelAdmin extends ModelAdmin {
    static $managed_models = array('MyDataObject');
    static $url_segment = 'mymodeladmin';
    static $menu_title = 'MyModelAdmin';
    static $model_importers = array();
}

class MyDataObject extends DataObject {
    private static $db = array('Name' => 'Varchar(255)');
    private static $has_many = array('HasManyDataObjects' => 'HasManyDataObject');

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

    Session::set('MyDataObjectID',$this->ID);
    Session::save();

        return $fields;
    }
}

class HasManyDataObject extends DataObject {
    private static $db = array('Name' => 'Varchar(255)');
    private static $has_one = array('MyDataObject' => 'MyDataObject');

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

        $myDataObject = MyDataObject::get()->ByID(Session::get('MyDataObjectID'));

        return $fields;
    }
}

我希望期待这样的工作......

$myDataObject = $this->MyDataObject();

......但没有。

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

非常感谢所有答案。

3 个答案:

答案 0 :(得分:3)

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

解决方法就像您已经发现的那样,以及#34;刮擦"主模型ID的URL并将该状态保存在某处,例如会话或HTML5 localStorage。通过使用SS_HTTPRequest查询当前控制器的getURL()实例,可以稍微减少拉出该ID的方法。您可能还会从params()中获得一些里程 - 将其转储以查看您有权访问的内容。让框架帮助你解决问题: - )

祝你好运。

答案 1 :(得分:0)

这里有一个旧的论坛帖子处理各种解决方案的相同问题: http://www.silverstripe.org/community/forums/data-model-questions/show/21517?start=8

有些人通过ParentID注入GridFieldEditForm,有些人从当前的Controller参数中获取它。

答案 2 :(得分:0)

添加并使用以下函数将返回“父”对象...

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);
}