alexmorgan.cr
alexmorgan.cr

Reputation: 300

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.

Upvotes: 1

Views: 2629

Answers (1)

qooplmao
qooplmao

Reputation: 17759

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

Upvotes: 4

Related Questions