Skip to content
This repository has been archived by the owner on Aug 3, 2023. It is now read-only.

Commit

Permalink
added some form-utils classes
Browse files Browse the repository at this point in the history
  • Loading branch information
ghua committed Sep 21, 2015
1 parent 13d0520 commit 1802304
Show file tree
Hide file tree
Showing 8 changed files with 3,063 additions and 3 deletions.
1 change: 0 additions & 1 deletion .gitignore
@@ -1,4 +1,3 @@
.komodotools
.idea
vendor/
Tests/app/cache/
9 changes: 9 additions & 0 deletions Resources/config/services.yml
Expand Up @@ -81,3 +81,12 @@ services:
- { name: ext_direct.search.field_processor }


ext_direct.utils.search_by_entity.helper:
class: Ext\DirectBundle\Utils\SearchByEntityHelper
calls:
- [ setEntityManager, [ @doctrine.orm.entity_manager ]]
- [ setAnnotationReader, [ @annotation_reader ] ]
- [ setAssociationProcessor, [ @ext_direct.utils.processor.association_processor ] ]

ext_direct.utils.processor.association_processor:
class: Ext\DirectBundle\Utils\Processor\AssociationProcessor
102 changes: 102 additions & 0 deletions Response/FormLoad.php
@@ -0,0 +1,102 @@
<?php

namespace Ext\DirectBundle\Response;

use Symfony\Component\Form\FormView;

/**
* Class FormLoad
*
* @package Ext\DirectBundle\Response
*/
class FormLoad extends Response
{

const ARRAY_REGEX = '/^(.+)\[\d+\]$/';

/**
* @param FormView $view
*
* @return $this
* @throws \InvalidArgumentException
*/
public function setContent($view)
{
if (!($view instanceof FormView)) {
throw new \InvalidArgumentException('setContent($view) must be instance of FormView');
}

$this->setData(
$this->compileResult(
$this->getNamesAndValues($view)
)
);

return $this;
}

/**
* @param FormView $view
*
* @return array
*/
private function getNamesAndValues(FormView $view)
{
$result = array();
foreach ($view as $child) {
$hasChildren = 0 < count($child);
if ($hasChildren) {
$result = array_merge($result, $this->getNamesAndValues($child));
} else {
$value = $child->vars['value'];

if (in_array('checkbox', $child->vars['block_prefixes']) && !$child->vars['checked']) {
$value = 0;
}

if (is_string($value) && preg_match('/^[1-9]\d*$/', $value)) {
$value = (int) $value;
}

if (is_array($value)) {
$value = array_map(function($v) {
if (is_string($v) && preg_match('/^[1-9]\d*$/', $v)) {
return (int) $v;
}

return $v;
}, $value);
}

$result[$child->vars['full_name']] = $value;
}
}

return $result;
}

/**
* @param array $result
*
* @return array
*/
protected function compileResult($result)
{
foreach ($result as $key => $value) {
if (preg_match(self::ARRAY_REGEX, $key, $match) && count($match) === 2) {
$newKey = $match[1] . '[]';

if (!isset($result[$newKey])) {
$result[$newKey] = array($value);
} else {
$result[$newKey][] = $value;
}

unset($result[$key]);
}
}

return $result;
}

}
103 changes: 103 additions & 0 deletions Tests/Response/FormLoadTest.php
@@ -0,0 +1,103 @@
<?php

namespace Ext\DirectBundle\Tests\Response;

use Ext\DirectBundle\Router\Rule;
use Ext\DirectBundle\Response\FormLoad;
use Symfony\Component\Form\FormView;

/**
* Class FormLoadTest
*
* @package Ext\DirectBundle\Tests\Response
*/
class FormLoadTest extends \PHPUnit_Framework_TestCase
{
/**
* @var \Ext\DirectBundle\Response\ResponseFactory
*/
private $responseFactory;

/**
* @inheritdoc
*/
public function setUp()
{
$rule = new Rule('alias', 'AcmeBundle_TestController');

$controllerResolver = $this->getMockBuilder('Ext\DirectBundle\Router\ControllerResolver')
->disableOriginalConstructor()
->getMock();
$controllerResolver->expects($this->any())
->method('getCurrentRule')
->will($this->returnValue($rule));

$responseFactory = $this->getMockBuilder('Ext\DirectBundle\Response\ResponseFactory')
->disableOriginalConstructor()
->getMock();
$responseFactory->expects($this->any())
->method('getResolver')
->will($this->returnValue($controllerResolver));


$this->responseFactory = $responseFactory;
}

/**
* @return array
*/
public function getFormView()
{
$root = new FormView();
$root->vars = array('full_name' => 'root', 'block_prefixes' => array('form'));
$text = new FormView($root);
$text->vars = array('full_name' => 'root[text]', 'value' => 'text', 'block_prefixes' => array('form', 'text'));

$collection = new FormView($root);
$collection->vars = array('full_name' => 'root[collection]', 'block_prefixes' => array('form', 'collection'));

$first = new FormView($collection);
$first->vars = array('full_name' => 'root[collection][0]', 'value' => 'first', 'block_prefixes' => array('form', 'text'));
$second = new FormView($collection);
$second->vars = array('full_name' => 'root[collection][1]', 'value' => 'second', 'block_prefixes' => array('form', 'text'));

$collection->children = array($first, $second);

$checkbox = new FormView($root);
$checkbox->vars = array(
'full_name' => 'root[checkbox]', 'value' => '1',
'block_prefixes' => array('form', 'checkbox'),
'checked' => false
);

$root->children = array($text, $collection, $checkbox);

return array(array($root));
}

/**
* @param FormView $view
*
* @dataProvider getFormView
*/
public function testGetNamesAndValues(FormView $view)
{
$response = new FormLoad();
$response->setFactory($this->responseFactory);
$response->setContent($view);
$response->extract();

$data = $response->getData();

$this->assertArrayHasKey('root[text]', $data);
$this->assertEquals('text', $data['root[text]']);

$this->assertArrayHasKey('root[collection][]', $data);
$this->assertEquals(array('first', 'second'), $data['root[collection][]']);

$this->assertArrayHasKey('root[checkbox]', $data);
$this->assertEquals('0', $data['root[checkbox]']);

}

}
46 changes: 46 additions & 0 deletions Tests/Utils/FilterRequestToFormDataTransformerTest.php
@@ -0,0 +1,46 @@
<?php

namespace Ext\DirectBundle\Utils;

use Ext\DirectBundle\Utils;

/**
* Class FilterRequestToFormDataTransformerTest
*
* @package Ext\DirectBundle\Utils
*/
class FilterRequestToFormDataTransformerTest extends \PHPUnit_Framework_TestCase
{
/**
* @return array
*/
public function getFilter()
{
$collection = array('form_name' => array(
'collection' => array('first' => 'first_value', 'second' => 'second_value')
));

return array(
array(
array(
array('property' => 'form_name[collection][first]', 'value' => 'first_value'),
array('property' => 'form_name[collection][second]', 'value' => 'second_value'),
),
$collection
)
);
}

/**
* @param array $filter
* @param array $result
*
* @dataProvider getFilter
*/
public function testTransform(array $filter, array $result)
{
$t = new FilterRequestToFormDataTransformer();
$this->assertEquals($result, $t->transform($filter));
}

}
65 changes: 65 additions & 0 deletions Utils/FilterRequestToFormDataTransformer.php
@@ -0,0 +1,65 @@
<?php

namespace Ext\DirectBundle\Utils;

/**
* Class FilterRequestToFormDataTransformer
*
* @package Ext\DirectBundle\Utils
*/
class FilterRequestToFormDataTransformer
{

private $filterKeys = array('property', 'value');

const PARTS_REGEXP = '/[\w\d_]+/';

/**
* @param array $filter
*
* @return array
*/
public function transform($filter)
{
$result = array();

foreach ($filter as $rule) {
$this->checkFilterKeys($rule);
$value = $rule['value'];

if (is_string($value) and in_array($value, array("true", "false"))) {
$value = filter_var($value, FILTER_VALIDATE_BOOLEAN);
}

if (preg_match_all(self::PARTS_REGEXP, $rule['property'], $parts)) {
$parts = $parts[0];
foreach ($parts as $part) {
$value = array(array_pop($parts) => $value);
}
}

$result = array_merge_recursive($result, $value);
}

return $result;
}



/**
* @param array $rule
*
* @return bool
* @throws \InvalidArgumentException
*/
private function checkFilterKeys(array $rule)
{
$diff = array_diff($this->filterKeys, array_keys($rule));
if (!empty($diff)) {
throw new \InvalidArgumentException('The request does not contains a required keys: ' . implode(', ', $diff));
}

return true;
}

}
2 changes: 0 additions & 2 deletions Utils/Processor/AssociationProcessor.php
Expand Up @@ -8,8 +8,6 @@
* Class AssociationProcessor
*
* @package Ext\DirectBundle\Utils\Processor
*
* @author Semyon Velichko <semyon@velichko.net>
*/
class AssociationProcessor extends AbstractProcessor
{
Expand Down

0 comments on commit 1802304

Please sign in to comment.