2017-11-15 22 views
6

से कंपाइलर पास के साथ सिम्फनी का पैरामीटर लोड करें इस प्रश्न के अनुसार How to load Symfony's config parameters from database (Doctrine) मुझे एक ही समस्या है। मुझे गतिशील रूप से पैरामीटर सेट करने की आवश्यकता है और मैं डेटा को दूसरी कस्टम सेवा से प्रदान करना चाहता हूं।कस्टम सेवा

तो, मैं घटना श्रोता जो चालू खाता इकाई की स्थापना

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 } 

और बहुत बस सेटर के साथ खाता प्रबंधक है और केवल गेटटर अगर मुझे वर्तमान खाते तक पहुंच की आवश्यकता है तो मैं

$this->get('app.manager.account_manager')->getCurrentAccount(); 

सब कुछ ठीक काम करता है।

अब मैं संकलक पास

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

मैं अशक्त हर बार के रूप में current_account मिला है, कोई बात नहीं क्या PassConfig मैं उपयोग के साथ मेरी सेवा से कुछ पैरामीटर सेट कोशिश कर रहा हूँ । कोई विचार?

आपके ध्यान के लिए धन्यवाद।

उत्तर

1

संकलन पास निष्पादित किया जाता है जब आप पहली बार सिम्फनी चलाते हैं (सीएलआई कमांड या पहला http अनुरोध)। एक बार जब कैश बनाया जाता है (संकलित) इस कोड को फिर से निष्पादित नहीं किया जाता है। मानकों के साथ

समाधान [मैं इस अनुशंसा नहीं करते हैं]

के रूप में कुछ सेवाओं अपने पैरामीटर से पहले प्रारंभ किया जा सकता है आपके पैरामीटर एक और HTTP अनुरोध आप एक पैरामीटर का उपयोग नहीं करना चाहिए एक से बदल सकते हैं तैयार और दूसरों है बाद। यद्यपि यदि आप जिस तरह से जाना चाहते हैं, तो आप एक ऐसा ईवेंट जोड़ सकते हैं जो कर्नेल अनुरोध को सुनता है और पैरामीटर को संशोधित/सेट करता है। उपयोगकर्ता/सत्र

में https://symfony.com/doc/current/components/http_kernel.html#component-http-kernel-event-table

वर्तमान खाते पर एक नज़र तो currentAccount लॉग इन उपयोगकर्ता, तुम क्यों उपयोगकर्ता या इसे करने के लिए सत्र और उपयोग अपनी सेवाओं से में यह जानकारी एकत्र नहीं करते पर निर्भर करता है है?

संबंधित मुद्दे