2017-11-15 300 views
6

Bu soruya How to load Symfony's config parameters from database (Doctrine) benzer bir sorunum var. Parametreyi dinamik olarak ayarlamalıyım ve başka bir özel hizmetten veri sağlamak istiyorum.Symfony'nin parametresini derleyici ile birlikte özel hizmetten geçirme

Yani,

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 (alt alan veya şu anda oturum açmış kullanıcı tarafından) cari varlık ayarı Etkinlik İşleyici

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 } 

Ve çok sade bir şekilde belirleyici ile yöneticisi hesabına sahip olmalı ve sadece alıcı. Cari hesaba erişim ihtiyacım olursa,

Her şey yolunda çalışır.

Şimdi olursa olsun kullandığınız PassConfig ben boş her zaman olduğu gibi current_account var

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

derleyici pass ile benim hizmetinden bazı parametreyi ayarlamak çalışıyorum . Herhangi bir fikir?

İlginiz için teşekkür ederiz.

cevap

1

Symfony'i ilk kez çalıştırdığınızda (CLI komutu veya ilk http isteği) derleme geçer. Önbellek bu kodu oluşturduktan (derlendiğinde) bir daha asla tekrar çalıştırılamaz. parametrelerle

Çözüm bazı hizmetler sizin parametreden önce başlatıldı edilebilir Parametreniz bir parametreyi kullanmamalısınız başka bir HTTP isteği için birinden değiştirebiliyorsanız

[Bunu önermiyoruz] hazır ve diğerleri ise sonra. Gitmek istediğiniz yol buysa da, çekirdek isteğini dinleyen ve oradaki parametreyi değiştiren/ayarlayan bir olay ekleyebilirsiniz. currentAccount Eğer hizmetlerinden kullanıcı veya buna oturum ve erişimde bu bilgi depolamak niye açmış kullanıcı bağlıdır Eğer kullanıcı/oturumda

yılında https://symfony.com/doc/current/components/http_kernel.html#component-http-kernel-event-table

Cari işlemler bir göz var mı?