Last active
May 11, 2022 10:08
-
-
Save aokhrimenko/021a16d0f27a1a44e432657115759d42 to your computer and use it in GitHub Desktop.
Add "Quick create" option for Association fields. Works only with Doctrine ORM mapping in attributes and Uuid as entity identifier. The idea is to create new entity if submitted value is not a valid Uuid.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| namespace App\EventSubscriber; | |
| use App\Entity\SimpleCreate; | |
| use Doctrine\ORM\Mapping\ManyToOne; | |
| use Doctrine\Persistence\ManagerRegistry; | |
| use EasyCorp\Bundle\EasyAdminBundle\Config\Action; | |
| use EasyCorp\Bundle\EasyAdminBundle\Context\AdminContext; | |
| use EasyCorp\Bundle\EasyAdminBundle\Contracts\Controller\CrudControllerInterface; | |
| use EasyCorp\Bundle\EasyAdminBundle\Field\AssociationField; | |
| use Symfony\Component\DependencyInjection\ContainerInterface; | |
| use Symfony\Component\EventDispatcher\EventSubscriberInterface; | |
| use EasyCorp\Bundle\EasyAdminBundle\Event\BeforeCrudActionEvent; | |
| use Symfony\Component\Uid\Uuid; | |
| class BeforeCrudActionSubscriber implements EventSubscriberInterface | |
| { | |
| public function __construct(private ManagerRegistry $doctrine, private ContainerInterface $container) | |
| { | |
| } | |
| public static function getSubscribedEvents() | |
| { | |
| return [ | |
| BeforeCrudActionEvent::class => 'onBeforeCrudActionEvent', | |
| ]; | |
| } | |
| public function onBeforeCrudActionEvent(BeforeCrudActionEvent $event) | |
| { | |
| $context = $event->getAdminContext(); | |
| if (!$this->isNewOrEditPage($context) && 'POST' !== $context->getRequest()->getMethod()) { | |
| return; | |
| } | |
| $reflectionClass = new \ReflectionClass($context->getEntity()->getFqcn()); | |
| $shortClassName = $reflectionClass->getShortName(); | |
| $formData = $context->getRequest()->get($shortClassName); | |
| if (!$formData) { | |
| return; | |
| } | |
| $em = $this->doctrine->getManagerForClass($context->getEntity()->getFqcn()); | |
| $crudControllerFqcn = $context->getCrudControllers()->findCrudFqcnByEntityFqcn($context->getEntity()->getFqcn()); | |
| /** @var CrudControllerInterface $crudControllerInstance */ | |
| $crudControllerInstance = $this->container->get($crudControllerFqcn); | |
| foreach ($crudControllerInstance->configureFields($context->getCrud()->getCurrentPage()) as $field) { | |
| if (!$field instanceof AssociationField) { | |
| continue; | |
| } | |
| $propertyName = $field->getAsDto()->getProperty(); | |
| if (!isset($formData[$propertyName])) { | |
| continue; | |
| } | |
| if (Uuid::isValid($formData[$propertyName])) { | |
| continue; | |
| } | |
| $attrs = ($reflectionClass->getProperty($propertyName)->getAttributes(ManyToOne::class)); | |
| if (1 !== count($attrs)) { | |
| continue; | |
| } | |
| $args = $attrs[0]->getArguments(); | |
| if (!isset($args['targetEntity'])) { | |
| continue; | |
| } | |
| $implements = class_implements($args['targetEntity']); | |
| if (!$implements || !isset($implements[SimpleCreate::class])) { | |
| continue; | |
| } | |
| /** @var SimpleCreate $target */ | |
| $target = new $args['targetEntity']; | |
| $target->setText($formData[$propertyName]); | |
| $em->persist($target); | |
| $em->flush(); | |
| $formData[$propertyName] = (string)$target->getId(); | |
| } | |
| $context->getRequest()->request->set($shortClassName, $formData); | |
| } | |
| private function isNewOrEditPage(AdminContext $context): bool | |
| { | |
| return in_array($context->getCrud()->getCurrentAction(), [Action::NEW, Action::EDIT]); | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| namespace App\Controller\Admin; | |
| use App\Entity\Example; | |
| use EasyCorp\Bundle\EasyAdminBundle\Controller\AbstractCrudController; | |
| use EasyCorp\Bundle\EasyAdminBundle\Field\AssociationField; | |
| use EasyCorp\Bundle\EasyAdminBundle\Field\TextField; | |
| class ExampleCrudController extends AbstractCrudController | |
| { | |
| public static function getEntityFqcn(): string | |
| { | |
| return Example::class; | |
| } | |
| public function configureFields(string $pageName): iterable | |
| { | |
| yield TextField::new('name'); | |
| yield AssociationField::new('type') | |
| ->setFormTypeOption('attr.data-ea-autocomplete-allow-item-create', 'true'); // this option adds "Add" functioality | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| namespace App\Entity; | |
| use Symfony\Component\Uid\Uuid; | |
| interface SimpleCreate | |
| { | |
| public function getId(): ?Uuid; | |
| public function setText(string $text): self; | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment