forked from claroline/CoreBundle
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
2 changed files
with
185 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,93 @@ | ||
<?php | ||
|
||
namespace Claroline\CoreBundle\Form\Handler; | ||
|
||
use JMS\DiExtraBundle\Annotation as DI; | ||
use Symfony\Component\Form\FormFactoryInterface; | ||
use Symfony\Component\HttpFoundation\Request; | ||
|
||
/** | ||
* Utility class for handling forms defined as services. | ||
* | ||
* @DI\Service("claroline.form_handler") | ||
*/ | ||
class FormHandler | ||
{ | ||
private $factory; | ||
private $currentForm; | ||
|
||
/** | ||
* @DI\InjectParams({ | ||
* "factory" = @DI\Inject("form.factory") | ||
* }) | ||
* | ||
* @param FormFactoryInterface $factory | ||
*/ | ||
public function __construct(FormFactoryInterface $factory) | ||
{ | ||
$this->factory = $factory; | ||
$this->currentForm = null; | ||
} | ||
|
||
/** | ||
* Returns whether a form is valid and stores it internally for future use. | ||
* | ||
* @param string $formReference The form type name | ||
* @param Request $request The request to be bound | ||
* @param mixed $data An entity or array to be bound | ||
* @param array $options The options to be passed to the form builder | ||
* @return bool | ||
*/ | ||
public function isValid($formReference, Request $request, $data = null, array $options = []) | ||
{ | ||
$form = $this->getForm($formReference, $data, $options); | ||
$form->handleRequest($request); | ||
|
||
return $form->isValid(); | ||
} | ||
|
||
/** | ||
* Returns the data associated to the current form. | ||
* | ||
* @return mixed | ||
* @throws \LogicException if no form has been handled yet | ||
*/ | ||
public function getData() | ||
{ | ||
return $this->getCurrentForm()->getData(); | ||
} | ||
|
||
/** | ||
* Creates and returns a form view either from the current form | ||
* or from a new form type reference passed as argument. | ||
* | ||
* @param string $formReference The form type name | ||
* @param mixed $data An entity or array to be bound | ||
* @param array $options The options to be passed to the form builder | ||
* @return mixed | ||
* @throws \LogicException if no reference is passed and | ||
* no form has been handled yet | ||
*/ | ||
public function getView($formReference = null, $data = null, array $options = []) | ||
{ | ||
if ($formReference) { | ||
$this->getForm($formReference, $data, $options); | ||
} | ||
|
||
return $this->getCurrentForm()->createView(); | ||
} | ||
|
||
private function getForm($reference, $data = null, array $options = []) | ||
{ | ||
return $this->currentForm = $this->factory->create($reference, $data, $options); | ||
} | ||
|
||
private function getCurrentForm() | ||
{ | ||
if (!$this->currentForm) { | ||
throw new \LogicException('No form has been handled yet'); | ||
} | ||
|
||
return $this->currentForm; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,92 @@ | ||
<?php | ||
|
||
namespace Claroline\CoreBundle\Form\Handler; | ||
|
||
use HeVinci\CompetencyBundle\Util\UnitTestCase; | ||
use Symfony\Component\HttpFoundation\Request; | ||
|
||
class FormHandlerTest extends UnitTestCase | ||
{ | ||
private $factory; | ||
private $handler; | ||
|
||
protected function setUp() | ||
{ | ||
$this->factory = $this->mock('Symfony\Component\Form\FormFactoryInterface'); | ||
$this->handler = new FormHandler($this->factory); | ||
} | ||
|
||
/** | ||
* @expectedException \LogicException | ||
* @dataProvider currentFormMethodProvider | ||
* @param string $method | ||
*/ | ||
public function testAccessToCurrentFormRequiresPreviousFetch($method) | ||
{ | ||
$this->handler->{$method}(); | ||
} | ||
|
||
public function testValidateAndRetrieveDataAndView() | ||
{ | ||
$form = $this->mock('Symfony\Component\Form\Form'); | ||
$request = new Request(); | ||
|
||
// validation | ||
$this->factory->expects($this->exactly(2)) | ||
->method('create') | ||
->withConsecutive( | ||
['form.ref'], | ||
['form.ref', 'DATA', ['options']] | ||
) | ||
->willReturn($form); | ||
$form->expects($this->exactly(2)) | ||
->method('isValid') | ||
->willReturnOnConsecutiveCalls(true, false); | ||
$this->assertTrue($this->handler->isValid('form.ref', $request)); | ||
$this->assertFalse($this->handler->isValid('form.ref', $request, 'DATA', ['options'])); | ||
|
||
// retrieval | ||
$form->expects($this->once()) | ||
->method('getData') | ||
->willReturn('DATA'); | ||
$form->expects($this->once()) | ||
->method('createView') | ||
->willReturn('VIEW'); | ||
|
||
$this->assertEquals('DATA', $this->handler->getData()); | ||
$this->assertEquals('VIEW', $this->handler->getView()); | ||
} | ||
|
||
public function testGetViewAndRetrieveData() | ||
{ | ||
$form = $this->mock('Symfony\Component\Form\Form'); | ||
$this->factory->expects($this->once()) | ||
->method('create') | ||
->with('form.ref') | ||
->willReturn($form); | ||
$form->expects($this->once()) | ||
->method('createView') | ||
->willReturn('VIEW'); | ||
$form->expects($this->once()) | ||
->method('getData') | ||
->willReturn('DATA'); | ||
|
||
$this->assertEquals('VIEW', $this->handler->getView('form.ref')); | ||
$this->assertEquals('DATA', $this->handler->getData()); | ||
} | ||
|
||
public function currentFormMethodProvider() | ||
{ | ||
return [ | ||
['getData'], | ||
['getView'] | ||
]; | ||
} | ||
|
||
protected function mock($class) | ||
{ | ||
return $this->getMockBuilder($class) | ||
->disableOriginalConstructor() | ||
->getMock(); | ||
} | ||
} |