2013-08-14 6 views
8

मैं इस कोड के बराबर और बहुत सारे नियंत्रक कार्यों में चल रहा हूं, मूल रूप से यह उपयोगकर्ता के उपयोगकर्ता नाम को पकड़ता है, और यदि वह उपयोगकर्ता नाम किसी ब्लॉग इकाई से जुड़ा हुआ है तो यह उपयोगकर्ता को अनुमति देगा ब्लॉग इकाई को देखने के लिए:Symfony2 सेवा में उपयोगकर्ता और सिद्धांत

$em = $this->getDoctrine()->getManager(); 
    $user = $this->get('security.context')->getToken()->getUser(); 
    $entities = $em->getRepository('MySiteBundle:Blog')->findBy(array('user' => $user)); 

    return $this->render('MySiteBundle:Blog:index.html.twig', array(
     'entities' => $entities, 

मैं इसे एक सेवा में ले जाना चाहता हूं ताकि मैं कोड पुनरावृत्ति पर कटौती कर सकूं। मैं जितना संभव हो अपने नियंत्रकों में ज्यादा तर्क करने से बचना चाहता हूं।

कहा जा रहा है, मुझे यकीन नहीं है कि मैं सेवा में उपयोगकर्ता सत्र और सिद्धांत का उपयोग कैसे कर सकता हूं।

यहाँ मेरी services.yml है:

mysite.user.blog: 
    class: MySite\SiteBundle\Services\BlogUser 

और यहाँ है कि कैसे मैं नियंत्रक में इसे कहते हैं प्रयास किया गया था:

public function testAction() { 
    $response = $this->get('mysite.user.blog'); 
    return new Response($response); 
} 

मैं एक घटना subscriber/listener टैग का उपयोग कर प्रयास किया, लेकिन है कि 'नहीं करता है मैं चाहता हूं कि काम पूरा करने के लिए प्रतीत होता है।

यहां सेवा में मेरा पूरी तरह से भयानक प्रयास है। मुझे कन्स्ट्रक्टर का उपयोग किए बिना इससे कोई प्रतिक्रिया नहीं मिल सका।

namespace MySite\SiteBundle\Services; 

use MySite\SiteBundle\Entity\Blog; 

class BlogUser { 

    protected $entities; 

    public function __construct(){ 
     $em = $this->getDoctrine()->getManager(); 
     $user = $this->get('security.context')->getToken()->getUser(); 
     $this->entities = $em->getRepository('MySiteBundle:Blog')->findBy(array('user' => $user)); 
    } 
} 

क्या मैं इस बारे में पूरी तरह से गलत तरीके से जा रहा हूं? क्या कोई बेहतर तरीका है कि मैं याद कर रहा हूं?

संपादित करें/उत्तर:

संशोधित मेरी नामकरण परंपरा एक छोटे से:

//services.yml 
mysite.user.blog.entities: 
    class: Mysite\SiteBundle\Services\BlogUser 
    arguments: ["@doctrine.orm.entity_manager", "@security.context"] 

नियंत्रक कार्रवाई में:

$userEntities = $this->get('mysite.user.blog.entities'); 
$entities = $userEntities->getEntities(); 

सेवा को खुद में:

class BlogUser { 

    protected $entities; 

    public function __construct($em, $securityContext){ 
     $user = $securityContext->getToken()->getUser(); 
     $this->entities = $em->getRepository('MySiteBundle:Blog')->findBy(array('user' => $user)); 
    } 
    public function getEntities(){ 
     return $this->entities; 
    } 
} 

अभी भी जरूरत है नियंत्रक में $ entities चर प्राप्त करने के लिए दो पंक्तियां, लेकिन यह वही चीज़ को परिभाषित करने से बेहतर तरीका है।

उत्तर

11

"Security.context" पदावनत किया गया है Symfony 2.6 के बाद से

कुछ समुदाय के बाद चर्चाएं, यह निर्णय लिया गया कि सुरक्षा कॉन्टेक्स्ट देता है एक साधारण टोकन/उपयोगकर्ता ऑब्जेक्ट को पुनर्प्राप्त करने के लिए बहुत अधिक निर्भरताएं। यही कारण है कि, सिम्फनी 2.6 से शुरू, इन सुरक्षा। कॉन्टेक्स्ट सेवा को हटा दिया गया है और दो नई सेवाओं में विभाजित किया गया है: security.authorization_checker और security.token_storage।

Source

इस प्रकार, कर यह होगा, पहले कॉन्फ़िगर करने के लिए आपकी सेवा नए तरीके के रूप में:

mysite.user.blog: 
    class: MySite\SiteBundle\Services\BlogUser 
    arguments: ["@doctrine.orm.entity_manager", "@security.token_storage"] 
फिर

सेवा वर्ग निर्माता में:

class BlogUser 
{ 
    protected $user; 
    protected $entities; 

    public function __construct(EntityManager $em, TokenStorage $tokenStorage) 
    { 
     $this->user = $tokenStorage->getToken()->getUser(); 
     $this->entities = $em->getRepository('MySiteBundle:Blog')->findBy(array('user' => $user)); 
    } 
} 
2

आप अपनी कस्टम सेवा में अन्य सेवाओं को इंजेक्ट करने के तरीके पर विचार कर रहे हैं। Service Container दस्तावेज़ीकरण पर एक नज़र डालें।

अपने मामले में, आप doctrine.orm.entity_manager और security.context सेवाओं को अपने BlogUser कक्षा में कन्स्ट्रक्टर इंजेक्शन के माध्यम से इंजेक्ट कर सकते हैं।

class BlogUser { 

    public function __construct($em, $securityContext) { 
     $user = $securityContext->getToken()->getUser(); 
     $this->entities = $em->getRepository('MySiteBundle:Blog')->findBy(array('user' => $user)); 
    } 

} 

और निम्नलिखित के रूप में अपनी सेवा को कॉन्फ़िगर: उदाहरण के लिए:

mysite.user.blog: 
    class: MySite\SiteBundle\Services\BlogUser 
    arguments: ["@doctrine.orm.entity_manager", "@security.context"] 
+2

के बाद के रूप में symfony v। 2.6 सुरक्षा संदर्भ को बहिष्कृत किया गया है: http://symfony.com/doc/current/book/security.html – 11mb

5

हाँ, आप इसे गलत तरीके से में कर रहे हैं। के अपने कोड पर नजर डालते हैं:

# call to undefined object method getDoctrine() 
    $em = $this->getDoctrine()->getManager(); 
    # call to undefined object method get() 
    $user = $this->get('security.context')->getToken()->getUser(); 

आप entitymanager और security.context अपने नियंत्रक में की तरह एक ही तरीके से आपकी सेवा में हो रही फोन नहीं कर सकते हैं। इसके बजाय, आपको इकाई प्रबंधक और security.context सेवाओं को इंजेक्ट करना होगा।उदाहरण:

# services.yml 
mysite.user.blog: 
    class: MySite\SiteBundle\Services\BlogUser 
    calls: 
     - [ setUserFromSecurityContext, [ @security.context ]] 
     - [ setEntityManager, [ @doctrine.orm.entity_manager ]] 

और बेहतर सेवा:

namespace Catablog\SiteBundle\Services; 

use MySite\SiteBundle\Entity\Blog; 

class BlogUser { 
    private $entityManager; 
    private $user; 

    public function setEntityManager(EntityManager $entityManager) 
    { 
     $this->entityManager = $entityManager; 
    } 

    public function setUserFromSecurityContext(SecurityContext $securityContext) 
    { 
     # notice, there are a cases when `getToken()` returns null, so improve this 
     $this->user = $securityContext->getToken()->getUser(); 
    } 
    public function getEntities(){ 
     # your code here 
    } 
} 

अधिक जानकारी के बारे में Dependency injection

+0

संपत्ति में कोई अंडरस्कोर नहीं रों! –

+1

@Pazi यह अभी भी मान्य गुण नाम है। – NHG

+0

क्या कॉल करता है: "सेवा का हिस्सा आपके द्वारा निर्दिष्ट कोई भी फ़ंक्शन चलाता है? क्या लचीलापन के अलावा कन्स्ट्रक्टर के बजाय इसका उपयोग करने का कोई फायदा है (या अलग-अलग सेवाओं द्वारा बुलाए गए एक ही कक्षा का फिर से उपयोग करना?) – gan

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