According to this question How to load Symfony's config parameters from database (Doctrine) I have a similar problem. I need to set the parameter dynamically and I want to provide data from another custom service.
So, I have Event Listener which setting current account entity (by sub-domain or currently logged user)
namespace AppBundle\EventListener;
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorage;
use Doctrine\ORM\EntityManager;
use AppBundle\Manager\AccountManager;
use Palma\UserBundle\Entity\User;
/**
* Class CurrentAccountListener
*
* @package AppBundle\EventListener
*/
class CurrentAccountListener {
/**
* @var TokenStorage
*/
private $tokenStorage;
/**
* @var EntityManager
*/
private $em;
/**
* @var AccountManager
*/
private $accountManager;
private $baseHost;
public function __construct(TokenStorage $tokenStorage, EntityManager $em, AccountManager $accountManager, $baseHost) {
$this->tokenStorage = $tokenStorage;
$this->em = $em;
$this->accountManager = $accountManager;
$this->baseHost = $baseHost;
}
public function onKernelRequest(GetResponseEvent $event) {
$request = $event->getRequest();
$accountManager = $this->accountManager;
$accountManager->setCurrentAccount( $this->getCurrentAccount($request) );
}
private function getCurrentAccount($request){
if($this->getCurrentAccountByLoggedUser()) {
return $this->getCurrentAccountByLoggedUser();
}
if($this->getCurrentAccountBySubDomain($request) ) {
return $this->getCurrentAccountBySubDomain($request);
}
return;
}
private function getCurrentAccountBySubDomain($request) {
$host = $request->getHost();
$baseHost = $this->baseHost;
$subdomain = str_replace('.'.$baseHost, '', $host);
$account = $this->em->getRepository('AppBundle:Account')
->findOneBy([ 'urlName' => $subdomain ]);
if(!$account) return;
return $account;
}
private function getCurrentAccountByLoggedUser() {
if( is_null($token = $this->tokenStorage->getToken()) ) return;
$user = $token->getUser();
return ($user instanceof User) ? $user->getAccount() : null;
}
}
services.yml
app.eventlistener.current_account_listener:
class: AppBundle\EventListener\CurrentAccountListener
arguments:
- "@security.token_storage"
- "@doctrine.orm.default_entity_manager"
- "@app.manager.account_manager"
- "%base_host%"
tags:
- { name: kernel.event_listener, event: kernel.request, method: onKernelRequest }
And very simply account manager with setter and getter only. If I need access to current account I call
$this->get('app.manager.account_manager')->getCurrentAccount();
Everything works fine.
Now I am trying set some parameter from my service with compiler pass
namespace AppBundle\DependencyInjection\Compiler;
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder;
class ParametersCompilerPass implements CompilerPassInterface {
const ACCOUNT_MANAGER_SERVICE_ID = 'app.manager.account_manager';
public function process(ContainerBuilder $container) {
if(!$container->has(self::ACCOUNT_MANAGER_SERVICE_ID)) {
return;
}
$currentAccount = $container->get(self::ACCOUNT_MANAGER_SERVICE_ID)
->getCurrentAccount();
$container->setParameter(
'current_account', $currentAccount
);
}
}
AppBundle.php
namespace AppBundle;
use AppBundle\DependencyInjection\Compiler\ParametersCompilerPass;
use Symfony\Component\DependencyInjection\Compiler\PassConfig;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\HttpKernel\Bundle\Bundle;
class AppBundle extends Bundle
{
public function build(ContainerBuilder $container)
{
parent::build($container);
$container->addCompilerPass(new ParametersCompilerPass(), PassConfig::TYPE_AFTER_REMOVING);
}
}
I got current_account as null every time, no matter what PassConfig I use. Any ideas?
Thank you for your attention.
Compilation pass are executed when you run Symfony for the first time (CLI command or first http request). Once the cache is build (compiled) this code it never gets executed again.
Solution with parameters [I do not recommend this]
If your parameter can change from one to another HTTP Request you should not use a parameter as some services may be initialized before your parameter is ready and others after. Although if this is the way you want to go, you can add an event that listens to the kernel request and modify/set the parameter there. Have a look at https://symfony.com/doc/current/components/http_kernel.html#component-http-kernel-event-table
Current account in the user / session
If currentAccount
depends on the user logged, why you do not store that info in the user or session and access to it from your services?
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With