I have differents users and they can define his own categories (entity Category, OneToMany with User)
After, when they come to add a new BlogPost, I want to filter the Category by assigned to the user
How can I do this?
Well I have been solved this adding a repository dynamic call inside EasyAdminFormType:
// EasyAdminBundle/Form/Type/EasyAdminFormType.php
//...
class EasyAdminFormType extends AbstractType
{
//...
protected $repository_function;
protected $repository_arguments;
public function buildForm(FormBuilderInterface $builder, array $options)
{
//...
foreach ($entityProperties as $name => $metadata) {
//...
if(isset($metadata["repository"])) {
$this->repository_function = $metadata["repository"]["function"];
$this->repository_arguments = $metadata["repository"]["params"];
$formFieldOptions["query_builder"] = function ($repository) {
return call_user_func_array(array($repository, $this->repository_function), $this->repository_arguments);
};
}
$formFieldType = $this->useLegacyFormComponent() ? $metadata['fieldType'] : $this->getFormTypeFqcn($metadata['fieldType']);
$builder->add($name, $formFieldType, $formFieldOptions);
}
}
//...
# easy_admin.yml
easy_admin:
entities:
BlogPost:
class: AppBundle\Entity\BlogPost
form:
fields:
#...
- { property: category, type_options: {required: true}, repository: {function: 'findAllByUsers', params: ['this could be optional', 'but arguments are awesome']} }
// AppBundle/Repository/CategoryRepository.php
//...
class CategoryRepository extends \Doctrine\ORM\EntityRepository
{
public function findAllByUsers($param1, $param2)
{
// do stuff
// important: needs return a queryBuilder object
$qb = $this->createQueryBuilder('c');
return $qb->->where('c.user = '$param1);
}
}
Edit: I have been post basically the concept of this, of course I will need send the user id as parameter
But would be interesting that easyadmin support repository function calls
If @javiereguiluz not think it necessary to include this feature, It can be closed
Sorry, I still don't have an opinion about this.
:+1:
@rubengc Did you have to copy/paste the original code for this? If yes, we might think about specific events we could throw from the FormType for example
@rubengc an awesome snippet, thanks! Added a compiler pass to replace EasyAdminFormType with the modified one and it works like a charm.
@Gyvastis i'm really fluent with compiler passes ;-)
Can you share your code or give a little explanation on how to do this ?
Thank you by advance
@dfinfo copy the EasyAdminFormType to your bundle, change the namespace & add the code that @rubengc suggested. Then add a compiler pass class to override the original form type service:
class OverrideEasyAdminFormTypeCompilerPass implements CompilerPassInterface
{
public function process(ContainerBuilder $container)
{
$definition = $container->getDefinition('easyadmin.form.type');
$definition->setClass(EasyAdminFormType::class); //this is your modified form class
}
}
And add the compiler pass to your main bundle class:
class YourBundle extends Bundle
{
public function build(ContainerBuilder $container)
{
parent::build($container);
$container->addCompilerPass(new OverrideEasyAdminFormTypeCompilerPass());
}
}
Thanks a lot, you saved my day and i'm beginning to see the light with this compiler stuff.
What about put this logic to custom configurator of JavierEguiluz\Bundle\EasyAdminBundle\Form\Type\Configurator\TypeConfiguratorInterface and don't override vendor class?
@grachevko suggestion works like a charm
class EntityConfigurator implements TypeConfiguratorInterface
{
private $repositoryFunction;
private $repositoryArguments;
public function configure($name, array $options, array $metadata, FormConfigInterface $parentConfig)
{
if (isset($metadata["repository"])) {
$this->repositoryFunction = $metadata["repository"]["function"];
$this->repositoryArguments = $metadata["repository"]["params"];
$options["query_builder"] = function ($repository) {
return call_user_func_array(
[
$repository,
$this->repositoryFunction,
],
$this->repositoryArguments ? $this->repositoryArguments : []
);
};
}
return $options;
}
public function supports($type, array $options, array $metadata)
{
return 'entity' === $type && 'association' === $metadata['type'];
}
}
//services.yml
AppBundle\Form\Type\Configurator\EntityConfigurator:
tags: { name: 'easyadmin.form.type.configurator' }
Most helpful comment
Well I have been solved this adding a repository dynamic call inside EasyAdminFormType:
Edit: I have been post basically the concept of this, of course I will need send the user id as parameter
But would be interesting that easyadmin support repository function calls