Skip to content

Instantly share code, notes, and snippets.

@dbu
Created August 2, 2012 09:42
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dbu/3235920 to your computer and use it in GitHub Desktop.
Save dbu/3235920 to your computer and use it in GitHub Desktop.
Use sonata ACL in list query
class UserAdmin
{
...
// i inject the security.context into the constructor to have it available
/**
* Alter list query to only see items i created
*/
public function createQuery($context = 'list')
{
/** @var $query \Doctrine\ORM\QueryBuilder */
$query = parent::createQuery($context);
// SELECT o FROM Liip\UserBundle\Entity\User o
// see only a limited set of results
$alias = $query->getRootAlias();
// always see myself
$query->where(
$query->expr()->eq("$alias.username", ':username')
);
$query->setParameter('username', $this->securityContext->getToken()->getUsername());
// always see users i created
$ownids = self::getOwnIds($query->getEntityManager(), $this->getClass(), $this->securityContext->getToken()->getUser());
if (!empty($ownids)) {
$query->orWhere($query->expr()->in("$alias.id", ':ownids'));
$query->setParameter('ownids', $ownids);
}
return $query;
}
/**
* Get all ids of objects of the given class owned by the given user
*
* Note: This needs to do a separate query as we do raw sql, which can not be mixed with
* the Doctrine DQL query for the entities.
*
* @param \Doctrine\ORM\EntityManager $em
* @param string $className the class to be managed
* @param mixed $user the user object
*
* @return array of object ids
*/
public static function getOwnIds(\Doctrine\ORM\EntityManager $em, $className, Sonata\UserBundle\Model\UserInterface $user)
{
$conn = $em->getConnection();
// TODO: can we let sonata generate this to be sure to not mess it up?
$userIdentity = get_class($user) . '-' . $user->getUsername();
$sql = "
SELECT object_identifier
FROM acl_object_identities
INNER JOIN acl_classes ON acl_object_identities.class_id = acl_classes.id
INNER JOIN acl_entries ON acl_object_identities.id = acl_entries.object_identity_id
INNER JOIN acl_security_identities ON acl_entries.security_identity_id = acl_security_identities.id
WHERE acl_classes.class_type = :className
AND acl_security_identities.identifier = :userIdentity
";
$stmt = $conn->prepare($sql);
$stmt->execute(array(':className' => $className, ':userIdentity' => $userIdentity));
$cols = $stmt->fetchAll(\PDO::FETCH_COLUMN);
$stmt->closeCursor();
return $cols;
}
}
@dbu
Copy link
Author

dbu commented Aug 3, 2012

updated to pass className and userIdentity as parameters, older versions of postgres do not like the unescaped backslashes from the PHP namespaces. with the parameter handling, pdo handles the escape for us.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment