Php 如何在Silverstripe中将对象访问限制为$has_one成员?

Php 如何在Silverstripe中将对象访问限制为$has_one成员?,php,silverstripe,silverstripe-4,Php,Silverstripe,Silverstripe 4,我正在处理一个Silverstripe 4.3.1项目,该项目有一个对象,其所有者成员通过$has\u one: class Object extends DataObject { private static $has_one = [ 'Member' => Member::class, ]; 我们希望限制管理员和所有者成员查看/编辑对象的能力 下面是我们使用的代码: public function canView($member = null) {

我正在处理一个Silverstripe 4.3.1项目,该项目有一个对象,其所有者成员通过
$has\u one
:

class Object extends DataObject
{
    private static $has_one = [
        'Member' => Member::class,
    ];
我们希望限制管理员和所有者成员查看/编辑对象的能力

下面是我们使用的代码:

public function canView($member = null)
{
    return Permission::check('ADMIN') or
        $this->Member()->ID === Security::getCurrentUser()->ID or
        $this->Member()->ID === $member->ID;
}

public function canEdit($member = null)
{
    return Permission::check('ADMIN') or
        $this->Member()->ID === Security::getCurrentUser()->ID or
        $this->Member()->ID === $member->ID;
}
据我所知,这种方法过去是有效的,但最近的框架升级或代码更改已经破坏了它

我们当前收到以下PHP错误:

试图在包含
$this->Member()->ID


有谁能为我指出如何修复这些错误的正确方向吗?

可能是一些
对象
实例没有
成员集。在这些情况下,调用
this->Member()->ID将出错,因为
Member()
返回null

首先,我们应该检查
$this->Member()
是否用于
对象。如果不是,我们可以返回false

public function canView($member = null)
{
    if (Permission::check('ADMIN')) {
        return true;
    }

    if (!$this || !$this->exists()) {
        return false;
    }

    if (!$this->Member() || !$this->Member()->exists()) {
        return false;
    }

    if ($this->Member()->ID === $member->ID) {
        return true;
    }

    if ($this->Member()->ID === Security::getCurrentUser()->ID) {
        return true;
    }

    return false;
}

public function canEdit($member = null)
{
    if (Permission::check('ADMIN')) {
        return true;
    }

    if (!$this || !$this->exists()) {
        return false;
    }

    if (!$this->Member() || !$this->Member()->exists()) {
        return false;
    }

    if ($this->Member()->ID === $member->ID) {
        return true;
    }

    if ($this->Member()->ID === Security::getCurrentUser()->ID) {
        return true;
    }

    return false;
}

作为旁注,当您知道不应该允许时,通常最好返回false,否则返回null以允许更高级别的组件也执行检查。如果返回true,则删除所有更高的逻辑以运行。示例:
Permission::check('ADMIN')
是在
DataObject::canView()
中完成的,因此如果(!$this->Member()->exists()){return false}则可以执行类似于
的操作,否则返回parent::canView($Member)
或其他操作(没有仔细查看实际的问题示例)