Cette question a commencé avec le fait que je ne comprenais pas pourquoi je ne pouvais pas passer de variables à une fonction d'assistance globale de symfony2 (service), mais grâce à des personnes plus lumineuses que moi, j'ai compris que mon erreur consistait à essayer d'utiliser le security_context à partir d'une classe ne ne pas l'avoir injecté alors ...
C'est le résultat final, le code qui fonctionne. Je n'ai trouvé aucun meilleur moyen de rendre cela utile à la communauté.
Voici comment vous pouvez obtenir l'utilisateur et d'autres données de security_context depuis une fonction globale ou une fonction d'assistance dans symfony2.
J'ai la classe et la fonction suivantes:
<?php
namespace BizTV\CommonBundle\Helper;
use Symfony\Component\DependencyInjection\ContainerInterface as Container;
class globalHelper {
private $container;
public function __construct(Container $container) {
$this->container = $container;
}
//This is a helper function that checks the permission on a single container
public function hasAccess($container)
{
$user = $this->container->get('security.context')->getToken()->getUser();
//do my stuff
}
}
... défini comme un service (dans app/config/config.yml) comme celui-ci ...
#Registering my global helper functions
services:
biztv.helper.globalHelper:
class: BizTV\CommonBundle\Helper\globalHelper
arguments: ['@service_container']
Maintenant, dans mon contrôleur, j'appelle cette fonction comme ceci ...
public function createAction($id) {
//do some stuff, transform $id into $entity of my type...
//Check if that container is within the company, and if user has access to it.
$helper = $this->get('biztv.helper.globalHelper');
$access = $helper->hasAccess($entity);
Je suppose que la première erreur (propriété non définie) s'est produite avant l'ajout de la propriété et du constructeur. Ensuite, vous avez la deuxième erreur. Cette autre erreur signifie que votre constructeur s'attend à recevoir un objet Container mais qu'il n'a rien reçu. En effet, lorsque vous avez défini votre service, vous n'avez pas indiqué au gestionnaire d'injection de dépendance que vous souhaitiez obtenir le conteneur. Changez votre définition de service en ceci:
services:
biztv.helper.globalHelper:
class: BizTV\CommonBundle\Helper\globalHelper
arguments: ['@service_container']
Le constructeur doit alors s'attendre à un objet de type Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\DependencyInjection\ContainerInterface as Container;
class globalHelper {
private $container;
public function __construct(Container $container) {
$this->container = $container;
}
Une approche qui fonctionne toujours, même si elle n’est pas la meilleure pratique en matière d’exploitation
global $kernel;
$assetsManager = $kernel->getContainer()->get('acme_assets.assets_manager');
Une autre option consiste à étendre ContainerAware:
use Symfony\Component\DependencyInjection\ContainerAware;
class MyService extends ContainerAware
{
....
}
ce qui vous permet d'appeler setContainer
dans la déclaration de service:
foo.my_service:
class: Foo\Bundle\Bar\Service\MyService
calls:
- [setContainer, [@service_container]]
Vous pouvez ensuite référencer le conteneur dans votre service comme ceci:
$container = $this->container;
Ce n’est peut-être pas la meilleure solution, mais ce que je fais, c’est que je passe le conteneur à la classe afin de l’avoir à chaque fois que j’en ai besoin.
$helpers = new Helpers();
or
$helpers = new Helpers($this->container);
/* My Class */
class Helpers
{
private $container;
public function __construct($container = null) {
$this->container = $container;
}
...
}
Travaille chaque fois pour moi.
Vous ne devez pas injecter le service_container
dans vos services. Dans votre exemple, vous devriez plutôt injecter l'ancien security.context
ou le plus récent security.token_storage
au lieu. Voir, par exemple, la section "Eviter que votre code ne dépende du conteneur" de http://symfony.com/doc/current/components/dependency_injection.html .
Ex:
<?php
namespace BizTV\CommonBundle\Helper;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorage;
class globalHelper {
private $securityTokenStorage;
public function __construct(TokenStorage $securityTokenStorage) {
$this->securityTokenStorage= $securityTokenStorage;
}
public function hasAccess($container)
{
$user = $this->securityTokenStorage->getToken()->getUser();
//do my stuff
}
}
app/config/config.yml:
services:
biztv.helper.globalHelper:
class: BizTV\CommonBundle\Helper\globalHelper
arguments: ['@security.token_storage']
Votre contrôleur:
public function createAction($id) {
$helper = $this->get('biztv.helper.globalHelper');
$access = $helper->hasAccess($entity);