Как сделать Symfony универсальным универсальным избирателем - PullRequest
2 голосов
/ 17 июня 2019

Я внедряю избирателей в свою систему, и я не могу понять, как создать / расширить / внедрить более общий способ для избирателей.

У меня есть следующий избиратель (минимизированный):

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;

    }
}

Этот работает нормально, как и .Однако, я также хочу один для Новостей, Пейдж, Навыков, Фу и Бар.

Я мог бы просто скопировать этого избирателя и изменить верхние переменные.Но так как это единственные 3 изменения, я хочу какой-то общий избиратель, который я могу загружать со значениями, например, при конструировании, в результате чего получается более твердый код с реальной логикой в ​​одном месте.

Но если яРасширяйте класс Generic с помощью Voter, он автоматически загружает его.Я хочу, чтобы он игнорировал универсальный класс и в итоге получил что-то вроде:

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

Может ли кто-нибудь указать мне правильное направление?

1 Ответ

2 голосов
/ 17 июня 2019

Я могу представить две возможности:

Переместите логику 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
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...