From bf9a5c1b5f0ce001d795a05bc4f915831b128932 Mon Sep 17 00:00:00 2001 From: Sadicov Vladimir Date: Thu, 25 Jan 2018 13:38:45 +0200 Subject: [PATCH 01/44] make:crud command initial commit --- src/Maker/MakeCrud.php | 133 ++++++++++++++++ src/Resources/help/MakeCrud.txt | 5 + .../controller/ControllerWithTwig.tpl.php | 145 ++++++++++++++++++ src/Resources/skeleton/crud/form/Type.tpl.php | 25 +++ .../skeleton/crud/templates/edit.tpl.php | 22 +++ .../skeleton/crud/templates/index.tpl.php | 27 ++++ .../skeleton/crud/templates/new.tpl.php | 9 ++ .../skeleton/crud/templates/show.tpl.php | 28 ++++ 8 files changed, 394 insertions(+) create mode 100644 src/Maker/MakeCrud.php create mode 100644 src/Resources/help/MakeCrud.txt create mode 100644 src/Resources/skeleton/crud/controller/ControllerWithTwig.tpl.php create mode 100644 src/Resources/skeleton/crud/form/Type.tpl.php create mode 100644 src/Resources/skeleton/crud/templates/edit.tpl.php create mode 100644 src/Resources/skeleton/crud/templates/index.tpl.php create mode 100644 src/Resources/skeleton/crud/templates/new.tpl.php create mode 100644 src/Resources/skeleton/crud/templates/show.tpl.php diff --git a/src/Maker/MakeCrud.php b/src/Maker/MakeCrud.php new file mode 100644 index 000000000..bb4e15ca0 --- /dev/null +++ b/src/Maker/MakeCrud.php @@ -0,0 +1,133 @@ + + */ +final class MakeCrud extends AbstractMaker +{ + private $router; + + private $entityManager; + + public function __construct(RouterInterface $router, EntityManagerInterface $entityManager) + { + $this->router = $router; + $this->entityManager = $entityManager; + } + + public static function getCommandName(): string + { + return 'make:crud'; + } + + /** + * {@inheritdoc} + */ + public function configureCommand(Command $command, InputConfiguration $inputConfig) + { + $command + ->setDescription('Creates crud for Doctrine entity class') + ->addArgument('entity-class', InputArgument::OPTIONAL, sprintf('The class name of the entity to create crud (e.g. %s)', Str::asClassName(Str::getRandomTerm()))) + ->setHelp(file_get_contents(__DIR__.'/../Resources/help/MakeCrud.txt')) + ; + } + + /** + * {@inheritdoc} + */ + public function configureDependencies(DependencyBuilder $dependencies) + { + $dependencies->addClassDependency( + Route::class, + 'annotations' + ); + + $dependencies->addClassDependency( + TwigBundle::class, + 'twig-bundle' + ); + + $dependencies->addClassDependency( + EntityManagerInterface::class, + 'orm-pack' + ); + } + + /** + * {@inheritdoc} + */ + public function interact(InputInterface $input, ConsoleStyle $io, Command $command) + { + } + + /** + * {@inheritdoc} + */ + public function getParameters(InputInterface $input): array + { + $entityClassName = Str::asClassName($input->getArgument('entity-class')); + Validator::validateClassName($entityClassName); + $controllerClassName = Str::asClassName($entityClassName, 'Controller'); + Validator::validateClassName($controllerClassName); + $formClassName = Str::asClassName($entityClassName, 'Type'); + Validator::validateClassName($formClassName); + + $metadata = $this->entityManager->getClassMetadata('App\\Entity\\'.$entityClassName); + + return [ + 'controller_class_name' => $controllerClassName, + 'entity_var_plural' => lcfirst(Inflector::pluralize($entityClassName)), + 'entity_var_singular' => lcfirst(Inflector::singularize($entityClassName)), + 'entity_class_name' => $entityClassName, + 'entity_identifier' => $metadata->identifier[0], + 'entity_fields' => $metadata->fieldMappings, + 'form_class_name' => $formClassName, + 'route_path' => Str::asRoutePath(str_replace('Controller', '', $controllerClassName)), + 'route_name' => Str::asRouteName(str_replace('Controller', '', $controllerClassName)), + ]; + } + + /** + * {@inheritdoc} + */ + public function getFiles(array $params): array + { + return [ + __DIR__.'/../Resources/skeleton/crud/controller/ControllerWithTwig.tpl.php' => 'src/Controller/'.$params['controller_class_name'].'.php', + __DIR__.'/../Resources/skeleton/crud/form/Type.tpl.php' => 'src/Form/'.$params['form_class_name'].'.php', + __DIR__.'/../Resources/skeleton/crud/templates/index.tpl.php' => 'templates/'.$params['route_name'].'/index.html.twig', + __DIR__.'/../Resources/skeleton/crud/templates/show.tpl.php' => 'templates/'.$params['route_name'].'/show.html.twig', + __DIR__.'/../Resources/skeleton/crud/templates/new.tpl.php' => 'templates/'.$params['route_name'].'/new.html.twig', + __DIR__.'/../Resources/skeleton/crud/templates/edit.tpl.php' => 'templates/'.$params['route_name'].'/edit.html.twig', + ]; + } + + /** + * {@inheritdoc} + */ + public function writeNextStepsMessage(array $params, ConsoleStyle $io) + { + if (!count($this->router->getRouteCollection())) { + $io->text(' Warning! No routes configuration defined yet.'); + $io->text(' You should probably uncomment the annotation routes in config/routes.yaml'); + $io->newLine(); + } + $io->text('Next: Check your new crud!'); + } +} diff --git a/src/Resources/help/MakeCrud.txt b/src/Resources/help/MakeCrud.txt new file mode 100644 index 000000000..9ec8d05bc --- /dev/null +++ b/src/Resources/help/MakeCrud.txt @@ -0,0 +1,5 @@ +The %command.name% command generates crud controller with templates for selected entity. + +php %command.full_name% BlogPost + +If the argument is missing, the command will ask for the entity class name interactively. \ No newline at end of file diff --git a/src/Resources/skeleton/crud/controller/ControllerWithTwig.tpl.php b/src/Resources/skeleton/crud/controller/ControllerWithTwig.tpl.php new file mode 100644 index 000000000..c6c0c6e9c --- /dev/null +++ b/src/Resources/skeleton/crud/controller/ControllerWithTwig.tpl.php @@ -0,0 +1,145 @@ + + +namespace App\Controller; + +use App\Entity\; +use App\Form\; +use Sensio\Bundle\FrameworkExtraBundle\Configuration\Method; +use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route; +use Symfony\Bundle\FrameworkBundle\Controller\Controller; +use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\HttpFoundation\Response; + +/** + * @Route("", name="_") + */ +class extends Controller +{ + /** + * @Route("/", name="index") + * + * @return Response + */ + public function index() + { + $ = $this->getDoctrine() + ->getRepository(::class) + ->findAll(); + + return $this->render('/index.html.twig', ['' => $]); + } + + /** + * @Route("/{}", name="show") + * @Method("GET") + * + * @param $ The entity + * + * @return Response + */ + public function show( $) + { + $deleteForm = $this->createDeleteForm($); + + return $this->render('/show.html.twig', [ + '' => $, + 'delete_form' => $deleteForm->createView(), + ]); + } + + /** + * @Route("/new", name="new") + * @Method({"GET", "POST"}) + * + * @param Request $request + * + * @return Response + */ + public function new(Request $request) + { + $ = new (); + $form = $this->createForm(::class, $); + $form->handleRequest($request); + + if ($form->isSubmitted() && $form->isValid()) { + $em = $this->getDoctrine()->getManager(); + $em->persist($); + $em->flush(); + + return $this->redirectToRoute('_edit', ['' => $->get()]); + } + + return $this->render('/new.html.twig', [ + '' => $, + 'form' => $form->createView(), + ]); + } + + /** + * @Route("/{}/edit", name="edit") + * @Method({"GET", "POST"}) + * + * @param Request $request + * @param $ The entity + * + * @return Response + */ + public function edit(Request $request, $) + { + $form = $this->createForm(::class, $); + $form->handleRequest($request); + + $deleteForm = $this->createDeleteForm($); + + if ($form->isSubmitted() && $form->isValid()) { + $this->getDoctrine()->getManager()->flush(); + + return $this->redirectToRoute('_edit', ['' => $->get()]); + } + + return $this->render('/edit.html.twig', [ + '' => $, + 'form' => $form->createView(), + 'delete_form' => $deleteForm->createView(), + ]); + } + + /** + * @Route("/{}", name="delete") + * @Method("DELETE") + * + * @param Request $request + * @param $ The entity + * + * @return Response + */ + public function delete(Request $request, $) + { + $form = $this->createDeleteForm($); + $form->handleRequest($request); + + if ($form->isSubmitted() && $form->isValid()) { + $em = $this->getDoctrine()->getManager(); + $em->remove($); + $em->flush(); + } + + return $this->redirectToRoute('_index'); + } + + /** + * Creates a form to delete a entity. + * + * @param $ The entity + * + * @return \Symfony\Component\Form\FormInterface The form + */ + private function createDeleteForm( $) + { + return $this->createFormBuilder() + ->setAction($this->generateUrl('_delete', ['' => $->get()])) + ->setMethod('DELETE') + ->getForm() + ; + } +} diff --git a/src/Resources/skeleton/crud/form/Type.tpl.php b/src/Resources/skeleton/crud/form/Type.tpl.php new file mode 100644 index 000000000..ebb32fb73 --- /dev/null +++ b/src/Resources/skeleton/crud/form/Type.tpl.php @@ -0,0 +1,25 @@ + + +namespace App\Form; + +use App\Entity\; +use Symfony\Component\Form\AbstractType; +use Symfony\Component\Form\FormBuilderInterface; +use Symfony\Component\OptionsResolver\OptionsResolver; + +class extends AbstractType +{ + public function buildForm(FormBuilderInterface $builder, array $options) + { + $builder + ->add('') + ; + } + + public function configureOptions(OptionsResolver $resolver) + { + $resolver->setDefaults([ + 'data_class' => ::class, + ]); + } +} diff --git a/src/Resources/skeleton/crud/templates/edit.tpl.php b/src/Resources/skeleton/crud/templates/edit.tpl.php new file mode 100644 index 000000000..1b3f66462 --- /dev/null +++ b/src/Resources/skeleton/crud/templates/edit.tpl.php @@ -0,0 +1,22 @@ +{% extends 'base.html.twig' %} + +{% block body %} +

Edit

+ + {{ form_start(form) }} + {{ form_widget(form) }} + + {{ form_end(form) }} + +
    +
  • + back to list +
  • +
  • + {{ form_start(delete_form) }} + + {{ form_end(delete_form) }} +
  • +
+ +{% endblock %} diff --git a/src/Resources/skeleton/crud/templates/index.tpl.php b/src/Resources/skeleton/crud/templates/index.tpl.php new file mode 100644 index 000000000..9b1610237 --- /dev/null +++ b/src/Resources/skeleton/crud/templates/index.tpl.php @@ -0,0 +1,27 @@ +{% extends 'base.html.twig' %} + +{% block body %} +

index

+ + + + + + + {% for in %} + + + + + + {% else %} + + + + {% endfor %} +
actions
{{ . }} + show + edit +
no records found
+ Create new +{% endblock %} \ No newline at end of file diff --git a/src/Resources/skeleton/crud/templates/new.tpl.php b/src/Resources/skeleton/crud/templates/new.tpl.php new file mode 100644 index 000000000..2ff62f5fa --- /dev/null +++ b/src/Resources/skeleton/crud/templates/new.tpl.php @@ -0,0 +1,9 @@ +{% extends 'base.html.twig' %} + +{% block body %} +

Create new

+ {{ form_start(form) }} + {{ form_widget(form) }} + + {{ form_end(form) }} +{% endblock %} diff --git a/src/Resources/skeleton/crud/templates/show.tpl.php b/src/Resources/skeleton/crud/templates/show.tpl.php new file mode 100644 index 000000000..3393e7757 --- /dev/null +++ b/src/Resources/skeleton/crud/templates/show.tpl.php @@ -0,0 +1,28 @@ +{% extends 'base.html.twig' %} + +{% block body %} +

+ + + + + + + + +
{{ . }}
+ +
    +
  • + back to list +
  • +
  • + edit +
  • +
  • + {{ form_start(delete_form) }} + + {{ form_end(delete_form) }} +
  • +
+{% endblock %} \ No newline at end of file From 4c0b6399ac71253d7755588191bd7f63f41fe1d4 Mon Sep 17 00:00:00 2001 From: Sadicov Vladimir Date: Thu, 25 Jan 2018 14:04:52 +0200 Subject: [PATCH 02/44] fix fabpot.ci CS --- src/Maker/MakeCrud.php | 8 +- .../controller/ControllerWithTwig.tpl.php | 74 +++++++++---------- src/Resources/skeleton/crud/form/Type.tpl.php | 10 +-- .../skeleton/crud/templates/edit.tpl.php | 4 +- .../skeleton/crud/templates/index.tpl.php | 14 ++-- .../skeleton/crud/templates/new.tpl.php | 2 +- .../skeleton/crud/templates/show.tpl.php | 10 +-- 7 files changed, 61 insertions(+), 61 deletions(-) diff --git a/src/Maker/MakeCrud.php b/src/Maker/MakeCrud.php index bb4e15ca0..721ffc7d3 100644 --- a/src/Maker/MakeCrud.php +++ b/src/Maker/MakeCrud.php @@ -90,7 +90,7 @@ public function getParameters(InputInterface $input): array $metadata = $this->entityManager->getClassMetadata('App\\Entity\\'.$entityClassName); - return [ + return array( 'controller_class_name' => $controllerClassName, 'entity_var_plural' => lcfirst(Inflector::pluralize($entityClassName)), 'entity_var_singular' => lcfirst(Inflector::singularize($entityClassName)), @@ -100,7 +100,7 @@ public function getParameters(InputInterface $input): array 'form_class_name' => $formClassName, 'route_path' => Str::asRoutePath(str_replace('Controller', '', $controllerClassName)), 'route_name' => Str::asRouteName(str_replace('Controller', '', $controllerClassName)), - ]; + ); } /** @@ -108,14 +108,14 @@ public function getParameters(InputInterface $input): array */ public function getFiles(array $params): array { - return [ + return array( __DIR__.'/../Resources/skeleton/crud/controller/ControllerWithTwig.tpl.php' => 'src/Controller/'.$params['controller_class_name'].'.php', __DIR__.'/../Resources/skeleton/crud/form/Type.tpl.php' => 'src/Form/'.$params['form_class_name'].'.php', __DIR__.'/../Resources/skeleton/crud/templates/index.tpl.php' => 'templates/'.$params['route_name'].'/index.html.twig', __DIR__.'/../Resources/skeleton/crud/templates/show.tpl.php' => 'templates/'.$params['route_name'].'/show.html.twig', __DIR__.'/../Resources/skeleton/crud/templates/new.tpl.php' => 'templates/'.$params['route_name'].'/new.html.twig', __DIR__.'/../Resources/skeleton/crud/templates/edit.tpl.php' => 'templates/'.$params['route_name'].'/edit.html.twig', - ]; + ); } /** diff --git a/src/Resources/skeleton/crud/controller/ControllerWithTwig.tpl.php b/src/Resources/skeleton/crud/controller/ControllerWithTwig.tpl.php index c6c0c6e9c..21e4c1d48 100644 --- a/src/Resources/skeleton/crud/controller/ControllerWithTwig.tpl.php +++ b/src/Resources/skeleton/crud/controller/ControllerWithTwig.tpl.php @@ -1,9 +1,9 @@ - + namespace App\Controller; -use App\Entity\; -use App\Form\; +use App\Entity\; +use App\Form\; use Sensio\Bundle\FrameworkExtraBundle\Configuration\Method; use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route; use Symfony\Bundle\FrameworkBundle\Controller\Controller; @@ -11,7 +11,7 @@ use Symfony\Component\HttpFoundation\Response; /** - * @Route("", name="_") + * @Route("", name="_") */ class extends Controller { @@ -22,27 +22,27 @@ class extends Controller */ public function index() { - $ = $this->getDoctrine() - ->getRepository(::class) + $ = $this->getDoctrine() + ->getRepository(::class) ->findAll(); - return $this->render('/index.html.twig', ['' => $]); + return $this->render('/index.html.twig', ['' => $]); } /** - * @Route("/{}", name="show") + * @Route("/{}", name="show") * @Method("GET") * - * @param $ The entity + * @param $ The entity * * @return Response */ - public function show( $) + public function show( $) { - $deleteForm = $this->createDeleteForm($); + $deleteForm = $this->createDeleteForm($); - return $this->render('/show.html.twig', [ - '' => $, + return $this->render('/show.html.twig', [ + '' => $, 'delete_form' => $deleteForm->createView(), ]); } @@ -57,87 +57,87 @@ public function show( $) */ public function new(Request $request) { - $ = new (); - $form = $this->createForm(::class, $); + $ = new (); + $form = $this->createForm(::class, $); $form->handleRequest($request); if ($form->isSubmitted() && $form->isValid()) { $em = $this->getDoctrine()->getManager(); - $em->persist($); + $em->persist($); $em->flush(); - return $this->redirectToRoute('_edit', ['' => $->get()]); + return $this->redirectToRoute('_edit', ['' => $->get()]); } - return $this->render('/new.html.twig', [ - '' => $, + return $this->render('/new.html.twig', [ + '' => $, 'form' => $form->createView(), ]); } /** - * @Route("/{}/edit", name="edit") + * @Route("/{}/edit", name="edit") * @Method({"GET", "POST"}) * * @param Request $request - * @param $ The entity + * @param $ The entity * * @return Response */ - public function edit(Request $request, $) + public function edit(Request $request, $) { - $form = $this->createForm(::class, $); + $form = $this->createForm(::class, $); $form->handleRequest($request); - $deleteForm = $this->createDeleteForm($); + $deleteForm = $this->createDeleteForm($); if ($form->isSubmitted() && $form->isValid()) { $this->getDoctrine()->getManager()->flush(); - return $this->redirectToRoute('_edit', ['' => $->get()]); + return $this->redirectToRoute('_edit', ['' => $->get()]); } - return $this->render('/edit.html.twig', [ - '' => $, + return $this->render('/edit.html.twig', [ + '' => $, 'form' => $form->createView(), 'delete_form' => $deleteForm->createView(), ]); } /** - * @Route("/{}", name="delete") + * @Route("/{}", name="delete") * @Method("DELETE") * * @param Request $request - * @param $ The entity + * @param $ The entity * * @return Response */ - public function delete(Request $request, $) + public function delete(Request $request, $) { - $form = $this->createDeleteForm($); + $form = $this->createDeleteForm($); $form->handleRequest($request); if ($form->isSubmitted() && $form->isValid()) { $em = $this->getDoctrine()->getManager(); - $em->remove($); + $em->remove($); $em->flush(); } - return $this->redirectToRoute('_index'); + return $this->redirectToRoute('_index'); } /** - * Creates a form to delete a entity. + * Creates a form to delete a entity. * - * @param $ The entity + * @param $ The entity * * @return \Symfony\Component\Form\FormInterface The form */ - private function createDeleteForm( $) + private function createDeleteForm( $) { return $this->createFormBuilder() - ->setAction($this->generateUrl('_delete', ['' => $->get()])) + ->setAction($this->generateUrl('_delete', ['' => $->get()])) ->setMethod('DELETE') ->getForm() ; diff --git a/src/Resources/skeleton/crud/form/Type.tpl.php b/src/Resources/skeleton/crud/form/Type.tpl.php index ebb32fb73..febc1c2ca 100644 --- a/src/Resources/skeleton/crud/form/Type.tpl.php +++ b/src/Resources/skeleton/crud/form/Type.tpl.php @@ -1,25 +1,25 @@ - + namespace App\Form; -use App\Entity\; +use App\Entity\; use Symfony\Component\Form\AbstractType; use Symfony\Component\Form\FormBuilderInterface; use Symfony\Component\OptionsResolver\OptionsResolver; -class extends AbstractType +class extends AbstractType { public function buildForm(FormBuilderInterface $builder, array $options) { $builder - ->add('') + ->add('') ; } public function configureOptions(OptionsResolver $resolver) { $resolver->setDefaults([ - 'data_class' => ::class, + 'data_class' => ::class, ]); } } diff --git a/src/Resources/skeleton/crud/templates/edit.tpl.php b/src/Resources/skeleton/crud/templates/edit.tpl.php index 1b3f66462..ccdf79cc0 100644 --- a/src/Resources/skeleton/crud/templates/edit.tpl.php +++ b/src/Resources/skeleton/crud/templates/edit.tpl.php @@ -1,7 +1,7 @@ {% extends 'base.html.twig' %} {% block body %} -

Edit

+

Edit

{{ form_start(form) }} {{ form_widget(form) }} @@ -10,7 +10,7 @@
  • - back to list + back to list
  • {{ form_start(delete_form) }} diff --git a/src/Resources/skeleton/crud/templates/index.tpl.php b/src/Resources/skeleton/crud/templates/index.tpl.php index 9b1610237..bb77f5a3c 100644 --- a/src/Resources/skeleton/crud/templates/index.tpl.php +++ b/src/Resources/skeleton/crud/templates/index.tpl.php @@ -1,27 +1,27 @@ {% extends 'base.html.twig' %} {% block body %} -

    index

    +

    index

    - + {% for in %} - + {% else %} - + {% endfor %}
    actions
    {{ . }}{{ . }} - show - edit + show + edit
    no records foundno records found
    - Create new + Create new {% endblock %} \ No newline at end of file diff --git a/src/Resources/skeleton/crud/templates/new.tpl.php b/src/Resources/skeleton/crud/templates/new.tpl.php index 2ff62f5fa..037c08b1e 100644 --- a/src/Resources/skeleton/crud/templates/new.tpl.php +++ b/src/Resources/skeleton/crud/templates/new.tpl.php @@ -1,7 +1,7 @@ {% extends 'base.html.twig' %} {% block body %} -

    Create new

    +

    Create new

    {{ form_start(form) }} {{ form_widget(form) }} diff --git a/src/Resources/skeleton/crud/templates/show.tpl.php b/src/Resources/skeleton/crud/templates/show.tpl.php index 3393e7757..d29b918b2 100644 --- a/src/Resources/skeleton/crud/templates/show.tpl.php +++ b/src/Resources/skeleton/crud/templates/show.tpl.php @@ -1,23 +1,23 @@ {% extends 'base.html.twig' %} {% block body %} -

    +

    - - + +
    {{ . }}{{ . }}
    • - back to list + back to list
    • - edit + edit
    • {{ form_start(delete_form) }} From 6cdda8f73611a830cece38d6197fc63c377a104b Mon Sep 17 00:00:00 2001 From: Sadicov Vladimir Date: Thu, 25 Jan 2018 14:06:09 +0200 Subject: [PATCH 03/44] final fix fabpot.ci CS --- .../skeleton/crud/controller/ControllerWithTwig.tpl.php | 2 +- src/Resources/skeleton/crud/templates/index.tpl.php | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Resources/skeleton/crud/controller/ControllerWithTwig.tpl.php b/src/Resources/skeleton/crud/controller/ControllerWithTwig.tpl.php index 21e4c1d48..1a1f25469 100644 --- a/src/Resources/skeleton/crud/controller/ControllerWithTwig.tpl.php +++ b/src/Resources/skeleton/crud/controller/ControllerWithTwig.tpl.php @@ -13,7 +13,7 @@ /** * @Route("", name="_") */ -class extends Controller +class extends Controller { /** * @Route("/", name="index") diff --git a/src/Resources/skeleton/crud/templates/index.tpl.php b/src/Resources/skeleton/crud/templates/index.tpl.php index bb77f5a3c..c7eae882e 100644 --- a/src/Resources/skeleton/crud/templates/index.tpl.php +++ b/src/Resources/skeleton/crud/templates/index.tpl.php @@ -8,9 +8,9 @@ actions - {% for in %} + {% for in %} - {{ . }} + {{ . }} show From e9f91ef367c57d01e6cf1a3232b68a2bceebe8ff Mon Sep 17 00:00:00 2001 From: Sadicov Vladimir Date: Thu, 25 Jan 2018 14:12:58 +0200 Subject: [PATCH 04/44] add MakeCrud class to makers.xml --- src/Resources/config/makers.xml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/Resources/config/makers.xml b/src/Resources/config/makers.xml index 46e1fa3c1..71f89ff0d 100644 --- a/src/Resources/config/makers.xml +++ b/src/Resources/config/makers.xml @@ -20,6 +20,12 @@ + + + + + + From 8e9bd670b22e725f4f3e57798c96964ac5b7407a Mon Sep 17 00:00:00 2001 From: Sadicov Vladimir Date: Wed, 31 Jan 2018 10:37:08 +0200 Subject: [PATCH 05/44] fix skeleton according to community recommendations --- .../controller/ControllerWithTwig.tpl.php | 31 ++++--------------- .../crud/templates/_delete_form.tpl.php | 5 +++ .../skeleton/crud/templates/_form.tpl.php | 4 +++ .../skeleton/crud/templates/edit.tpl.php | 18 +++-------- .../skeleton/crud/templates/index.tpl.php | 14 ++++++--- .../skeleton/crud/templates/new.tpl.php | 7 ++--- .../skeleton/crud/templates/show.tpl.php | 19 ++++-------- 7 files changed, 37 insertions(+), 61 deletions(-) create mode 100644 src/Resources/skeleton/crud/templates/_delete_form.tpl.php create mode 100644 src/Resources/skeleton/crud/templates/_form.tpl.php diff --git a/src/Resources/skeleton/crud/controller/ControllerWithTwig.tpl.php b/src/Resources/skeleton/crud/controller/ControllerWithTwig.tpl.php index 1a1f25469..2749ebb09 100644 --- a/src/Resources/skeleton/crud/controller/ControllerWithTwig.tpl.php +++ b/src/Resources/skeleton/crud/controller/ControllerWithTwig.tpl.php @@ -43,7 +43,6 @@ public function show( $) return $this->render('/show.html.twig', [ '' => $, - 'delete_form' => $deleteForm->createView(), ]); } @@ -100,7 +99,6 @@ public function edit(Request $request, $render('/edit.html.twig', [ '' => $, 'form' => $form->createView(), - 'delete_form' => $deleteForm->createView(), ]); } @@ -115,31 +113,14 @@ public function edit(Request $request, $ $) { - $form = $this->createDeleteForm($); - $form->handleRequest($request); - - if ($form->isSubmitted() && $form->isValid()) { - $em = $this->getDoctrine()->getManager(); - $em->remove($); - $em->flush(); + if (!$this->isCsrfTokenValid('delete'.$->get(), $request->request->get('token'))) { + return $this->redirectToRoute('_index'); } - return $this->redirectToRoute('_index'); - } + $em = $this->getDoctrine()->getManager(); + $em->remove($); + $em->flush(); - /** - * Creates a form to delete a entity. - * - * @param $ The entity - * - * @return \Symfony\Component\Form\FormInterface The form - */ - private function createDeleteForm( $) - { - return $this->createFormBuilder() - ->setAction($this->generateUrl('_delete', ['' => $->get()])) - ->setMethod('DELETE') - ->getForm() - ; + return $this->redirectToRoute('_index'); } } diff --git a/src/Resources/skeleton/crud/templates/_delete_form.tpl.php b/src/Resources/skeleton/crud/templates/_delete_form.tpl.php new file mode 100644 index 000000000..951765569 --- /dev/null +++ b/src/Resources/skeleton/crud/templates/_delete_form.tpl.php @@ -0,0 +1,5 @@ +
      + + + +
      \ No newline at end of file diff --git a/src/Resources/skeleton/crud/templates/_form.tpl.php b/src/Resources/skeleton/crud/templates/_form.tpl.php new file mode 100644 index 000000000..298051be2 --- /dev/null +++ b/src/Resources/skeleton/crud/templates/_form.tpl.php @@ -0,0 +1,4 @@ +{{ form_start(form) }} + {{ form_widget(form) }} + +{{ form_end(form) }} \ No newline at end of file diff --git a/src/Resources/skeleton/crud/templates/edit.tpl.php b/src/Resources/skeleton/crud/templates/edit.tpl.php index ccdf79cc0..d961d926e 100644 --- a/src/Resources/skeleton/crud/templates/edit.tpl.php +++ b/src/Resources/skeleton/crud/templates/edit.tpl.php @@ -3,20 +3,10 @@ {% block body %}

      Edit

      - {{ form_start(form) }} - {{ form_widget(form) }} - - {{ form_end(form) }} + {% include '/_form.html.twig' with {'form': form, 'button_label': 'Edit'} only %} -
        -
      • - back to list -
      • -
      • - {{ form_start(delete_form) }} - - {{ form_end(delete_form) }} -
      • -
      + back to list + + {% include '/_delete_form.html.twig' with {'identifier': .} only %} {% endblock %} diff --git a/src/Resources/skeleton/crud/templates/index.tpl.php b/src/Resources/skeleton/crud/templates/index.tpl.php index c7eae882e..d9253bb55 100644 --- a/src/Resources/skeleton/crud/templates/index.tpl.php +++ b/src/Resources/skeleton/crud/templates/index.tpl.php @@ -3,11 +3,14 @@ {% block body %}

      index

      - - - - - + + + + + + + + {% for in %} @@ -22,6 +25,7 @@ {% endfor %} +
      actions
      actions
      {{ . }}no records found
      Create new {% endblock %} \ No newline at end of file diff --git a/src/Resources/skeleton/crud/templates/new.tpl.php b/src/Resources/skeleton/crud/templates/new.tpl.php index 037c08b1e..a298a3e12 100644 --- a/src/Resources/skeleton/crud/templates/new.tpl.php +++ b/src/Resources/skeleton/crud/templates/new.tpl.php @@ -2,8 +2,7 @@ {% block body %}

      Create new

      - {{ form_start(form) }} - {{ form_widget(form) }} - - {{ form_end(form) }} + + {% include '/_form.html.twig' with {'form': form} only %} + {% endblock %} diff --git a/src/Resources/skeleton/crud/templates/show.tpl.php b/src/Resources/skeleton/crud/templates/show.tpl.php index d29b918b2..c89574e8f 100644 --- a/src/Resources/skeleton/crud/templates/show.tpl.php +++ b/src/Resources/skeleton/crud/templates/show.tpl.php @@ -12,17 +12,10 @@ -
        -
      • - back to list -
      • -
      • - edit -
      • -
      • - {{ form_start(delete_form) }} - - {{ form_end(delete_form) }} -
      • -
      + back to list + + edit + + {% include '/_delete_form.html.twig' with {'identifier': .} only %} + {% endblock %} \ No newline at end of file From 08d4bc51535c65dffa0bef8aa3d472cb97bde345 Mon Sep 17 00:00:00 2001 From: Sadicov Vladimir Date: Wed, 31 Jan 2018 10:44:53 +0200 Subject: [PATCH 06/44] trying tests --- src/Maker/MakeCrud.php | 11 +++++---- src/Resources/config/makers.xml | 9 +++++++- tests/Maker/FunctionalTest.php | 19 +++++++++++++++ .../MakeCrud/src/Entity/SweetFood.php | 23 +++++++++++++++++++ 4 files changed, 57 insertions(+), 5 deletions(-) create mode 100644 tests/fixtures/MakeCrud/src/Entity/SweetFood.php diff --git a/src/Maker/MakeCrud.php b/src/Maker/MakeCrud.php index 721ffc7d3..39f95cdba 100644 --- a/src/Maker/MakeCrud.php +++ b/src/Maker/MakeCrud.php @@ -4,6 +4,7 @@ use Doctrine\Common\Inflector\Inflector; use Doctrine\ORM\EntityManagerInterface; +use Psr\Container\ContainerInterface; use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route; use Symfony\Bundle\MakerBundle\ConsoleStyle; use Symfony\Bundle\MakerBundle\DependencyBuilder; @@ -23,12 +24,12 @@ final class MakeCrud extends AbstractMaker { private $router; - private $entityManager; + private $locator; - public function __construct(RouterInterface $router, EntityManagerInterface $entityManager) + public function __construct(RouterInterface $router, ContainerInterface $serviceLocator) { $this->router = $router; - $this->entityManager = $entityManager; + $this->locator = $serviceLocator; } public static function getCommandName(): string @@ -88,7 +89,7 @@ public function getParameters(InputInterface $input): array $formClassName = Str::asClassName($entityClassName, 'Type'); Validator::validateClassName($formClassName); - $metadata = $this->entityManager->getClassMetadata('App\\Entity\\'.$entityClassName); + $metadata = $this->locator->get('doctrine')->getManager()->getClassMetadata('App\\Entity\\'.$entityClassName); return array( 'controller_class_name' => $controllerClassName, @@ -111,6 +112,8 @@ public function getFiles(array $params): array return array( __DIR__.'/../Resources/skeleton/crud/controller/ControllerWithTwig.tpl.php' => 'src/Controller/'.$params['controller_class_name'].'.php', __DIR__.'/../Resources/skeleton/crud/form/Type.tpl.php' => 'src/Form/'.$params['form_class_name'].'.php', + __DIR__.'/../Resources/skeleton/crud/templates/_delete_form.tpl.php' => 'templates/'.$params['route_name'].'/_delete_form.html.twig', + __DIR__.'/../Resources/skeleton/crud/templates/_form.tpl.php' => 'templates/'.$params['route_name'].'/_form.html.twig', __DIR__.'/../Resources/skeleton/crud/templates/index.tpl.php' => 'templates/'.$params['route_name'].'/index.html.twig', __DIR__.'/../Resources/skeleton/crud/templates/show.tpl.php' => 'templates/'.$params['route_name'].'/show.html.twig', __DIR__.'/../Resources/skeleton/crud/templates/new.tpl.php' => 'templates/'.$params['route_name'].'/new.html.twig', diff --git a/src/Resources/config/makers.xml b/src/Resources/config/makers.xml index 71f89ff0d..11eb35752 100644 --- a/src/Resources/config/makers.xml +++ b/src/Resources/config/makers.xml @@ -22,7 +22,14 @@ - + + + + + + + + diff --git a/tests/Maker/FunctionalTest.php b/tests/Maker/FunctionalTest.php index ebc6f3331..16bae3838 100644 --- a/tests/Maker/FunctionalTest.php +++ b/tests/Maker/FunctionalTest.php @@ -11,6 +11,7 @@ use Symfony\Bundle\MakerBundle\Maker\MakeAuthenticator; use Symfony\Bundle\MakerBundle\Maker\MakeCommand; use Symfony\Bundle\MakerBundle\Maker\MakeController; +use Symfony\Bundle\MakerBundle\Maker\MakeCrud; use Symfony\Bundle\MakerBundle\Maker\MakeEntity; use Symfony\Bundle\MakerBundle\Maker\MakeForm; use Symfony\Bundle\MakerBundle\Maker\MakeFunctionalTest; @@ -223,6 +224,24 @@ public function getCommandTests() $this->assertContains('No database changes were detected', $output); }) ]; + + yield 'crud' => [MakerTestDetails::createTest( + $this->getMakerInstance(MakeCrud::class), + [ + // entity class name + 'SweetFood', + ]) + ->setFixtureFilesPath(__DIR__.'/../fixtures/MakeCrud') + ->addReplacement( + '.env', + 'mysql://db_user:db_password@127.0.0.1:3306/db_name', + 'sqlite:///%kernel.project_dir%/var/app.db' + ) + ->addExtraDependencies('doctrine/orm') + ->assert(function(string $output, string $directory) { + $this->assertContains('Success', $output); + }) + ]; } /** diff --git a/tests/fixtures/MakeCrud/src/Entity/SweetFood.php b/tests/fixtures/MakeCrud/src/Entity/SweetFood.php new file mode 100644 index 000000000..1da61ecb4 --- /dev/null +++ b/tests/fixtures/MakeCrud/src/Entity/SweetFood.php @@ -0,0 +1,23 @@ + Date: Wed, 31 Jan 2018 13:00:46 +0200 Subject: [PATCH 07/44] trying tests 2 --- tests/Maker/FunctionalTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/Maker/FunctionalTest.php b/tests/Maker/FunctionalTest.php index 16bae3838..0686aba90 100644 --- a/tests/Maker/FunctionalTest.php +++ b/tests/Maker/FunctionalTest.php @@ -237,7 +237,7 @@ public function getCommandTests() 'mysql://db_user:db_password@127.0.0.1:3306/db_name', 'sqlite:///%kernel.project_dir%/var/app.db' ) - ->addExtraDependencies('doctrine/orm') + ->addExtraDependencies('symfony/orm-pack') ->assert(function(string $output, string $directory) { $this->assertContains('Success', $output); }) From f189efd91486784cfe1dcea27852644d47758884 Mon Sep 17 00:00:00 2001 From: Sadicov Vladimir Date: Wed, 31 Jan 2018 14:09:20 +0200 Subject: [PATCH 08/44] fix tests --- src/Maker/MakeCrud.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Maker/MakeCrud.php b/src/Maker/MakeCrud.php index 39f95cdba..69aa18d13 100644 --- a/src/Maker/MakeCrud.php +++ b/src/Maker/MakeCrud.php @@ -3,7 +3,7 @@ namespace Symfony\Bundle\MakerBundle\Maker; use Doctrine\Common\Inflector\Inflector; -use Doctrine\ORM\EntityManagerInterface; +use Doctrine\ORM\EntityManager; use Psr\Container\ContainerInterface; use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route; use Symfony\Bundle\MakerBundle\ConsoleStyle; @@ -65,7 +65,7 @@ public function configureDependencies(DependencyBuilder $dependencies) ); $dependencies->addClassDependency( - EntityManagerInterface::class, + EntityManager::class, 'orm-pack' ); } From 9961f43e2ef22d8107406d44aefef6636c073b75 Mon Sep 17 00:00:00 2001 From: Sadicov Vladimir Date: Wed, 31 Jan 2018 14:14:35 +0200 Subject: [PATCH 09/44] fix fabpot.io cs --- .../skeleton/crud/templates/edit.tpl.php | 4 +- .../skeleton/crud/templates/new.tpl.php | 2 +- tests/Maker/FunctionalTest.php | 124 +++++++++--------- 3 files changed, 65 insertions(+), 65 deletions(-) diff --git a/src/Resources/skeleton/crud/templates/edit.tpl.php b/src/Resources/skeleton/crud/templates/edit.tpl.php index d961d926e..510f96cde 100644 --- a/src/Resources/skeleton/crud/templates/edit.tpl.php +++ b/src/Resources/skeleton/crud/templates/edit.tpl.php @@ -3,10 +3,10 @@ {% block body %}

      Edit

      - {% include '/_form.html.twig' with {'form': form, 'button_label': 'Edit'} only %} + {% include '/_form.html.twig' with {'form': form, 'button_label': 'Edit'} only %} back to list - {% include '/_delete_form.html.twig' with {'identifier': .} only %} + {% include '/_delete_form.html.twig' with {'identifier': .} only %} {% endblock %} diff --git a/src/Resources/skeleton/crud/templates/new.tpl.php b/src/Resources/skeleton/crud/templates/new.tpl.php index a298a3e12..615c05cee 100644 --- a/src/Resources/skeleton/crud/templates/new.tpl.php +++ b/src/Resources/skeleton/crud/templates/new.tpl.php @@ -3,6 +3,6 @@ {% block body %}

      Create new

      - {% include '/_form.html.twig' with {'form': form} only %} + {% include '/_form.html.twig' with {'form': form} only %} {% endblock %} diff --git a/tests/Maker/FunctionalTest.php b/tests/Maker/FunctionalTest.php index 0686aba90..73819ffac 100644 --- a/tests/Maker/FunctionalTest.php +++ b/tests/Maker/FunctionalTest.php @@ -51,30 +51,30 @@ public function testCommands(MakerTestDetails $makerTestDetails) public function getCommandTests() { - yield 'command' => [MakerTestDetails::createTest( + yield 'command' => array(MakerTestDetails::createTest( $this->getMakerInstance(MakeCommand::class), - [ + array( // command name 'app:foo', - ]) + )) ->setFixtureFilesPath(__DIR__.'/../fixtures/MakeCommand') - ]; + ); - yield 'controller' => [MakerTestDetails::createTest( + yield 'controller' => array(MakerTestDetails::createTest( $this->getMakerInstance(MakeController::class), - [ + array( // controller class name 'FooBar', - ]) + )) ->setFixtureFilesPath(__DIR__.'/../fixtures/MakeController') - ]; + ); - yield 'entity' => [MakerTestDetails::createTest( + yield 'entity' => array(MakerTestDetails::createTest( $this->getMakerInstance(MakeEntity::class), - [ + array( // entity class name 'TastyFood', - ]) + )) ->setFixtureFilesPath(__DIR__.'/../fixtures/MakeEntity') ->addReplacement( 'phpunit.xml.dist', @@ -89,98 +89,98 @@ public function getCommandTests() 'sqlite:///%kernel.project_dir%/var/app.db' ) ->addPostMakeCommand('./bin/console doctrine:schema:create --env=test') - ]; + ); - yield 'form' => [MakerTestDetails::createTest( + yield 'form' => array(MakerTestDetails::createTest( $this->getMakerInstance(MakeForm::class), - [ + array( // form name 'FooBar', - ]) - ]; + )) + ); - yield 'functional' => [MakerTestDetails::createTest( + yield 'functional' => array(MakerTestDetails::createTest( $this->getMakerInstance(MakeFunctionalTest::class), - [ + array( // functional test class name 'FooBar', - ]) + )) ->setFixtureFilesPath(__DIR__.'/../fixtures/MakeFunctional') - ]; + ); - yield 'subscriber' => [MakerTestDetails::createTest( + yield 'subscriber' => array(MakerTestDetails::createTest( $this->getMakerInstance(MakeSubscriber::class), - [ + array( // subscriber name 'FooBar', // event name 'kernel.request', - ]) - ]; + )) + ); - yield 'subscriber_unknown_event_class' => [MakerTestDetails::createTest( + yield 'subscriber_unknown_event_class' => array(MakerTestDetails::createTest( $this->getMakerInstance(MakeSubscriber::class), - [ + array( // subscriber name 'FooBar', // event name 'foo.unknown_event', - ]) - ]; + )) + ); - yield 'serializer_encoder' => [MakerTestDetails::createTest( + yield 'serializer_encoder' => array(MakerTestDetails::createTest( $this->getMakerInstance(MakeSerializerEncoder::class), - [ + array( // encoder class name 'FooBarEncoder', // encoder format 'foobar', - ]) - ]; + )) + ); - yield 'twig_extension' => [MakerTestDetails::createTest( + yield 'twig_extension' => array(MakerTestDetails::createTest( $this->getMakerInstance(MakeTwigExtension::class), - [ + array( // extension class name 'FooBar', - ]) - ]; + )) + ); - yield 'unit_test' => [MakerTestDetails::createTest( + yield 'unit_test' => array(MakerTestDetails::createTest( $this->getMakerInstance(MakeUnitTest::class), - [ + array( // class name 'FooBar', - ]) - ]; + )) + ); - yield 'validator' => [MakerTestDetails::createTest( + yield 'validator' => array(MakerTestDetails::createTest( $this->getMakerInstance(MakeValidator::class), - [ + array( // validator name 'FooBar', - ]) - ]; + )) + ); - yield 'voter' => [MakerTestDetails::createTest( + yield 'voter' => array(MakerTestDetails::createTest( $this->getMakerInstance(MakeVoter::class), - [ + array( // voter class name 'FooBar', - ]) - ]; + )) + ); - yield 'auth_empty' => [MakerTestDetails::createTest( + yield 'auth_empty' => array(MakerTestDetails::createTest( $this->getMakerInstance(MakeAuthenticator::class), - [ + array( // class name 'AppCustomAuthenticator', - ]) - ]; + )) + ); - yield 'migration_with_changes' => [MakerTestDetails::createTest( + yield 'migration_with_changes' => array(MakerTestDetails::createTest( $this->getMakerInstance(MakeMigration::class), - [/* no input */]) + array(/* no input */)) ->setFixtureFilesPath(__DIR__.'/../fixtures/MakeMigration') ->addReplacement( '.env', @@ -204,11 +204,11 @@ public function getCommandTests() $iterator->rewind(); $this->assertContains(sprintf('"src/Migrations/%s"', $iterator->current()->getFilename()), $output); }) - ]; + ); - yield 'migration_no_changes' => [MakerTestDetails::createTest( + yield 'migration_no_changes' => array(MakerTestDetails::createTest( $this->getMakerInstance(MakeMigration::class), - [/* no input */]) + array(/* no input */)) ->setFixtureFilesPath(__DIR__.'/../fixtures/MakeMigration') ->addReplacement( '.env', @@ -223,14 +223,14 @@ public function getCommandTests() $this->assertContains('No database changes were detected', $output); }) - ]; + ); - yield 'crud' => [MakerTestDetails::createTest( + yield 'crud' => array(MakerTestDetails::createTest( $this->getMakerInstance(MakeCrud::class), - [ + array( // entity class name 'SweetFood', - ]) + )) ->setFixtureFilesPath(__DIR__.'/../fixtures/MakeCrud') ->addReplacement( '.env', @@ -241,7 +241,7 @@ public function getCommandTests() ->assert(function(string $output, string $directory) { $this->assertContains('Success', $output); }) - ]; + ); } /** From 791241dbc39c9d1d750c88ff15f989467cd008a3 Mon Sep 17 00:00:00 2001 From: Sadicov Vladimir Date: Wed, 31 Jan 2018 14:17:12 +0200 Subject: [PATCH 10/44] fix fabpot.io cs 2 --- .../skeleton/crud/templates/show.tpl.php | 2 +- tests/Maker/FunctionalTest.php | 32 +++++++++---------- 2 files changed, 17 insertions(+), 17 deletions(-) diff --git a/src/Resources/skeleton/crud/templates/show.tpl.php b/src/Resources/skeleton/crud/templates/show.tpl.php index c89574e8f..bcad81166 100644 --- a/src/Resources/skeleton/crud/templates/show.tpl.php +++ b/src/Resources/skeleton/crud/templates/show.tpl.php @@ -16,6 +16,6 @@ edit - {% include '/_delete_form.html.twig' with {'identifier': .} only %} + {% include '/_delete_form.html.twig' with {'identifier': .} only %} {% endblock %} \ No newline at end of file diff --git a/tests/Maker/FunctionalTest.php b/tests/Maker/FunctionalTest.php index 73819ffac..3d11911fc 100644 --- a/tests/Maker/FunctionalTest.php +++ b/tests/Maker/FunctionalTest.php @@ -57,7 +57,7 @@ public function getCommandTests() // command name 'app:foo', )) - ->setFixtureFilesPath(__DIR__.'/../fixtures/MakeCommand') + ->setFixtureFilesPath(__DIR__.'/../fixtures/MakeCommand'), ); yield 'controller' => array(MakerTestDetails::createTest( @@ -66,7 +66,7 @@ public function getCommandTests() // controller class name 'FooBar', )) - ->setFixtureFilesPath(__DIR__.'/../fixtures/MakeController') + ->setFixtureFilesPath(__DIR__.'/../fixtures/MakeController'), ); yield 'entity' => array(MakerTestDetails::createTest( @@ -88,7 +88,7 @@ public function getCommandTests() 'mysql://db_user:db_password@127.0.0.1:3306/db_name', 'sqlite:///%kernel.project_dir%/var/app.db' ) - ->addPostMakeCommand('./bin/console doctrine:schema:create --env=test') + ->addPostMakeCommand('./bin/console doctrine:schema:create --env=test'), ); yield 'form' => array(MakerTestDetails::createTest( @@ -96,7 +96,7 @@ public function getCommandTests() array( // form name 'FooBar', - )) + )), ); yield 'functional' => array(MakerTestDetails::createTest( @@ -105,7 +105,7 @@ public function getCommandTests() // functional test class name 'FooBar', )) - ->setFixtureFilesPath(__DIR__.'/../fixtures/MakeFunctional') + ->setFixtureFilesPath(__DIR__.'/../fixtures/MakeFunctional'), ); yield 'subscriber' => array(MakerTestDetails::createTest( @@ -115,7 +115,7 @@ public function getCommandTests() 'FooBar', // event name 'kernel.request', - )) + )), ); yield 'subscriber_unknown_event_class' => array(MakerTestDetails::createTest( @@ -125,7 +125,7 @@ public function getCommandTests() 'FooBar', // event name 'foo.unknown_event', - )) + )), ); yield 'serializer_encoder' => array(MakerTestDetails::createTest( @@ -135,7 +135,7 @@ public function getCommandTests() 'FooBarEncoder', // encoder format 'foobar', - )) + )), ); yield 'twig_extension' => array(MakerTestDetails::createTest( @@ -143,7 +143,7 @@ public function getCommandTests() array( // extension class name 'FooBar', - )) + )), ); yield 'unit_test' => array(MakerTestDetails::createTest( @@ -151,7 +151,7 @@ public function getCommandTests() array( // class name 'FooBar', - )) + )), ); yield 'validator' => array(MakerTestDetails::createTest( @@ -159,7 +159,7 @@ public function getCommandTests() array( // validator name 'FooBar', - )) + )), ); yield 'voter' => array(MakerTestDetails::createTest( @@ -167,7 +167,7 @@ public function getCommandTests() array( // voter class name 'FooBar', - )) + )), ); yield 'auth_empty' => array(MakerTestDetails::createTest( @@ -175,7 +175,7 @@ public function getCommandTests() array( // class name 'AppCustomAuthenticator', - )) + )), ); yield 'migration_with_changes' => array(MakerTestDetails::createTest( @@ -203,7 +203,7 @@ public function getCommandTests() $iterator = $finder->getIterator(); $iterator->rewind(); $this->assertContains(sprintf('"src/Migrations/%s"', $iterator->current()->getFilename()), $output); - }) + }), ); yield 'migration_no_changes' => array(MakerTestDetails::createTest( @@ -222,7 +222,7 @@ public function getCommandTests() $this->assertNotContains('Success', $output); $this->assertContains('No database changes were detected', $output); - }) + }), ); yield 'crud' => array(MakerTestDetails::createTest( @@ -240,7 +240,7 @@ public function getCommandTests() ->addExtraDependencies('symfony/orm-pack') ->assert(function(string $output, string $directory) { $this->assertContains('Success', $output); - }) + }), ); } From 478b457442162b076190dd62898cc6380ae78991 Mon Sep 17 00:00:00 2001 From: Sadicov Vladimir Date: Wed, 31 Jan 2018 14:18:53 +0200 Subject: [PATCH 11/44] fix fabpot.io cs 3 --- tests/Maker/FunctionalTest.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/Maker/FunctionalTest.php b/tests/Maker/FunctionalTest.php index 3d11911fc..1db2b9f14 100644 --- a/tests/Maker/FunctionalTest.php +++ b/tests/Maker/FunctionalTest.php @@ -191,7 +191,7 @@ public function getCommandTests() // only requires doctrine/dbal. But we're testing with the ORM, // so let's install it ->addExtraDependencies('doctrine/orm') - ->assert(function(string $output, string $directory) { + ->assert(function (string $output, string $directory) { $this->assertContains('Success', $output); $finder = new Finder(); @@ -218,7 +218,7 @@ public function getCommandTests() ->addExtraDependencies('doctrine/orm') // sync the database, so no changes are needed ->addPreMakeCommand('./bin/console doctrine:schema:create --env=test') - ->assert(function(string $output, string $directory) { + ->assert(function (string $output, string $directory) { $this->assertNotContains('Success', $output); $this->assertContains('No database changes were detected', $output); @@ -238,7 +238,7 @@ public function getCommandTests() 'sqlite:///%kernel.project_dir%/var/app.db' ) ->addExtraDependencies('symfony/orm-pack') - ->assert(function(string $output, string $directory) { + ->assert(function (string $output, string $directory) { $this->assertContains('Success', $output); }), ); From 207d8be14d5f10ef6a4bd666da35dddba42fa0df Mon Sep 17 00:00:00 2001 From: Sadicov Vladimir Date: Fri, 2 Feb 2018 10:16:48 +0200 Subject: [PATCH 12/44] add exception if entity doesn't exists --- src/Maker/MakeCrud.php | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/Maker/MakeCrud.php b/src/Maker/MakeCrud.php index 69aa18d13..dceb48419 100644 --- a/src/Maker/MakeCrud.php +++ b/src/Maker/MakeCrud.php @@ -8,6 +8,7 @@ use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route; use Symfony\Bundle\MakerBundle\ConsoleStyle; use Symfony\Bundle\MakerBundle\DependencyBuilder; +use Symfony\Bundle\MakerBundle\Exception\RuntimeCommandException; use Symfony\Bundle\MakerBundle\InputConfiguration; use Symfony\Bundle\MakerBundle\Str; use Symfony\Bundle\MakerBundle\Validator; @@ -89,7 +90,7 @@ public function getParameters(InputInterface $input): array $formClassName = Str::asClassName($entityClassName, 'Type'); Validator::validateClassName($formClassName); - $metadata = $this->locator->get('doctrine')->getManager()->getClassMetadata('App\\Entity\\'.$entityClassName); + $metadata = $this->getEntityMetadata($entityClassName); return array( 'controller_class_name' => $controllerClassName, @@ -133,4 +134,13 @@ public function writeNextStepsMessage(array $params, ConsoleStyle $io) } $io->text('Next: Check your new crud!'); } + + private function getEntityMetadata($entityClassName) + { + try { + return $this->locator->get('doctrine')->getManager()->getClassMetadata('App\\Entity\\'.$entityClassName); + } catch (\Doctrine\Common\Persistence\Mapping\MappingException $exception) { + throw new RuntimeCommandException(sprintf('Entity "%s" doesn\'t exists in your project. May be you would like to create it with "make:entity" command?', $entityClassName)); + } + } } From 1b0f17a39381702a4f457b4f0c99477789b1a13c Mon Sep 17 00:00:00 2001 From: Sadicov Vladimir Date: Fri, 2 Feb 2018 10:17:55 +0200 Subject: [PATCH 13/44] test remove some phpdoc comments to pass travis.ci --- .../controller/ControllerWithTwig.tpl.php | 20 ------------------- 1 file changed, 20 deletions(-) diff --git a/src/Resources/skeleton/crud/controller/ControllerWithTwig.tpl.php b/src/Resources/skeleton/crud/controller/ControllerWithTwig.tpl.php index 2749ebb09..f0357dd2b 100644 --- a/src/Resources/skeleton/crud/controller/ControllerWithTwig.tpl.php +++ b/src/Resources/skeleton/crud/controller/ControllerWithTwig.tpl.php @@ -17,8 +17,6 @@ class extends Controller { /** * @Route("/", name="index") - * - * @return Response */ public function index() { @@ -32,10 +30,6 @@ public function index() /** * @Route("/{}", name="show") * @Method("GET") - * - * @param $ The entity - * - * @return Response */ public function show( $) { @@ -49,10 +43,6 @@ public function show( $) /** * @Route("/new", name="new") * @Method({"GET", "POST"}) - * - * @param Request $request - * - * @return Response */ public function new(Request $request) { @@ -77,11 +67,6 @@ public function new(Request $request) /** * @Route("/{}/edit", name="edit") * @Method({"GET", "POST"}) - * - * @param Request $request - * @param $ The entity - * - * @return Response */ public function edit(Request $request, $) { @@ -105,11 +90,6 @@ public function edit(Request $request, $}", name="delete") * @Method("DELETE") - * - * @param Request $request - * @param $ The entity - * - * @return Response */ public function delete(Request $request, $) { From 31d9e814cd974598a640f2f6e59b8396beb99689 Mon Sep 17 00:00:00 2001 From: Sadicov Vladimir Date: Fri, 2 Feb 2018 10:53:31 +0200 Subject: [PATCH 14/44] fix templates generation with date fields in entity --- .../skeleton/crud/controller/ControllerWithTwig.tpl.php | 2 ++ src/Resources/skeleton/crud/templates/index.tpl.php | 2 +- src/Resources/skeleton/crud/templates/show.tpl.php | 2 +- 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/Resources/skeleton/crud/controller/ControllerWithTwig.tpl.php b/src/Resources/skeleton/crud/controller/ControllerWithTwig.tpl.php index f0357dd2b..750a159b2 100644 --- a/src/Resources/skeleton/crud/controller/ControllerWithTwig.tpl.php +++ b/src/Resources/skeleton/crud/controller/ControllerWithTwig.tpl.php @@ -17,6 +17,8 @@ class extends Controller { /** * @Route("/", name="index") + * + * @return Response */ public function index() { diff --git a/src/Resources/skeleton/crud/templates/index.tpl.php b/src/Resources/skeleton/crud/templates/index.tpl.php index d9253bb55..a59bb6e7c 100644 --- a/src/Resources/skeleton/crud/templates/index.tpl.php +++ b/src/Resources/skeleton/crud/templates/index.tpl.php @@ -13,7 +13,7 @@ {% for in %} - {{ . }} + {{ . }} show diff --git a/src/Resources/skeleton/crud/templates/show.tpl.php b/src/Resources/skeleton/crud/templates/show.tpl.php index bcad81166..b0ba1d82e 100644 --- a/src/Resources/skeleton/crud/templates/show.tpl.php +++ b/src/Resources/skeleton/crud/templates/show.tpl.php @@ -7,7 +7,7 @@ - {{ . }} + {{ . }} From 7783313fc0db91b9e4f119aae35543409fda5a31 Mon Sep 17 00:00:00 2001 From: Sadicov Vladimir Date: Fri, 2 Feb 2018 11:01:13 +0200 Subject: [PATCH 15/44] fix fobpot.io cs --- src/Resources/skeleton/crud/templates/index.tpl.php | 2 +- src/Resources/skeleton/crud/templates/show.tpl.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Resources/skeleton/crud/templates/index.tpl.php b/src/Resources/skeleton/crud/templates/index.tpl.php index a59bb6e7c..bc1094a3d 100644 --- a/src/Resources/skeleton/crud/templates/index.tpl.php +++ b/src/Resources/skeleton/crud/templates/index.tpl.php @@ -13,7 +13,7 @@ {% for in %} - {{ . }} + {{ . }} show diff --git a/src/Resources/skeleton/crud/templates/show.tpl.php b/src/Resources/skeleton/crud/templates/show.tpl.php index b0ba1d82e..cf419bb09 100644 --- a/src/Resources/skeleton/crud/templates/show.tpl.php +++ b/src/Resources/skeleton/crud/templates/show.tpl.php @@ -7,7 +7,7 @@ - {{ . }} + {{ . }} From 5157e0a8e68e2013353ee1c1fc11a36eebfdca5f Mon Sep 17 00:00:00 2001 From: Vladimir Sadicov Date: Mon, 5 Feb 2018 18:30:45 +0200 Subject: [PATCH 16/44] fix interception of /new url by show action --- .../controller/ControllerWithTwig.tpl.php | 26 +++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/src/Resources/skeleton/crud/controller/ControllerWithTwig.tpl.php b/src/Resources/skeleton/crud/controller/ControllerWithTwig.tpl.php index 750a159b2..957e8dc36 100644 --- a/src/Resources/skeleton/crud/controller/ControllerWithTwig.tpl.php +++ b/src/Resources/skeleton/crud/controller/ControllerWithTwig.tpl.php @@ -29,19 +29,6 @@ public function index() return $this->render('/index.html.twig', ['' => $]); } - /** - * @Route("/{}", name="show") - * @Method("GET") - */ - public function show( $) - { - $deleteForm = $this->createDeleteForm($); - - return $this->render('/show.html.twig', [ - '' => $, - ]); - } - /** * @Route("/new", name="new") * @Method({"GET", "POST"}) @@ -66,6 +53,19 @@ public function new(Request $request) ]); } + /** + * @Route("/{}", name="show") + * @Method("GET") + */ + public function show( $) + { + $deleteForm = $this->createDeleteForm($); + + return $this->render('/show.html.twig', [ + '' => $, + ]); + } + /** * @Route("/{}/edit", name="edit") * @Method({"GET", "POST"}) From 42047a64fb87737bded9fd0bf22f92eee107592e Mon Sep 17 00:00:00 2001 From: Vladimir Sadicov Date: Mon, 5 Feb 2018 18:40:01 +0200 Subject: [PATCH 17/44] fix Token parameter name in delete action --- .../skeleton/crud/controller/ControllerWithTwig.tpl.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Resources/skeleton/crud/controller/ControllerWithTwig.tpl.php b/src/Resources/skeleton/crud/controller/ControllerWithTwig.tpl.php index 957e8dc36..a1299b8d3 100644 --- a/src/Resources/skeleton/crud/controller/ControllerWithTwig.tpl.php +++ b/src/Resources/skeleton/crud/controller/ControllerWithTwig.tpl.php @@ -95,7 +95,7 @@ public function edit(Request $request, $ $) { - if (!$this->isCsrfTokenValid('delete'.$->get(), $request->request->get('token'))) { + if (!$this->isCsrfTokenValid('delete'.$->get(), $request->request->get('_token'))) { return $this->redirectToRoute('_index'); } From ff9a08dff41d10b59c77257639ab2e5b0868092a Mon Sep 17 00:00:00 2001 From: Sadicov Vladimir Date: Mon, 5 Feb 2018 19:11:47 +0200 Subject: [PATCH 18/44] some fixes --- src/Resources/skeleton/crud/templates/_delete_form.tpl.php | 2 +- src/Resources/skeleton/crud/templates/index.tpl.php | 2 +- src/Resources/skeleton/crud/templates/show.tpl.php | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Resources/skeleton/crud/templates/_delete_form.tpl.php b/src/Resources/skeleton/crud/templates/_delete_form.tpl.php index 951765569..b7a97cffe 100644 --- a/src/Resources/skeleton/crud/templates/_delete_form.tpl.php +++ b/src/Resources/skeleton/crud/templates/_delete_form.tpl.php @@ -1,4 +1,4 @@ -
      + diff --git a/src/Resources/skeleton/crud/templates/index.tpl.php b/src/Resources/skeleton/crud/templates/index.tpl.php index bc1094a3d..b8118dfbe 100644 --- a/src/Resources/skeleton/crud/templates/index.tpl.php +++ b/src/Resources/skeleton/crud/templates/index.tpl.php @@ -13,7 +13,7 @@ {% for in %} - {{ . }} + {{ . }} show diff --git a/src/Resources/skeleton/crud/templates/show.tpl.php b/src/Resources/skeleton/crud/templates/show.tpl.php index cf419bb09..4b4baf277 100644 --- a/src/Resources/skeleton/crud/templates/show.tpl.php +++ b/src/Resources/skeleton/crud/templates/show.tpl.php @@ -7,7 +7,7 @@ - {{ . }} + {{ . }} From 6f1c296a9cfad5a06da1c504fd97a1b265a200d7 Mon Sep 17 00:00:00 2001 From: Sadicov Vladimir Date: Sat, 10 Feb 2018 21:58:57 +0200 Subject: [PATCH 19/44] array style fix --- tests/Maker/FunctionalTest.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/tests/Maker/FunctionalTest.php b/tests/Maker/FunctionalTest.php index f138318e2..a93f4052c 100644 --- a/tests/Maker/FunctionalTest.php +++ b/tests/Maker/FunctionalTest.php @@ -255,14 +255,14 @@ public function getCommandTests() $this->assertContains('No database changes were detected', $output); }), - ); + ]; - yield 'crud' => array(MakerTestDetails::createTest( + yield 'crud' => [MakerTestDetails::createTest( $this->getMakerInstance(MakeCrud::class), - array( + [ // entity class name 'SweetFood', - )) + ]) ->setFixtureFilesPath(__DIR__.'/../fixtures/MakeCrud') ->addReplacement( '.env', @@ -273,7 +273,7 @@ public function getCommandTests() ->assert(function (string $output, string $directory) { $this->assertContains('Success', $output); }), - ); + ]; } /** From 71d2e901b6e8e5b1fca144da6eace3ac47d36fbd Mon Sep 17 00:00:00 2001 From: Sadicov Vladimir Date: Sun, 11 Feb 2018 19:48:37 +0200 Subject: [PATCH 20/44] some code refactoring + testing new GeneratorHelper to simplify skeleton templates --- src/GeneratorHelper.php | 79 ++++++++++++++++++ src/Maker/MakeCrud.php | 83 ++++++++++++------- src/Resources/config/makers.xml | 1 + ...lerWithTwig.tpl.php => Controller.tpl.php} | 0 .../skeleton/crud/templates/edit.tpl.php | 7 +- .../skeleton/crud/templates/index.tpl.php | 16 ++-- .../skeleton/crud/templates/new.tpl.php | 7 +- .../skeleton/crud/templates/show.tpl.php | 16 ++-- 8 files changed, 155 insertions(+), 54 deletions(-) create mode 100644 src/GeneratorHelper.php rename src/Resources/skeleton/crud/controller/{ControllerWithTwig.tpl.php => Controller.tpl.php} (100%) diff --git a/src/GeneratorHelper.php b/src/GeneratorHelper.php new file mode 100644 index 000000000..a5cb6537d --- /dev/null +++ b/src/GeneratorHelper.php @@ -0,0 +1,79 @@ + + + + + $title + +HTML; + } + + return $code; + } + + public function getBodyStart($baseLayoutExists): string + { + if ($baseLayoutExists) { + $code = << +HTML; + } + + return $code; + } + + public function getBodyEnd($baseLayoutExists): string + { + if ($baseLayoutExists) { + $code = << + +HTML; + } + + return $code; + } +} diff --git a/src/Maker/MakeCrud.php b/src/Maker/MakeCrud.php index dceb48419..8c6d6c957 100644 --- a/src/Maker/MakeCrud.php +++ b/src/Maker/MakeCrud.php @@ -4,11 +4,14 @@ use Doctrine\Common\Inflector\Inflector; use Doctrine\ORM\EntityManager; +use Doctrine\ORM\Mapping\ClassMetadataInfo; use Psr\Container\ContainerInterface; use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route; use Symfony\Bundle\MakerBundle\ConsoleStyle; use Symfony\Bundle\MakerBundle\DependencyBuilder; use Symfony\Bundle\MakerBundle\Exception\RuntimeCommandException; +use Symfony\Bundle\MakerBundle\FileManager; +use Symfony\Bundle\MakerBundle\GeneratorHelper; use Symfony\Bundle\MakerBundle\InputConfiguration; use Symfony\Bundle\MakerBundle\Str; use Symfony\Bundle\MakerBundle\Validator; @@ -16,7 +19,9 @@ use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputInterface; +use Symfony\Component\Form\AbstractType; use Symfony\Component\Routing\RouterInterface; +use Symfony\Component\Validator\Validation; /** * @author Sadicov Vladimir @@ -24,12 +29,13 @@ final class MakeCrud extends AbstractMaker { private $router; - + private $fileManager; private $locator; - public function __construct(RouterInterface $router, ContainerInterface $serviceLocator) + public function __construct(RouterInterface $router, FileManager $fileManager, ContainerInterface $serviceLocator) { $this->router = $router; + $this->fileManager = $fileManager; $this->locator = $serviceLocator; } @@ -50,27 +56,6 @@ public function configureCommand(Command $command, InputConfiguration $inputConf ; } - /** - * {@inheritdoc} - */ - public function configureDependencies(DependencyBuilder $dependencies) - { - $dependencies->addClassDependency( - Route::class, - 'annotations' - ); - - $dependencies->addClassDependency( - TwigBundle::class, - 'twig-bundle' - ); - - $dependencies->addClassDependency( - EntityManager::class, - 'orm-pack' - ); - } - /** * {@inheritdoc} */ @@ -92,7 +77,12 @@ public function getParameters(InputInterface $input): array $metadata = $this->getEntityMetadata($entityClassName); + $baseLayoutExists = $this->fileManager->fileExists('templates/base.html.twig'); + + $helper = new GeneratorHelper(); + return array( + 'helper' => $helper, 'controller_class_name' => $controllerClassName, 'entity_var_plural' => lcfirst(Inflector::pluralize($entityClassName)), 'entity_var_singular' => lcfirst(Inflector::singularize($entityClassName)), @@ -102,6 +92,7 @@ public function getParameters(InputInterface $input): array 'form_class_name' => $formClassName, 'route_path' => Str::asRoutePath(str_replace('Controller', '', $controllerClassName)), 'route_name' => Str::asRouteName(str_replace('Controller', '', $controllerClassName)), + 'base_layout_exists' => $baseLayoutExists, ); } @@ -111,8 +102,8 @@ public function getParameters(InputInterface $input): array public function getFiles(array $params): array { return array( - __DIR__.'/../Resources/skeleton/crud/controller/ControllerWithTwig.tpl.php' => 'src/Controller/'.$params['controller_class_name'].'.php', - __DIR__.'/../Resources/skeleton/crud/form/Type.tpl.php' => 'src/Form/'.$params['form_class_name'].'.php', + __DIR__.'/../Resources/skeleton/crud/controller/Controller.tpl.php' => 'src/Controller/'.$params['controller_class_name'].'.php', +// __DIR__.'/../Resources/skeleton/crud/form/Type.tpl.php' => 'src/Form/'.$params['form_class_name'].'.php', __DIR__.'/../Resources/skeleton/crud/templates/_delete_form.tpl.php' => 'templates/'.$params['route_name'].'/_delete_form.html.twig', __DIR__.'/../Resources/skeleton/crud/templates/_form.tpl.php' => 'templates/'.$params['route_name'].'/_form.html.twig', __DIR__.'/../Resources/skeleton/crud/templates/index.tpl.php' => 'templates/'.$params['route_name'].'/index.html.twig', @@ -122,17 +113,45 @@ public function getFiles(array $params): array ); } + public function writeSuccessMessage(array $params, ConsoleStyle $io) + { + parent::writeSuccessMessage($params, $io); + + $io->text('Next: Check your new crud!'); + } + /** * {@inheritdoc} */ - public function writeNextStepsMessage(array $params, ConsoleStyle $io) + public function configureDependencies(DependencyBuilder $dependencies) { - if (!count($this->router->getRouteCollection())) { - $io->text(' Warning! No routes configuration defined yet.'); - $io->text(' You should probably uncomment the annotation routes in config/routes.yaml'); - $io->newLine(); - } - $io->text('Next: Check your new crud!'); + $dependencies->addClassDependency( + Route::class, + 'annotations' + ); + +// $dependencies->addClassDependency( +// AbstractType::class, +// // technically only form is needed, but the user will *probably* also want validation +// 'form' +// ); +// +// $dependencies->addClassDependency( +// Validation::class, +// 'validator', +// // add as an optional dependency: the user *probably* wants validation +// false +// ); + + $dependencies->addClassDependency( + TwigBundle::class, + 'twig-bundle' + ); + + $dependencies->addClassDependency( + EntityManager::class, + 'orm-pack' + ); } private function getEntityMetadata($entityClassName) diff --git a/src/Resources/config/makers.xml b/src/Resources/config/makers.xml index ef3d5a945..fb21450fc 100644 --- a/src/Resources/config/makers.xml +++ b/src/Resources/config/makers.xml @@ -23,6 +23,7 @@ + diff --git a/src/Resources/skeleton/crud/controller/ControllerWithTwig.tpl.php b/src/Resources/skeleton/crud/controller/Controller.tpl.php similarity index 100% rename from src/Resources/skeleton/crud/controller/ControllerWithTwig.tpl.php rename to src/Resources/skeleton/crud/controller/Controller.tpl.php diff --git a/src/Resources/skeleton/crud/templates/edit.tpl.php b/src/Resources/skeleton/crud/templates/edit.tpl.php index 510f96cde..25feb6c8b 100644 --- a/src/Resources/skeleton/crud/templates/edit.tpl.php +++ b/src/Resources/skeleton/crud/templates/edit.tpl.php @@ -1,6 +1,7 @@ -{% extends 'base.html.twig' %} +getHead($base_layout_exists, 'Edit '.$entity_class_name); ?> + +getBodyStart($base_layout_exists); ?> -{% block body %}

      Edit

      {% include '/_form.html.twig' with {'form': form, 'button_label': 'Edit'} only %} @@ -9,4 +10,4 @@ {% include '/_delete_form.html.twig' with {'identifier': .} only %} -{% endblock %} +getBodyEnd($base_layout_exists); ?> diff --git a/src/Resources/skeleton/crud/templates/index.tpl.php b/src/Resources/skeleton/crud/templates/index.tpl.php index b8118dfbe..79e44c5f7 100644 --- a/src/Resources/skeleton/crud/templates/index.tpl.php +++ b/src/Resources/skeleton/crud/templates/index.tpl.php @@ -1,21 +1,20 @@ -{% extends 'base.html.twig' %} +getHead($base_layout_exists, $entity_class_name.' index'); ?> + +getBodyStart($base_layout_exists); ?> -{% block body %}

      index

      - - + {% for in %} - - - + @@ -28,4 +27,5 @@
      actionsactions
      {{ . }} + {{ getEntityFieldPrintCode($entity_var_singular, $field); ?> }} show edit
      Create new -{% endblock %} \ No newline at end of file + +getBodyEnd($base_layout_exists); ?> diff --git a/src/Resources/skeleton/crud/templates/new.tpl.php b/src/Resources/skeleton/crud/templates/new.tpl.php index 615c05cee..31bf4637d 100644 --- a/src/Resources/skeleton/crud/templates/new.tpl.php +++ b/src/Resources/skeleton/crud/templates/new.tpl.php @@ -1,8 +1,9 @@ -{% extends 'base.html.twig' %} +getHead($base_layout_exists, 'New '.$entity_class_name); ?> + +getBodyStart($base_layout_exists); ?> -{% block body %}

      Create new

      {% include '/_form.html.twig' with {'form': form} only %} -{% endblock %} +getBodyEnd($base_layout_exists); ?> diff --git a/src/Resources/skeleton/crud/templates/show.tpl.php b/src/Resources/skeleton/crud/templates/show.tpl.php index 4b4baf277..d2e7982ea 100644 --- a/src/Resources/skeleton/crud/templates/show.tpl.php +++ b/src/Resources/skeleton/crud/templates/show.tpl.php @@ -1,16 +1,16 @@ -{% extends 'base.html.twig' %} +getHead($base_layout_exists, $entity_class_name); ?> + +getBodyStart($base_layout_exists); ?> -{% block body %}

      - - +
      + - + - -
      {{ . }}{{ getEntityFieldPrintCode($entity_var_singular, $field); ?> }}
      + back to list @@ -18,4 +18,4 @@ {% include '/_delete_form.html.twig' with {'identifier': .} only %} -{% endblock %} \ No newline at end of file +getBodyEnd($base_layout_exists); ?> From 3787739a95675c6c42bd5c4f95a0bbe8805b33c5 Mon Sep 17 00:00:00 2001 From: Sadicov Vladimir Date: Sun, 11 Feb 2018 19:53:30 +0200 Subject: [PATCH 21/44] cs fix --- src/GeneratorHelper.php | 9 +++++++++ src/Maker/MakeCrud.php | 18 +++++++++++++----- 2 files changed, 22 insertions(+), 5 deletions(-) diff --git a/src/GeneratorHelper.php b/src/GeneratorHelper.php index a5cb6537d..2457954b3 100644 --- a/src/GeneratorHelper.php +++ b/src/GeneratorHelper.php @@ -1,5 +1,14 @@ + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + namespace Symfony\Bundle\MakerBundle; class GeneratorHelper diff --git a/src/Maker/MakeCrud.php b/src/Maker/MakeCrud.php index 8c6d6c957..0c8f05727 100644 --- a/src/Maker/MakeCrud.php +++ b/src/Maker/MakeCrud.php @@ -1,10 +1,18 @@ + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + namespace Symfony\Bundle\MakerBundle\Maker; use Doctrine\Common\Inflector\Inflector; use Doctrine\ORM\EntityManager; -use Doctrine\ORM\Mapping\ClassMetadataInfo; use Psr\Container\ContainerInterface; use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route; use Symfony\Bundle\MakerBundle\ConsoleStyle; @@ -81,7 +89,7 @@ public function getParameters(InputInterface $input): array $helper = new GeneratorHelper(); - return array( + return [ 'helper' => $helper, 'controller_class_name' => $controllerClassName, 'entity_var_plural' => lcfirst(Inflector::pluralize($entityClassName)), @@ -93,7 +101,7 @@ public function getParameters(InputInterface $input): array 'route_path' => Str::asRoutePath(str_replace('Controller', '', $controllerClassName)), 'route_name' => Str::asRouteName(str_replace('Controller', '', $controllerClassName)), 'base_layout_exists' => $baseLayoutExists, - ); + ]; } /** @@ -101,7 +109,7 @@ public function getParameters(InputInterface $input): array */ public function getFiles(array $params): array { - return array( + return [ __DIR__.'/../Resources/skeleton/crud/controller/Controller.tpl.php' => 'src/Controller/'.$params['controller_class_name'].'.php', // __DIR__.'/../Resources/skeleton/crud/form/Type.tpl.php' => 'src/Form/'.$params['form_class_name'].'.php', __DIR__.'/../Resources/skeleton/crud/templates/_delete_form.tpl.php' => 'templates/'.$params['route_name'].'/_delete_form.html.twig', @@ -110,7 +118,7 @@ public function getFiles(array $params): array __DIR__.'/../Resources/skeleton/crud/templates/show.tpl.php' => 'templates/'.$params['route_name'].'/show.html.twig', __DIR__.'/../Resources/skeleton/crud/templates/new.tpl.php' => 'templates/'.$params['route_name'].'/new.html.twig', __DIR__.'/../Resources/skeleton/crud/templates/edit.tpl.php' => 'templates/'.$params['route_name'].'/edit.html.twig', - ); + ]; } public function writeSuccessMessage(array $params, ConsoleStyle $io) From 7ed6b8b6da16464d3447f3849155e8c7004aa98b Mon Sep 17 00:00:00 2001 From: Sadicov Vladimir Date: Mon, 12 Feb 2018 12:59:04 +0200 Subject: [PATCH 22/44] improved tests --- src/GeneratorHelper.php | 3 ++ src/Maker/MakeCrud.php | 35 ++++++++++--------- tests/Maker/FunctionalTest.php | 12 ++++--- .../MakeCrud/src/Entity/SweetFood.php | 16 +++++++++ .../tests/GeneratedCrudControllerTest.php | 28 +++++++++++++++ 5 files changed, 73 insertions(+), 21 deletions(-) create mode 100644 tests/fixtures/MakeCrud/tests/GeneratedCrudControllerTest.php diff --git a/src/GeneratorHelper.php b/src/GeneratorHelper.php index 2457954b3..da60b1ad2 100644 --- a/src/GeneratorHelper.php +++ b/src/GeneratorHelper.php @@ -11,6 +11,9 @@ namespace Symfony\Bundle\MakerBundle; +/** + * @author Sadicov Vladimir + */ class GeneratorHelper { public function getEntityFieldPrintCode($entity, $field): string diff --git a/src/Maker/MakeCrud.php b/src/Maker/MakeCrud.php index 0c8f05727..c9d714d5c 100644 --- a/src/Maker/MakeCrud.php +++ b/src/Maker/MakeCrud.php @@ -11,8 +11,9 @@ namespace Symfony\Bundle\MakerBundle\Maker; +use Doctrine\Bundle\DoctrineBundle\DoctrineBundle; use Doctrine\Common\Inflector\Inflector; -use Doctrine\ORM\EntityManager; +use Doctrine\ORM\Mapping\Column; use Psr\Container\ContainerInterface; use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route; use Symfony\Bundle\MakerBundle\ConsoleStyle; @@ -111,7 +112,7 @@ public function getFiles(array $params): array { return [ __DIR__.'/../Resources/skeleton/crud/controller/Controller.tpl.php' => 'src/Controller/'.$params['controller_class_name'].'.php', -// __DIR__.'/../Resources/skeleton/crud/form/Type.tpl.php' => 'src/Form/'.$params['form_class_name'].'.php', + __DIR__.'/../Resources/skeleton/crud/form/Type.tpl.php' => 'src/Form/'.$params['form_class_name'].'.php', __DIR__.'/../Resources/skeleton/crud/templates/_delete_form.tpl.php' => 'templates/'.$params['route_name'].'/_delete_form.html.twig', __DIR__.'/../Resources/skeleton/crud/templates/_form.tpl.php' => 'templates/'.$params['route_name'].'/_form.html.twig', __DIR__.'/../Resources/skeleton/crud/templates/index.tpl.php' => 'templates/'.$params['route_name'].'/index.html.twig', @@ -138,18 +139,15 @@ public function configureDependencies(DependencyBuilder $dependencies) 'annotations' ); -// $dependencies->addClassDependency( -// AbstractType::class, -// // technically only form is needed, but the user will *probably* also want validation -// 'form' -// ); -// -// $dependencies->addClassDependency( -// Validation::class, -// 'validator', -// // add as an optional dependency: the user *probably* wants validation -// false -// ); + $dependencies->addClassDependency( + AbstractType::class, + 'form' + ); + + $dependencies->addClassDependency( + Validation::class, + 'validator' + ); $dependencies->addClassDependency( TwigBundle::class, @@ -157,8 +155,13 @@ public function configureDependencies(DependencyBuilder $dependencies) ); $dependencies->addClassDependency( - EntityManager::class, - 'orm-pack' + DoctrineBundle::class, + 'orm' + ); + + $dependencies->addClassDependency( + Column::class, + 'orm' ); } diff --git a/tests/Maker/FunctionalTest.php b/tests/Maker/FunctionalTest.php index a93f4052c..442f72a22 100644 --- a/tests/Maker/FunctionalTest.php +++ b/tests/Maker/FunctionalTest.php @@ -254,7 +254,7 @@ public function getCommandTests() $this->assertNotContains('Success', $output); $this->assertContains('No database changes were detected', $output); - }), + }) ]; yield 'crud' => [MakerTestDetails::createTest( @@ -264,15 +264,17 @@ public function getCommandTests() 'SweetFood', ]) ->setFixtureFilesPath(__DIR__.'/../fixtures/MakeCrud') + ->addReplacement( + 'phpunit.xml.dist', + 'mysql://db_user:db_password@127.0.0.1:3306/db_name', + 'sqlite:///%kernel.project_dir%/var/app.db' + ) ->addReplacement( '.env', 'mysql://db_user:db_password@127.0.0.1:3306/db_name', 'sqlite:///%kernel.project_dir%/var/app.db' ) - ->addExtraDependencies('symfony/orm-pack') - ->assert(function (string $output, string $directory) { - $this->assertContains('Success', $output); - }), + ->addPreMakeCommand('./bin/console doctrine:schema:create --env=test') ]; } diff --git a/tests/fixtures/MakeCrud/src/Entity/SweetFood.php b/tests/fixtures/MakeCrud/src/Entity/SweetFood.php index 1da61ecb4..ee7bc28be 100644 --- a/tests/fixtures/MakeCrud/src/Entity/SweetFood.php +++ b/tests/fixtures/MakeCrud/src/Entity/SweetFood.php @@ -20,4 +20,20 @@ class SweetFood * @ORM\Column(name="title", type="string", length=255) */ private $title; + + /** + * @return mixed + */ + public function getTitle() + { + return $this->title; + } + + /** + * @param mixed $title + */ + public function setTitle($title) + { + $this->title = $title; + } } diff --git a/tests/fixtures/MakeCrud/tests/GeneratedCrudControllerTest.php b/tests/fixtures/MakeCrud/tests/GeneratedCrudControllerTest.php new file mode 100644 index 000000000..5b2fd3ca4 --- /dev/null +++ b/tests/fixtures/MakeCrud/tests/GeneratedCrudControllerTest.php @@ -0,0 +1,28 @@ +request('GET', '/sweet/food/'); + + $this->assertEquals(200, $client->getResponse()->getStatusCode()); + $this->assertContains('', $client->getResponse()->getContent()); + $this->assertContains('SweetFood index', $client->getResponse()->getContent()); + } + + public function testNewAction() + { + $client = self::createClient(); + $client->request('GET', '/sweet/food/new'); + + $this->assertEquals(200, $client->getResponse()->getStatusCode()); + $this->assertContains('', $client->getResponse()->getContent()); + $this->assertContains('New SweetFood', $client->getResponse()->getContent()); + } +} From 40456950e7d93bb13f3406c0097d899bf5625793 Mon Sep 17 00:00:00 2001 From: Sadicov Vladimir Date: Mon, 12 Feb 2018 23:27:37 +0200 Subject: [PATCH 23/44] removed unnecessary code --- src/Resources/skeleton/crud/controller/Controller.tpl.php | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/Resources/skeleton/crud/controller/Controller.tpl.php b/src/Resources/skeleton/crud/controller/Controller.tpl.php index a1299b8d3..3546db7de 100644 --- a/src/Resources/skeleton/crud/controller/Controller.tpl.php +++ b/src/Resources/skeleton/crud/controller/Controller.tpl.php @@ -59,8 +59,6 @@ public function new(Request $request) */ public function show( $) { - $deleteForm = $this->createDeleteForm($); - return $this->render('/show.html.twig', [ '' => $, ]); @@ -75,8 +73,6 @@ public function edit(Request $request, $createForm(::class, $); $form->handleRequest($request); - $deleteForm = $this->createDeleteForm($); - if ($form->isSubmitted() && $form->isValid()) { $this->getDoctrine()->getManager()->flush(); From 7555a3ae470481c5974eaa196af47a99c8f68194 Mon Sep 17 00:00:00 2001 From: Sadicov Vladimir Date: Tue, 13 Feb 2018 13:24:03 +0200 Subject: [PATCH 24/44] improved make:form command --- src/Doctrine/DoctrineEntityHelper.php | 58 ++++++++++++ src/Doctrine/DoctrineMetadataFactory.php | 88 +++++++++++++++++++ src/FileManager.php | 9 ++ src/GeneratorHelper.php | 13 +++ src/Maker/MakeForm.php | 77 ++++++++++++++-- src/Resources/config/makers.xml | 2 + src/Resources/config/services.xml | 4 + src/Resources/skeleton/form/Type.tpl.php | 18 ++-- tests/Maker/FunctionalTest.php | 13 +++ .../MakeForm/tests/GeneratedFormTest.php | 29 ++++++ .../MakeFormForEntity/src/Entity/SourFood.php | 39 ++++++++ .../tests/GeneratedFormTest.php | 33 +++++++ 12 files changed, 371 insertions(+), 12 deletions(-) create mode 100644 src/Doctrine/DoctrineEntityHelper.php create mode 100644 src/Doctrine/DoctrineMetadataFactory.php create mode 100644 tests/fixtures/MakeForm/tests/GeneratedFormTest.php create mode 100644 tests/fixtures/MakeFormForEntity/src/Entity/SourFood.php create mode 100644 tests/fixtures/MakeFormForEntity/tests/GeneratedFormTest.php diff --git a/src/Doctrine/DoctrineEntityHelper.php b/src/Doctrine/DoctrineEntityHelper.php new file mode 100644 index 000000000..d9408dcca --- /dev/null +++ b/src/Doctrine/DoctrineEntityHelper.php @@ -0,0 +1,58 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Bundle\MakerBundle\Doctrine; + +use Doctrine\Common\Persistence\ManagerRegistry; +use Doctrine\ORM\Mapping\ClassMetadataInfo; + +/** + * @author Sadicov Vladimir + */ +final class DoctrineEntityHelper +{ + private $metadataFactory = null; + + public function __construct(ManagerRegistry $registry = null) + { + if (null !== $registry) { + $this->metadataFactory = new DoctrineMetadataFactory($registry); + } + } + + public function isDoctrineConnected(): bool + { + return null !== $this->metadataFactory; + } + + public function getFormFieldsFromEntity(string $entityClassName): array + { + $metadata = $this->getEntityMetadata($entityClassName); + + $fields = (array) $metadata->fieldNames; + // Remove the primary key field if it's not managed manually + if (!$metadata->isIdentifierNatural()) { + $fields = array_diff($fields, $metadata->identifier); + } + foreach ($metadata->associationMappings as $fieldName => $relation) { + if (ClassMetadataInfo::ONE_TO_MANY !== $relation['type']) { + $fields[] = $fieldName; + } + } + + return $fields; + } + + private function getEntityMetadata($entityClassName): ClassMetadataInfo + { + return $this->metadataFactory->getMetadataForClass('App\\Entity\\'.$entityClassName); + } +} diff --git a/src/Doctrine/DoctrineMetadataFactory.php b/src/Doctrine/DoctrineMetadataFactory.php new file mode 100644 index 000000000..b5a616539 --- /dev/null +++ b/src/Doctrine/DoctrineMetadataFactory.php @@ -0,0 +1,88 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Bundle\MakerBundle\Doctrine; + +use Doctrine\Common\Persistence\ManagerRegistry; +use Doctrine\ORM\Mapping\ClassMetadata; +use Doctrine\ORM\Tools\DisconnectedClassMetadataFactory; + +/** + * Simpler version of DoctrineBundle's DisconnectedMetadataFactory, to + * avoid PSR-4 issues. + * + * @internal + * + * @author Fabien Potencier + * @author Ryan Weaver + */ +final class DoctrineMetadataFactory +{ + private $registry; + + /** + * Constructor. + * + * @param ManagerRegistry $registry A ManagerRegistry instance + */ + public function __construct(ManagerRegistry $registry) + { + $this->registry = $registry; + } + + /** + * @param string $namespace + * + * @return array|ClassMetadata[] + */ + public function getMetadataForNamespace($namespace) + { + $metadata = []; + foreach ($this->getAllMetadata() as $m) { + if (0 === strpos($m->name, $namespace)) { + $metadata[] = $m; + } + } + + return $metadata; + } + + public function getMetadataForClass(string $entity): ?ClassMetadata + { + foreach ($this->registry->getManagers() as $em) { + $cmf = new DisconnectedClassMetadataFactory(); + $cmf->setEntityManager($em); + + if (!$cmf->isTransient($entity)) { + return $cmf->getMetadataFor($entity); + } + } + + return null; + } + + /** + * @return array + */ + private function getAllMetadata() + { + $metadata = []; + foreach ($this->registry->getManagers() as $em) { + $cmf = new DisconnectedClassMetadataFactory(); + $cmf->setEntityManager($em); + foreach ($cmf->getAllMetadata() as $m) { + $metadata[] = $m; + } + } + + return $metadata; + } +} diff --git a/src/FileManager.php b/src/FileManager.php index 6359adb8c..92e5d013b 100644 --- a/src/FileManager.php +++ b/src/FileManager.php @@ -13,6 +13,7 @@ use Symfony\Component\Console\Style\SymfonyStyle; use Symfony\Component\Filesystem\Filesystem; +use Symfony\Component\Finder\Finder; /** * @author Javier Eguiluz @@ -65,6 +66,14 @@ public function relativizePath($absolutePath): string return is_dir($absolutePath) ? rtrim($relativePath, '/').'/' : $relativePath; } + public function createFinder(string $in) + { + $finder = new Finder(); + $finder->in($this->absolutizePath($in)); + + return $finder; + } + private function absolutizePath($path): string { if (0 === strpos($path, '/')) { diff --git a/src/GeneratorHelper.php b/src/GeneratorHelper.php index da60b1ad2..b4d229f22 100644 --- a/src/GeneratorHelper.php +++ b/src/GeneratorHelper.php @@ -16,6 +16,19 @@ */ class GeneratorHelper { + public function getFormFieldsPrintCode(array $formFields): string + { + $printCode = ''; + + foreach ($formFields as $fieldName) { + $printCode .= <<add('$fieldName') +PHP; + } + + return $printCode; + } + public function getEntityFieldPrintCode($entity, $field): string { $printCode = $entity.'.'.$field['fieldName']; diff --git a/src/Maker/MakeForm.php b/src/Maker/MakeForm.php index ee58d20f1..3cd9e398f 100644 --- a/src/Maker/MakeForm.php +++ b/src/Maker/MakeForm.php @@ -11,23 +11,39 @@ namespace Symfony\Bundle\MakerBundle\Maker; +use Doctrine\Bundle\DoctrineBundle\DoctrineBundle; use Symfony\Bundle\MakerBundle\ConsoleStyle; use Symfony\Bundle\MakerBundle\DependencyBuilder; +use Symfony\Bundle\MakerBundle\Doctrine\DoctrineEntityHelper; +use Symfony\Bundle\MakerBundle\Exception\RuntimeCommandException; +use Symfony\Bundle\MakerBundle\FileManager; +use Symfony\Bundle\MakerBundle\GeneratorHelper; use Symfony\Bundle\MakerBundle\InputConfiguration; use Symfony\Bundle\MakerBundle\Str; use Symfony\Bundle\MakerBundle\Validator; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputInterface; +use Symfony\Component\Console\Input\InputOption; use Symfony\Component\Form\AbstractType; use Symfony\Component\Validator\Validation; /** * @author Javier Eguiluz * @author Ryan Weaver + * @author Sadicov Vladimir */ final class MakeForm extends AbstractMaker { + private $fileManager; + private $entityHelper; + + public function __construct(FileManager $fileManager, DoctrineEntityHelper $entityHelper) + { + $this->fileManager = $fileManager; + $this->entityHelper = $entityHelper; + } + public static function getCommandName(): string { return 'make:form'; @@ -38,19 +54,62 @@ public function configureCommand(Command $command, InputConfiguration $inputConf $command ->setDescription('Creates a new form class') ->addArgument('name', InputArgument::OPTIONAL, sprintf('The name of the form class (e.g. %sType)', Str::asClassName(Str::getRandomTerm()))) + ->addOption('entity', null, InputOption::VALUE_NONE, 'Generate form class from existing entity') ->setHelp(file_get_contents(__DIR__.'/../Resources/help/MakeForm.txt')) ; } + public function interact(InputInterface $input, ConsoleStyle $io, Command $command) + { + $entityFormGeneration = $input->getOption('entity'); + + if ($this->entityHelper->isDoctrineConnected()) { + $entityClassName = Str::removeSuffix(Str::asClassName($input->getArgument('name')), 'Type'); + + $entityExists = $this->fileManager->fileExists('src/Entity/'.$entityClassName.'.php'); + + if ($entityFormGeneration && !$entityExists) { + throw new RuntimeCommandException(sprintf('Entity "%s" doesn\'t exists in your project. May be you would like to create it with "make:entity" command?', $entityClassName)); + } + + if ((!$entityFormGeneration && !$entityExists) || $entityFormGeneration) { + return; + } + + $io->block( + sprintf('Entity "%s" found in your project', $entityClassName), + null, + 'fg=yellow' + ); + $entityFormGeneration = $io->confirm('Do you want to generate a form for an entity?', true); + + $input->setOption('entity', $entityFormGeneration); + } elseif ($entityFormGeneration) { + $io->block([ + 'Doctrine not found, falling back to simple form generation', + ], null, 'fg=yellow'); + $input->setOption('entity', false); + } + } + public function getParameters(InputInterface $input): array { $formClassName = Str::asClassName($input->getArgument('name'), 'Type'); Validator::validateClassName($formClassName); - $entityClassName = Str::removeSuffix($formClassName, 'Type'); + + $entityFormGeneration = $input->getOption('entity'); + + $entityClassName = $entityFormGeneration ? Str::removeSuffix($formClassName, 'Type') : false; + + $formFields = $entityFormGeneration ? $this->entityHelper->getFormFieldsFromEntity($entityClassName) : ['field_name']; + + $helper = new GeneratorHelper(); return [ + 'helper' => $helper, 'form_class_name' => $formClassName, 'entity_class_name' => $entityClassName, + 'form_fields' => $formFields, ]; } @@ -65,10 +124,12 @@ public function writeSuccessMessage(array $params, ConsoleStyle $io) { parent::writeSuccessMessage($params, $io); - $io->text([ - 'Next: Add fields to your form and start using it.', - 'Find the documentation at https://symfony.com/doc/current/forms.html', - ]); + if (!$params['entity_class_name']) { + $io->text([ + 'Next: Add fields to your form and start using it.', + 'Find the documentation at https://symfony.com/doc/current/forms.html', + ]); + } } public function configureDependencies(DependencyBuilder $dependencies) @@ -85,5 +146,11 @@ public function configureDependencies(DependencyBuilder $dependencies) // add as an optional dependency: the user *probably* wants validation false ); + + $dependencies->addClassDependency( + DoctrineBundle::class, + 'orm', + false + ); } } diff --git a/src/Resources/config/makers.xml b/src/Resources/config/makers.xml index fb21450fc..134a4559f 100644 --- a/src/Resources/config/makers.xml +++ b/src/Resources/config/makers.xml @@ -44,6 +44,8 @@
      + + diff --git a/src/Resources/config/services.xml b/src/Resources/config/services.xml index fadeb037b..b9a856a5f 100644 --- a/src/Resources/config/services.xml +++ b/src/Resources/config/services.xml @@ -23,5 +23,9 @@ + + + + diff --git a/src/Resources/skeleton/form/Type.tpl.php b/src/Resources/skeleton/form/Type.tpl.php index 679e61d43..345babc44 100644 --- a/src/Resources/skeleton/form/Type.tpl.php +++ b/src/Resources/skeleton/form/Type.tpl.php @@ -1,26 +1,30 @@ - + namespace App\Form; -use App\Entity\; +use App\Entity\; + use Symfony\Component\Form\AbstractType; use Symfony\Component\Form\FormBuilderInterface; -use Symfony\Component\OptionsResolver\OptionsResolver; +use Symfony\Component\OptionsResolver\OptionsResolver; + -class extends AbstractType +class extends AbstractType { public function buildForm(FormBuilderInterface $builder, array $options) { $builder - ->add('field_name') +getFormFieldsPrintCode($form_fields); ?> + ; } + public function configureOptions(OptionsResolver $resolver) { $resolver->setDefaults([ - // uncomment if you want to bind to a class - //'data_class' => ::class, + 'data_class' => ::class, ]); } + } diff --git a/tests/Maker/FunctionalTest.php b/tests/Maker/FunctionalTest.php index 442f72a22..a91d81845 100644 --- a/tests/Maker/FunctionalTest.php +++ b/tests/Maker/FunctionalTest.php @@ -129,6 +129,19 @@ public function getCommandTests() // form name 'FooBar', ]) + ->setFixtureFilesPath(__DIR__.'/../fixtures/MakeForm') + ]; + + yield 'entity_form' => [MakerTestDetails::createTest( + $this->getMakerInstance(MakeForm::class), + [ + // Entity name + 'SourFood', + // agree with use Entity for form generation + 'yes' + ]) + ->addExtraDependencies('orm') + ->setFixtureFilesPath(__DIR__.'/../fixtures/MakeFormForEntity') ]; yield 'functional' => [MakerTestDetails::createTest( diff --git a/tests/fixtures/MakeForm/tests/GeneratedFormTest.php b/tests/fixtures/MakeForm/tests/GeneratedFormTest.php new file mode 100644 index 000000000..0e9881d57 --- /dev/null +++ b/tests/fixtures/MakeForm/tests/GeneratedFormTest.php @@ -0,0 +1,29 @@ + 'field_value' + ]; + + $form = $this->factory->create(FooBarType::class); + $form->submit($formData); + + $this->assertTrue($form->isSynchronized()); + $this->assertEquals($formData, $form->getData()); + + $view = $form->createView(); + $children = $view->children; + + foreach (array_keys($formData) as $key) { + $this->assertArrayHasKey($key, $children); + } + } +} diff --git a/tests/fixtures/MakeFormForEntity/src/Entity/SourFood.php b/tests/fixtures/MakeFormForEntity/src/Entity/SourFood.php new file mode 100644 index 000000000..0beae7e10 --- /dev/null +++ b/tests/fixtures/MakeFormForEntity/src/Entity/SourFood.php @@ -0,0 +1,39 @@ +title; + } + + /** + * @param mixed $title + */ + public function setTitle($title) + { + $this->title = $title; + } +} diff --git a/tests/fixtures/MakeFormForEntity/tests/GeneratedFormTest.php b/tests/fixtures/MakeFormForEntity/tests/GeneratedFormTest.php new file mode 100644 index 000000000..5ccb84de9 --- /dev/null +++ b/tests/fixtures/MakeFormForEntity/tests/GeneratedFormTest.php @@ -0,0 +1,33 @@ + 'lemon' + ]; + + $form = $this->factory->create(SourFoodType::class); + $form->submit($formData); + + $object = new SourFood(); + $object->setTitle('lemon'); + + $this->assertTrue($form->isSynchronized()); + $this->assertEquals($object, $form->getData()); + + $view = $form->createView(); + $children = $view->children; + + foreach (array_keys($formData) as $key) { + $this->assertArrayHasKey($key, $children); + } + } +} From e24b22c431f3cc6ccfa6b40208a45465afca16a2 Mon Sep 17 00:00:00 2001 From: Sadicov Vladimir Date: Tue, 13 Feb 2018 13:34:11 +0200 Subject: [PATCH 25/44] fix to use with php 7.0 --- src/Doctrine/DoctrineMetadataFactory.php | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/Doctrine/DoctrineMetadataFactory.php b/src/Doctrine/DoctrineMetadataFactory.php index b5a616539..1ae71b0a1 100644 --- a/src/Doctrine/DoctrineMetadataFactory.php +++ b/src/Doctrine/DoctrineMetadataFactory.php @@ -55,7 +55,12 @@ public function getMetadataForNamespace($namespace) return $metadata; } - public function getMetadataForClass(string $entity): ?ClassMetadata + /** + * @param string $entity + * + * @return ClassMetadata|null + */ + public function getMetadataForClass(string $entity) { foreach ($this->registry->getManagers() as $em) { $cmf = new DisconnectedClassMetadataFactory(); From 52a20bb129568245d2eeef0e6f6396664a4560ca Mon Sep 17 00:00:00 2001 From: Sadicov Vladimir Date: Tue, 13 Feb 2018 14:19:41 +0200 Subject: [PATCH 26/44] improve make:crud command to use make:form logic for form generation --- src/Doctrine/DoctrineEntityHelper.php | 7 ++++- src/Maker/MakeCrud.php | 26 ++++++++----------- src/Resources/config/makers.xml | 9 +------ src/Resources/skeleton/crud/form/Type.tpl.php | 25 ------------------ .../crud/templates/_delete_form.tpl.php | 2 +- tests/Maker/FunctionalTest.php | 21 +++++++++++++++ 6 files changed, 40 insertions(+), 50 deletions(-) delete mode 100644 src/Resources/skeleton/crud/form/Type.tpl.php diff --git a/src/Doctrine/DoctrineEntityHelper.php b/src/Doctrine/DoctrineEntityHelper.php index d9408dcca..9beddc375 100644 --- a/src/Doctrine/DoctrineEntityHelper.php +++ b/src/Doctrine/DoctrineEntityHelper.php @@ -51,7 +51,12 @@ public function getFormFieldsFromEntity(string $entityClassName): array return $fields; } - private function getEntityMetadata($entityClassName): ClassMetadataInfo + /** + * @param $entityClassName + * + * @return \Doctrine\ORM\Mapping\ClassMetadata|null + */ + public function getEntityMetadata($entityClassName) { return $this->metadataFactory->getMetadataForClass('App\\Entity\\'.$entityClassName); } diff --git a/src/Maker/MakeCrud.php b/src/Maker/MakeCrud.php index c9d714d5c..b099fccce 100644 --- a/src/Maker/MakeCrud.php +++ b/src/Maker/MakeCrud.php @@ -14,10 +14,10 @@ use Doctrine\Bundle\DoctrineBundle\DoctrineBundle; use Doctrine\Common\Inflector\Inflector; use Doctrine\ORM\Mapping\Column; -use Psr\Container\ContainerInterface; use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route; use Symfony\Bundle\MakerBundle\ConsoleStyle; use Symfony\Bundle\MakerBundle\DependencyBuilder; +use Symfony\Bundle\MakerBundle\Doctrine\DoctrineEntityHelper; use Symfony\Bundle\MakerBundle\Exception\RuntimeCommandException; use Symfony\Bundle\MakerBundle\FileManager; use Symfony\Bundle\MakerBundle\GeneratorHelper; @@ -39,13 +39,13 @@ final class MakeCrud extends AbstractMaker { private $router; private $fileManager; - private $locator; + private $entityHelper; - public function __construct(RouterInterface $router, FileManager $fileManager, ContainerInterface $serviceLocator) + public function __construct(RouterInterface $router, FileManager $fileManager, DoctrineEntityHelper $entityHelper) { $this->router = $router; $this->fileManager = $fileManager; - $this->locator = $serviceLocator; + $this->entityHelper = $entityHelper; } public static function getCommandName(): string @@ -84,7 +84,11 @@ public function getParameters(InputInterface $input): array $formClassName = Str::asClassName($entityClassName, 'Type'); Validator::validateClassName($formClassName); - $metadata = $this->getEntityMetadata($entityClassName); + if (!$this->fileManager->fileExists('src/Entity/'.$entityClassName.'.php')) { + throw new RuntimeCommandException(sprintf('Entity "%s" doesn\'t exists in your project. May be you would like to create it with "make:entity" command?', $entityClassName)); + } + + $metadata = $this->entityHelper->getEntityMetadata($entityClassName); $baseLayoutExists = $this->fileManager->fileExists('templates/base.html.twig'); @@ -99,6 +103,7 @@ public function getParameters(InputInterface $input): array 'entity_identifier' => $metadata->identifier[0], 'entity_fields' => $metadata->fieldMappings, 'form_class_name' => $formClassName, + 'form_fields' => $this->entityHelper->getFormFieldsFromEntity($entityClassName), 'route_path' => Str::asRoutePath(str_replace('Controller', '', $controllerClassName)), 'route_name' => Str::asRouteName(str_replace('Controller', '', $controllerClassName)), 'base_layout_exists' => $baseLayoutExists, @@ -112,7 +117,7 @@ public function getFiles(array $params): array { return [ __DIR__.'/../Resources/skeleton/crud/controller/Controller.tpl.php' => 'src/Controller/'.$params['controller_class_name'].'.php', - __DIR__.'/../Resources/skeleton/crud/form/Type.tpl.php' => 'src/Form/'.$params['form_class_name'].'.php', + __DIR__.'/../Resources/skeleton/form/Type.tpl.php' => 'src/Form/'.$params['form_class_name'].'.php', __DIR__.'/../Resources/skeleton/crud/templates/_delete_form.tpl.php' => 'templates/'.$params['route_name'].'/_delete_form.html.twig', __DIR__.'/../Resources/skeleton/crud/templates/_form.tpl.php' => 'templates/'.$params['route_name'].'/_form.html.twig', __DIR__.'/../Resources/skeleton/crud/templates/index.tpl.php' => 'templates/'.$params['route_name'].'/index.html.twig', @@ -164,13 +169,4 @@ public function configureDependencies(DependencyBuilder $dependencies) 'orm' ); } - - private function getEntityMetadata($entityClassName) - { - try { - return $this->locator->get('doctrine')->getManager()->getClassMetadata('App\\Entity\\'.$entityClassName); - } catch (\Doctrine\Common\Persistence\Mapping\MappingException $exception) { - throw new RuntimeCommandException(sprintf('Entity "%s" doesn\'t exists in your project. May be you would like to create it with "make:entity" command?', $entityClassName)); - } - } } diff --git a/src/Resources/config/makers.xml b/src/Resources/config/makers.xml index 134a4559f..50e9de8f1 100644 --- a/src/Resources/config/makers.xml +++ b/src/Resources/config/makers.xml @@ -24,14 +24,7 @@ - - - - - - - - + diff --git a/src/Resources/skeleton/crud/form/Type.tpl.php b/src/Resources/skeleton/crud/form/Type.tpl.php deleted file mode 100644 index febc1c2ca..000000000 --- a/src/Resources/skeleton/crud/form/Type.tpl.php +++ /dev/null @@ -1,25 +0,0 @@ - - -namespace App\Form; - -use App\Entity\; -use Symfony\Component\Form\AbstractType; -use Symfony\Component\Form\FormBuilderInterface; -use Symfony\Component\OptionsResolver\OptionsResolver; - -class extends AbstractType -{ - public function buildForm(FormBuilderInterface $builder, array $options) - { - $builder - ->add('') - ; - } - - public function configureOptions(OptionsResolver $resolver) - { - $resolver->setDefaults([ - 'data_class' => ::class, - ]); - } -} diff --git a/src/Resources/skeleton/crud/templates/_delete_form.tpl.php b/src/Resources/skeleton/crud/templates/_delete_form.tpl.php index b7a97cffe..0cc542780 100644 --- a/src/Resources/skeleton/crud/templates/_delete_form.tpl.php +++ b/src/Resources/skeleton/crud/templates/_delete_form.tpl.php @@ -1,5 +1,5 @@ - + \ No newline at end of file diff --git a/tests/Maker/FunctionalTest.php b/tests/Maker/FunctionalTest.php index a91d81845..112cc73c5 100644 --- a/tests/Maker/FunctionalTest.php +++ b/tests/Maker/FunctionalTest.php @@ -289,6 +289,27 @@ public function getCommandTests() ) ->addPreMakeCommand('./bin/console doctrine:schema:create --env=test') ]; + + yield 'crud_with_no_base' => [MakerTestDetails::createTest( + $this->getMakerInstance(MakeCrud::class), + [ + // entity class name + 'SweetFood', + ]) + ->setFixtureFilesPath(__DIR__.'/../fixtures/MakeCrud') + ->addReplacement( + 'phpunit.xml.dist', + 'mysql://db_user:db_password@127.0.0.1:3306/db_name', + 'sqlite:///%kernel.project_dir%/var/app.db' + ) + ->addReplacement( + '.env', + 'mysql://db_user:db_password@127.0.0.1:3306/db_name', + 'sqlite:///%kernel.project_dir%/var/app.db' + ) + ->addPreMakeCommand('./bin/console doctrine:schema:create --env=test') + ->addPreMakeCommand('rm templates/base.html.twig') + ]; } /** From 1b95509e1173ad95350d101f239251ef1a173d9a Mon Sep 17 00:00:00 2001 From: Sadicov Vladimir Date: Tue, 13 Feb 2018 21:58:26 +0200 Subject: [PATCH 27/44] add csrf dependency it's necessary for delete action in crud and for better security --- src/Maker/MakeCrud.php | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/Maker/MakeCrud.php b/src/Maker/MakeCrud.php index b099fccce..0987066b3 100644 --- a/src/Maker/MakeCrud.php +++ b/src/Maker/MakeCrud.php @@ -30,6 +30,7 @@ use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Form\AbstractType; use Symfony\Component\Routing\RouterInterface; +use Symfony\Component\Security\Csrf\CsrfTokenManager; use Symfony\Component\Validator\Validation; /** @@ -168,5 +169,10 @@ public function configureDependencies(DependencyBuilder $dependencies) Column::class, 'orm' ); + + $dependencies->addClassDependency( + CsrfTokenManager::class, + 'security-csrf' + ); } } From 404c38f42f3cc6a0b85c3d75cb60a0eb3ce21052 Mon Sep 17 00:00:00 2001 From: Sadicov Vladimir Date: Wed, 21 Feb 2018 19:29:58 +0200 Subject: [PATCH 28/44] update all to lastest bundle code --- src/Doctrine/DoctrineEntityHelper.php | 32 +++- src/Doctrine/DoctrineMetadataFactory.php | 2 +- src/GeneratorHelper.php | 58 +----- src/Maker/MakeCrud.php | 171 +++++++++++------- src/Maker/MakeForm.php | 34 +++- src/Resources/config/makers.xml | 2 - .../crud/controller/Controller.tpl.php | 8 +- .../crud/templates/_delete_form.tpl.php | 4 +- .../skeleton/crud/templates/edit.tpl.php | 4 +- .../skeleton/crud/templates/index.tpl.php | 8 +- .../skeleton/crud/templates/new.tpl.php | 4 +- .../skeleton/crud/templates/show.tpl.php | 26 +-- src/Resources/skeleton/form/Type.tpl.php | 8 +- tests/Maker/FunctionalTest.php | 3 +- .../MakeCrud/src/Entity/SweetFood.php | 5 + .../MakeFormForEntity/src/Entity/SourFood.php | 8 + 16 files changed, 221 insertions(+), 156 deletions(-) diff --git a/src/Doctrine/DoctrineEntityHelper.php b/src/Doctrine/DoctrineEntityHelper.php index 9beddc375..e7bf387c7 100644 --- a/src/Doctrine/DoctrineEntityHelper.php +++ b/src/Doctrine/DoctrineEntityHelper.php @@ -16,6 +16,8 @@ /** * @author Sadicov Vladimir + * + * @internal */ final class DoctrineEntityHelper { @@ -33,6 +35,28 @@ public function isDoctrineConnected(): bool return null !== $this->metadataFactory; } + /** + * @return array + */ + public function getEntitiesForAutocomplete(): array + { + $entities = ['none']; + $allMetadata = $this->metadataFactory->getAllMetadata(); + /** @var ClassMetadataInfo $metadata */ + foreach ($allMetadata as $metadata) { + $entities[] = preg_replace('#^[^\\\\]*\\\\Entity\\\\(.*)#', '$1', $metadata->name); + } + + return $entities; + } + + /** + * @param string $entityClassName + * + * @return array + * + * @throws \Exception + */ public function getFormFieldsFromEntity(string $entityClassName): array { $metadata = $this->getEntityMetadata($entityClassName); @@ -55,9 +79,15 @@ public function getFormFieldsFromEntity(string $entityClassName): array * @param $entityClassName * * @return \Doctrine\ORM\Mapping\ClassMetadata|null + * + * @throws \Exception */ public function getEntityMetadata($entityClassName) { - return $this->metadataFactory->getMetadataForClass('App\\Entity\\'.$entityClassName); + if (null === $this->metadataFactory) { + throw new \Exception('Somehow the doctrine service is missing. Is DoctrineBundle installed?'); + } + + return $this->metadataFactory->getMetadataForClass($entityClassName); } } diff --git a/src/Doctrine/DoctrineMetadataFactory.php b/src/Doctrine/DoctrineMetadataFactory.php index 1ae71b0a1..24fce23b6 100644 --- a/src/Doctrine/DoctrineMetadataFactory.php +++ b/src/Doctrine/DoctrineMetadataFactory.php @@ -77,7 +77,7 @@ public function getMetadataForClass(string $entity) /** * @return array */ - private function getAllMetadata() + public function getAllMetadata() { $metadata = []; foreach ($this->registry->getManagers() as $em) { diff --git a/src/GeneratorHelper.php b/src/GeneratorHelper.php index b4d229f22..9adc54fd6 100644 --- a/src/GeneratorHelper.php +++ b/src/GeneratorHelper.php @@ -13,22 +13,11 @@ /** * @author Sadicov Vladimir + * + * @internal */ class GeneratorHelper { - public function getFormFieldsPrintCode(array $formFields): string - { - $printCode = ''; - - foreach ($formFields as $fieldName) { - $printCode .= <<add('$fieldName') -PHP; - } - - return $printCode; - } - public function getEntityFieldPrintCode($entity, $field): string { $printCode = $entity.'.'.$field['fieldName']; @@ -51,54 +40,19 @@ public function getEntityFieldPrintCode($entity, $field): string public function getHead($baseLayoutExists, $title): string { if ($baseLayoutExists) { - $code = << - - - - $title - -HTML; } - return $code; - } - - public function getBodyStart($baseLayoutExists): string - { - if ($baseLayoutExists) { - $code = << -HTML; - } + return << - return $code; - } +$title - public function getBodyEnd($baseLayoutExists): string - { - if ($baseLayoutExists) { - $code = << - HTML; - } - - return $code; } } diff --git a/src/Maker/MakeCrud.php b/src/Maker/MakeCrud.php index 0987066b3..0abb17392 100644 --- a/src/Maker/MakeCrud.php +++ b/src/Maker/MakeCrud.php @@ -18,18 +18,16 @@ use Symfony\Bundle\MakerBundle\ConsoleStyle; use Symfony\Bundle\MakerBundle\DependencyBuilder; use Symfony\Bundle\MakerBundle\Doctrine\DoctrineEntityHelper; -use Symfony\Bundle\MakerBundle\Exception\RuntimeCommandException; use Symfony\Bundle\MakerBundle\FileManager; +use Symfony\Bundle\MakerBundle\Generator; use Symfony\Bundle\MakerBundle\GeneratorHelper; use Symfony\Bundle\MakerBundle\InputConfiguration; use Symfony\Bundle\MakerBundle\Str; -use Symfony\Bundle\MakerBundle\Validator; use Symfony\Bundle\TwigBundle\TwigBundle; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Form\AbstractType; -use Symfony\Component\Routing\RouterInterface; use Symfony\Component\Security\Csrf\CsrfTokenManager; use Symfony\Component\Validator\Validation; @@ -38,13 +36,11 @@ */ final class MakeCrud extends AbstractMaker { - private $router; private $fileManager; private $entityHelper; - public function __construct(RouterInterface $router, FileManager $fileManager, DoctrineEntityHelper $entityHelper) + public function __construct(FileManager $fileManager, DoctrineEntityHelper $entityHelper) { - $this->router = $router; $this->fileManager = $fileManager; $this->entityHelper = $entityHelper; } @@ -66,71 +62,117 @@ public function configureCommand(Command $command, InputConfiguration $inputConf ; } - /** - * {@inheritdoc} - */ - public function interact(InputInterface $input, ConsoleStyle $io, Command $command) + public function generate(InputInterface $input, ConsoleStyle $io, Generator $generator) { - } + $entityClassNameDetails = $generator->createClassNameDetails( + $input->getArgument('entity-class'), + 'Entity\\' + ); - /** - * {@inheritdoc} - */ - public function getParameters(InputInterface $input): array - { - $entityClassName = Str::asClassName($input->getArgument('entity-class')); - Validator::validateClassName($entityClassName); - $controllerClassName = Str::asClassName($entityClassName, 'Controller'); - Validator::validateClassName($controllerClassName); - $formClassName = Str::asClassName($entityClassName, 'Type'); - Validator::validateClassName($formClassName); - - if (!$this->fileManager->fileExists('src/Entity/'.$entityClassName.'.php')) { - throw new RuntimeCommandException(sprintf('Entity "%s" doesn\'t exists in your project. May be you would like to create it with "make:entity" command?', $entityClassName)); - } + $controllerClassNameDetails = $generator->createClassNameDetails( + $entityClassNameDetails->getRelativeNameWithoutSuffix(), + 'Controller\\', + 'Controller' + ); + + $formClassNameDetails = $generator->createClassNameDetails( + $entityClassNameDetails->getRelativeNameWithoutSuffix(), + 'Form\\', + 'Type' + ); - $metadata = $this->entityHelper->getEntityMetadata($entityClassName); + $metadata = $this->entityHelper->getEntityMetadata($entityClassNameDetails->getFullName()); + $entityVarPlural = lcfirst(Inflector::pluralize($entityClassNameDetails->getShortName())); + $entityVarSingular = lcfirst(Inflector::singularize($entityClassNameDetails->getShortName())); + $routeName = Str::asRouteName($controllerClassNameDetails->getRelativeNameWithoutSuffix()); + + $generator->generateClass( + $controllerClassNameDetails->getFullName(), + 'crud/controller/Controller.tpl.php', + [ + 'entity_full_class_name' => $entityClassNameDetails->getFullName(), + 'entity_class_name' => $entityClassNameDetails->getShortName(), + 'form_full_class_name' => $formClassNameDetails->getFullName(), + 'form_class_name' => $formClassNameDetails->getShortName(), + 'route_path' => Str::asRoutePath($controllerClassNameDetails->getRelativeNameWithoutSuffix()), + 'route_name' => $routeName, + 'entity_var_plural' => $entityVarPlural, + 'entity_var_singular' => $entityVarSingular, + 'entity_identifier' => $metadata->identifier[0], + ] + ); - $baseLayoutExists = $this->fileManager->fileExists('templates/base.html.twig'); + $formFields = $this->entityHelper->getFormFieldsFromEntity($entityClassNameDetails->getFullName()); $helper = new GeneratorHelper(); - return [ - 'helper' => $helper, - 'controller_class_name' => $controllerClassName, - 'entity_var_plural' => lcfirst(Inflector::pluralize($entityClassName)), - 'entity_var_singular' => lcfirst(Inflector::singularize($entityClassName)), - 'entity_class_name' => $entityClassName, - 'entity_identifier' => $metadata->identifier[0], - 'entity_fields' => $metadata->fieldMappings, - 'form_class_name' => $formClassName, - 'form_fields' => $this->entityHelper->getFormFieldsFromEntity($entityClassName), - 'route_path' => Str::asRoutePath(str_replace('Controller', '', $controllerClassName)), - 'route_name' => Str::asRouteName(str_replace('Controller', '', $controllerClassName)), - 'base_layout_exists' => $baseLayoutExists, - ]; - } + $generator->generateClass( + $formClassNameDetails->getFullName(), + 'form/Type.tpl.php', + [ + 'entity_class_exists' => true, + 'entity_full_class_name' => $entityClassNameDetails->getFullName(), + 'entity_class_name' => $entityClassNameDetails->getShortName(), + 'form_fields' => $formFields, + 'helper' => $helper + ] + ); - /** - * {@inheritdoc} - */ - public function getFiles(array $params): array - { - return [ - __DIR__.'/../Resources/skeleton/crud/controller/Controller.tpl.php' => 'src/Controller/'.$params['controller_class_name'].'.php', - __DIR__.'/../Resources/skeleton/form/Type.tpl.php' => 'src/Form/'.$params['form_class_name'].'.php', - __DIR__.'/../Resources/skeleton/crud/templates/_delete_form.tpl.php' => 'templates/'.$params['route_name'].'/_delete_form.html.twig', - __DIR__.'/../Resources/skeleton/crud/templates/_form.tpl.php' => 'templates/'.$params['route_name'].'/_form.html.twig', - __DIR__.'/../Resources/skeleton/crud/templates/index.tpl.php' => 'templates/'.$params['route_name'].'/index.html.twig', - __DIR__.'/../Resources/skeleton/crud/templates/show.tpl.php' => 'templates/'.$params['route_name'].'/show.html.twig', - __DIR__.'/../Resources/skeleton/crud/templates/new.tpl.php' => 'templates/'.$params['route_name'].'/new.html.twig', - __DIR__.'/../Resources/skeleton/crud/templates/edit.tpl.php' => 'templates/'.$params['route_name'].'/edit.html.twig', + $baseLayoutExists = $this->fileManager->fileExists('templates/base.html.twig'); + $templatesPath = Str::asFilePath($controllerClassNameDetails->getRelativeNameWithoutSuffix()); + + $templates = [ + '_delete_form' => [ + 'route_name' => $routeName, + 'entity_identifier' => $metadata->identifier[0], + ], + '_form' => [], + 'edit' => [ + 'helper' => $helper, + 'base_layout_exists' => $baseLayoutExists, + 'entity_class_name' => $entityClassNameDetails->getShortName(), + 'entity_var_singular' => $entityVarSingular, + 'entity_identifier' => $metadata->identifier[0], + 'route_name' => $routeName, + ], + 'index' => [ + 'helper' => $helper, + 'base_layout_exists' => $baseLayoutExists, + 'entity_class_name' => $entityClassNameDetails->getShortName(), + 'entity_var_plural' => $entityVarPlural, + 'entity_var_singular' => $entityVarSingular, + 'entity_identifier' => $metadata->identifier[0], + 'entity_fields' => $metadata->fieldMappings, + 'route_name' => $routeName, + ], + 'new' => [ + 'helper' => $helper, + 'base_layout_exists' => $baseLayoutExists, + 'entity_class_name' => $entityClassNameDetails->getShortName(), + 'route_name' => $routeName, + ], + 'show' => [ + 'helper' => $helper, + 'base_layout_exists' => $baseLayoutExists, + 'entity_class_name' => $entityClassNameDetails->getShortName(), + 'entity_var_singular' => $entityVarSingular, + 'entity_identifier' => $metadata->identifier[0], + 'entity_fields' => $metadata->fieldMappings, + 'route_name' => $routeName, + ], ]; - } - public function writeSuccessMessage(array $params, ConsoleStyle $io) - { - parent::writeSuccessMessage($params, $io); + foreach ($templates as $template => $variables) { + $generator->generateFile( + 'templates/'.$templatesPath.'/'.$template.'.html.twig', + 'crud/templates/'.$template.'.tpl.php', + $variables + ); + } + + $generator->writeChanges(); + + $this->writeSuccessMessage($io); $io->text('Next: Check your new crud!'); } @@ -162,12 +204,7 @@ public function configureDependencies(DependencyBuilder $dependencies) $dependencies->addClassDependency( DoctrineBundle::class, - 'orm' - ); - - $dependencies->addClassDependency( - Column::class, - 'orm' + 'orm-pack' ); $dependencies->addClassDependency( diff --git a/src/Maker/MakeForm.php b/src/Maker/MakeForm.php index c0f1c7c38..631707f9c 100644 --- a/src/Maker/MakeForm.php +++ b/src/Maker/MakeForm.php @@ -11,15 +11,17 @@ namespace Symfony\Bundle\MakerBundle\Maker; +use Doctrine\Bundle\DoctrineBundle\DoctrineBundle; use Symfony\Bundle\MakerBundle\ConsoleStyle; use Symfony\Bundle\MakerBundle\DependencyBuilder; +use Symfony\Bundle\MakerBundle\Doctrine\DoctrineEntityHelper; use Symfony\Bundle\MakerBundle\Generator; use Symfony\Bundle\MakerBundle\InputConfiguration; use Symfony\Bundle\MakerBundle\Str; -use Symfony\Bundle\MakerBundle\Validator; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputInterface; +use Symfony\Component\Console\Question\Question; use Symfony\Component\Form\AbstractType; use Symfony\Component\Validator\Validation; @@ -29,6 +31,13 @@ */ final class MakeForm extends AbstractMaker { + private $entityHelper; + + public function __construct(DoctrineEntityHelper $entityHelper) + { + $this->entityHelper = $entityHelper; + } + public static function getCommandName(): string { return 'make:form'; @@ -43,6 +52,16 @@ public function configureCommand(Command $command, InputConfiguration $inputConf ; } + public function interact(InputInterface $input, ConsoleStyle $io, Command $command) + { + if (null != $input->getArgument('name') && $this->entityHelper->isDoctrineConnected()) { + $question = new Question("Enter the class or entity name that the new form will be bound to (empty for none)"); + $question->setAutocompleterValues($this->entityHelper->getEntitiesForAutocomplete()); + //$entity = $io->choice("Enter the class or entity name that the new form will be bound to", $this->entityHelper->getEntitiesForAutocomplete(), 'none'); + $entity = $io->askQuestion($question); + } + } + public function generate(InputInterface $input, ConsoleStyle $io, Generator $generator) { $formClassNameDetails = $generator->createClassNameDetails( @@ -56,13 +75,18 @@ public function generate(InputInterface $input, ConsoleStyle $io, Generator $gen 'Entity\\' ); + $entityClassExists = class_exists($entityClassNameDetails->getFullName()); + + $formFields = $entityClassExists ? $this->entityHelper->getFormFieldsFromEntity($entityClassNameDetails->getFullName()) : ['field_name']; + $generator->generateClass( $formClassNameDetails->getFullName(), 'form/Type.tpl.php', [ - 'entity_class_exists' => class_exists($entityClassNameDetails->getFullName()), + 'entity_class_exists' => $entityClassExists, 'entity_full_class_name' => $entityClassNameDetails->getFullName(), 'entity_class_name' => $entityClassNameDetails->getShortName(), + 'form_fields' => $formFields, ] ); @@ -90,5 +114,11 @@ public function configureDependencies(DependencyBuilder $dependencies) // add as an optional dependency: the user *probably* wants validation false ); + + $dependencies->addClassDependency( + DoctrineBundle::class, + 'orm', + false + ); } } diff --git a/src/Resources/config/makers.xml b/src/Resources/config/makers.xml index dd3a2518e..9a73b44d4 100644 --- a/src/Resources/config/makers.xml +++ b/src/Resources/config/makers.xml @@ -21,7 +21,6 @@
      - @@ -36,7 +35,6 @@ - diff --git a/src/Resources/skeleton/crud/controller/Controller.tpl.php b/src/Resources/skeleton/crud/controller/Controller.tpl.php index 3546db7de..b2097531e 100644 --- a/src/Resources/skeleton/crud/controller/Controller.tpl.php +++ b/src/Resources/skeleton/crud/controller/Controller.tpl.php @@ -1,9 +1,9 @@ -namespace App\Controller; +namespace ; -use App\Entity\; -use App\Form\; +use ; +use ; use Sensio\Bundle\FrameworkExtraBundle\Configuration\Method; use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route; use Symfony\Bundle\FrameworkBundle\Controller\Controller; @@ -13,7 +13,7 @@ /** * @Route("", name="_") */ -class extends Controller +class extends Controller { /** * @Route("/", name="index") diff --git a/src/Resources/skeleton/crud/templates/_delete_form.tpl.php b/src/Resources/skeleton/crud/templates/_delete_form.tpl.php index 0cc542780..77685d39d 100644 --- a/src/Resources/skeleton/crud/templates/_delete_form.tpl.php +++ b/src/Resources/skeleton/crud/templates/_delete_form.tpl.php @@ -1,5 +1,5 @@ -
      - + +
      \ No newline at end of file diff --git a/src/Resources/skeleton/crud/templates/edit.tpl.php b/src/Resources/skeleton/crud/templates/edit.tpl.php index 25feb6c8b..858d7a819 100644 --- a/src/Resources/skeleton/crud/templates/edit.tpl.php +++ b/src/Resources/skeleton/crud/templates/edit.tpl.php @@ -1,6 +1,6 @@ getHead($base_layout_exists, 'Edit '.$entity_class_name); ?> -getBodyStart($base_layout_exists); ?> +{% block body %}

      Edit

      @@ -10,4 +10,4 @@ {% include '/_delete_form.html.twig' with {'identifier': .} only %} -getBodyEnd($base_layout_exists); ?> +{% endblock %} \ No newline at end of file diff --git a/src/Resources/skeleton/crud/templates/index.tpl.php b/src/Resources/skeleton/crud/templates/index.tpl.php index 79e44c5f7..1073dc5f7 100644 --- a/src/Resources/skeleton/crud/templates/index.tpl.php +++ b/src/Resources/skeleton/crud/templates/index.tpl.php @@ -1,6 +1,6 @@ getHead($base_layout_exists, $entity_class_name.' index'); ?> -getBodyStart($base_layout_exists); ?> +{% block body %}

      index

      @@ -15,8 +15,8 @@ {% else %} @@ -28,4 +28,4 @@
      {{ getEntityFieldPrintCode($entity_var_singular, $field); ?> }} - show - edit + show + edit
      Create new -getBodyEnd($base_layout_exists); ?> +{% endblock %} \ No newline at end of file diff --git a/src/Resources/skeleton/crud/templates/new.tpl.php b/src/Resources/skeleton/crud/templates/new.tpl.php index 31bf4637d..dc0d67bfc 100644 --- a/src/Resources/skeleton/crud/templates/new.tpl.php +++ b/src/Resources/skeleton/crud/templates/new.tpl.php @@ -1,9 +1,9 @@ getHead($base_layout_exists, 'New '.$entity_class_name); ?> -getBodyStart($base_layout_exists); ?> +{% block body %}

      Create new

      {% include '/_form.html.twig' with {'form': form} only %} -getBodyEnd($base_layout_exists); ?> +{% endblock %} \ No newline at end of file diff --git a/src/Resources/skeleton/crud/templates/show.tpl.php b/src/Resources/skeleton/crud/templates/show.tpl.php index d2e7982ea..776097615 100644 --- a/src/Resources/skeleton/crud/templates/show.tpl.php +++ b/src/Resources/skeleton/crud/templates/show.tpl.php @@ -1,21 +1,23 @@ -getHead($base_layout_exists, $entity_class_name); ?> +getHead($base_layout_exists, $entity_class_name) ?> -getBodyStart($base_layout_exists); ?> +{% block body %} -

      - - +

      +
      + - - + + -
      {{ getEntityFieldPrintCode($entity_var_singular, $field); ?> }}{{ getEntityFieldPrintCode($entity_var_singular, $field) ?> }}
      + + + - back to list + back to list - edit + edit - {% include '/_delete_form.html.twig' with {'identifier': .} only %} + {% include '/_delete_form.html.twig' with {'identifier': .} only %} -getBodyEnd($base_layout_exists); ?> +{% endblock %} \ No newline at end of file diff --git a/src/Resources/skeleton/form/Type.tpl.php b/src/Resources/skeleton/form/Type.tpl.php index 716f5ecb0..d23b7da77 100644 --- a/src/Resources/skeleton/form/Type.tpl.php +++ b/src/Resources/skeleton/form/Type.tpl.php @@ -14,7 +14,10 @@ class extends AbstractType public function buildForm(FormBuilderInterface $builder, array $options) { $builder - ->add('field_name') + + ->add('') + + ; } @@ -22,8 +25,7 @@ public function configureOptions(OptionsResolver $resolver) { $resolver->setDefaults([ - // uncomment if you want to bind to a class - //'data_class' => ::class, + 'data_class' => ::class, ]); } diff --git a/tests/Maker/FunctionalTest.php b/tests/Maker/FunctionalTest.php index 5fe9d02bd..3168a966e 100644 --- a/tests/Maker/FunctionalTest.php +++ b/tests/Maker/FunctionalTest.php @@ -182,8 +182,7 @@ public function getCommandTests() [ // Entity name 'SourFood', - // agree with use Entity for form generation - 'yes' + 'SourFood', ]) ->addExtraDependencies('orm') ->setFixtureFilesPath(__DIR__.'/../fixtures/MakeFormForEntity') diff --git a/tests/fixtures/MakeCrud/src/Entity/SweetFood.php b/tests/fixtures/MakeCrud/src/Entity/SweetFood.php index ee7bc28be..66590eaf7 100644 --- a/tests/fixtures/MakeCrud/src/Entity/SweetFood.php +++ b/tests/fixtures/MakeCrud/src/Entity/SweetFood.php @@ -21,6 +21,11 @@ class SweetFood */ private $title; + public function getId() + { + return $this->id; + } + /** * @return mixed */ diff --git a/tests/fixtures/MakeFormForEntity/src/Entity/SourFood.php b/tests/fixtures/MakeFormForEntity/src/Entity/SourFood.php index 0beae7e10..dd78930fa 100644 --- a/tests/fixtures/MakeFormForEntity/src/Entity/SourFood.php +++ b/tests/fixtures/MakeFormForEntity/src/Entity/SourFood.php @@ -21,6 +21,14 @@ class SourFood */ private $title; + /** + * @return mixed + */ + public function getId() + { + return $this->id; + } + /** * @return mixed */ From 60c0005d180eb96d0a7584e9eb0a17963bcf16bc Mon Sep 17 00:00:00 2001 From: Sadicov Vladimir Date: Thu, 22 Feb 2018 10:08:00 +0200 Subject: [PATCH 29/44] php cs fix --- src/Doctrine/DoctrineEntityHelper.php | 2 +- src/Maker/MakeCrud.php | 3 +-- src/Maker/MakeForm.php | 2 +- 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/src/Doctrine/DoctrineEntityHelper.php b/src/Doctrine/DoctrineEntityHelper.php index e7bf387c7..8534e2e95 100644 --- a/src/Doctrine/DoctrineEntityHelper.php +++ b/src/Doctrine/DoctrineEntityHelper.php @@ -46,7 +46,7 @@ public function getEntitiesForAutocomplete(): array foreach ($allMetadata as $metadata) { $entities[] = preg_replace('#^[^\\\\]*\\\\Entity\\\\(.*)#', '$1', $metadata->name); } - + return $entities; } diff --git a/src/Maker/MakeCrud.php b/src/Maker/MakeCrud.php index 0abb17392..d5affef27 100644 --- a/src/Maker/MakeCrud.php +++ b/src/Maker/MakeCrud.php @@ -13,7 +13,6 @@ use Doctrine\Bundle\DoctrineBundle\DoctrineBundle; use Doctrine\Common\Inflector\Inflector; -use Doctrine\ORM\Mapping\Column; use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route; use Symfony\Bundle\MakerBundle\ConsoleStyle; use Symfony\Bundle\MakerBundle\DependencyBuilder; @@ -114,7 +113,7 @@ public function generate(InputInterface $input, ConsoleStyle $io, Generator $gen 'entity_full_class_name' => $entityClassNameDetails->getFullName(), 'entity_class_name' => $entityClassNameDetails->getShortName(), 'form_fields' => $formFields, - 'helper' => $helper + 'helper' => $helper, ] ); diff --git a/src/Maker/MakeForm.php b/src/Maker/MakeForm.php index 631707f9c..8cd22a519 100644 --- a/src/Maker/MakeForm.php +++ b/src/Maker/MakeForm.php @@ -55,7 +55,7 @@ public function configureCommand(Command $command, InputConfiguration $inputConf public function interact(InputInterface $input, ConsoleStyle $io, Command $command) { if (null != $input->getArgument('name') && $this->entityHelper->isDoctrineConnected()) { - $question = new Question("Enter the class or entity name that the new form will be bound to (empty for none)"); + $question = new Question('Enter the class or entity name that the new form will be bound to (empty for none)'); $question->setAutocompleterValues($this->entityHelper->getEntitiesForAutocomplete()); //$entity = $io->choice("Enter the class or entity name that the new form will be bound to", $this->entityHelper->getEntitiesForAutocomplete(), 'none'); $entity = $io->askQuestion($question); From ad8a4fb9154e8ddeee2bc5d3a91a049b04673f7b Mon Sep 17 00:00:00 2001 From: Sadicov Vladimir Date: Thu, 22 Feb 2018 13:41:17 +0200 Subject: [PATCH 30/44] fix tests on appveyor --- tests/Maker/FunctionalTest.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/Maker/FunctionalTest.php b/tests/Maker/FunctionalTest.php index 1d3a8bee8..e09fb23cd 100644 --- a/tests/Maker/FunctionalTest.php +++ b/tests/Maker/FunctionalTest.php @@ -331,7 +331,7 @@ public function getCommandTests() 'mysql://db_user:db_password@127.0.0.1:3306/db_name', 'sqlite:///%kernel.project_dir%/var/app.db' ) - ->addPreMakeCommand('./bin/console doctrine:schema:create --env=test') + ->addPreMakeCommand('php bin/console doctrine:schema:create --env=test') ]; yield 'crud_with_no_base' => [MakerTestDetails::createTest( @@ -351,7 +351,7 @@ public function getCommandTests() 'mysql://db_user:db_password@127.0.0.1:3306/db_name', 'sqlite:///%kernel.project_dir%/var/app.db' ) - ->addPreMakeCommand('./bin/console doctrine:schema:create --env=test') + ->addPreMakeCommand('php bin/console doctrine:schema:create --env=test') ->addPreMakeCommand('rm templates/base.html.twig') ]; } From db30634d770e3f74400d2819a347547a11b385ed Mon Sep 17 00:00:00 2001 From: Sadicov Vladimir Date: Fri, 23 Feb 2018 11:10:14 +0200 Subject: [PATCH 31/44] added tests for crud testig --- tests/Maker/FunctionalTest.php | 42 +++++++++++++ .../tests/GeneratedCrudControllerTest.php | 62 ++++++++++++++++--- 2 files changed, 95 insertions(+), 9 deletions(-) diff --git a/tests/Maker/FunctionalTest.php b/tests/Maker/FunctionalTest.php index e09fb23cd..c506b7b5d 100644 --- a/tests/Maker/FunctionalTest.php +++ b/tests/Maker/FunctionalTest.php @@ -321,6 +321,8 @@ public function getCommandTests() 'SweetFood', ]) ->setFixtureFilesPath(__DIR__.'/../fixtures/MakeCrud') + // need for crud web tests + ->addExtraDependencies('symfony/css-selector') ->addReplacement( 'phpunit.xml.dist', 'mysql://db_user:db_password@127.0.0.1:3306/db_name', @@ -332,6 +334,25 @@ public function getCommandTests() 'sqlite:///%kernel.project_dir%/var/app.db' ) ->addPreMakeCommand('php bin/console doctrine:schema:create --env=test') + ->assert(function(string $output, string $directory) { + $this->assertFileExists($directory.'/src/Controller/SweetFoodController.php'); + $this->assertFileExists($directory.'/src/Form/SweetFoodType.php'); + $this->assertFileExists($directory.'/templates/sweet_food/_delete_form.html.twig'); + $this->assertFileExists($directory.'/templates/sweet_food/_form.html.twig'); + $this->assertFileExists($directory.'/templates/sweet_food/index.html.twig'); + $this->assertFileExists($directory.'/templates/sweet_food/new.html.twig'); + $this->assertFileExists($directory.'/templates/sweet_food/edit.html.twig'); + $this->assertFileExists($directory.'/templates/sweet_food/show.html.twig'); + + $this->assertContains('created: src/Controller/SweetFoodController.php', $output); + $this->assertContains('created: src/Form/SweetFoodType.php', $output); + $this->assertContains('created: templates/sweet_food/_delete_form.html.twig', $output); + $this->assertContains('created: templates/sweet_food/_form.html.twig', $output); + $this->assertContains('created: templates/sweet_food/index.html.twig', $output); + $this->assertContains('created: templates/sweet_food/new.html.twig', $output); + $this->assertContains('created: templates/sweet_food/edit.html.twig', $output); + $this->assertContains('created: templates/sweet_food/show.html.twig', $output); + }) ]; yield 'crud_with_no_base' => [MakerTestDetails::createTest( @@ -341,6 +362,8 @@ public function getCommandTests() 'SweetFood', ]) ->setFixtureFilesPath(__DIR__.'/../fixtures/MakeCrud') + // need for crud web tests + ->addExtraDependencies('symfony/css-selector') ->addReplacement( 'phpunit.xml.dist', 'mysql://db_user:db_password@127.0.0.1:3306/db_name', @@ -353,6 +376,25 @@ public function getCommandTests() ) ->addPreMakeCommand('php bin/console doctrine:schema:create --env=test') ->addPreMakeCommand('rm templates/base.html.twig') + ->assert(function(string $output, string $directory) { + $this->assertFileExists($directory.'/src/Controller/SweetFoodController.php'); + $this->assertFileExists($directory.'/src/Form/SweetFoodType.php'); + $this->assertFileExists($directory.'/templates/sweet_food/_delete_form.html.twig'); + $this->assertFileExists($directory.'/templates/sweet_food/_form.html.twig'); + $this->assertFileExists($directory.'/templates/sweet_food/index.html.twig'); + $this->assertFileExists($directory.'/templates/sweet_food/new.html.twig'); + $this->assertFileExists($directory.'/templates/sweet_food/edit.html.twig'); + $this->assertFileExists($directory.'/templates/sweet_food/show.html.twig'); + + $this->assertContains('created: src/Controller/SweetFoodController.php', $output); + $this->assertContains('created: src/Form/SweetFoodType.php', $output); + $this->assertContains('created: templates/sweet_food/_delete_form.html.twig', $output); + $this->assertContains('created: templates/sweet_food/_form.html.twig', $output); + $this->assertContains('created: templates/sweet_food/index.html.twig', $output); + $this->assertContains('created: templates/sweet_food/new.html.twig', $output); + $this->assertContains('created: templates/sweet_food/edit.html.twig', $output); + $this->assertContains('created: templates/sweet_food/show.html.twig', $output); + }) ]; } diff --git a/tests/fixtures/MakeCrud/tests/GeneratedCrudControllerTest.php b/tests/fixtures/MakeCrud/tests/GeneratedCrudControllerTest.php index 5b2fd3ca4..a59188bda 100644 --- a/tests/fixtures/MakeCrud/tests/GeneratedCrudControllerTest.php +++ b/tests/fixtures/MakeCrud/tests/GeneratedCrudControllerTest.php @@ -9,20 +9,64 @@ class GeneratedCrudControllerTest extends WebTestCase public function testIndexAction() { $client = self::createClient(); - $client->request('GET', '/sweet/food/'); - - $this->assertEquals(200, $client->getResponse()->getStatusCode()); + $crawler = $client->request('GET', '/sweet/food/'); + $this->assertTrue($client->getResponse()->isSuccessful()); $this->assertContains('', $client->getResponse()->getContent()); $this->assertContains('SweetFood index', $client->getResponse()->getContent()); - } - public function testNewAction() - { - $client = self::createClient(); - $client->request('GET', '/sweet/food/new'); + $newLink = $crawler->filter('a:contains("Create new")')->eq(0)->link(); - $this->assertEquals(200, $client->getResponse()->getStatusCode()); + $crawler = $client->click($newLink); + $this->assertTrue($client->getResponse()->isSuccessful()); $this->assertContains('', $client->getResponse()->getContent()); $this->assertContains('New SweetFood', $client->getResponse()->getContent()); + + $newForm = $crawler->selectButton('Save')->form(); + $client->submit($newForm, ['sweet_food[title]' => 'Candy']); + $this->assertTrue($client->getResponse()->isRedirect()); + + $crawler = $client->followRedirect(); + $this->assertTrue($client->getResponse()->isSuccessful()); + $this->assertContains('', $client->getResponse()->getContent()); + $this->assertContains('Edit SweetFood', $client->getResponse()->getContent()); + $this->assertGreaterThan(0, $crawler->filter('input[type=text]')->count()); + $this->assertEquals('Candy', $crawler->filter('input[type=text]')->attr('value')); + + $editForm = $crawler->selectButton('Edit')->form(); + $client->submit($editForm, ['sweet_food[title]' => 'Candy edited']); + $this->assertTrue($client->getResponse()->isRedirect()); + + $crawler = $client->followRedirect(); + $this->assertTrue($client->getResponse()->isSuccessful()); + $this->assertContains('', $client->getResponse()->getContent()); + $this->assertContains('Edit SweetFood', $client->getResponse()->getContent()); + $this->assertGreaterThan(0, $crawler->filter('input[type=text]')->count()); + $this->assertEquals('Candy edited', $crawler->filter('input[type=text]')->attr('value')); + + $backTolistLink = $crawler->filter('a:contains("back to list")')->eq(0)->link(); + + $crawler = $client->click($backTolistLink); + $this->assertTrue($client->getResponse()->isSuccessful()); + $this->assertContains('', $client->getResponse()->getContent()); + $this->assertContains('SweetFood index', $client->getResponse()->getContent()); + $this->assertContains('Candy edited', $client->getResponse()->getContent()); + + $showLink = $crawler->filter('a:contains("show")')->eq(0)->link(); + + $crawler = $client->click($showLink); + $this->assertTrue($client->getResponse()->isSuccessful()); + $this->assertContains('', $client->getResponse()->getContent()); + $this->assertContains('SweetFood', $client->getResponse()->getContent()); + $this->assertContains('Candy edited', $client->getResponse()->getContent()); + + $deleteForm = $crawler->selectButton('Delete')->form(); + $client->submit($deleteForm); + $this->assertTrue($client->getResponse()->isRedirect()); + + $client->followRedirect(); + $this->assertTrue($client->getResponse()->isSuccessful()); + $this->assertContains('', $client->getResponse()->getContent()); + $this->assertContains('SweetFood index', $client->getResponse()->getContent()); + $this->assertContains('no records found', $client->getResponse()->getContent()); } } From 44b7851022d062fc12bb1a8d31700461b097a46a Mon Sep 17 00:00:00 2001 From: Sadicov Vladimir Date: Mon, 26 Feb 2018 20:41:19 +0200 Subject: [PATCH 32/44] completed improvement of make:form command --- src/Maker/MakeForm.php | 48 ++++++++++++------- .../skeleton/form/SimpleType.tpl.php | 24 ++++++++++ src/Resources/skeleton/form/Type.tpl.php | 2 +- 3 files changed, 55 insertions(+), 19 deletions(-) create mode 100644 src/Resources/skeleton/form/SimpleType.tpl.php diff --git a/src/Maker/MakeForm.php b/src/Maker/MakeForm.php index 8cd22a519..2f2e612b2 100644 --- a/src/Maker/MakeForm.php +++ b/src/Maker/MakeForm.php @@ -32,6 +32,7 @@ final class MakeForm extends AbstractMaker { private $entityHelper; + private $boundEntityOrClass = true; public function __construct(DoctrineEntityHelper $entityHelper) { @@ -57,8 +58,7 @@ public function interact(InputInterface $input, ConsoleStyle $io, Command $comma if (null != $input->getArgument('name') && $this->entityHelper->isDoctrineConnected()) { $question = new Question('Enter the class or entity name that the new form will be bound to (empty for none)'); $question->setAutocompleterValues($this->entityHelper->getEntitiesForAutocomplete()); - //$entity = $io->choice("Enter the class or entity name that the new form will be bound to", $this->entityHelper->getEntitiesForAutocomplete(), 'none'); - $entity = $io->askQuestion($question); + $this->boundEntityOrClass = $io->askQuestion($question); } } @@ -70,25 +70,37 @@ public function generate(InputInterface $input, ConsoleStyle $io, Generator $gen 'Type' ); - $entityClassNameDetails = $generator->createClassNameDetails( - $formClassNameDetails->getRelativeNameWithoutSuffix(), - 'Entity\\' - ); + if (null === $this->boundEntityOrClass) { - $entityClassExists = class_exists($entityClassNameDetails->getFullName()); + $generator->generateClass( + $formClassNameDetails->getFullName(), + 'form/SimpleType.tpl.php', + [ ] + ); - $formFields = $entityClassExists ? $this->entityHelper->getFormFieldsFromEntity($entityClassNameDetails->getFullName()) : ['field_name']; + } else { - $generator->generateClass( - $formClassNameDetails->getFullName(), - 'form/Type.tpl.php', - [ - 'entity_class_exists' => $entityClassExists, - 'entity_full_class_name' => $entityClassNameDetails->getFullName(), - 'entity_class_name' => $entityClassNameDetails->getShortName(), - 'form_fields' => $formFields, - ] - ); + $entityClassNameDetails = $generator->createClassNameDetails( + true == $this->boundEntityOrClass ? $formClassNameDetails->getRelativeNameWithoutSuffix() : $this->boundEntityOrClass, + 'Entity\\' + ); + + $entityClassExists = class_exists($entityClassNameDetails->getFullName()); + + $formFields = $entityClassExists ? $this->entityHelper->getFormFieldsFromEntity($entityClassNameDetails->getFullName()) : ['field_name']; + + $generator->generateClass( + $formClassNameDetails->getFullName(), + 'form/Type.tpl.php', + [ + 'entity_class_exists' => $entityClassExists, + 'entity_full_class_name' => $entityClassNameDetails->getFullName(), + 'entity_class_name' => $entityClassNameDetails->getShortName(), + 'form_fields' => $formFields, + ] + ); + + } $generator->writeChanges(); diff --git a/src/Resources/skeleton/form/SimpleType.tpl.php b/src/Resources/skeleton/form/SimpleType.tpl.php new file mode 100644 index 000000000..60137fb40 --- /dev/null +++ b/src/Resources/skeleton/form/SimpleType.tpl.php @@ -0,0 +1,24 @@ + + +namespace ; + +use Symfony\Component\Form\AbstractType; +use Symfony\Component\Form\FormBuilderInterface; +use Symfony\Component\OptionsResolver\OptionsResolver; + +class extends AbstractType +{ + public function buildForm(FormBuilderInterface $builder, array $options) + { + $builder + ->add('form_field') + ; + } + + public function configureOptions(OptionsResolver $resolver) + { + $resolver->setDefaults([ + //configure form options here + ]); + } +} diff --git a/src/Resources/skeleton/form/Type.tpl.php b/src/Resources/skeleton/form/Type.tpl.php index d23b7da77..dc3aefd93 100644 --- a/src/Resources/skeleton/form/Type.tpl.php +++ b/src/Resources/skeleton/form/Type.tpl.php @@ -1,6 +1,6 @@ -namespace ; +namespace ; use ; From 772f0db3ea875bfc34fa16aeddb44fcbbe67d7cb Mon Sep 17 00:00:00 2001 From: Sadicov Vladimir Date: Mon, 26 Feb 2018 21:16:34 +0200 Subject: [PATCH 33/44] fix make:form --- src/Maker/MakeForm.php | 20 +++++++++++++++----- src/Resources/skeleton/form/Type.tpl.php | 1 - 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/src/Maker/MakeForm.php b/src/Maker/MakeForm.php index 2f2e612b2..7c1b1a970 100644 --- a/src/Maker/MakeForm.php +++ b/src/Maker/MakeForm.php @@ -51,14 +51,24 @@ public function configureCommand(Command $command, InputConfiguration $inputConf ->addArgument('name', InputArgument::OPTIONAL, sprintf('The name of the form class (e.g. %sType)', Str::asClassName(Str::getRandomTerm()))) ->setHelp(file_get_contents(__DIR__.'/../Resources/help/MakeForm.txt')) ; + + $inputConf->setArgumentAsNonInteractive('name'); } public function interact(InputInterface $input, ConsoleStyle $io, Command $command) { - if (null != $input->getArgument('name') && $this->entityHelper->isDoctrineConnected()) { - $question = new Question('Enter the class or entity name that the new form will be bound to (empty for none)'); - $question->setAutocompleterValues($this->entityHelper->getEntitiesForAutocomplete()); - $this->boundEntityOrClass = $io->askQuestion($question); + if (is_null($input->getArgument('name'))) { + $argument = $command->getDefinition()->getArgument('name'); + $question = new Question($argument->getDescription()); + $value = $io->askQuestion($question); + + $input->setArgument('name', $value); + + if ($this->entityHelper->isDoctrineConnected()) { + $question = new Question('Enter the class or entity name that the new form will be bound to (empty for none)'); + $question->setAutocompleterValues($this->entityHelper->getEntitiesForAutocomplete()); + $this->boundEntityOrClass = $io->askQuestion($question); + } } } @@ -81,7 +91,7 @@ public function generate(InputInterface $input, ConsoleStyle $io, Generator $gen } else { $entityClassNameDetails = $generator->createClassNameDetails( - true == $this->boundEntityOrClass ? $formClassNameDetails->getRelativeNameWithoutSuffix() : $this->boundEntityOrClass, + true === $this->boundEntityOrClass ? $formClassNameDetails->getRelativeNameWithoutSuffix() : $this->boundEntityOrClass, 'Entity\\' ); diff --git a/src/Resources/skeleton/form/Type.tpl.php b/src/Resources/skeleton/form/Type.tpl.php index dc3aefd93..6c35753f1 100644 --- a/src/Resources/skeleton/form/Type.tpl.php +++ b/src/Resources/skeleton/form/Type.tpl.php @@ -17,7 +17,6 @@ public function buildForm(FormBuilderInterface $builder, array $options) ->add('') - ; } From 2ebff8ce1ad25a3cc6f4ab993154b659646dcee0 Mon Sep 17 00:00:00 2001 From: Sadicov Vladimir Date: Tue, 27 Feb 2018 14:11:23 +0200 Subject: [PATCH 34/44] fix cs and improvements according to review request --- src/Doctrine/DoctrineEntityHelper.php | 13 +++---- src/Maker/MakeCrud.php | 1 + src/Maker/MakeForm.php | 10 ++---- .../crud/controller/Controller.tpl.php | 35 +++++++------------ .../crud/templates/_delete_form.tpl.php | 4 +-- .../skeleton/crud/templates/edit.tpl.php | 10 +++--- .../skeleton/crud/templates/index.tpl.php | 24 +++++++------ .../skeleton/crud/templates/new.tpl.php | 6 ++-- .../skeleton/crud/templates/show.tpl.php | 13 +++---- tests/Maker/FunctionalTest.php | 28 ++------------- .../tests/GeneratedCrudControllerTest.php | 7 +++- 11 files changed, 60 insertions(+), 91 deletions(-) diff --git a/src/Doctrine/DoctrineEntityHelper.php b/src/Doctrine/DoctrineEntityHelper.php index 8534e2e95..5a5902386 100644 --- a/src/Doctrine/DoctrineEntityHelper.php +++ b/src/Doctrine/DoctrineEntityHelper.php @@ -21,26 +21,21 @@ */ final class DoctrineEntityHelper { - private $metadataFactory = null; + private $metadataFactory; public function __construct(ManagerRegistry $registry = null) { - if (null !== $registry) { - $this->metadataFactory = new DoctrineMetadataFactory($registry); - } + $this->metadataFactory = null !== $registry ? new DoctrineMetadataFactory($registry) : null; } - public function isDoctrineConnected(): bool + public function isDoctrineInstalled(): bool { return null !== $this->metadataFactory; } - /** - * @return array - */ public function getEntitiesForAutocomplete(): array { - $entities = ['none']; + $entities = []; $allMetadata = $this->metadataFactory->getAllMetadata(); /** @var ClassMetadataInfo $metadata */ foreach ($allMetadata as $metadata) { diff --git a/src/Maker/MakeCrud.php b/src/Maker/MakeCrud.php index d5affef27..9e1a53fa3 100644 --- a/src/Maker/MakeCrud.php +++ b/src/Maker/MakeCrud.php @@ -123,6 +123,7 @@ public function generate(InputInterface $input, ConsoleStyle $io, Generator $gen $templates = [ '_delete_form' => [ 'route_name' => $routeName, + 'entity_var_singular' => $entityVarSingular, 'entity_identifier' => $metadata->identifier[0], ], '_form' => [], diff --git a/src/Maker/MakeForm.php b/src/Maker/MakeForm.php index 7c1b1a970..1386d6f13 100644 --- a/src/Maker/MakeForm.php +++ b/src/Maker/MakeForm.php @@ -57,14 +57,14 @@ public function configureCommand(Command $command, InputConfiguration $inputConf public function interact(InputInterface $input, ConsoleStyle $io, Command $command) { - if (is_null($input->getArgument('name'))) { + if (null === $input->getArgument('name')) { $argument = $command->getDefinition()->getArgument('name'); $question = new Question($argument->getDescription()); $value = $io->askQuestion($question); $input->setArgument('name', $value); - if ($this->entityHelper->isDoctrineConnected()) { + if ($this->entityHelper->isDoctrineInstalled()) { $question = new Question('Enter the class or entity name that the new form will be bound to (empty for none)'); $question->setAutocompleterValues($this->entityHelper->getEntitiesForAutocomplete()); $this->boundEntityOrClass = $io->askQuestion($question); @@ -81,15 +81,12 @@ public function generate(InputInterface $input, ConsoleStyle $io, Generator $gen ); if (null === $this->boundEntityOrClass) { - $generator->generateClass( $formClassNameDetails->getFullName(), 'form/SimpleType.tpl.php', - [ ] + [] ); - } else { - $entityClassNameDetails = $generator->createClassNameDetails( true === $this->boundEntityOrClass ? $formClassNameDetails->getRelativeNameWithoutSuffix() : $this->boundEntityOrClass, 'Entity\\' @@ -109,7 +106,6 @@ public function generate(InputInterface $input, ConsoleStyle $io, Generator $gen 'form_fields' => $formFields, ] ); - } $generator->writeChanges(); diff --git a/src/Resources/skeleton/crud/controller/Controller.tpl.php b/src/Resources/skeleton/crud/controller/Controller.tpl.php index b2097531e..c3c5c8d0b 100644 --- a/src/Resources/skeleton/crud/controller/Controller.tpl.php +++ b/src/Resources/skeleton/crud/controller/Controller.tpl.php @@ -4,21 +4,18 @@ use ; use ; -use Sensio\Bundle\FrameworkExtraBundle\Configuration\Method; -use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route; use Symfony\Bundle\FrameworkBundle\Controller\Controller; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; +use Symfony\Component\Routing\Annotation\Route; /** - * @Route("", name="_") + * @Route("") */ class extends Controller { /** - * @Route("/", name="index") - * - * @return Response + * @Route("/", name="_index", methods="GET"): Response */ public function index() { @@ -30,10 +27,9 @@ public function index() } /** - * @Route("/new", name="new") - * @Method({"GET", "POST"}) + * @Route("/new", name="_new", methods="GET|POST") */ - public function new(Request $request) + public function new(Request $request): Response { $ = new (); $form = $this->createForm(::class, $); @@ -44,7 +40,7 @@ public function new(Request $request) $em->persist($); $em->flush(); - return $this->redirectToRoute('_edit', ['' => $->get()]); + return $this->redirectToRoute('_index'); } return $this->render('/new.html.twig', [ @@ -54,21 +50,17 @@ public function new(Request $request) } /** - * @Route("/{}", name="show") - * @Method("GET") + * @Route("/{}", name="_show", methods="GET") */ - public function show( $) + public function show( $): Response { - return $this->render('/show.html.twig', [ - '' => $, - ]); + return $this->render('/show.html.twig', ['' => $]); } /** - * @Route("/{}/edit", name="edit") - * @Method({"GET", "POST"}) + * @Route("/{}/edit", name="_edit", methods="GET|POST") */ - public function edit(Request $request, $) + public function edit(Request $request, $): Response { $form = $this->createForm(::class, $); $form->handleRequest($request); @@ -86,10 +78,9 @@ public function edit(Request $request, $}", name="delete") - * @Method("DELETE") + * @Route("/{}", name="_delete", methods="DELETE") */ - public function delete(Request $request, $) + public function delete(Request $request, $): Response { if (!$this->isCsrfTokenValid('delete'.$->get(), $request->request->get('_token'))) { return $this->redirectToRoute('_index'); diff --git a/src/Resources/skeleton/crud/templates/_delete_form.tpl.php b/src/Resources/skeleton/crud/templates/_delete_form.tpl.php index 77685d39d..9a0446fcb 100644 --- a/src/Resources/skeleton/crud/templates/_delete_form.tpl.php +++ b/src/Resources/skeleton/crud/templates/_delete_form.tpl.php @@ -1,5 +1,5 @@ -
      + - +
      \ No newline at end of file diff --git a/src/Resources/skeleton/crud/templates/edit.tpl.php b/src/Resources/skeleton/crud/templates/edit.tpl.php index 858d7a819..c71c22a91 100644 --- a/src/Resources/skeleton/crud/templates/edit.tpl.php +++ b/src/Resources/skeleton/crud/templates/edit.tpl.php @@ -1,13 +1,13 @@ -getHead($base_layout_exists, 'Edit '.$entity_class_name); ?> +getHead($base_layout_exists, 'Edit '.$entity_class_name) ?> {% block body %} -

      Edit

      +

      Edit

      - {% include '/_form.html.twig' with {'form': form, 'button_label': 'Edit'} only %} + {{ include('/_form.html.twig', {'form': form, 'button_label': 'Edit'}) }} - back to list + back to list - {% include '/_delete_form.html.twig' with {'identifier': .} only %} + {{ include('/_delete_form.html.twig', {'': }) }} {% endblock %} \ No newline at end of file diff --git a/src/Resources/skeleton/crud/templates/index.tpl.php b/src/Resources/skeleton/crud/templates/index.tpl.php index 1073dc5f7..ecf2c1c3b 100644 --- a/src/Resources/skeleton/crud/templates/index.tpl.php +++ b/src/Resources/skeleton/crud/templates/index.tpl.php @@ -2,30 +2,34 @@ {% block body %} -

      index

      +

      index

      - - + + + + - {% for in %} + {% for in %} - - + + {% else %} - + {% endfor %}
      actionsactions
      {{ getEntityFieldPrintCode($entity_var_singular, $field); ?> }} - show - edit + + {{ getEntityFieldPrintCode($entity_var_singular, $field) ?> }} + show + edit
      no records foundno records found
      - Create new + Create new {% endblock %} \ No newline at end of file diff --git a/src/Resources/skeleton/crud/templates/new.tpl.php b/src/Resources/skeleton/crud/templates/new.tpl.php index dc0d67bfc..400e01b02 100644 --- a/src/Resources/skeleton/crud/templates/new.tpl.php +++ b/src/Resources/skeleton/crud/templates/new.tpl.php @@ -1,9 +1,9 @@ -getHead($base_layout_exists, 'New '.$entity_class_name); ?> +getHead($base_layout_exists, 'New '.$entity_class_name) ?> {% block body %} -

      Create new

      +

      Create new

      - {% include '/_form.html.twig' with {'form': form} only %} + {{ include('/_form.html.twig', {'form': form}) }} {% endblock %} \ No newline at end of file diff --git a/src/Resources/skeleton/crud/templates/show.tpl.php b/src/Resources/skeleton/crud/templates/show.tpl.php index 776097615..0f9c30fc7 100644 --- a/src/Resources/skeleton/crud/templates/show.tpl.php +++ b/src/Resources/skeleton/crud/templates/show.tpl.php @@ -5,19 +5,20 @@

      + - - - - + + + + - +
      {{ getEntityFieldPrintCode($entity_var_singular, $field) ?> }}
      {{ getEntityFieldPrintCode($entity_var_singular, $field) ?> }}
      back to list edit - {% include '/_delete_form.html.twig' with {'identifier': .} only %} + {{ include('/_delete_form.html.twig', {'': }) }} {% endblock %} \ No newline at end of file diff --git a/tests/Maker/FunctionalTest.php b/tests/Maker/FunctionalTest.php index c506b7b5d..ed308003e 100644 --- a/tests/Maker/FunctionalTest.php +++ b/tests/Maker/FunctionalTest.php @@ -177,11 +177,11 @@ public function getCommandTests() ->setFixtureFilesPath(__DIR__.'/../fixtures/MakeForm') ]; - yield 'entity_form' => [MakerTestDetails::createTest( + yield 'form_with_entity' => [MakerTestDetails::createTest( $this->getMakerInstance(MakeForm::class), [ // Entity name - 'SourFood', + 'SourFoodType', 'SourFood', ]) ->addExtraDependencies('orm') @@ -337,21 +337,9 @@ public function getCommandTests() ->assert(function(string $output, string $directory) { $this->assertFileExists($directory.'/src/Controller/SweetFoodController.php'); $this->assertFileExists($directory.'/src/Form/SweetFoodType.php'); - $this->assertFileExists($directory.'/templates/sweet_food/_delete_form.html.twig'); - $this->assertFileExists($directory.'/templates/sweet_food/_form.html.twig'); - $this->assertFileExists($directory.'/templates/sweet_food/index.html.twig'); - $this->assertFileExists($directory.'/templates/sweet_food/new.html.twig'); - $this->assertFileExists($directory.'/templates/sweet_food/edit.html.twig'); - $this->assertFileExists($directory.'/templates/sweet_food/show.html.twig'); $this->assertContains('created: src/Controller/SweetFoodController.php', $output); $this->assertContains('created: src/Form/SweetFoodType.php', $output); - $this->assertContains('created: templates/sweet_food/_delete_form.html.twig', $output); - $this->assertContains('created: templates/sweet_food/_form.html.twig', $output); - $this->assertContains('created: templates/sweet_food/index.html.twig', $output); - $this->assertContains('created: templates/sweet_food/new.html.twig', $output); - $this->assertContains('created: templates/sweet_food/edit.html.twig', $output); - $this->assertContains('created: templates/sweet_food/show.html.twig', $output); }) ]; @@ -379,21 +367,9 @@ public function getCommandTests() ->assert(function(string $output, string $directory) { $this->assertFileExists($directory.'/src/Controller/SweetFoodController.php'); $this->assertFileExists($directory.'/src/Form/SweetFoodType.php'); - $this->assertFileExists($directory.'/templates/sweet_food/_delete_form.html.twig'); - $this->assertFileExists($directory.'/templates/sweet_food/_form.html.twig'); - $this->assertFileExists($directory.'/templates/sweet_food/index.html.twig'); - $this->assertFileExists($directory.'/templates/sweet_food/new.html.twig'); - $this->assertFileExists($directory.'/templates/sweet_food/edit.html.twig'); - $this->assertFileExists($directory.'/templates/sweet_food/show.html.twig'); $this->assertContains('created: src/Controller/SweetFoodController.php', $output); $this->assertContains('created: src/Form/SweetFoodType.php', $output); - $this->assertContains('created: templates/sweet_food/_delete_form.html.twig', $output); - $this->assertContains('created: templates/sweet_food/_form.html.twig', $output); - $this->assertContains('created: templates/sweet_food/index.html.twig', $output); - $this->assertContains('created: templates/sweet_food/new.html.twig', $output); - $this->assertContains('created: templates/sweet_food/edit.html.twig', $output); - $this->assertContains('created: templates/sweet_food/show.html.twig', $output); }) ]; } diff --git a/tests/fixtures/MakeCrud/tests/GeneratedCrudControllerTest.php b/tests/fixtures/MakeCrud/tests/GeneratedCrudControllerTest.php index a59188bda..53497879b 100644 --- a/tests/fixtures/MakeCrud/tests/GeneratedCrudControllerTest.php +++ b/tests/fixtures/MakeCrud/tests/GeneratedCrudControllerTest.php @@ -28,9 +28,14 @@ public function testIndexAction() $crawler = $client->followRedirect(); $this->assertTrue($client->getResponse()->isSuccessful()); $this->assertContains('', $client->getResponse()->getContent()); + $this->assertContains('SweetFood index', $client->getResponse()->getContent()); + $this->assertContains('Candy', $client->getResponse()->getContent()); + + $editLink = $crawler->filter('a:contains("edit")')->eq(0)->link(); + $crawler = $client->click($editLink); + $this->assertContains('', $client->getResponse()->getContent()); $this->assertContains('Edit SweetFood', $client->getResponse()->getContent()); $this->assertGreaterThan(0, $crawler->filter('input[type=text]')->count()); - $this->assertEquals('Candy', $crawler->filter('input[type=text]')->attr('value')); $editForm = $crawler->selectButton('Edit')->form(); $client->submit($editForm, ['sweet_food[title]' => 'Candy edited']); From 3d319bd407bcfa9c0883367a0d9397e77fcf9e17 Mon Sep 17 00:00:00 2001 From: Sadicov Vladimir Date: Wed, 28 Feb 2018 13:02:22 +0200 Subject: [PATCH 35/44] some skeleton improvements --- src/Doctrine/DoctrineEntityHelper.php | 4 +- src/Generator.php | 6 ++ ...atorHelper.php => GeneratorTwigHelper.php} | 13 ++- src/Maker/MakeCrud.php | 93 +++++++++++-------- src/Resources/config/makers.xml | 1 - .../crud/controller/Controller.tpl.php | 72 +++++++------- .../skeleton/crud/templates/_form.tpl.php | 4 +- .../skeleton/crud/templates/edit.tpl.php | 25 +++-- .../skeleton/crud/templates/index.tpl.php | 68 ++++++++------ .../skeleton/crud/templates/new.tpl.php | 21 ++++- .../skeleton/crud/templates/show.tpl.php | 42 ++++++--- 11 files changed, 218 insertions(+), 131 deletions(-) rename src/{GeneratorHelper.php => GeneratorTwigHelper.php} (81%) diff --git a/src/Doctrine/DoctrineEntityHelper.php b/src/Doctrine/DoctrineEntityHelper.php index 5a5902386..0125c4dc6 100644 --- a/src/Doctrine/DoctrineEntityHelper.php +++ b/src/Doctrine/DoctrineEntityHelper.php @@ -13,6 +13,7 @@ use Doctrine\Common\Persistence\ManagerRegistry; use Doctrine\ORM\Mapping\ClassMetadataInfo; +use Symfony\Bundle\MakerBundle\Util\ClassNameDetails; /** * @author Sadicov Vladimir @@ -39,7 +40,8 @@ public function getEntitiesForAutocomplete(): array $allMetadata = $this->metadataFactory->getAllMetadata(); /** @var ClassMetadataInfo $metadata */ foreach ($allMetadata as $metadata) { - $entities[] = preg_replace('#^[^\\\\]*\\\\Entity\\\\(.*)#', '$1', $metadata->name); + $entityClassDetails = new ClassNameDetails($metadata->name, 'App\\Entity'); + $entities[] = $entityClassDetails->getRelativeName(); } return $entities; diff --git a/src/Generator.php b/src/Generator.php index 12a892d55..e48139797 100644 --- a/src/Generator.php +++ b/src/Generator.php @@ -21,12 +21,14 @@ class Generator { private $fileManager; + private $twigHelper; private $pendingOperations = []; private $namespacePrefix; public function __construct(FileManager $fileManager, $namespacePrefix) { $this->fileManager = $fileManager; + $this->twigHelper = new GeneratorTwigHelper($fileManager); $this->namespacePrefix = rtrim($namespacePrefix, '\\'); } @@ -60,6 +62,10 @@ public function generateClass(string $className, string $templateName, array $va */ public function generateFile(string $targetPath, string $templateName, array $variables) { + $variables = array_merge($variables, [ + 'helper' => $this->twigHelper, + ]); + $this->addOperation($targetPath, $templateName, $variables); } diff --git a/src/GeneratorHelper.php b/src/GeneratorTwigHelper.php similarity index 81% rename from src/GeneratorHelper.php rename to src/GeneratorTwigHelper.php index 9adc54fd6..5d8f3b1a3 100644 --- a/src/GeneratorHelper.php +++ b/src/GeneratorTwigHelper.php @@ -16,8 +16,15 @@ * * @internal */ -class GeneratorHelper +class GeneratorTwigHelper { + private $baseLayoutExists; + + public function __construct(FileManager $fileManager) + { + $this->baseLayoutExists = $fileManager->fileExists('templates/base.html.twig'); + } + public function getEntityFieldPrintCode($entity, $field): string { $printCode = $entity.'.'.$field['fieldName']; @@ -37,9 +44,9 @@ public function getEntityFieldPrintCode($entity, $field): string return $printCode; } - public function getHead($baseLayoutExists, $title): string + public function getHeadPrintCode($title): string { - if ($baseLayoutExists) { + if ($this->baseLayoutExists) { return <<fileManager = $fileManager; $this->entityHelper = $entityHelper; } @@ -59,41 +57,66 @@ public function configureCommand(Command $command, InputConfiguration $inputConf ->addArgument('entity-class', InputArgument::OPTIONAL, sprintf('The class name of the entity to create crud (e.g. %s)', Str::asClassName(Str::getRandomTerm()))) ->setHelp(file_get_contents(__DIR__.'/../Resources/help/MakeCrud.txt')) ; + + $inputConfig->setArgumentAsNonInteractive('entity-class'); + } + + public function interact(InputInterface $input, ConsoleStyle $io, Command $command) + { + $argument = $command->getDefinition()->getArgument('entity-class'); + + $question = new Question($argument->getDescription()); + $question->setValidator([Validator::class, 'notBlank']); + $question->setAutocompleterValues($this->entityHelper->getEntitiesForAutocomplete()); + + $value = $io->askQuestion($question); + + $input->setArgument('entity-class', $value); } public function generate(InputInterface $input, ConsoleStyle $io, Generator $generator) { - $entityClassNameDetails = $generator->createClassNameDetails( + $entityClassDetails = $generator->createClassNameDetails( $input->getArgument('entity-class'), 'Entity\\' ); - $controllerClassNameDetails = $generator->createClassNameDetails( - $entityClassNameDetails->getRelativeNameWithoutSuffix(), + $repositoryClassDetails = $generator->createClassNameDetails( + $entityClassDetails->getRelativeName(), + 'Repository\\', + 'Repository' + ); + + $controllerClassDetails = $generator->createClassNameDetails( + $entityClassDetails->getRelativeNameWithoutSuffix(), 'Controller\\', 'Controller' ); - $formClassNameDetails = $generator->createClassNameDetails( - $entityClassNameDetails->getRelativeNameWithoutSuffix(), + $formClassDetails = $generator->createClassNameDetails( + $entityClassDetails->getRelativeNameWithoutSuffix(), 'Form\\', 'Type' ); - $metadata = $this->entityHelper->getEntityMetadata($entityClassNameDetails->getFullName()); - $entityVarPlural = lcfirst(Inflector::pluralize($entityClassNameDetails->getShortName())); - $entityVarSingular = lcfirst(Inflector::singularize($entityClassNameDetails->getShortName())); - $routeName = Str::asRouteName($controllerClassNameDetails->getRelativeNameWithoutSuffix()); + $metadata = $this->entityHelper->getEntityMetadata($entityClassDetails->getFullName()); + $entityVarPlural = lcfirst(Inflector::pluralize($entityClassDetails->getShortName())); + $entityVarSingular = lcfirst(Inflector::singularize($entityClassDetails->getShortName())); + $routeName = Str::asRouteName($controllerClassDetails->getRelativeNameWithoutSuffix()); $generator->generateClass( - $controllerClassNameDetails->getFullName(), + $controllerClassDetails->getFullName(), 'crud/controller/Controller.tpl.php', [ - 'entity_full_class_name' => $entityClassNameDetails->getFullName(), - 'entity_class_name' => $entityClassNameDetails->getShortName(), - 'form_full_class_name' => $formClassNameDetails->getFullName(), - 'form_class_name' => $formClassNameDetails->getShortName(), - 'route_path' => Str::asRoutePath($controllerClassNameDetails->getRelativeNameWithoutSuffix()), + 'entity_full_class_name' => $entityClassDetails->getFullName(), + 'entity_class_name' => $entityClassDetails->getShortName(), + 'repository_exists' => class_exists($repositoryClassDetails->getFullName()), + 'repository_full_class_name' => $repositoryClassDetails->getFullName(), + 'repository_class_name' => $repositoryClassDetails->getShortName(), + 'repository_var' => lcfirst(Inflector::singularize($repositoryClassDetails->getShortName())), + 'form_full_class_name' => $formClassDetails->getFullName(), + 'form_class_name' => $formClassDetails->getShortName(), + 'route_path' => Str::asRoutePath($controllerClassDetails->getRelativeNameWithoutSuffix()), 'route_name' => $routeName, 'entity_var_plural' => $entityVarPlural, 'entity_var_singular' => $entityVarSingular, @@ -101,24 +124,20 @@ public function generate(InputInterface $input, ConsoleStyle $io, Generator $gen ] ); - $formFields = $this->entityHelper->getFormFieldsFromEntity($entityClassNameDetails->getFullName()); - - $helper = new GeneratorHelper(); + $formFields = $this->entityHelper->getFormFieldsFromEntity($entityClassDetails->getFullName()); $generator->generateClass( - $formClassNameDetails->getFullName(), + $formClassDetails->getFullName(), 'form/Type.tpl.php', [ 'entity_class_exists' => true, - 'entity_full_class_name' => $entityClassNameDetails->getFullName(), - 'entity_class_name' => $entityClassNameDetails->getShortName(), + 'entity_full_class_name' => $entityClassDetails->getFullName(), + 'entity_class_name' => $entityClassDetails->getShortName(), 'form_fields' => $formFields, - 'helper' => $helper, ] ); - $baseLayoutExists = $this->fileManager->fileExists('templates/base.html.twig'); - $templatesPath = Str::asFilePath($controllerClassNameDetails->getRelativeNameWithoutSuffix()); + $templatesPath = Str::asFilePath($controllerClassDetails->getRelativeNameWithoutSuffix()); $templates = [ '_delete_form' => [ @@ -128,17 +147,13 @@ public function generate(InputInterface $input, ConsoleStyle $io, Generator $gen ], '_form' => [], 'edit' => [ - 'helper' => $helper, - 'base_layout_exists' => $baseLayoutExists, - 'entity_class_name' => $entityClassNameDetails->getShortName(), + 'entity_class_name' => $entityClassDetails->getShortName(), 'entity_var_singular' => $entityVarSingular, 'entity_identifier' => $metadata->identifier[0], 'route_name' => $routeName, ], 'index' => [ - 'helper' => $helper, - 'base_layout_exists' => $baseLayoutExists, - 'entity_class_name' => $entityClassNameDetails->getShortName(), + 'entity_class_name' => $entityClassDetails->getShortName(), 'entity_var_plural' => $entityVarPlural, 'entity_var_singular' => $entityVarSingular, 'entity_identifier' => $metadata->identifier[0], @@ -146,15 +161,11 @@ public function generate(InputInterface $input, ConsoleStyle $io, Generator $gen 'route_name' => $routeName, ], 'new' => [ - 'helper' => $helper, - 'base_layout_exists' => $baseLayoutExists, - 'entity_class_name' => $entityClassNameDetails->getShortName(), + 'entity_class_name' => $entityClassDetails->getShortName(), 'route_name' => $routeName, ], 'show' => [ - 'helper' => $helper, - 'base_layout_exists' => $baseLayoutExists, - 'entity_class_name' => $entityClassNameDetails->getShortName(), + 'entity_class_name' => $entityClassDetails->getShortName(), 'entity_var_singular' => $entityVarSingular, 'entity_identifier' => $metadata->identifier[0], 'entity_fields' => $metadata->fieldMappings, diff --git a/src/Resources/config/makers.xml b/src/Resources/config/makers.xml index 9a73b44d4..08497436e 100644 --- a/src/Resources/config/makers.xml +++ b/src/Resources/config/makers.xml @@ -21,7 +21,6 @@ - diff --git a/src/Resources/skeleton/crud/controller/Controller.tpl.php b/src/Resources/skeleton/crud/controller/Controller.tpl.php index c3c5c8d0b..1c04e99a2 100644 --- a/src/Resources/skeleton/crud/controller/Controller.tpl.php +++ b/src/Resources/skeleton/crud/controller/Controller.tpl.php @@ -1,95 +1,105 @@ - + -namespace ; +namespace ; -use ; -use ; +use ; +use ; + +use ; + use Symfony\Bundle\FrameworkBundle\Controller\Controller; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\Routing\Annotation\Route; /** - * @Route("") + * @Route("") */ class extends Controller { /** - * @Route("/", name="_index", methods="GET"): Response + * @Route("/", name="_index", methods="GET"): Response */ + + public function index( $) + { + return $this->render('/index.html.twig', ['' => $->findAll()]); + } + public function index() { - $ = $this->getDoctrine() - ->getRepository(::class) + $ = $this->getDoctrine() + ->getRepository(::class) ->findAll(); - return $this->render('/index.html.twig', ['' => $]); + return $this->render('/index.html.twig', ['' => $]); } + /** - * @Route("/new", name="_new", methods="GET|POST") + * @Route("/new", name="_new", methods="GET|POST") */ public function new(Request $request): Response { - $ = new (); - $form = $this->createForm(::class, $); + $ = new (); + $form = $this->createForm(::class, $); $form->handleRequest($request); if ($form->isSubmitted() && $form->isValid()) { $em = $this->getDoctrine()->getManager(); - $em->persist($); + $em->persist($); $em->flush(); - return $this->redirectToRoute('_index'); + return $this->redirectToRoute('_index'); } - return $this->render('/new.html.twig', [ - '' => $, + return $this->render('/new.html.twig', [ + '' => $, 'form' => $form->createView(), ]); } /** - * @Route("/{}", name="_show", methods="GET") + * @Route("/{}", name="_show", methods="GET") */ - public function show( $): Response + public function show( $): Response { - return $this->render('/show.html.twig', ['' => $]); + return $this->render('/show.html.twig', ['' => $]); } /** - * @Route("/{}/edit", name="_edit", methods="GET|POST") + * @Route("/{}/edit", name="_edit", methods="GET|POST") */ - public function edit(Request $request, $): Response + public function edit(Request $request, $): Response { - $form = $this->createForm(::class, $); + $form = $this->createForm(::class, $); $form->handleRequest($request); if ($form->isSubmitted() && $form->isValid()) { $this->getDoctrine()->getManager()->flush(); - return $this->redirectToRoute('_edit', ['' => $->get()]); + return $this->redirectToRoute('_edit', ['' => $->get()]); } - return $this->render('/edit.html.twig', [ - '' => $, + return $this->render('/edit.html.twig', [ + '' => $, 'form' => $form->createView(), ]); } /** - * @Route("/{}", name="_delete", methods="DELETE") + * @Route("/{}", name="_delete", methods="DELETE") */ - public function delete(Request $request, $): Response + public function delete(Request $request, $): Response { - if (!$this->isCsrfTokenValid('delete'.$->get(), $request->request->get('_token'))) { - return $this->redirectToRoute('_index'); + if (!$this->isCsrfTokenValid('delete'.$->get(), $request->request->get('_token'))) { + return $this->redirectToRoute('_index'); } $em = $this->getDoctrine()->getManager(); - $em->remove($); + $em->remove($); $em->flush(); - return $this->redirectToRoute('_index'); + return $this->redirectToRoute('_index'); } } diff --git a/src/Resources/skeleton/crud/templates/_form.tpl.php b/src/Resources/skeleton/crud/templates/_form.tpl.php index 298051be2..920bd3da6 100644 --- a/src/Resources/skeleton/crud/templates/_form.tpl.php +++ b/src/Resources/skeleton/crud/templates/_form.tpl.php @@ -1,4 +1,6 @@ {{ form_start(form) }} {{ form_widget(form) }} - +
      + +
      {{ form_end(form) }} \ No newline at end of file diff --git a/src/Resources/skeleton/crud/templates/edit.tpl.php b/src/Resources/skeleton/crud/templates/edit.tpl.php index c71c22a91..05eb01730 100644 --- a/src/Resources/skeleton/crud/templates/edit.tpl.php +++ b/src/Resources/skeleton/crud/templates/edit.tpl.php @@ -1,13 +1,24 @@ -getHead($base_layout_exists, 'Edit '.$entity_class_name) ?> +getHeadPrintCode('Edit '.$entity_class_name) ?> -{% block body %} - -

      Edit

      +{% block stylesheets %} + +{% endblock %} - {{ include('/_form.html.twig', {'form': form, 'button_label': 'Edit'}) }} +{% block body %} +
      +

      Edit

      - back to list + {{ include('/_form.html.twig', {'form': form, 'button_label': 'Edit'}) }} - {{ include('/_delete_form.html.twig', {'': }) }} +
      + back to list + {{ include('/_delete_form.html.twig', {'': }) }} +
      +
      {% endblock %} \ No newline at end of file diff --git a/src/Resources/skeleton/crud/templates/index.tpl.php b/src/Resources/skeleton/crud/templates/index.tpl.php index ecf2c1c3b..850d0e835 100644 --- a/src/Resources/skeleton/crud/templates/index.tpl.php +++ b/src/Resources/skeleton/crud/templates/index.tpl.php @@ -1,35 +1,49 @@ -getHead($base_layout_exists, $entity_class_name.' index'); ?> +getHeadPrintCode($entity_class_name.' index'); ?> -{% block body %} +{% block stylesheets %} + +{% endblock %} -

      index

      - - - +{% block body %} +
      +

      index

      +
      + + - + - - - - - {% for in %} - + + + + + {% for in %} + - + - - - {% else %} - - - - {% endfor %} - -
      actions
      actions
      {{ getEntityFieldPrintCode($entity_var_singular, $field) ?> }}{{ getEntityFieldPrintCode($entity_var_singular, $field) ?> }} - show - edit -
      no records found
      - Create new + + show + edit + + + {% else %} + + no records found + + {% endfor %} + + + + {% endblock %} \ No newline at end of file diff --git a/src/Resources/skeleton/crud/templates/new.tpl.php b/src/Resources/skeleton/crud/templates/new.tpl.php index 400e01b02..a0b8cd2eb 100644 --- a/src/Resources/skeleton/crud/templates/new.tpl.php +++ b/src/Resources/skeleton/crud/templates/new.tpl.php @@ -1,9 +1,22 @@ -getHead($base_layout_exists, 'New '.$entity_class_name) ?> +getHeadPrintCode('New '.$entity_class_name) ?> -{% block body %} +{% block stylesheets %} + +{% endblock %} -

      Create new

      +{% block body %} +
      +

      Create new

      - {{ include('/_form.html.twig', {'form': form}) }} + {{ include('/_form.html.twig', {'form': form}) }} + +
      {% endblock %} \ No newline at end of file diff --git a/src/Resources/skeleton/crud/templates/show.tpl.php b/src/Resources/skeleton/crud/templates/show.tpl.php index 0f9c30fc7..fefc6aa7f 100644 --- a/src/Resources/skeleton/crud/templates/show.tpl.php +++ b/src/Resources/skeleton/crud/templates/show.tpl.php @@ -1,24 +1,36 @@ -getHead($base_layout_exists, $entity_class_name) ?> +getHeadPrintCode($entity_class_name) ?> -{% block body %} +{% block stylesheets %} + +{% endblock %} -

      +{% block body %} +
      +

      - - +
      + - - - - + + + + - -
      {{ getEntityFieldPrintCode($entity_var_singular, $field) ?> }}
      {{ getEntityFieldPrintCode($entity_var_singular, $field) ?> }}
      - - back to list + + - edit +
      + back to list - {{ include('/_delete_form.html.twig', {'': }) }} + edit + {{ include('/_delete_form.html.twig', {'': }) }} +
      +
      {% endblock %} \ No newline at end of file From ba0438fa399d0305d69c451a6d1dab75466659ed Mon Sep 17 00:00:00 2001 From: Sadicov Vladimir Date: Wed, 28 Feb 2018 13:15:51 +0200 Subject: [PATCH 36/44] phpcs fix --- src/Test/MakerTestCase.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Test/MakerTestCase.php b/src/Test/MakerTestCase.php index 66b5209bd..4dd13b016 100644 --- a/src/Test/MakerTestCase.php +++ b/src/Test/MakerTestCase.php @@ -288,4 +288,4 @@ private function processReplacements(array $replacements, $rootDir) file_put_contents($path, str_replace($replacement['find'], $replacement['replace'], $contents)); } } -} \ No newline at end of file +} From ee988651090e4e1481fb525123ee699edfe80b4c Mon Sep 17 00:00:00 2001 From: Ryan Weaver Date: Fri, 2 Mar 2018 15:05:52 -0500 Subject: [PATCH 37/44] making test name less specific so we can run only it --- tests/Maker/FunctionalTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/Maker/FunctionalTest.php b/tests/Maker/FunctionalTest.php index ed308003e..44fb522ea 100644 --- a/tests/Maker/FunctionalTest.php +++ b/tests/Maker/FunctionalTest.php @@ -314,7 +314,7 @@ public function getCommandTests() }) ]; - yield 'crud' => [MakerTestDetails::createTest( + yield 'crud_basic' => [MakerTestDetails::createTest( $this->getMakerInstance(MakeCrud::class), [ // entity class name From 204f5aa35f6e2e81bf8f98126e8de56d04b315f3 Mon Sep 17 00:00:00 2001 From: Sadicov Vladimir Date: Sat, 3 Mar 2018 13:33:41 +0200 Subject: [PATCH 38/44] final fix for skeleton templates --- src/GeneratorTwigHelper.php | 36 +++++----- .../crud/controller/Controller.tpl.php | 6 +- .../crud/templates/_delete_form.tpl.php | 2 +- .../skeleton/crud/templates/_form.tpl.php | 4 +- .../skeleton/crud/templates/edit.tpl.php | 22 ++----- .../skeleton/crud/templates/index.tpl.php | 66 ++++++++----------- .../skeleton/crud/templates/new.tpl.php | 20 ++---- .../skeleton/crud/templates/show.tpl.php | 39 ++++------- .../tests/GeneratedCrudControllerTest.php | 2 +- 9 files changed, 74 insertions(+), 123 deletions(-) diff --git a/src/GeneratorTwigHelper.php b/src/GeneratorTwigHelper.php index 5d8f3b1a3..d22da8a42 100644 --- a/src/GeneratorTwigHelper.php +++ b/src/GeneratorTwigHelper.php @@ -13,32 +13,36 @@ /** * @author Sadicov Vladimir - * - * @internal */ -class GeneratorTwigHelper +final class GeneratorTwigHelper { - private $baseLayoutExists; + private $fileManager; public function __construct(FileManager $fileManager) { - $this->baseLayoutExists = $fileManager->fileExists('templates/base.html.twig'); + $this->fileManager = $fileManager; } public function getEntityFieldPrintCode($entity, $field): string { $printCode = $entity.'.'.$field['fieldName']; - if (in_array($field['type'], ['datetime'])) { - $printCode = $printCode.' ? '.$printCode.'|date(\'Y-m-d H:i:s\') : \'\''; - } elseif (in_array($field['type'], ['date'])) { - $printCode = $printCode.' ? '.$printCode.'|date(\'Y-m-d\') : \'\''; - } elseif (in_array($field['type'], ['time'])) { - $printCode = $printCode.' ? '.$printCode.'|date(\'H:i:s\') : \'\''; - } elseif (in_array($field['type'], ['array'])) { - $printCode = $printCode.' ? '.$printCode.'|join(\', \') : \'\''; - } elseif (in_array($field['type'], ['boolean'])) { - $printCode = $printCode.' ? \'Yes\' : \'No\''; + switch ($field['type']) { + case 'datetime': + $printCode .= ' ? '.$printCode.'|date(\'Y-m-d H:i:s\') : \'\''; + break; + case 'date': + $printCode .= ' ? '.$printCode.'|date(\'Y-m-d\') : \'\''; + break; + case 'time': + $printCode .= ' ? '.$printCode.'|date(\'H:i:s\') : \'\''; + break; + case 'array': + $printCode .= ' ? '.$printCode.'|join(\', \') : \'\''; + break; + case 'boolean': + $printCode .= ' ? \'Yes\' : \'No\''; + break; } return $printCode; @@ -46,7 +50,7 @@ public function getEntityFieldPrintCode($entity, $field): string public function getHeadPrintCode($title): string { - if ($this->baseLayoutExists) { + if ($this->fileManager->fileExists('templates/base.html.twig')) { return << extends Controller { /** - * @Route("/", name="_index", methods="GET"): Response + * @Route("/", name="_index", methods="GET") */ - public function index( $) + public function index( $): Response { return $this->render('/index.html.twig', ['' => $->findAll()]); } - public function index() + public function index(): Response { $ = $this->getDoctrine() ->getRepository(::class) diff --git a/src/Resources/skeleton/crud/templates/_delete_form.tpl.php b/src/Resources/skeleton/crud/templates/_delete_form.tpl.php index 9a0446fcb..5a1f6d0aa 100644 --- a/src/Resources/skeleton/crud/templates/_delete_form.tpl.php +++ b/src/Resources/skeleton/crud/templates/_delete_form.tpl.php @@ -1,5 +1,5 @@
      - +
      \ No newline at end of file diff --git a/src/Resources/skeleton/crud/templates/_form.tpl.php b/src/Resources/skeleton/crud/templates/_form.tpl.php index 920bd3da6..92948ade0 100644 --- a/src/Resources/skeleton/crud/templates/_form.tpl.php +++ b/src/Resources/skeleton/crud/templates/_form.tpl.php @@ -1,6 +1,4 @@ {{ form_start(form) }} {{ form_widget(form) }} -
      - -
      + {{ form_end(form) }} \ No newline at end of file diff --git a/src/Resources/skeleton/crud/templates/edit.tpl.php b/src/Resources/skeleton/crud/templates/edit.tpl.php index 05eb01730..e6a9a8f9b 100644 --- a/src/Resources/skeleton/crud/templates/edit.tpl.php +++ b/src/Resources/skeleton/crud/templates/edit.tpl.php @@ -1,24 +1,12 @@ getHeadPrintCode('Edit '.$entity_class_name) ?> -{% block stylesheets %} - -{% endblock %} - {% block body %} -
      -

      Edit

      +

      Edit

      + + {{ include('/_form.html.twig', {'button_label': 'Update'}) }} - {{ include('/_form.html.twig', {'form': form, 'button_label': 'Edit'}) }} + back to list -
      - back to list + {{ include('/_delete_form.html.twig') }} - {{ include('/_delete_form.html.twig', {'': }) }} -
      -
      {% endblock %} \ No newline at end of file diff --git a/src/Resources/skeleton/crud/templates/index.tpl.php b/src/Resources/skeleton/crud/templates/index.tpl.php index 850d0e835..8b231a0f4 100644 --- a/src/Resources/skeleton/crud/templates/index.tpl.php +++ b/src/Resources/skeleton/crud/templates/index.tpl.php @@ -1,49 +1,35 @@ getHeadPrintCode($entity_class_name.' index'); ?> -{% block stylesheets %} - -{% endblock %} - {% block body %} -
      -

      index

      - - - +

      index

      + +
      + + - + - - - - - {% for in %} - + + + + + {% for in %} + - + - - - {% else %} - - - - {% endfor %} - -
      actions
      actions
      {{ getEntityFieldPrintCode($entity_var_singular, $field) ?> }}{{ getEntityFieldPrintCode($entity_var_singular, $field) ?> }} - show - edit -
      no records found
      + + show + edit + + + {% else %} + + no records found + + {% endfor %} + + - -
      + Create new {% endblock %} \ No newline at end of file diff --git a/src/Resources/skeleton/crud/templates/new.tpl.php b/src/Resources/skeleton/crud/templates/new.tpl.php index a0b8cd2eb..bd5539836 100644 --- a/src/Resources/skeleton/crud/templates/new.tpl.php +++ b/src/Resources/skeleton/crud/templates/new.tpl.php @@ -1,22 +1,10 @@ getHeadPrintCode('New '.$entity_class_name) ?> -{% block stylesheets %} - -{% endblock %} - {% block body %} -
      -

      Create new

      +

      Create new

      + + {{ include('/_form.html.twig') }} - {{ include('/_form.html.twig', {'form': form}) }} + back to list - -
      {% endblock %} \ No newline at end of file diff --git a/src/Resources/skeleton/crud/templates/show.tpl.php b/src/Resources/skeleton/crud/templates/show.tpl.php index fefc6aa7f..856fc2143 100644 --- a/src/Resources/skeleton/crud/templates/show.tpl.php +++ b/src/Resources/skeleton/crud/templates/show.tpl.php @@ -1,36 +1,23 @@ getHeadPrintCode($entity_class_name) ?> -{% block stylesheets %} - -{% endblock %} - {% block body %} -
      -

      +

      - - +
      + - - - - + + + + - -
      {{ getEntityFieldPrintCode($entity_var_singular, $field) ?> }}
      {{ getEntityFieldPrintCode($entity_var_singular, $field) ?> }}
      + + + + back to list -
      - back to list + edit - edit + {{ include('/_delete_form.html.twig') }} - {{ include('/_delete_form.html.twig', {'': }) }} -
      -
      {% endblock %} \ No newline at end of file diff --git a/tests/fixtures/MakeCrud/tests/GeneratedCrudControllerTest.php b/tests/fixtures/MakeCrud/tests/GeneratedCrudControllerTest.php index 53497879b..0b94c6b40 100644 --- a/tests/fixtures/MakeCrud/tests/GeneratedCrudControllerTest.php +++ b/tests/fixtures/MakeCrud/tests/GeneratedCrudControllerTest.php @@ -37,7 +37,7 @@ public function testIndexAction() $this->assertContains('Edit SweetFood', $client->getResponse()->getContent()); $this->assertGreaterThan(0, $crawler->filter('input[type=text]')->count()); - $editForm = $crawler->selectButton('Edit')->form(); + $editForm = $crawler->selectButton('Update')->form(); $client->submit($editForm, ['sweet_food[title]' => 'Candy edited']); $this->assertTrue($client->getResponse()->isRedirect()); From b3bf87889e00c5f7eb360c57e872f8831d9d9abe Mon Sep 17 00:00:00 2001 From: Sadicov Vladimir Date: Tue, 6 Mar 2018 13:46:28 +0200 Subject: [PATCH 39/44] some make:form improvements + experiments --- src/Doctrine/DoctrineEntityDetails.php | 52 +++++++++ src/Doctrine/DoctrineEntityHelper.php | 41 ++++--- src/Maker/MakeCrud.php | 101 ++++++++++-------- src/Maker/MakeForm.php | 65 ++++++----- .../crud/controller/Controller.tpl.php | 4 +- .../skeleton/crud/templates/edit.tpl.php | 1 - .../skeleton/crud/templates/new.tpl.php | 1 - .../skeleton/crud/templates/show.tpl.php | 1 - .../skeleton/form/SimpleType.tpl.php | 24 ----- src/Resources/skeleton/form/Type.tpl.php | 14 +-- tests/Maker/FunctionalTest.php | 1 + 11 files changed, 177 insertions(+), 128 deletions(-) create mode 100644 src/Doctrine/DoctrineEntityDetails.php delete mode 100644 src/Resources/skeleton/form/SimpleType.tpl.php diff --git a/src/Doctrine/DoctrineEntityDetails.php b/src/Doctrine/DoctrineEntityDetails.php new file mode 100644 index 000000000..54dcb1bfd --- /dev/null +++ b/src/Doctrine/DoctrineEntityDetails.php @@ -0,0 +1,52 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Bundle\MakerBundle\Doctrine; + +/** + * @author Sadicov Vladimir + */ +final class DoctrineEntityDetails +{ + private $repositoryClass; + + private $identifier; + private $displayFields; + private $formFields; + + public function __construct($repositoryClass, $identifier, $displayFields, $formFields) + { + $this->repositoryClass = $repositoryClass; + $this->identifier = $identifier; + $this->displayFields = $displayFields; + $this->formFields = $formFields; + } + + public function getRepositoryClass() + { + return $this->repositoryClass; + } + + public function getIdentifier() + { + return $this->identifier; + } + + public function getDisplayFields() + { + return $this->displayFields; + } + + public function getFormFields() + { + return $this->formFields; + } +} diff --git a/src/Doctrine/DoctrineEntityHelper.php b/src/Doctrine/DoctrineEntityHelper.php index 0125c4dc6..ea56a77cb 100644 --- a/src/Doctrine/DoctrineEntityHelper.php +++ b/src/Doctrine/DoctrineEntityHelper.php @@ -29,7 +29,7 @@ public function __construct(ManagerRegistry $registry = null) $this->metadataFactory = null !== $registry ? new DoctrineMetadataFactory($registry) : null; } - public function isDoctrineInstalled(): bool + private function isDoctrineInstalled(): bool { return null !== $this->metadataFactory; } @@ -37,11 +37,14 @@ public function isDoctrineInstalled(): bool public function getEntitiesForAutocomplete(): array { $entities = []; - $allMetadata = $this->metadataFactory->getAllMetadata(); - /** @var ClassMetadataInfo $metadata */ - foreach ($allMetadata as $metadata) { - $entityClassDetails = new ClassNameDetails($metadata->name, 'App\\Entity'); - $entities[] = $entityClassDetails->getRelativeName(); + + if ($this->isDoctrineInstalled()) { + $allMetadata = $this->metadataFactory->getAllMetadata(); + /** @var ClassMetadataInfo $metadata */ + foreach ($allMetadata as $metadata) { + $entityClassDetails = new ClassNameDetails($metadata->name, 'App\\Entity'); + $entities[] = $entityClassDetails->getRelativeName(); + } } return $entities; @@ -50,14 +53,27 @@ public function getEntitiesForAutocomplete(): array /** * @param string $entityClassName * - * @return array - * + * @return null|DoctrineEntityDetails * @throws \Exception */ - public function getFormFieldsFromEntity(string $entityClassName): array + public function createDoctrineDetails(string $entityClassName) { $metadata = $this->getEntityMetadata($entityClassName); + if (null !== $metadata) { + return new DoctrineEntityDetails( + $metadata->customRepositoryClassName, + $metadata->identifier[0], + $metadata->fieldMappings, + $this->getFormFieldsFromEntity($metadata) + ); + } + + return null; + } + + public function getFormFieldsFromEntity(ClassMetadataInfo $metadata): array + { $fields = (array) $metadata->fieldNames; // Remove the primary key field if it's not managed manually if (!$metadata->isIdentifierNatural()) { @@ -72,13 +88,6 @@ public function getFormFieldsFromEntity(string $entityClassName): array return $fields; } - /** - * @param $entityClassName - * - * @return \Doctrine\ORM\Mapping\ClassMetadata|null - * - * @throws \Exception - */ public function getEntityMetadata($entityClassName) { if (null === $this->metadataFactory) { diff --git a/src/Maker/MakeCrud.php b/src/Maker/MakeCrud.php index d910538f9..d3fffec43 100644 --- a/src/Maker/MakeCrud.php +++ b/src/Maker/MakeCrud.php @@ -53,8 +53,8 @@ public static function getCommandName(): string public function configureCommand(Command $command, InputConfiguration $inputConfig) { $command - ->setDescription('Creates crud for Doctrine entity class') - ->addArgument('entity-class', InputArgument::OPTIONAL, sprintf('The class name of the entity to create crud (e.g. %s)', Str::asClassName(Str::getRandomTerm()))) + ->setDescription('Creates CRUD for Doctrine entity class') + ->addArgument('entity-class', InputArgument::OPTIONAL, sprintf('The class name of the entity to create CRUD (e.g. %s)', Str::asClassName(Str::getRandomTerm()))) ->setHelp(file_get_contents(__DIR__.'/../Resources/help/MakeCrud.txt')) ; @@ -63,15 +63,17 @@ public function configureCommand(Command $command, InputConfiguration $inputConf public function interact(InputInterface $input, ConsoleStyle $io, Command $command) { - $argument = $command->getDefinition()->getArgument('entity-class'); + if (null === $input->getArgument('entity-class')) { + $argument = $command->getDefinition()->getArgument('entity-class'); - $question = new Question($argument->getDescription()); - $question->setValidator([Validator::class, 'notBlank']); - $question->setAutocompleterValues($this->entityHelper->getEntitiesForAutocomplete()); + $question = new Question($argument->getDescription()); + $question->setValidator([Validator::class, 'validateClassName']); + $question->setAutocompleterValues($this->entityHelper->getEntitiesForAutocomplete()); - $value = $io->askQuestion($question); + $value = $io->askQuestion($question); - $input->setArgument('entity-class', $value); + $input->setArgument('entity-class', $value); + } } public function generate(InputInterface $input, ConsoleStyle $io, Generator $generator) @@ -81,11 +83,23 @@ public function generate(InputInterface $input, ConsoleStyle $io, Generator $gen 'Entity\\' ); - $repositoryClassDetails = $generator->createClassNameDetails( - $entityClassDetails->getRelativeName(), - 'Repository\\', - 'Repository' - ); + $entityDoctrineDetails = $this->entityHelper->createDoctrineDetails($entityClassDetails->getFullName()); + + $repositoryVars = []; + + if (null !== $entityDoctrineDetails->getRepositoryClass()) { + $repositoryClassDetails = $generator->createClassNameDetails( + '\\'.$entityDoctrineDetails->getRepositoryClass(), + 'Repository\\', + 'Repository' + ); + + $repositoryVars = [ + 'repository_full_class_name' => $repositoryClassDetails->getFullName(), + 'repository_class_name' => $repositoryClassDetails->getShortName(), + 'repository_var' => lcfirst(Inflector::singularize($repositoryClassDetails->getShortName())), + ]; + } $controllerClassDetails = $generator->createClassNameDetails( $entityClassDetails->getRelativeNameWithoutSuffix(), @@ -93,13 +107,16 @@ public function generate(InputInterface $input, ConsoleStyle $io, Generator $gen 'Controller' ); - $formClassDetails = $generator->createClassNameDetails( - $entityClassDetails->getRelativeNameWithoutSuffix(), - 'Form\\', - 'Type' - ); + $iter = 0; + do { + $formClassDetails = $generator->createClassNameDetails( + $entityClassDetails->getRelativeNameWithoutSuffix().($iter ?: ''), + 'Form\\', + 'Type' + ); + ++$iter; + } while (class_exists($formClassDetails->getFullName())); - $metadata = $this->entityHelper->getEntityMetadata($entityClassDetails->getFullName()); $entityVarPlural = lcfirst(Inflector::pluralize($entityClassDetails->getShortName())); $entityVarSingular = lcfirst(Inflector::singularize($entityClassDetails->getShortName())); $routeName = Str::asRouteName($controllerClassDetails->getRelativeNameWithoutSuffix()); @@ -107,25 +124,21 @@ public function generate(InputInterface $input, ConsoleStyle $io, Generator $gen $generator->generateClass( $controllerClassDetails->getFullName(), 'crud/controller/Controller.tpl.php', - [ - 'entity_full_class_name' => $entityClassDetails->getFullName(), - 'entity_class_name' => $entityClassDetails->getShortName(), - 'repository_exists' => class_exists($repositoryClassDetails->getFullName()), - 'repository_full_class_name' => $repositoryClassDetails->getFullName(), - 'repository_class_name' => $repositoryClassDetails->getShortName(), - 'repository_var' => lcfirst(Inflector::singularize($repositoryClassDetails->getShortName())), - 'form_full_class_name' => $formClassDetails->getFullName(), - 'form_class_name' => $formClassDetails->getShortName(), - 'route_path' => Str::asRoutePath($controllerClassDetails->getRelativeNameWithoutSuffix()), - 'route_name' => $routeName, - 'entity_var_plural' => $entityVarPlural, - 'entity_var_singular' => $entityVarSingular, - 'entity_identifier' => $metadata->identifier[0], - ] + array_merge([ + 'entity_full_class_name' => $entityClassDetails->getFullName(), + 'entity_class_name' => $entityClassDetails->getShortName(), + 'form_full_class_name' => $formClassDetails->getFullName(), + 'form_class_name' => $formClassDetails->getShortName(), + 'route_path' => Str::asRoutePath($controllerClassDetails->getRelativeNameWithoutSuffix()), + 'route_name' => $routeName, + 'entity_var_plural' => $entityVarPlural, + 'entity_var_singular' => $entityVarSingular, + 'entity_identifier' => $entityDoctrineDetails->getIdentifier(), + ], + $repositoryVars + ) ); - $formFields = $this->entityHelper->getFormFieldsFromEntity($entityClassDetails->getFullName()); - $generator->generateClass( $formClassDetails->getFullName(), 'form/Type.tpl.php', @@ -133,7 +146,7 @@ public function generate(InputInterface $input, ConsoleStyle $io, Generator $gen 'entity_class_exists' => true, 'entity_full_class_name' => $entityClassDetails->getFullName(), 'entity_class_name' => $entityClassDetails->getShortName(), - 'form_fields' => $formFields, + 'form_fields' => $entityDoctrineDetails->getFormFields(), ] ); @@ -143,21 +156,21 @@ public function generate(InputInterface $input, ConsoleStyle $io, Generator $gen '_delete_form' => [ 'route_name' => $routeName, 'entity_var_singular' => $entityVarSingular, - 'entity_identifier' => $metadata->identifier[0], + 'entity_identifier' => $entityDoctrineDetails->getIdentifier(), ], '_form' => [], 'edit' => [ 'entity_class_name' => $entityClassDetails->getShortName(), 'entity_var_singular' => $entityVarSingular, - 'entity_identifier' => $metadata->identifier[0], + 'entity_identifier' => $entityDoctrineDetails->getIdentifier(), 'route_name' => $routeName, ], 'index' => [ 'entity_class_name' => $entityClassDetails->getShortName(), 'entity_var_plural' => $entityVarPlural, 'entity_var_singular' => $entityVarSingular, - 'entity_identifier' => $metadata->identifier[0], - 'entity_fields' => $metadata->fieldMappings, + 'entity_identifier' => $entityDoctrineDetails->getIdentifier(), + 'entity_fields' => $entityDoctrineDetails->getDisplayFields(), 'route_name' => $routeName, ], 'new' => [ @@ -167,8 +180,8 @@ public function generate(InputInterface $input, ConsoleStyle $io, Generator $gen 'show' => [ 'entity_class_name' => $entityClassDetails->getShortName(), 'entity_var_singular' => $entityVarSingular, - 'entity_identifier' => $metadata->identifier[0], - 'entity_fields' => $metadata->fieldMappings, + 'entity_identifier' => $entityDoctrineDetails->getIdentifier(), + 'entity_fields' => $entityDoctrineDetails->getDisplayFields(), 'route_name' => $routeName, ], ]; @@ -185,7 +198,7 @@ public function generate(InputInterface $input, ConsoleStyle $io, Generator $gen $this->writeSuccessMessage($io); - $io->text('Next: Check your new crud!'); + $io->text(sprintf('Next: Check your new CRUD by going to %s/', Str::asRoutePath($controllerClassDetails->getRelativeNameWithoutSuffix()))); } /** diff --git a/src/Maker/MakeForm.php b/src/Maker/MakeForm.php index 1386d6f13..f167b36ea 100644 --- a/src/Maker/MakeForm.php +++ b/src/Maker/MakeForm.php @@ -18,6 +18,7 @@ use Symfony\Bundle\MakerBundle\Generator; use Symfony\Bundle\MakerBundle\InputConfiguration; use Symfony\Bundle\MakerBundle\Str; +use Symfony\Bundle\MakerBundle\Validator; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputInterface; @@ -32,7 +33,6 @@ final class MakeForm extends AbstractMaker { private $entityHelper; - private $boundEntityOrClass = true; public function __construct(DoctrineEntityHelper $entityHelper) { @@ -49,26 +49,22 @@ public function configureCommand(Command $command, InputConfiguration $inputConf $command ->setDescription('Creates a new form class') ->addArgument('name', InputArgument::OPTIONAL, sprintf('The name of the form class (e.g. %sType)', Str::asClassName(Str::getRandomTerm()))) + ->addArgument('bound-class', InputArgument::OPTIONAL, 'The name of Entity or custom model class that the new form will be bound to (empty for none)') ->setHelp(file_get_contents(__DIR__.'/../Resources/help/MakeForm.txt')) ; - $inputConf->setArgumentAsNonInteractive('name'); + $inputConf->setArgumentAsNonInteractive('bound-class'); } public function interact(InputInterface $input, ConsoleStyle $io, Command $command) { - if (null === $input->getArgument('name')) { - $argument = $command->getDefinition()->getArgument('name'); - $question = new Question($argument->getDescription()); - $value = $io->askQuestion($question); + if (null === $input->getArgument('bound-class')) { + $argument = $command->getDefinition()->getArgument('bound-class'); - $input->setArgument('name', $value); + $question = new Question($argument->getDescription()); + $question->setAutocompleterValues($this->entityHelper->getEntitiesForAutocomplete()); - if ($this->entityHelper->isDoctrineInstalled()) { - $question = new Question('Enter the class or entity name that the new form will be bound to (empty for none)'); - $question->setAutocompleterValues($this->entityHelper->getEntitiesForAutocomplete()); - $this->boundEntityOrClass = $io->askQuestion($question); - } + $input->setArgument('bound-class', $io->askQuestion($question)); } } @@ -80,34 +76,37 @@ public function generate(InputInterface $input, ConsoleStyle $io, Generator $gen 'Type' ); - if (null === $this->boundEntityOrClass) { - $generator->generateClass( - $formClassNameDetails->getFullName(), - 'form/SimpleType.tpl.php', - [] - ); - } else { - $entityClassNameDetails = $generator->createClassNameDetails( - true === $this->boundEntityOrClass ? $formClassNameDetails->getRelativeNameWithoutSuffix() : $this->boundEntityOrClass, + $formFields = ['field_name']; + $boundClassVars = []; + + $boundClass = $input->getArgument('bound-class'); + + if (null !== $boundClass) { + $boundClassDetails = $generator->createClassNameDetails( + $boundClass, 'Entity\\' ); - $entityClassExists = class_exists($entityClassNameDetails->getFullName()); + if (class_exists($boundClassDetails->getFullName())) { + $doctrineEntityDetails = $this->entityHelper->createDoctrineDetails($boundClassDetails->getFullName()); - $formFields = $entityClassExists ? $this->entityHelper->getFormFieldsFromEntity($entityClassNameDetails->getFullName()) : ['field_name']; + if (null !== $doctrineEntityDetails) { + $formFields = $doctrineEntityDetails->getFormFields(); + } - $generator->generateClass( - $formClassNameDetails->getFullName(), - 'form/Type.tpl.php', - [ - 'entity_class_exists' => $entityClassExists, - 'entity_full_class_name' => $entityClassNameDetails->getFullName(), - 'entity_class_name' => $entityClassNameDetails->getShortName(), - 'form_fields' => $formFields, - ] - ); + $boundClassVars = [ + 'bounded_full_class_name' => $boundClassDetails->getFullName(), + 'bounded_class_name' => $boundClassDetails->getShortName() + ]; + } } + $generator->generateClass( + $formClassNameDetails->getFullName(), + 'form/Type.tpl.php', + array_merge(['form_fields' => $formFields], $boundClassVars) + ); + $generator->writeChanges(); $this->writeSuccessMessage($io); diff --git a/src/Resources/skeleton/crud/controller/Controller.tpl.php b/src/Resources/skeleton/crud/controller/Controller.tpl.php index fd24d9fd7..2e8b1ab7f 100644 --- a/src/Resources/skeleton/crud/controller/Controller.tpl.php +++ b/src/Resources/skeleton/crud/controller/Controller.tpl.php @@ -4,7 +4,7 @@ use ; use ; - + use ; use Symfony\Bundle\FrameworkBundle\Controller\Controller; @@ -20,7 +20,7 @@ class extends Controller /** * @Route("/", name="_index", methods="GET") */ - + public function index( $): Response { return $this->render('/index.html.twig', ['' => $->findAll()]); diff --git a/src/Resources/skeleton/crud/templates/edit.tpl.php b/src/Resources/skeleton/crud/templates/edit.tpl.php index e6a9a8f9b..073bd26f5 100644 --- a/src/Resources/skeleton/crud/templates/edit.tpl.php +++ b/src/Resources/skeleton/crud/templates/edit.tpl.php @@ -8,5 +8,4 @@ back to list {{ include('/_delete_form.html.twig') }} - {% endblock %} \ No newline at end of file diff --git a/src/Resources/skeleton/crud/templates/new.tpl.php b/src/Resources/skeleton/crud/templates/new.tpl.php index bd5539836..92b7d0a0e 100644 --- a/src/Resources/skeleton/crud/templates/new.tpl.php +++ b/src/Resources/skeleton/crud/templates/new.tpl.php @@ -6,5 +6,4 @@ {{ include('/_form.html.twig') }} back to list - {% endblock %} \ No newline at end of file diff --git a/src/Resources/skeleton/crud/templates/show.tpl.php b/src/Resources/skeleton/crud/templates/show.tpl.php index 856fc2143..d2b00650f 100644 --- a/src/Resources/skeleton/crud/templates/show.tpl.php +++ b/src/Resources/skeleton/crud/templates/show.tpl.php @@ -19,5 +19,4 @@ edit {{ include('/_delete_form.html.twig') }} - {% endblock %} \ No newline at end of file diff --git a/src/Resources/skeleton/form/SimpleType.tpl.php b/src/Resources/skeleton/form/SimpleType.tpl.php deleted file mode 100644 index 60137fb40..000000000 --- a/src/Resources/skeleton/form/SimpleType.tpl.php +++ /dev/null @@ -1,24 +0,0 @@ - - -namespace ; - -use Symfony\Component\Form\AbstractType; -use Symfony\Component\Form\FormBuilderInterface; -use Symfony\Component\OptionsResolver\OptionsResolver; - -class extends AbstractType -{ - public function buildForm(FormBuilderInterface $builder, array $options) - { - $builder - ->add('form_field') - ; - } - - public function configureOptions(OptionsResolver $resolver) - { - $resolver->setDefaults([ - //configure form options here - ]); - } -} diff --git a/src/Resources/skeleton/form/Type.tpl.php b/src/Resources/skeleton/form/Type.tpl.php index 6c35753f1..1d85ec8fa 100644 --- a/src/Resources/skeleton/form/Type.tpl.php +++ b/src/Resources/skeleton/form/Type.tpl.php @@ -2,9 +2,9 @@ namespace ; - -use ; - + +use ; + use Symfony\Component\Form\AbstractType; use Symfony\Component\Form\FormBuilderInterface; use Symfony\Component\OptionsResolver\OptionsResolver; @@ -23,9 +23,11 @@ public function buildForm(FormBuilderInterface $builder, array $options) public function configureOptions(OptionsResolver $resolver) { $resolver->setDefaults([ - - 'data_class' => ::class, - + + 'data_class' => ::class, + + // Configure your form options here + ]); } } diff --git a/tests/Maker/FunctionalTest.php b/tests/Maker/FunctionalTest.php index 44fb522ea..4605527a1 100644 --- a/tests/Maker/FunctionalTest.php +++ b/tests/Maker/FunctionalTest.php @@ -173,6 +173,7 @@ public function getCommandTests() [ // form name 'FooBar', + '', ]) ->setFixtureFilesPath(__DIR__.'/../fixtures/MakeForm') ]; From f740e2ecb8e41b9adb8a1a0edabad74ccc8de42f Mon Sep 17 00:00:00 2001 From: Sadicov Vladimir Date: Tue, 6 Mar 2018 14:01:49 +0200 Subject: [PATCH 40/44] fix variables to follow official recommendations --- src/Maker/MakeCrud.php | 16 +++++++++++----- .../skeleton/crud/controller/Controller.tpl.php | 8 ++++---- .../skeleton/crud/templates/_delete_form.tpl.php | 4 ++-- .../skeleton/crud/templates/index.tpl.php | 8 ++++---- .../skeleton/crud/templates/show.tpl.php | 4 ++-- 5 files changed, 23 insertions(+), 17 deletions(-) diff --git a/src/Maker/MakeCrud.php b/src/Maker/MakeCrud.php index d3fffec43..1405acaab 100644 --- a/src/Maker/MakeCrud.php +++ b/src/Maker/MakeCrud.php @@ -119,6 +119,10 @@ public function generate(InputInterface $input, ConsoleStyle $io, Generator $gen $entityVarPlural = lcfirst(Inflector::pluralize($entityClassDetails->getShortName())); $entityVarSingular = lcfirst(Inflector::singularize($entityClassDetails->getShortName())); + + $entityTwigVarPlural = Str::asTwigVariable($entityVarPlural); + $entityTwigVarSingular = Str::asTwigVariable($entityVarSingular); + $routeName = Str::asRouteName($controllerClassDetails->getRelativeNameWithoutSuffix()); $generator->generateClass( @@ -132,7 +136,9 @@ public function generate(InputInterface $input, ConsoleStyle $io, Generator $gen 'route_path' => Str::asRoutePath($controllerClassDetails->getRelativeNameWithoutSuffix()), 'route_name' => $routeName, 'entity_var_plural' => $entityVarPlural, + 'entity_twig_var_plural' => $entityTwigVarPlural, 'entity_var_singular' => $entityVarSingular, + 'entity_twig_var_singular' => $entityTwigVarSingular, 'entity_identifier' => $entityDoctrineDetails->getIdentifier(), ], $repositoryVars @@ -155,20 +161,20 @@ public function generate(InputInterface $input, ConsoleStyle $io, Generator $gen $templates = [ '_delete_form' => [ 'route_name' => $routeName, - 'entity_var_singular' => $entityVarSingular, + 'entity_twig_var_singular' => $entityTwigVarSingular, 'entity_identifier' => $entityDoctrineDetails->getIdentifier(), ], '_form' => [], 'edit' => [ 'entity_class_name' => $entityClassDetails->getShortName(), - 'entity_var_singular' => $entityVarSingular, + 'entity_twig_var_singular' => $entityTwigVarSingular, 'entity_identifier' => $entityDoctrineDetails->getIdentifier(), 'route_name' => $routeName, ], 'index' => [ 'entity_class_name' => $entityClassDetails->getShortName(), - 'entity_var_plural' => $entityVarPlural, - 'entity_var_singular' => $entityVarSingular, + 'entity_twig_var_plural' => $entityTwigVarPlural, + 'entity_twig_var_singular' => $entityTwigVarSingular, 'entity_identifier' => $entityDoctrineDetails->getIdentifier(), 'entity_fields' => $entityDoctrineDetails->getDisplayFields(), 'route_name' => $routeName, @@ -179,7 +185,7 @@ public function generate(InputInterface $input, ConsoleStyle $io, Generator $gen ], 'show' => [ 'entity_class_name' => $entityClassDetails->getShortName(), - 'entity_var_singular' => $entityVarSingular, + 'entity_twig_var_singular' => $entityTwigVarSingular, 'entity_identifier' => $entityDoctrineDetails->getIdentifier(), 'entity_fields' => $entityDoctrineDetails->getDisplayFields(), 'route_name' => $routeName, diff --git a/src/Resources/skeleton/crud/controller/Controller.tpl.php b/src/Resources/skeleton/crud/controller/Controller.tpl.php index 2e8b1ab7f..3fb128a24 100644 --- a/src/Resources/skeleton/crud/controller/Controller.tpl.php +++ b/src/Resources/skeleton/crud/controller/Controller.tpl.php @@ -32,7 +32,7 @@ public function index(): Response ->getRepository(::class) ->findAll(); - return $this->render('/index.html.twig', ['' => $]); + return $this->render('/index.html.twig', ['' => $]); } @@ -54,7 +54,7 @@ public function new(Request $request): Response } return $this->render('/new.html.twig', [ - '' => $, + '' => $, 'form' => $form->createView(), ]); } @@ -64,7 +64,7 @@ public function new(Request $request): Response */ public function show( $): Response { - return $this->render('/show.html.twig', ['' => $]); + return $this->render('/show.html.twig', ['' => $]); } /** @@ -82,7 +82,7 @@ public function edit(Request $request, $render('/edit.html.twig', [ - '' => $, + '' => $, 'form' => $form->createView(), ]); } diff --git a/src/Resources/skeleton/crud/templates/_delete_form.tpl.php b/src/Resources/skeleton/crud/templates/_delete_form.tpl.php index 5a1f6d0aa..b4f075c50 100644 --- a/src/Resources/skeleton/crud/templates/_delete_form.tpl.php +++ b/src/Resources/skeleton/crud/templates/_delete_form.tpl.php @@ -1,5 +1,5 @@ -
      + - +
      \ No newline at end of file diff --git a/src/Resources/skeleton/crud/templates/index.tpl.php b/src/Resources/skeleton/crud/templates/index.tpl.php index 8b231a0f4..0ffd18cac 100644 --- a/src/Resources/skeleton/crud/templates/index.tpl.php +++ b/src/Resources/skeleton/crud/templates/index.tpl.php @@ -13,14 +13,14 @@ - {% for in %} + {% for in %} - {{ getEntityFieldPrintCode($entity_var_singular, $field) ?> }} + {{ getEntityFieldPrintCode($entity_twig_var_singular, $field) ?> }} - show - edit + show + edit {% else %} diff --git a/src/Resources/skeleton/crud/templates/show.tpl.php b/src/Resources/skeleton/crud/templates/show.tpl.php index d2b00650f..199e85e33 100644 --- a/src/Resources/skeleton/crud/templates/show.tpl.php +++ b/src/Resources/skeleton/crud/templates/show.tpl.php @@ -8,7 +8,7 @@ - {{ getEntityFieldPrintCode($entity_var_singular, $field) ?> }} + {{ getEntityFieldPrintCode($entity_twig_var_singular, $field) ?> }} @@ -16,7 +16,7 @@ back to list - edit + edit {{ include('/_delete_form.html.twig') }} {% endblock %} \ No newline at end of file From ada7db0087855ce3acf11977e71def09ba461034 Mon Sep 17 00:00:00 2001 From: Sadicov Vladimir Date: Tue, 6 Mar 2018 14:03:05 +0200 Subject: [PATCH 41/44] fix phpcs --- src/Doctrine/DoctrineEntityHelper.php | 1 + src/Maker/MakeForm.php | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Doctrine/DoctrineEntityHelper.php b/src/Doctrine/DoctrineEntityHelper.php index ea56a77cb..d15efb266 100644 --- a/src/Doctrine/DoctrineEntityHelper.php +++ b/src/Doctrine/DoctrineEntityHelper.php @@ -54,6 +54,7 @@ public function getEntitiesForAutocomplete(): array * @param string $entityClassName * * @return null|DoctrineEntityDetails + * * @throws \Exception */ public function createDoctrineDetails(string $entityClassName) diff --git a/src/Maker/MakeForm.php b/src/Maker/MakeForm.php index f167b36ea..cbedf3d8c 100644 --- a/src/Maker/MakeForm.php +++ b/src/Maker/MakeForm.php @@ -96,7 +96,7 @@ public function generate(InputInterface $input, ConsoleStyle $io, Generator $gen $boundClassVars = [ 'bounded_full_class_name' => $boundClassDetails->getFullName(), - 'bounded_class_name' => $boundClassDetails->getShortName() + 'bounded_class_name' => $boundClassDetails->getShortName(), ]; } } From 0d9e637efb998928972fc736034270af2123d935 Mon Sep 17 00:00:00 2001 From: Sadicov Vladimir Date: Wed, 7 Mar 2018 13:19:48 +0200 Subject: [PATCH 42/44] added validation on arguments --- src/Maker/MakeCrud.php | 6 +++-- src/Maker/MakeForm.php | 24 +++++++++-------- src/Validator.php | 47 ++++++++++++++++++++++++++++++++++ tests/Maker/FunctionalTest.php | 2 +- 4 files changed, 65 insertions(+), 14 deletions(-) diff --git a/src/Maker/MakeCrud.php b/src/Maker/MakeCrud.php index 1405acaab..63d20a1d3 100644 --- a/src/Maker/MakeCrud.php +++ b/src/Maker/MakeCrud.php @@ -66,9 +66,11 @@ public function interact(InputInterface $input, ConsoleStyle $io, Command $comma if (null === $input->getArgument('entity-class')) { $argument = $command->getDefinition()->getArgument('entity-class'); + $entities = $this->entityHelper->getEntitiesForAutocomplete(); + $question = new Question($argument->getDescription()); - $question->setValidator([Validator::class, 'validateClassName']); - $question->setAutocompleterValues($this->entityHelper->getEntitiesForAutocomplete()); + $question->setValidator(function ($answer) use ($entities) {return Validator::entityExists($answer, $entities); }); + $question->setAutocompleterValues($entities); $value = $io->askQuestion($question); diff --git a/src/Maker/MakeForm.php b/src/Maker/MakeForm.php index cbedf3d8c..8d85bb801 100644 --- a/src/Maker/MakeForm.php +++ b/src/Maker/MakeForm.php @@ -61,8 +61,12 @@ public function interact(InputInterface $input, ConsoleStyle $io, Command $comma if (null === $input->getArgument('bound-class')) { $argument = $command->getDefinition()->getArgument('bound-class'); + $entities = $this->entityHelper->getEntitiesForAutocomplete(); + $question = new Question($argument->getDescription()); - $question->setAutocompleterValues($this->entityHelper->getEntitiesForAutocomplete()); + $question->setValidator(function ($answer) use ($entities) {return Validator::existsOrNull($answer, $entities); }); + $question->setAutocompleterValues($entities); + $question->setMaxAttempts(3); $input->setArgument('bound-class', $io->askQuestion($question)); } @@ -87,18 +91,16 @@ public function generate(InputInterface $input, ConsoleStyle $io, Generator $gen 'Entity\\' ); - if (class_exists($boundClassDetails->getFullName())) { - $doctrineEntityDetails = $this->entityHelper->createDoctrineDetails($boundClassDetails->getFullName()); - - if (null !== $doctrineEntityDetails) { - $formFields = $doctrineEntityDetails->getFormFields(); - } + $doctrineEntityDetails = $this->entityHelper->createDoctrineDetails($boundClassDetails->getFullName()); - $boundClassVars = [ - 'bounded_full_class_name' => $boundClassDetails->getFullName(), - 'bounded_class_name' => $boundClassDetails->getShortName(), - ]; + if (null !== $doctrineEntityDetails) { + $formFields = $doctrineEntityDetails->getFormFields(); } + + $boundClassVars = [ + 'bounded_full_class_name' => $boundClassDetails->getFullName(), + 'bounded_class_name' => $boundClassDetails->getShortName(), + ]; } $generator->generateClass( diff --git a/src/Validator.php b/src/Validator.php index 443f12f9b..7ffec5e1e 100644 --- a/src/Validator.php +++ b/src/Validator.php @@ -46,4 +46,51 @@ public static function notBlank(string $value = null): string return $value; } + + public static function existsOrNull(string $className = null, array $entites = []) + { + if (null !== $className) { + self::validateClassName($className); + + if (0 === strpos($className, '\\')) { + self::classExists($className); + } else { + self::entityExists($className, $entites); + } + } + + return $className; + } + + public static function classExists(string $className, string $errorMessage = ''): string + { + self::notBlank($className); + + if (!class_exists($className)) { + $errorMessage = $errorMessage ?: sprintf('Class "%s" does\'t exists. Please enter existing full class name', $className); + + throw new RuntimeCommandException($errorMessage); + } + + return $className; + } + + public static function entityExists(string $className = null, array $entites = []): string + { + self::notBlank($className); + + if (empty($entites)) { + throw new RuntimeCommandException(sprintf('There is no registered entites. Please create entity before use this command', $className)); + } + + if (0 === strpos($className, '\\')) { + self::classExists($className, sprintf('Entity "%s" does\'t exists. Please enter existing one or create new', $className)); + } + + if (!in_array($className, $entites)) { + throw new RuntimeCommandException(sprintf('Entity "%s" does\'t exists. Please enter existing one or create new', $className)); + } + + return $className; + } } diff --git a/tests/Maker/FunctionalTest.php b/tests/Maker/FunctionalTest.php index 4605527a1..b6ba4c0cb 100644 --- a/tests/Maker/FunctionalTest.php +++ b/tests/Maker/FunctionalTest.php @@ -168,7 +168,7 @@ public function getCommandTests() }) ]; - yield 'form' => [MakerTestDetails::createTest( + yield 'form_basic' => [MakerTestDetails::createTest( $this->getMakerInstance(MakeForm::class), [ // form name From 2ec8ff025b2faea354aefb51cce649d9379bf8f7 Mon Sep 17 00:00:00 2001 From: Sadicov Vladimir Date: Fri, 9 Mar 2018 11:23:22 +0200 Subject: [PATCH 43/44] fix form variables --- src/Maker/MakeCrud.php | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/Maker/MakeCrud.php b/src/Maker/MakeCrud.php index 63d20a1d3..118a4a9a9 100644 --- a/src/Maker/MakeCrud.php +++ b/src/Maker/MakeCrud.php @@ -151,9 +151,8 @@ public function generate(InputInterface $input, ConsoleStyle $io, Generator $gen $formClassDetails->getFullName(), 'form/Type.tpl.php', [ - 'entity_class_exists' => true, - 'entity_full_class_name' => $entityClassDetails->getFullName(), - 'entity_class_name' => $entityClassDetails->getShortName(), + 'bounded_full_class_name' => $entityClassDetails->getFullName(), + 'bounded_class_name' => $entityClassDetails->getShortName(), 'form_fields' => $entityDoctrineDetails->getFormFields(), ] ); From 2683114ac3259b1fae0ce457413523ac585afa34 Mon Sep 17 00:00:00 2001 From: Sadicov Vladimir Date: Mon, 12 Mar 2018 10:10:08 +0200 Subject: [PATCH 44/44] some improvements --- src/Doctrine/DoctrineEntityDetails.php | 2 ++ src/Maker/MakeCrud.php | 3 +-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/Doctrine/DoctrineEntityDetails.php b/src/Doctrine/DoctrineEntityDetails.php index 54dcb1bfd..03cb28276 100644 --- a/src/Doctrine/DoctrineEntityDetails.php +++ b/src/Doctrine/DoctrineEntityDetails.php @@ -13,6 +13,8 @@ /** * @author Sadicov Vladimir + * + * @internal */ final class DoctrineEntityDetails { diff --git a/src/Maker/MakeCrud.php b/src/Maker/MakeCrud.php index 118a4a9a9..2da7fa81b 100644 --- a/src/Maker/MakeCrud.php +++ b/src/Maker/MakeCrud.php @@ -69,7 +69,6 @@ public function interact(InputInterface $input, ConsoleStyle $io, Command $comma $entities = $this->entityHelper->getEntitiesForAutocomplete(); $question = new Question($argument->getDescription()); - $question->setValidator(function ($answer) use ($entities) {return Validator::entityExists($answer, $entities); }); $question->setAutocompleterValues($entities); $value = $io->askQuestion($question); @@ -81,7 +80,7 @@ public function interact(InputInterface $input, ConsoleStyle $io, Command $comma public function generate(InputInterface $input, ConsoleStyle $io, Generator $generator) { $entityClassDetails = $generator->createClassNameDetails( - $input->getArgument('entity-class'), + Validator::entityExists($input->getArgument('entity-class'), $this->entityHelper->getEntitiesForAutocomplete()), 'Entity\\' );