1
\$\begingroup\$

I have a fairly ugly controller method I would like to refactor / extract. I can only test this in an integration-type test which kind of signals a code smell.

The method processes the form and needs to do one of 5 things, depending on which button was pressed

  1. if submitted and valid (button 1) => update some values on the entity and re-render the form
  2. if submitted and valid (button 2) => perform another controller action that shows a .pdf print of the entity
  3. if submitted and valid (button 3) => save entity and redirect
  4. if not submitted or not valid => render form (plus errors)

In code it looks kind of like this:

protected function processForm(Request $request, MyEntity $entity)
{
    $form = $this->createForm(new MyEntityType, $entity);

    if ($form->handleRequest($request)->isValid()) {

        $alteredEntity = SomeClass:performStuffOnEntity($entity);

        if ($form->get('button1')->isClicked()) {
            $form = $this->createForm(
                new MyEntityType, $alteredEntity
            );
        }
        else if ($form->get('button2')->isClicked()) {
            return $this->pdfPreview($alteredEntity);
        }
        else if ($form->get('button3')->isClicked()) {
            return $this->persistAndRedirectToEntity(
                $alteredEntity
            );
        }
    }

    return $this->render(
        'MyBundle:MyEntity:new.html.twig', array(
            'form' => $form->createView(),
    ));
}

There are actually two buttons like button1; I left one out for brevity of the example.

Ideas:

  1. I have tried to extract this into a EntityFormWizard of some sort but this ended up as a cluttered Object with too many dependencies (Router, Templating, Form) which was also a pain to test.

  2. Using FormEvents I wanted to extract at least the altering of the entity depending on which button was pressed into a FormEventListener, but the only place where I can alter the Entity is the FormEvents::PRE_SET_DATA event, but in there I have problems figuring out which button was clicked.

Do I have to live with my integration test for this behavior or is there a way to extract it and test it with a unit test?

\$\endgroup\$
  • \$\begingroup\$ This question appears to be off-topic because it seems like you are asking us how to write code for you, or how to do something other than increase readability, performance, speed, etc \$\endgroup\$ – Malachi Nov 22 '13 at 4:49
  • 1
    \$\begingroup\$ I disagree; I think that rearranging code for testability is on topic. However, we haven't been given enough context to understand the problem. This might be a situation where it makes sense to post the code of greatest concern here, and the rest on GitHub or something. \$\endgroup\$ – 200_success Nov 22 '13 at 6:54
  • \$\begingroup\$ Hi, not trying to get my code written for me. Everything in here exists already. Just looking for a better abstraction or advice how to extract that method cleverly. If I extract it as it is I end up with exactly the same dependencies as in the controller. So I wouldnt really gain anything. \$\endgroup\$ – user1777136 Nov 22 '13 at 10:03

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.