Reputation: 300
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
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