Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

 
Reply to this topicStart new topic
> [SF] Translatable i ustawienie locale na podstawie sesji (services)
blackroger
post
Post #1





Grupa: Zarejestrowani
Postów: 176
Pomógł: 0
Dołączył: 8.11.2008

Ostrzeżenie: (0%)
-----


Prośba o pomoc.

mam zdefiniowany dodatek w services:

  1. services:
  2. # Doctrine Extension listeners to handle behaviors
  3.  
  4. gedmo.listener.translatable:
  5. class: Gedmo\Translatable\TranslatableListener
  6. tags:
  7. - { name: doctrine.event_subscriber, connection: default }
  8. calls:
  9. - [ setAnnotationReader, [ @annotation_reader ] ]
  10. - [ setTranslatableLocale, [ %locale% ] ]
  11. - [ setTranslationFallback, [ true ] ]
  12.  


Jak zrobić aby metoda setTranslatableLocale dostawała parametr z sesyjnego getLocale? Teraz parametr jest pobierany bezpośrednio z parametrs.ini, a ja chcę aby tam trafiała wartość z sesji...

Przy wielojęzyczności zmiany krajów powinny być transparentne dla systemu i wiem, że można sobie uruchamiać setTranslatableLocale w kontrolerze, ale mi chodzi o automat i service container.

Ten post edytował blackroger 29.03.2013, 13:00:55
Go to the top of the page
+Quote Post
blackroger
post
Post #2





Grupa: Zarejestrowani
Postów: 176
Pomógł: 0
Dołączył: 8.11.2008

Ostrzeżenie: (0%)
-----


Przy przekazaniu:
  1. gedmo.listener.translatable:
  2. class: Gedmo\Translatable\TranslatableListener
  3. tags:
  4. - { name: doctrine.event_subscriber, connection: default }
  5. calls:
  6. - [ setAnnotationReader, [ @annotation_reader ] ]
  7. - [ setTranslatableLocale, [ @request ] ]
  8. - [ setTranslationFallback, [ true ] ]
  9.  


Wyrzuca błąd:

ScopeWideningInjectionException: Scope Widening Injection detected: The definition "gedmo.listener.translatable" references the service "request" which belongs to a narrower scope. Generally, it is safer to either move "gedmo.listener.translatable" to scope "request" or alternatively rely on the provider pattern by injecting the container itself, and requesting the service "request" each time it is needed. In rare, special cases however that might not be necessary, then you can set the reference to strict=false to get rid of this error.
Go to the top of the page
+Quote Post
Crozin
post
Post #3





Grupa: Zarejestrowani
Postów: 6 476
Pomógł: 1306
Dołączył: 6.08.2006
Skąd: Kraków

Ostrzeżenie: (0%)
-----


Treść błędu zawiera klarowne wyjaśnienie i możliwe rozwiązania. Nie mniej jednak przeczytaj sobie poniższy artykuł: http://symfony.com/doc/master/cookbook/ser...ner/scopes.html
Go to the top of the page
+Quote Post
blackroger
post
Post #4





Grupa: Zarejestrowani
Postów: 176
Pomógł: 0
Dołączył: 8.11.2008

Ostrzeżenie: (0%)
-----


Hmmm... czytałem już ten artykuł ale do mojego przypadku nie za bardzo mogę dostosować którąś z opcji.

Class Gedmo\Translatable\TranslatableListener nie mogę w żaden sposób zmieniać, ani dodać settera (setter injection), ani grzebać w konstruktorze. Czytając po forach niektórzy sugerują uzycie dodatkowej klasy np. RequestInjector, która tworzyłaby funkcję serwisu proxy dla request:

  1. namespace Lib;
  2.  
  3. use Symfony\Component\DependencyInjection\ContainerInterface as Container;
  4.  
  5. class RequestInjector
  6. {
  7.  
  8. protected $container;
  9.  
  10. public function __construct(Container $container)
  11. {
  12. $this->container = $container;
  13. }
  14.  
  15. public function getRequest()
  16. {
  17. return $this->container->get('request');
  18. }
  19.  
  20. public function getLocale()
  21. {
  22. $this->container->get('request')->getLocale();
  23. }
  24. }
  25.  


Mam pytanie. Czy istnieje możliwość wywołania metody bezpośrednio na service?

  1. request_injector
  2. class: Lib\RequestInjector
  3. public: false
  4. arguments: ['@service_container']
  5.  
  6.  
  7.  
  8. gedmo.listener.translatable:
  9. class: Gedmo\Translatable\TranslatableListener
  10. tags:
  11. - { name: doctrine.event_subscriber, connection: default }
  12. calls:
  13. - [ setAnnotationReader, [ @annotation_reader ] ]
  14. - [ setTranslatableLocale, [ @request_injector ] ] # jak tu zwrócić samo getLocale?(IMG:style_emoticons/default/questionmark.gif) (IMG:style_emoticons/default/questionmark.gif) ?
  15. - [ setTranslationFallback, [ true ] ]
  16.  
  17.  


Czy da się tak zrobić, aby zwrócić do metody setTranslatableLocale sama wartość, poprzez wywołanie metody na RequestInjector? I czy to nie kłóci się z logiką services?

Ten post edytował blackroger 31.03.2013, 11:26:23
Go to the top of the page
+Quote Post
Crozin
post
Post #5





Grupa: Zarejestrowani
Postów: 6 476
Pomógł: 1306
Dołączył: 6.08.2006
Skąd: Kraków

Ostrzeżenie: (0%)
-----


Musiałbyś tutaj skorzystać z service-factory i factory-method. Zawsze jednak możesz utworzyć swoją własną klasę, dziedziczącą po Gedmo\Translatable\TranslatableListener dodać jej settera, który przyjmuje RequestInjectora i wywołuje dziedziczoną setTranslatableLocale().
Go to the top of the page
+Quote Post
blackroger
post
Post #6





Grupa: Zarejestrowani
Postów: 176
Pomógł: 0
Dołączył: 8.11.2008

Ostrzeżenie: (0%)
-----


Heh ...właśnie tak to załatwiam...TranslatableListenerService dziedziczący po TranslatableListener rozszerzający o setRequest....

Dobra nadal nie działa jak powinno....ehhh....

TranslatableListenerService:

  1.  
  2. namespace Lib\Service;
  3.  
  4. use Gedmo\Translatable\TranslatableListener;
  5. use Lib\RequestInjector;
  6.  
  7. class TranslatableListenerService extends TranslatableListener
  8. {
  9. public function setTranslatableLocale($locale)
  10. {
  11. if($locale instanceof RequestInjector)
  12. {
  13. $locale = $locale->getRequest()->getLocale();
  14. }
  15. echo $locale;exit;
  16. parent::setTranslatableLocale($locale);
  17. }
  18. }
  19.  


RequestInjector:

  1. namespace Lib;
  2.  
  3. use Symfony\Component\DependencyInjection\ContainerInterface as Container;
  4.  
  5. class RequestInjector
  6. {
  7.  
  8. protected $container;
  9.  
  10. public function __construct(Container $container)
  11. {
  12. $this->container = $container;
  13. }
  14.  
  15. public function getRequest()
  16. {
  17. return $this->container->get('request');
  18. }
  19.  
  20. public function getLocale()
  21. {
  22. return $this->getRequest()->getLocale();
  23. }
  24. }
  25.  


services.yml:

  1. gedmo.listener.translatable:
  2. class: Lib\Service\TranslatableListenerService
  3. tags:
  4. - { name: doctrine.event_subscriber, connection: default }
  5. calls:
  6. - [ setAnnotationReader, [ @annotation_reader ] ]
  7. - [ setTranslatableLocale, [ @request_injector ] ]
  8. - [ setTranslationFallback, [ true ] ]
  9.  



Nadal nie jest tak jak powinno. Przy clear cache:
[Symfony\Component\DependencyInjection\Exception\InactiveScopeException]
You cannot create a service ("request") of an inactive scope ("request").


Pomocy...



Ten post edytował blackroger 31.03.2013, 19:48:05
Go to the top of the page
+Quote Post
Crozin
post
Post #7





Grupa: Zarejestrowani
Postów: 6 476
Pomógł: 1306
Dołączył: 6.08.2006
Skąd: Kraków

Ostrzeżenie: (0%)
-----


Ponieważ próbujesz odwołać się do usługi request w momencie gdy nie jest ona dostępna. Wywołanie akcji z poziomu konsoli nie tworzy usługi request, nie tworzy w ogóle całego zasięgu request. Co musisz zrobić? Przed zwróceniem usługi request z poziomu RequestInjectora, sprawdź czy zasięg (scope) request jest w ogóle dostępny i aktywny przy pomocy ContainerInterface::isScopeActive().

Co zrobić w przypadku gdy nie jest? Metoda getLocale() może z powodzeniem zwrócić parametr default_locale, zaś metoda getRequest() powinna zwrócić NULL. Tutaj trzeba od razu zwrócić uwagę, że w przypadku gdy istnieje możliwość, że zamiast jakiejś usługi zostanie zwrócony NULL w definicji usługi korzystającej z owej niepewnej zależości powinno dodać się onInvalidReference=ignore.
Go to the top of the page
+Quote Post

Reply to this topicStart new topic
2 Użytkowników czyta ten temat (2 Gości i 0 Anonimowych użytkowników)
0 Zarejestrowanych:

 



RSS Aktualny czas: 27.09.2025 - 08:14