【问题标题】:How to make Symfony multi-entity generic Voter如何制作 Symfony 多实体通用 Voter
【发布时间】:2019-06-17 07:25:53
【问题描述】:

我正在我的系统中实现选民,但我不知道如何为选民创建/扩展/实施更通用的方式。

我有以下选民(缩小):

class EventVoter extends Voter {
    private $roleBaseName = 'ROLE_EVENT';
    private $classname = Event::class;
    private $ownershipMethod = 'getCreatedBy';

    protected function supports($attribute, $subject) {
        // Only vote on {$this->classname} objects
        if (!$subject instanceof $this->classname) {
            return false;
        }
        return true;
    }

    protected function voteOnAttribute($attribute, $subject, TokenInterface $token) {
        // Check if you own this specific entry:
        return $subject->{$this->ownershipMethod} === $user;

    }
}

这个可以正常工作。但是,我还想要一个用于 News、Page、Skill、Foo 和 Bar。

我可以复制这个选民并更改顶部变量。但由于这些是仅有的 3 个更改,我想要某种通用选民,我可以加载值,例如在构造上,产生更可靠的代码,真正的逻辑在一个地方。

但如果我用 Voter 扩展 Generic 类,它会自动加载它。我希望它忽略泛型类,并最终得到类似:

class EventVoter extends GenericVoter
{
    private $roleBaseName = 'ROLE_EVENT';
    private $classname = Event::class;
    private $ownershipMethod = 'getCreatedBy';

    // Possibly, if required at all:
    protected function voteOnAttribute($attribute, $subject, TokenInterface $token){
        return parent::voteOnAttribute($attribute, $subject,$token)
    }
}

谁能指出我正确的方向?

【问题讨论】:

  • 我想检查您是否可以查看新闻以及是否可以查看事件等。它们都有相同的逻辑要检查。你能写一个关于实体+接口的简单例子吗?听起来像是我可能想要的东西。并且抽象类可能也是,不确定你是否可以扩展那些,但值得一试

标签: php symfony


【解决方案1】:

我能想到两种可能:

ownershipMethod 逻辑移动到接口并在您的实体中实现它,在supports 中检查该接口。您仍然需要一些逻辑来计算角色。

class GenericVoter extends Voter {
    protected function supports($attribute, $subject) {
        if (!$subject instanceof OwnershipInterface) {
            return false;
        }
        return true;
    }

    protected function voteOnAttribute($attribute, $subject, TokenInterface $token) {
        return $subject->getOwnership() === $user;
    }
}

interface OwnershipInterface {
    public function getOwnership();
}

/**
 * @Entity
 */
class Event implements OwnershipInterface {
    public function getOwnership() {
       return $this->getCreatedBy();
    }
}

另一种是将你的GenericVoter声明为abstract,这样就不会自动加载了:

abstract class GenericVoter extends Voter {
    abstract public function getOwnershipMethod();
    abstract public function getRole();
    abstract public function getClass();

    protected function supports($attribute, $subject) {
        if (!$subject instanceof $this->getClass()) {
            return false;
        }
        return true;
    }

    protected function voteOnAttribute($attribute, $subject, TokenInterface $token) {
      return $subject->{$this->getOwnershipMethod()} === $user;
    }
}

class EventVoter extends GenericVoter {
    public function getClass() {
        return Event:class;
    }
    // Implement other abstract functions
}

【讨论】:

  • 第一个示例可能是我正在寻找的,尤其是将所有权功能移至实体。我现在要试一试:)
  • 界面建议正是我想要的。只有一个投票者可以处理多个实体,而无需为每个实体创建投票者,谢谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-08-21
  • 1970-01-01
  • 2015-10-02
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多