简体   繁体   中英

Symfony entity manager as a service

i'm creatin a custom class what i what to use as a service in my app to provide DB data into different areas, so i have a form builder that before create i need to pass a list of users, so i'm creating a service:

Site/Bundle/Services/UserService:

    <?php


namespace Mangocele\coreBundle\Services;
use Doctrine\ORM\EntityManager;
use Symfony\Component\DependencyInjection\ContainerInterface as Container;


class UserService {
    protected $entities;

    public function __construct($em){
        $this->entities = $em->getRepository('MangoceleUserBundle:User')->findAll();
    }
    public function getEntities(){
        return $this->entities;
    }
}

Then i'm registering in my bundle service.yml:

services:
    my.custom.service.id:
        class: Mangocele\coreBundle\Services\UserService
        arguments: ["@doctrine.orm.entity_manager"]

Importing in app/config:

imports:
...
    - { resource: "@MangocelecoreBundle/Resources/config/services.yml" }

and trying to call it in my form builder calls[Mangocele\\coreBundle\\Form]:

<?php

namespace Mangocele\coreBundle\Form;

use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;

use Mangocele\coreBundle\Services\UserService;
use Mangocele\UserBundle\Entity\User;
use Mangocele\UserBundle\Form\UserType;

use Doctrine\ORM\EntityManager;



class EmpresasType extends AbstractType
{


    private function getUserData(){
        $userEntities = $this->get('my.custom.service.id');
        $entities = $userEntities->getEntities();
    }



    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $userEntities = $this->get('my.custom.service.id');
        $entities = $userEntities->getEntities();
        print_r($entities);
        die();
    }
}

but at the end when i try to get the result i got this error:

UndefinedMethodException: Attempted to call method "get" on class "Mangocele\coreBundle\Form\EmpresasType" in /Applications/XAMPP/xamppfiles/htdocs/mangocele/site/src/Mangocele/coreBundle/Form/EmpresasType.php line 29. Did you mean to call: "getName", "getParent"?

not sure what i'm doing wrong. thanks in advance.

The reason your service isn't available using the $this->get() or $this->container->get() is because you are using Controller methods/properties in a object that doesn't have the same methods or properties.

The base Symfony Controller has the @service_container injected into it meaning that you can use

$this->container->get('some.kind.of.service');

which get the injected container and then "gets" the service from that. When you call

$this->get('some.kind.of.service');

from in the controller it is just a method that calls the previous $this->container->get() action.

Your Type Issue

To use your service in your form type you need to pass it in as an argument in your service file like you did with your UserService .

services:
    my.custom.form.type:
        class: Mangocele\coreBundle\Form\EmpresasType
        arguments:
            - @my.custom.service.id
        tags:
            - { name: form.type, alias: the.same.as.the.return.from.getName() }

And then you would use this in your type like so..

class EmpresasType extends AbstractType
{
    protected $userService;

    public function __construct(UserService $userService)
    {
        $this->userService = $userService;
    }

    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $userEntities = $this->userService->getEntities();
        print_r($entities);
        die();
    }

    public getName()
    {
        return 'the.same.as.the.alias';
    }
}

While this will work there are a few issues with your approach that you may wish to clear up.

Firstly you are creating a service that replicates a tiny part of the functionality of a repository. You could, instead, create and inject a repository.

Generate a repository

services:
    mangocele.repository.user:
        class: Doctrine\Common\Persistence\ObjectRepository
        factory_service: doctrine # this is an instance of Registry
        factory_method: getRepository
        arguments:
            - "MangoceleUserBundle:User"

Then inject the repository to you Type as mentioned previously and use it in your Type like so..

class EmpresasType extends AbstractType
{
    protected $userRepository;

    public function __construct(RepostoryInterface $userRepsitory)
    {
        $this->userRepsitory = $userRepository;
    }

    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $userEntities = $this->userRepository->getAll();
        print_r($entities);
        die();
    }

    ....
}

Secondly , from what I can guess (although I may be wrong here so I apologise if I am) you are passing the users into your Type so that they are selectable in some kind of form field. You can, however, use a form field that calls the repository itself and uses the actual entities to create your dropdown/radio buttons, checkboxes like so..

namespace ....

use Doctrine\ORM\EntityRepository;
use ... etc.

class EmpresasType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('users', 'entity', array(
                                   // Entity class
                'class'         => 'MangoceleUserBundle:User',
                                   // Display field
                'property'      => 'username',
                                   // Closure with repository query
                'query_builder' => function(EntityRepository $repo) {
                    return $repo->createQueryBuilder('u')
                        ->orderBy('u.name', 'ASC');
                },
                'multiple'      => false,
                'expanded'      => false,
            ))
        ;
    }
}

Then you can add the multiple and expanded stuff as mentioned on http://symfony.com/doc/current/reference/forms/types/choice.html#select-tag-checkboxes-or-radio-buttons

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM