Dans mon dernier projet, j’ai dû lier une interface admin à un utilisateur, c’est-à-dire que je ne devais afficher que les objets que l’utilisateur a crée. Lorsqu’il crée un nouvel objet, on doit directement l’y associer.
Cette modification s’effectuer en 2 étapes, tous d’abord, on va lier l’utilisateur avec l’objet que l’on crée dans l’admin.
Au niveau de notre classe Admin, on doit définir la méthode getNewInstance
, ainsi qu’une méthode qui permet d’injecter le security context afin de récupérer l’utilisateur courant.
<?php
class ObjectAdmin extends Admin
{
private $context;
public function getNewInstance()
{
return new Object($this->getUser());
}
public function setSecurityContext($context)
{
$this->context = $context;
}
public function getUser()
{
$token = $this->context->getToken();
if (null !== $token) {
return $token->getUser();
}
return null;
}
}
Ensuite au niveau de notre fichier services.xml
on doit ajouter le security context
.
<service id="admin.object" class="%admin.object.class%">
<tag name="sonata.admin"/>
<call method="setSecurityContext">
<argument type="service" id="security.context"/>
</call>
</service>
Deuxième étape, on ne doit afficher que les objets de l’utilisateur, pour ce là, on doit étendre le ModelManager
et redéfinir la méthode createQuery
<?php
use Sonata\AdminBundle\Model\ORM\ModelManager;
class ObjectModelManager extends ModelManager
{
private $context;
public function __construct(EntityManager $em, $security_context)
{
parent::__construct($em);
$this->context = $security_context;
}
public function getUser()
{
$token = $this->context->getToken();
if (null !== $token) {
return $token->getUser();
}
return null;
}
public function createQuery($class, $alias = 'o')
{
$qb = parent::createQuery($class, $alias);
$qb->andWhere($alias.'.user = :user');
$qb->setParameter('user', $this->getUser());
return $qb;
}
}
Ensuite on doit ajouter un service associé a cette classe
<service id="admin.object.manager" class="%admin.object.manager%">
<argument type="service" id="doctrine.orm.entity_manager" />
<argument type="service" id="security.context" />
</service>
Et définir dans la configuration du projet que l’on veut utiliser notre classe.
# config.yml
sonata_admin:
admin_services:
admin.object:
model_manager: admin.object.manager