diff --git a/.travis.yml b/.travis.yml index da40526..98d0468 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,11 +1,10 @@ language: php -php: [5.3,5.4,5.5,5.6] +php: [5.3,5.4,5.5,5.6,7.0] env: - - SF_VERSION='~2.3.0,>=2.3.19' - - SF_VERSION='~2.4.0,>=2.4.9' - - SF_VERSION='~2.5.0,>=2.5.3,<=2.5.4' + - SF_VERSION='~2.7.0' + - SF_VERSION='~2.8.0' before_script: - export WEB_FIXTURES_HOST=http://localhost/index.php @@ -14,7 +13,6 @@ before_script: - export DISPLAY=:99.0 - sleep 4 - - Tests/app/switch_sf_version.sh "$SF_VERSION" - curl -sS https://getcomposer.org/installer | php - php -d memory_limit=-1 composer.phar require "symfony/symfony:${SF_VERSION}" - php -d memory_limit=-1 composer.phar install -n @@ -31,6 +29,7 @@ before_script: - sudo apt-get update > /dev/null - sudo apt-get install -y --force-yes apache2 libapache2-mod-fastcgi > /dev/null # enable php-fpm + - if [[ ${TRAVIS_PHP_VERSION:0:2} == "7." ]]; then sudo cp ~/.phpenv/versions/$(phpenv version-name)/etc/php-fpm.d/www.conf.default ~/.phpenv/versions/$(phpenv version-name)/etc/php-fpm.d/www.conf; fi - sudo cp ~/.phpenv/versions/$(phpenv version-name)/etc/php-fpm.conf.default ~/.phpenv/versions/$(phpenv version-name)/etc/php-fpm.conf - sudo a2enmod rewrite actions fastcgi alias - echo "cgi.fix_pathinfo = 1" >> ~/.phpenv/versions/$(phpenv version-name)/etc/php.ini diff --git a/Factory/JsFormValidatorFactory.php b/Factory/JsFormValidatorFactory.php index b7cdd8c..68c8fe6 100644 --- a/Factory/JsFormValidatorFactory.php +++ b/Factory/JsFormValidatorFactory.php @@ -5,16 +5,20 @@ use Fp\JsFormValidatorBundle\Form\Constraint\UniqueEntity; use Fp\JsFormValidatorBundle\Model\JsConfig; use Fp\JsFormValidatorBundle\Model\JsFormElement; +use Symfony\Component\Form\ChoiceList\ChoiceListInterface; use Symfony\Component\Form\DataTransformerInterface; -use Symfony\Component\Form\Extension\Core\ChoiceList\ChoiceListInterface; +use Symfony\Component\Form\Extension\Core\DataTransformer\ChoicesToBooleanArrayTransformer; +use Symfony\Component\Form\Extension\Core\DataTransformer\ChoiceToBooleanArrayTransformer; use Symfony\Component\Form\Form; use Symfony\Component\Form\FormInterface; +use Symfony\Component\Form\ResolvedFormTypeInterface; +use Symfony\Component\Routing\Generator\UrlGeneratorInterface; use Symfony\Component\Translation\TranslatorInterface; use Symfony\Component\Validator\Constraint; use Symfony\Component\Validator\Mapping\ClassMetadata; use Symfony\Component\Validator\Mapping\GetterMetadata; use Symfony\Component\Validator\Mapping\PropertyMetadata; -use Symfony\Component\Validator\ValidatorInterface; +use Symfony\Component\Validator\Validator\ValidatorInterface; /** * This factory uses to parse a form to a tree of JsFormElement's @@ -63,7 +67,7 @@ class JsFormValidatorFactory /** * @param ValidatorInterface $validator * @param TranslatorInterface $translator - * @param \Symfony\Component\Routing\Generator\UrlGeneratorInterface $router + * @param UrlGeneratorInterface $router * @param array $config * @param string $domain */ @@ -91,7 +95,7 @@ public function __construct( */ protected function getMetadataFor($className) { - return $this->validator->getMetadataFactory()->getMetadataFor($className); + return $this->validator->getMetadataFor($className); } /** @@ -242,12 +246,12 @@ public function createJsModel(Form $form) $model = new JsFormElement; $model->id = $this->getElementId($form); $model->name = $form->getName(); - $model->type = $conf->getType()->getInnerType()->getName(); + $model->type = $this->getFormTypeHierarchy($conf->getType()); $model->invalidMessage = $this->translateMessage( $conf->getOption('invalid_message'), $conf->getOption('invalid_message_parameters') ); - $model->transformers = $this->parseTransformers($form->getConfig()->getViewTransformers()); + $model->transformers = $this->parseTransformers($this->getViewTransformers($form)); $model->cascade = $conf->getOption('cascade_validation'); $model->bubbling = $conf->getOption('error_bubbling'); $model->data = $this->getValidationData($form); @@ -262,6 +266,19 @@ public function createJsModel(Form $form) return $model; } + private function getFormTypeHierarchy(ResolvedFormTypeInterface $formType) + { + $type = array( + $formType->getName(), + ); + + while ($formType = $formType->getParent()) { + $type[] = $formType->getName(); + } + + return $type; + } + /** * Create the JsFormElement for all the children of specified element * @@ -315,8 +332,8 @@ protected function getValidationData(Form $form) $parent = $form->getParent(); if ($parent && null !== $parent->getConfig()->getDataClass()) { $classMetadata = $metadata = $this->getMetadataFor($parent->getConfig()->getDataClass()); - if ($classMetadata->hasMemberMetadatas($form->getName())) { - $metadata = $classMetadata->getMemberMetadatas($form->getName()); + if ($classMetadata->hasPropertyMetadata($form->getName())) { + $metadata = $classMetadata->getPropertyMetadata($form->getName()); /** @var PropertyMetadata $item */ foreach ($metadata as $item) { $this->composeValidationData( @@ -428,8 +445,8 @@ protected function getValidationGroups(Form $form) // If groups is an array - return groups as is $result = $groups; } elseif ($groups instanceof \Closure) { - // If groups is a Closure - return the form class name to look for javascript - $result = $this->getElementId($form); + // If groups is a Closure - return the closure response + $result = $groups($form); } return $result; @@ -448,6 +465,32 @@ protected function isProcessableElement($element) && ('hidden' !== $element->getConfig()->getType()->getName()); } + /** + * Gets view transformers from the given form. + * Merges in an extra Choice(s)ToBooleanArrayTransformer transformer in case of expanded choice. + * + * @param FormInterface $form + * + * @return array + */ + protected function getViewTransformers(FormInterface $form) + { + $config = $form->getConfig(); + $type = $config->getType()->getInnerType()->getName(); + $viewTransformers = $config->getViewTransformers(); + + // Choice(s)ToBooleanArrayTransformer was deprecated in SF2.7 in favor of CheckboxListMapper and RadioListMapper + if ($type === 'choice' && $config->getOption('expanded')) { + $choiceList = $config->getOption('choice_list'); + $transformer = $config->getOption('multiple') + ? @new ChoicesToBooleanArrayTransformer($choiceList) + : @new ChoiceToBooleanArrayTransformer($choiceList, $config->getOption('placeholder')); + array_unshift($viewTransformers, $transformer); + } + + return $viewTransformers; + } + /** * Convert transformers objects to data arrays * @@ -471,7 +514,6 @@ protected function parseTransformers(array $transformers) $result[] = $item; } - return $result; } @@ -495,7 +537,7 @@ protected function getTransformerParam(DataTransformerInterface $transformer, $p } elseif (is_scalar($value) || is_array($value)) { $result = $value; } elseif ($value instanceof ChoiceListInterface) { - $result = $value->getChoices(); + $result = array_values($value->getChoices()); } return $result; diff --git a/Model/JsModelAbstract.php b/Model/JsModelAbstract.php index 20f4339..59bb792 100644 --- a/Model/JsModelAbstract.php +++ b/Model/JsModelAbstract.php @@ -2,6 +2,8 @@ namespace Fp\JsFormValidatorBundle\Model; +use Symfony\Component\Validator\Constraint; + /** * All the models inherited from this class converted to a similar Javascript model by printing them as a string * @@ -38,6 +40,11 @@ public function __toString() */ public static function phpValueToJs($value) { + // Initialize "groups" option if it is not set + if ($value instanceof Constraint) { + $value->groups; + } + // For object which has own __toString method if ($value instanceof JsModelAbstract) { return $value->toJsString(); @@ -101,4 +108,4 @@ public function toArray() return $result; } -} \ No newline at end of file +} diff --git a/README.md b/README.md index 0b57f56..080c363 100644 --- a/README.md +++ b/README.md @@ -1,20 +1,21 @@ # FpJsFormValidatorBundle -[![Build Status](https://travis-ci.org/formapro/JsFormValidatorBundle.svg?branch=1.2)](https://travis-ci.org/formapro/JsFormValidatorBundle) +[![Build Status](https://travis-ci.org/formapro/JsFormValidatorBundle.svg?branch=1.3)](https://travis-ci.org/formapro/JsFormValidatorBundle) [![Total Downloads](https://poser.pugx.org/fp/jsformvalidator-bundle/downloads.png)](https://packagist.org/packages/fp/jsformvalidator-bundle) -This module enables validation of the Symfony2 forms on the JavaScript side. +This module enables validation of the Symfony 2.7+ forms on the JavaScript side. It converts form type constraints into JavaScript validation rules. +If you have Symfony 3 or more - you need to use [Version 1.4+](https://github.com/formapro/JsFormValidatorBundle/tree/master) -## 1 Installation +If you have Symfony 2.3+ - you need to use [Version 1.2.*](https://github.com/formapro/JsFormValidatorBundle/tree/1.2) -[Upgrade from the previous version](https://github.com/formapro/JsFormValidatorBundle/blob/master/UPGRADE-1.1.md) +## 1 Installation ### 1.1 Download FpJsFormValidatorBundle using composer Run in terminal: ```bash -$ php composer.phar require "fp/jsformvalidator-bundle":"v1.2.*" +$ php composer.phar require "fp/jsformvalidator-bundle":"v1.3.*" ``` ### 1.2 Enable the bundle diff --git a/Resources/public/js/FpJsFormValidator.js b/Resources/public/js/FpJsFormValidator.js index 2f346aa..a88ab88 100644 --- a/Resources/public/js/FpJsFormValidator.js +++ b/Resources/public/js/FpJsFormValidator.js @@ -1,3 +1,29 @@ +function FpJsFormError(message) { + this.message = message; + this.atPath = null; + + this.getTarget = function(rootElement) { + if (!this.atPath) { + return rootElement; + } + + var path = this.atPath.split('.'); + var targetElement = rootElement; + var pathSegment; + + while (pathSegment = path.shift()) { + if (!targetElement.children[pathSegment]) { + return targetElement; + } + + targetElement = targetElement.children[pathSegment]; + } + + // fallback to rootElement in case the targetElement is not found + return targetElement || rootElement; + } +} + function FpJsFormElement() { this.id = ''; this.name = ''; @@ -26,22 +52,47 @@ function FpJsFormElement() { var self = this; var sourceId = 'form-error-' + String(this.id).replace(/_/g, '-'); - self.errors[sourceId] = FpJsFormValidator.validateElement(self); - - var errorPath = FpJsFormValidator.getErrorPathElement(self); - var domNode = errorPath.domNode; - if (!domNode) { - for (var childName in errorPath.children) { - var childDomNode = errorPath.children[childName].domNode; - if (childDomNode) { - domNode = childDomNode; - break; + this.clearErrorsRecursively(sourceId); + + if (this.domNode && this.domNode.disabled) { + return true; + } + + var validationErrors = FpJsFormValidator.validateElement(self); + + var invalidTargets = {}; + var validationError, errorTarget; + for (var v = 0, vel = validationErrors.length; v < vel; ++v) { + validationError = validationErrors[v]; + errorTarget = validationError.getTarget(self); + + invalidTargets[errorTarget.id] = errorTarget; + + if (!errorTarget.errors[sourceId]) { + errorTarget.errors[sourceId] = []; + } + + errorTarget.errors[sourceId].push(validationError.message); + } + + for (var id in invalidTargets) { + self = invalidTargets[id]; + + var errorPath = FpJsFormValidator.getErrorPathElement(self); + var domNode = errorPath.domNode; + if (!domNode) { + for (var childName in errorPath.children) { + var childDomNode = errorPath.children[childName].domNode; + if (childDomNode) { + domNode = childDomNode; + break; + } } } + errorPath.showErrors.apply(domNode, [self.errors[sourceId], sourceId]); } - errorPath.showErrors.apply(domNode, [self.errors[sourceId], sourceId]); - return self.errors[sourceId].length == 0; + return validationErrors.length === 0; }; this.validateRecursively = function () { @@ -67,6 +118,24 @@ function FpJsFormElement() { return true; }; + this.clearErrors = function(sourceId) { + if (!sourceId) { + for (sourceId in this.errors) { + this.clearErrors(sourceId); + } + } else { + this.errors[sourceId] = []; + this.showErrors.apply(this.domNode, [this.errors[sourceId], sourceId]); + } + }; + + this.clearErrorsRecursively = function (sourceId) { + this.clearErrors(sourceId); + for (var childName in this.children) { + this.children[childName].clearErrorsRecursively(sourceId); + } + }; + this.showErrors = function (errors, sourceId) { if (!(this instanceof HTMLElement)) { return; @@ -375,6 +444,10 @@ var FpJsFormValidator = new function () { this.customizeMethods = new FpJsCustomizeMethods(); this.constraintsCounter = 0; + function elementIsType(element, type) { + return element.type.indexOf(type) >= 0; + } + //noinspection JSUnusedGlobalSymbols this.addModel = function (model, onLoad) { var self = this; @@ -511,7 +584,7 @@ var FpJsFormValidator = new function () { this.checkParentCascadeOption = function (element) { var result = true; - if (element.parent && !element.parent.cascade && 'collection' != element.parent.type) { + if (element.parent && !element.parent.cascade && !elementIsType(element.parent, 'collection')) { result = false; } else if (element.parent) { result = this.checkParentCascadeOption(element.parent); @@ -531,12 +604,19 @@ var FpJsFormValidator = new function () { this.validateConstraints = function (value, constraints, groups, owner) { var errors = []; var i = constraints.length; + while (i--) { if (this.checkValidationGroups(groups, constraints[i])) { errors = errors.concat(constraints[i].validate(value, owner)); } } + for (var e = 0, el = errors.length; e < el; ++e) { + if (typeof errors[e] === 'string') { + errors[e] = new FpJsFormError(errors[e]); + } + } + return errors; }; @@ -569,7 +649,7 @@ var FpJsFormValidator = new function () { if (i && undefined === value) { value = this.getMappedValue(element); - } else if ('collection' == element.type) { + } else if (elementIsType(element, 'collection')) { value = {}; for (var childName in element.children) { value[childName] = this.getMappedValue(element.children[childName]); @@ -609,7 +689,7 @@ var FpJsFormValidator = new function () { } var value; - if ('checkbox' == element.type || 'radio' == element.type) { + if (elementIsType(element, 'checkbox') || elementIsType(element, 'radio')) { value = element.domNode.checked; } else if ('select' === element.domNode.tagName.toLowerCase()) { value = []; diff --git a/Resources/public/js/constraints/Choice.js b/Resources/public/js/constraints/Choice.js index fade18b..f2ce4eb 100644 --- a/Resources/public/js/constraints/Choice.js +++ b/Resources/public/js/constraints/Choice.js @@ -28,12 +28,10 @@ function SymfonyComponentValidatorConstraintsChoice() { if (this.multiple) { if (invalidCnt) { - while (invalidCnt--) { - errors.push(this.multipleMessage.replace( - '{{ value }}', - FpJsBaseConstraint.formatValue(invalidList[invalidCnt]) - )); - } + errors.push(this.multipleMessage.replace( + '{{ value }}', + FpJsBaseConstraint.formatValue(invalidList[0]) + )); } if (!isNaN(this.min) && value.length < this.min) { errors.push(this.minMessage); diff --git a/Resources/public/js/constraints/False.js b/Resources/public/js/constraints/False.js index cd54e9a..ad84b61 100644 --- a/Resources/public/js/constraints/False.js +++ b/Resources/public/js/constraints/False.js @@ -4,15 +4,4 @@ * @constructor * @author dev.ymalcev@gmail.com */ -function SymfonyComponentValidatorConstraintsFalse() { - this.message = ''; - - this.validate = function (value) { - var errors = []; - if ('' !== value && false !== value) { - errors.push(this.message.replace('{{ value }}', FpJsBaseConstraint.formatValue(value))); - } - - return errors; - } -} +var SymfonyComponentValidatorConstraintsFalse = SymfonyComponentValidatorConstraintsIsFalse; diff --git a/Resources/public/js/constraints/IsFalse.js b/Resources/public/js/constraints/IsFalse.js new file mode 100644 index 0000000..512f493 --- /dev/null +++ b/Resources/public/js/constraints/IsFalse.js @@ -0,0 +1,18 @@ +//noinspection JSUnusedGlobalSymbols +/** + * Checks if value is (bool) false + * @constructor + * @author dev.ymalcev@gmail.com + */ +function SymfonyComponentValidatorConstraintsIsFalse() { + this.message = ''; + + this.validate = function (value) { + var errors = []; + if ('' !== value && false !== value) { + errors.push(this.message.replace('{{ value }}', FpJsBaseConstraint.formatValue(value))); + } + + return errors; + } +} diff --git a/Resources/public/js/constraints/IsNull.js b/Resources/public/js/constraints/IsNull.js new file mode 100644 index 0000000..c630ecb --- /dev/null +++ b/Resources/public/js/constraints/IsNull.js @@ -0,0 +1,18 @@ +//noinspection JSUnusedGlobalSymbols +/** + * Checks if value is null + * @constructor + * @author dev.ymalcev@gmail.com + */ +function SymfonyComponentValidatorConstraintsIsNull() { + this.message = ''; + + this.validate = function(value) { + var errors = []; + if (null !== value) { + errors.push(this.message.replace('{{ value }}', FpJsBaseConstraint.formatValue(value))); + } + + return errors; + } +} diff --git a/Resources/public/js/constraints/IsTrue.js b/Resources/public/js/constraints/IsTrue.js new file mode 100644 index 0000000..322db60 --- /dev/null +++ b/Resources/public/js/constraints/IsTrue.js @@ -0,0 +1,23 @@ +//noinspection JSUnusedGlobalSymbols +/** + * Checks if value is (bool) true + * @constructor + * @author dev.ymalcev@gmail.com + */ +function SymfonyComponentValidatorConstraintsIsTrue() { + this.message = ''; + + this.validate = function(value) { + if ('' === value) { + return []; + } + + var errors = []; + if (true !== value) { + errors.push(this.message.replace('{{ value }}', FpJsBaseConstraint.formatValue(value))); + } + + return errors; + } +} + diff --git a/Resources/public/js/constraints/Null.js b/Resources/public/js/constraints/Null.js index b1113be..8e3bce0 100644 --- a/Resources/public/js/constraints/Null.js +++ b/Resources/public/js/constraints/Null.js @@ -4,15 +4,4 @@ * @constructor * @author dev.ymalcev@gmail.com */ -function SymfonyComponentValidatorConstraintsNull() { - this.message = ''; - - this.validate = function(value) { - var errors = []; - if (null !== value) { - errors.push(this.message.replace('{{ value }}', FpJsBaseConstraint.formatValue(value))); - } - - return errors; - } -} +var SymfonyComponentValidatorConstraintsNull = SymfonyComponentValidatorConstraintsIsNull; diff --git a/Resources/public/js/constraints/True.js b/Resources/public/js/constraints/True.js index 2441ce8..dd8ad53 100644 --- a/Resources/public/js/constraints/True.js +++ b/Resources/public/js/constraints/True.js @@ -4,20 +4,4 @@ * @constructor * @author dev.ymalcev@gmail.com */ -function SymfonyComponentValidatorConstraintsTrue() { - this.message = ''; - - this.validate = function(value) { - if ('' === value) { - return []; - } - - var errors = []; - if (true !== value) { - errors.push(this.message.replace('{{ value }}', FpJsBaseConstraint.formatValue(value))); - } - - return errors; - } -} - +var SymfonyComponentValidatorConstraintsTrue = SymfonyComponentValidatorConstraintsIsTrue; diff --git a/Tests/BaseMinkTestCase.php b/Tests/BaseMinkTestCase.php index a0e7345..b3ffe92 100644 --- a/Tests/BaseMinkTestCase.php +++ b/Tests/BaseMinkTestCase.php @@ -139,12 +139,9 @@ protected function makeScreenshot() } try { - $name = date('Y-m-d_H:i:s') . '.png'; - file_put_contents( - '/tmp/' . $name, - $this->session->getScreenshot() - ); - $imageUrl = $this->getUploader()->upload('/tmp/' . $name); + $path = sprintf('%s/%s.png', sys_get_temp_dir(), date('Y-m-d_H-i-s')); + file_put_contents($path, $this->session->getScreenshot()); + $imageUrl = $this->getUploader()->upload($path); } catch (\Exception $e) { $imageUrl = $e->getMessage(); } diff --git a/Tests/Factory/JsFormValidatorFactoryTest.php b/Tests/Factory/JsFormValidatorFactoryTest.php new file mode 100644 index 0000000..64bd672 --- /dev/null +++ b/Tests/Factory/JsFormValidatorFactoryTest.php @@ -0,0 +1,121 @@ +factory = $this->getMockBuilder('Fp\JsFormValidatorBundle\Factory\JsFormValidatorFactory') + ->disableOriginalConstructor() + ->getMock(); + } + + /** + * Tears down test class properties. + */ + public function tearDown() + { + $this->factory = null; + } + + /** + * Tests the getValidationGroups() method when returning an empty array. + */ + public function testGetValidationGroupsWhenEmpty() + { + // Given + $formConfig = $this->getMock('Symfony\Component\Form\FormConfigInterface'); + $formConfig + ->expects($this->once()) + ->method('getOption') + ->with($this->equalTo('validation_groups')) + ->will($this->returnValue(null)); + + $form = $this->getMockBuilder('Symfony\Component\Form\Form') + ->disableOriginalConstructor() + ->getMock(); + + $form->expects($this->once())->method('getConfig')->will($this->returnValue($formConfig)); + + $factory = new \ReflectionMethod($this->factory, 'getValidationGroups'); + $factory->setAccessible(true); + + // When + $result = $factory->invoke($this->factory, $form); + + // Then + $this->assertEquals(array('Default'), $result, 'Should return Default as validation_groups'); + } + + /** + * Tests the getValidationGroups() method when using a simple array. + */ + public function testGetValidationGroupsWhenArray() + { + // Given + $formConfig = $this->getMock('Symfony\Component\Form\FormConfigInterface'); + $formConfig + ->expects($this->once()) + ->method('getOption') + ->with($this->equalTo('validation_groups')) + ->will($this->returnValue(array('test1', 'test2'))); + + $form = $this->getMockBuilder('Symfony\Component\Form\Form') + ->disableOriginalConstructor() + ->getMock(); + + $form->expects($this->once())->method('getConfig')->will($this->returnValue($formConfig)); + + $factory = new \ReflectionMethod($this->factory, 'getValidationGroups'); + $factory->setAccessible(true); + + // When + $result = $factory->invoke($this->factory, $form); + + // Then + $this->assertEquals(array('test1', 'test2'), $result, 'Should return the validation_groups array'); + } + + /** + * Tests the getValidationGroups() method when using a Closure. + */ + public function testGetValidationGroupsWhenClosure() + { + // Given + $formConfig = $this->getMock('Symfony\Component\Form\FormConfigInterface'); + $formConfig + ->expects($this->once()) + ->method('getOption') + ->with($this->equalTo('validation_groups')) + ->will($this->returnValue(function () { return array('person'); })); + + $form = $this->getMockBuilder('Symfony\Component\Form\Form') + ->disableOriginalConstructor() + ->getMock(); + + $form->expects($this->once())->method('getConfig')->will($this->returnValue($formConfig)); + + $factory = new \ReflectionMethod($this->factory, 'getValidationGroups'); + $factory->setAccessible(true); + + // When + $result = $factory->invoke($this->factory, $form); + + // Then + $this->assertEquals(array('person'), $result, 'Should return the closure response as validation_groups'); + } +} \ No newline at end of file diff --git a/Tests/Fixtures/Entity.php b/Tests/Fixtures/Entity.php index 7729800..5ccf618 100644 --- a/Tests/Fixtures/Entity.php +++ b/Tests/Fixtures/Entity.php @@ -74,7 +74,7 @@ public function setName($name) /** * @return bool - * @Assert\True(message = "wrong_name") + * @Assert\IsTrue(message = "wrong_name") */ public function isNameLegal() { diff --git a/Tests/Functional/MainFunctionalTest.php b/Tests/Functional/MainFunctionalTest.php index 73033b2..fbc531f 100644 --- a/Tests/Functional/MainFunctionalTest.php +++ b/Tests/Functional/MainFunctionalTest.php @@ -321,12 +321,12 @@ public function testCollection() $addComment->click(); $submit->click(); - $this->assertEquals($getExpected(4, 3, 0), array_count_values($getErrors())); + $this->assertEquals($getExpected(1, 1, 0), array_count_values($getErrors())); $this->find('#del_form_task_tags_2')->click(); $this->find('#del_form_task_comments_1')->click(); $submit->click(); - $this->assertEquals($getExpected(3, 2, 0), array_count_values($getErrors())); + $this->assertEquals($getExpected(1, 1, 0), array_count_values($getErrors())); $page->findField('form_task_tags_0_title')->setValue('asdf'); $page->findField('form_task_tags_1_title')->setValue('asdf'); @@ -462,4 +462,4 @@ public function testPassForm_invalid() $this->assertTrue($page->hasContent('Fp\JsFormValidatorBundle\Exception\UndefinedFormException'), 'Exception was thrown'); $this->assertTrue($page->hasContent("Form 'wrong_name' was not found. Existing forms: async_load"), 'Correct message'); } -} \ No newline at end of file +} diff --git a/Tests/TestBundles/DefaultTestBundle/Controller/FunctionalTestsController.php b/Tests/TestBundles/DefaultTestBundle/Controller/FunctionalTestsController.php index aaca67c..3a0bed1 100644 --- a/Tests/TestBundles/DefaultTestBundle/Controller/FunctionalTestsController.php +++ b/Tests/TestBundles/DefaultTestBundle/Controller/FunctionalTestsController.php @@ -24,11 +24,12 @@ use Symfony\Component\Validator\Constraints\DateTime; use Symfony\Component\Validator\Constraints\Email; use Symfony\Component\Validator\Constraints\EqualTo; -use Symfony\Component\Validator\Constraints\False; use Symfony\Component\Validator\Constraints\GreaterThan; use Symfony\Component\Validator\Constraints\GreaterThanOrEqual; use Symfony\Component\Validator\Constraints\IdenticalTo; use Symfony\Component\Validator\Constraints\Ip; +use Symfony\Component\Validator\Constraints\IsFalse; +use Symfony\Component\Validator\Constraints\IsTrue; use Symfony\Component\Validator\Constraints\Length; use Symfony\Component\Validator\Constraints\LessThan; use Symfony\Component\Validator\Constraints\LessThanOrEqual; @@ -37,7 +38,6 @@ use Symfony\Component\Validator\Constraints\NotIdenticalTo; use Symfony\Component\Validator\Constraints\Range; use Symfony\Component\Validator\Constraints\Time; -use Symfony\Component\Validator\Constraints\True; use Symfony\Component\Validator\Constraints\Type; use Symfony\Component\Validator\Constraints\Url; @@ -293,10 +293,10 @@ public function transformersAction(Request $request, $isValid, $js) 'checkbox', array( 'constraints' => array( - new True(array( + new IsTrue(array( 'message' => 'checkbox_false' )), - new False(array( + new IsFalse(array( 'message' => 'checkbox_true' )) ) @@ -307,10 +307,10 @@ public function transformersAction(Request $request, $isValid, $js) 'radio', array( 'constraints' => array( - new True(array( + new IsTrue(array( 'message' => 'radio_false' )), - new False(array( + new IsFalse(array( 'message' => 'radio_true' )) ) @@ -469,7 +469,7 @@ public function emptyAction( 'constraints' => array( new Email(array('message' => 'wrong_email')), new EqualTo(array('value' => 'asdf', 'message' => 'wrong_equal_to')), - new False(array('message' => 'wrong_false')), + new IsFalse(array('message' => 'wrong_false')), new GreaterThan(array('value' => 5, 'message' => 'wrong_greater_than')), new GreaterThanOrEqual(array('value' => 5, 'message' => 'wrong_greater_than_or_equal')), new IdenticalTo(array('value' => 5, 'message' => 'wrong_identical_to')), @@ -491,7 +491,7 @@ public function emptyAction( new Time(array('message' => 'wrong_time')), new Date(array('message' => 'wrong_date')), new DateTime(array('message' => 'wrong_date_time')), - new True(array('message' => 'wrong_true')), + new IsTrue(array('message' => 'wrong_true')), new Type(array('type' => 'integer', 'message' => 'wrong_type')), new Url(array('message' => 'wrong_url')), ) diff --git a/Tests/TestBundles/DefaultTestBundle/Entity/BasicConstraintsEntity.php b/Tests/TestBundles/DefaultTestBundle/Entity/BasicConstraintsEntity.php index 37313f5..8219c0a 100644 --- a/Tests/TestBundles/DefaultTestBundle/Entity/BasicConstraintsEntity.php +++ b/Tests/TestBundles/DefaultTestBundle/Entity/BasicConstraintsEntity.php @@ -352,7 +352,7 @@ public function getDatetime() /** * @return bool - * @Assert\True(message="true_value") + * @Assert\IsTrue(message="true_value") */ public function isTrue() { @@ -361,7 +361,7 @@ public function isTrue() /** * @return bool - * @Assert\False(message="false_value") + * @Assert\IsFalse(message="false_value") */ public function isFalse() { @@ -370,7 +370,7 @@ public function isFalse() /** * @return bool - * @Assert\Null(message="null_{{ value }}") + * @Assert\IsNull(message="null_{{ value }}") */ public function isNull() { @@ -711,7 +711,7 @@ public function isValidSingleChoice() */ public function isValidMultipleChoice() { - return $this->_t_get(array('June', 'July'), array('June', 'May', 'September')); + return $this->_t_get(array('June', 'July'), array('June', 'May')); } /** diff --git a/Tests/TestBundles/DefaultTestBundle/Entity/CustomizationEntity.php b/Tests/TestBundles/DefaultTestBundle/Entity/CustomizationEntity.php index 9b8ba1f..ff09310 100644 --- a/Tests/TestBundles/DefaultTestBundle/Entity/CustomizationEntity.php +++ b/Tests/TestBundles/DefaultTestBundle/Entity/CustomizationEntity.php @@ -189,7 +189,7 @@ public function setEmail($email) /** * @return bool * - * @Assert\True( + * @Assert\IsTrue( * message="getter_message", * groups={"groups_callback"} * ) diff --git a/Tests/TestBundles/DefaultTestBundle/Entity/TestEntity.php b/Tests/TestBundles/DefaultTestBundle/Entity/TestEntity.php index bad2909..3b9aec7 100644 --- a/Tests/TestBundles/DefaultTestBundle/Entity/TestEntity.php +++ b/Tests/TestBundles/DefaultTestBundle/Entity/TestEntity.php @@ -116,11 +116,11 @@ public function setEmail($email) /** * @return bool - * @Assert\True( + * @Assert\IsTrue( * message="getter_groups_array_message", * groups={"groups_array"} * ) - * @Assert\True( + * @Assert\IsTrue( * message="getter_no_groups_message" * ) */ diff --git a/Tests/TestBundles/DefaultTestBundle/Entity/TestSubEntity.php b/Tests/TestBundles/DefaultTestBundle/Entity/TestSubEntity.php index a0a6329..2d7c52e 100644 --- a/Tests/TestBundles/DefaultTestBundle/Entity/TestSubEntity.php +++ b/Tests/TestBundles/DefaultTestBundle/Entity/TestSubEntity.php @@ -74,15 +74,15 @@ public function getName() /** * @return bool - * @Assert\True( + * @Assert\IsTrue( * message="sub_entity_getter_groups_child_message", * groups={"groups_child"} * ) - * @Assert\True( + * @Assert\IsTrue( * message="sub_entity_getter_groups_array_message", * groups={"groups_array"} * ) - * @Assert\True( + * @Assert\IsTrue( * message="sub_entity_getter_no_groups_message" * ) */ diff --git a/Tests/TestBundles/DefaultTestBundle/Resources/views/FunctionalTests/index.html.twig b/Tests/TestBundles/DefaultTestBundle/Resources/views/FunctionalTests/index.html.twig index 5bc0b3e..c1dcc05 100644 --- a/Tests/TestBundles/DefaultTestBundle/Resources/views/FunctionalTests/index.html.twig +++ b/Tests/TestBundles/DefaultTestBundle/Resources/views/FunctionalTests/index.html.twig @@ -74,7 +74,7 @@ 'isTypeScalar': function() { return _t.get(1, [1,2,3]); }, 'isTypeString': function() { return _t.get('1', 1); }, 'isValidSingleChoice': function() { return _t.get('male', 'wrong_choice'); }, - 'isValidMultipleChoice': function() { return _t.get(['June', 'July'], ['June', 'May', 'September']); }, + 'isValidMultipleChoice': function() { return _t.get(['June', 'July'], ['June', 'May']); }, 'isMinMultipleChoice': function() { return _t.get(['June', 'July'], ['June']); }, 'isMaxMultipleChoice': function() { return _t.get(['June'], ['June', 'July']); }, diff --git a/Tests/TestBundles/DefaultTestBundle/Twig/Extension/TestTwigExtension.php b/Tests/TestBundles/DefaultTestBundle/Twig/Extension/TestTwigExtension.php index 0ede9fe..deac8a4 100644 --- a/Tests/TestBundles/DefaultTestBundle/Twig/Extension/TestTwigExtension.php +++ b/Tests/TestBundles/DefaultTestBundle/Twig/Extension/TestTwigExtension.php @@ -12,9 +12,6 @@ */ class TestTwigExtension extends \Twig_Extension { - /** @var \Twig_Environment */ - protected $env; - /** * @var Kernel */ @@ -25,21 +22,13 @@ public function __construct($kernel) $this->kernel = $kernel; } - /** - * @param \Twig_Environment $environment - */ - public function initRuntime(\Twig_Environment $environment) - { - $this->env = $environment; - } - /** * {@inheritdoc} */ public function getFunctions() { return array( - 'update_js_lib' => new \Twig_Function_Method($this, 'updateJsLib'), + new \Twig_SimpleFunction('update_js_lib', array($this, 'updateJsLib')), ); } diff --git a/Tests/app/AppKernel.php b/Tests/app/AppKernel.php index 710d0a5..92712ad 100644 --- a/Tests/app/AppKernel.php +++ b/Tests/app/AppKernel.php @@ -42,13 +42,6 @@ public function registerContainerConfiguration(LoaderInterface $loader) $loader->load(__DIR__.'/Resources/config.php'); } - /** - * An empty init function - */ - public function init() - { - } - /** * @param string $name * @param string $extension diff --git a/Tests/app/Resources/BasicConstraintsEntity_sf_2_3.php b/Tests/app/Resources/BasicConstraintsEntity_sf_2_3.php index 24905d7..4e096d1 100644 --- a/Tests/app/Resources/BasicConstraintsEntity_sf_2_3.php +++ b/Tests/app/Resources/BasicConstraintsEntity_sf_2_3.php @@ -712,7 +712,7 @@ public function isValidSingleChoice() */ public function isValidMultipleChoice() { - return $this->_t_get(array('June', 'July'), array('June', 'May', 'September')); + return $this->_t_get(array('June', 'July'), array('June', 'May')); } /** diff --git a/Tests/app/Resources/config.php b/Tests/app/Resources/config.php index 684628b..a2b5161 100644 --- a/Tests/app/Resources/config.php +++ b/Tests/app/Resources/config.php @@ -53,9 +53,7 @@ $container->loadFromExtension('twig', array( 'debug' => true, 'strict_variables' => true, - 'form' => array( - 'resources' => array('DefaultTestBundle::form_theme.html.twig') - ), + 'form_themes' => array('DefaultTestBundle::form_theme.html.twig') )); $container->loadFromExtension('doctrine', array( 'orm' => array( diff --git a/Twig/Extension/JsFormValidatorTwigExtension.php b/Twig/Extension/JsFormValidatorTwigExtension.php index 4950216..a1f16fa 100644 --- a/Twig/Extension/JsFormValidatorTwigExtension.php +++ b/Twig/Extension/JsFormValidatorTwigExtension.php @@ -12,17 +12,6 @@ */ class JsFormValidatorTwigExtension extends \Twig_Extension { - /** @var \Twig_Environment */ - protected $env; - - /** - * @param \Twig_Environment $environment - */ - public function initRuntime(\Twig_Environment $environment) - { - $this->env = $environment; - } - /** * @var JsFormValidatorFactory */ @@ -53,8 +42,12 @@ public function __construct(JsFormValidatorFactory $factory) public function getFunctions() { return array( - 'init_js_validation' => new \Twig_Function_Method($this, 'getJsValidator', array('is_safe' => array('html'))), - 'js_validator_config' => new \Twig_Function_Method($this, 'getConfig', array('is_safe' => array('html'))), + new \Twig_SimpleFunction('init_js_validation', array($this, 'getJsValidator'), array( + 'is_safe' => array('html') + )), + new \Twig_SimpleFunction('js_validator_config', array($this, 'getConfig'), array( + 'is_safe' => array('html') + )), ); } diff --git a/composer.json b/composer.json index 6892948..f15740a 100644 --- a/composer.json +++ b/composer.json @@ -19,15 +19,15 @@ "require": { "php": ">=5.3.2", - "symfony/form": ">=2.3,<=2.5.4", - "symfony/validator": "~2.3.0,>=2.3.19||~2.4.0,>=2.4.9||~2.5.0,>=2.5.3,<=2.5.4", - "symfony/symfony": "~2.3.0,>=2.3.19" + "symfony/form": "^2.7", + "symfony/validator": "^2.7" }, "require-dev": { "doctrine/orm": ">=2.2.3", - "doctrine/doctrine-bundle": "~1.2", - "symfony/assetic-bundle": ">=2.3,<=2.5.4", + "doctrine/doctrine-bundle": "~1.4", + "symfony/symfony": "^2.7", + "symfony/assetic-bundle": ">=2.5", "phpunit/phpunit": "3.7.*", "behat/mink-bundle": "dev-master", "behat/mink-selenium2-driver": "1.1.0", @@ -51,7 +51,7 @@ "extra": { "branch-alias": { - "dev-master": "1.1-dev" + "dev-master": "1.3-dev" } } }