Author: Bernhard Schussek (bernhard.schussek@symfony.com)
Inheritance: implements IteratorAggregate
 /**
  * Validates the form and its domain object.
  *
  * @param FormInterface $form A FormInterface instance
  */
 public function validate(FormInterface $form)
 {
     if ($form->isRoot()) {
         $mapping = array();
         $forms = array();
         $this->buildFormPathMapping($form, $mapping);
         $this->buildDataPathMapping($form, $mapping);
         $this->buildNamePathMapping($form, $forms);
         $this->resolveMappingPlaceholders($mapping, $forms);
         // Validate the form in group "Default"
         // Validation of the data in the custom group is done by validateData(),
         // which is constrained by the Execute constraint
         if ($form->hasAttribute('validation_constraint')) {
             $violations = $this->validator->validateValue($form->getData(), $form->getAttribute('validation_constraint'), self::getFormValidationGroups($form));
             if ($violations) {
                 foreach ($violations as $violation) {
                     $propertyPath = new PropertyPath($violation->getPropertyPath());
                     $template = $violation->getMessageTemplate();
                     $parameters = $violation->getMessageParameters();
                     $error = new FormError($template, $parameters);
                     $child = $form;
                     foreach ($propertyPath->getElements() as $element) {
                         $children = $child->getChildren();
                         if (!isset($children[$element])) {
                             if ($form->isSynchronized()) {
                                 $form->addError($error);
                             }
                             break;
                         }
                         $child = $children[$element];
                     }
                     if ($child->isSynchronized()) {
                         $child->addError($error);
                     }
                 }
             }
         } elseif (count($violations = $this->validator->validate($form))) {
             foreach ($violations as $violation) {
                 $propertyPath = $violation->getPropertyPath();
                 $template = $violation->getMessageTemplate();
                 $parameters = $violation->getMessageParameters();
                 $error = new FormError($template, $parameters);
                 foreach ($mapping as $mappedPath => $child) {
                     if (preg_match($mappedPath, $propertyPath)) {
                         if ($child->isSynchronized()) {
                             $child->addError($error);
                         }
                         continue 2;
                     }
                 }
                 if ($form->isSynchronized()) {
                     $form->addError($error);
                 }
             }
         }
     }
 }
 public function transform($entity)
 {
     if (null === $entity) {
         return null;
     }
     if (!$this->unitOfWork->isInIdentityMap($entity)) {
         throw new FormException('Entities passed to the choice field must be managed');
     }
     if ($this->property) {
         $propertyPath = new PropertyPath($this->property);
         return $propertyPath->getValue($entity);
     }
     return current($this->unitOfWork->getEntityIdentifier($entity));
 }
Example #3
0
 /**
  * Initializes the choices and returns them
  *
  * The choices are generated from the models. If the models have a
  * composite identifier, the choices are indexed using ascending integers.
  * Otherwise the identifiers are used as indices.
  *
  * If the models were passed in the "choices" option, this method
  * does not have any significant overhead. Otherwise, if a query object
  * was passed in the "query" option, this query is now used and executed.
  * In the last case, all models for the underlying class are fetched.
  *
  * If the option "property" was passed, the property path in that option
  * is used as option values. Otherwise this method tries to convert
  * objects to strings using __toString().
  *
  * @return array  An array of choices
  */
 protected function load()
 {
     parent::load();
     if ($this->choices) {
         $models = $this->choices;
     } else {
         $models = $this->query->find();
     }
     $this->choices = array();
     $this->models = array();
     foreach ($models as $key => $model) {
         if ($this->propertyPath) {
             // If the property option was given, use it
             $value = $this->propertyPath->getValue($model);
         } else {
             // Otherwise expect a __toString() method in the model
             $value = (string) $model;
         }
         if (count($this->identifier) > 1) {
             // When the identifier consists of multiple field, use
             // naturally ordered keys to refer to the choices
             $this->choices[$key] = $value;
             $this->models[$key] = $model;
         } else {
             // When the identifier is a single field, index choices by
             // model ID for performance reasons
             $id = current($this->getIdentifierValues($model));
             $this->choices[$id] = $value;
             $this->models[$id] = $model;
         }
     }
 }
Example #4
0
 /**
  * Converts entities into choices with support for groups.
  *
  * The choices are generated from the entities. If the entities have a
  * composite identifier, the choices are indexed using ascending integers.
  * Otherwise the identifiers are used as indices.
  *
  * If the option "property" was passed, the property path in that option
  * is used as option values. Otherwise this method tries to convert
  * objects to strings using __toString().
  *
  * @param array  $entities An array of entities
  * @param string $group    A group name
  */
 private function loadEntities($entities, $group = null)
 {
     foreach ($entities as $key => $entity) {
         if (is_array($entity)) {
             // Entities are in named groups
             $this->loadEntities($entity, $key);
             continue;
         }
         if ($this->propertyPath) {
             // If the property option was given, use it
             $value = $this->propertyPath->getValue($entity);
         } else {
             $value = (string) $entity;
         }
         if (count($this->identifier) > 1) {
             // When the identifier consists of multiple field, use
             // naturally ordered keys to refer to the choices
             $id = $key;
         } else {
             // When the identifier is a single field, index choices by
             // entity ID for performance reasons
             $id = current($this->getIdentifierValues($entity));
         }
         if (null === $group) {
             // Flat list of choices
             $this->choices[$id] = $value;
         } else {
             // Nested choices
             $this->choices[$group][$id] = $value;
         }
         $this->entities[$id] = $entity;
     }
 }
 public function validate($value, Constraint $constraint)
 {
     // Aplica la ruta de la propiedad si es especificada
     if ($constraint->propertyPath) {
         $propertyPath = new PropertyPath($constraint->propertyPath);
         $value = $propertyPath->getValue($value);
     }
     // Chequea que el valor no esta en el array
     foreach ($this->collectionValues as $aValue) {
         if (spl_object_hash($value) == spl_object_hash($aValue)) {
             $this->context->addViolation($constraint->message, array());
         }
     }
     //if(in_array($value, $this->collectionValues))
     //  $this->context->addViolation($constraint->message, array());
     // Agrega el valor en el array para los siguientes items de la validacion
     $this->collectionValues[] = $value;
 }
Example #6
0
 /**
  * Creates a new violation path from a string.
  *
  * @param string $violationPath The property path of a {@link ConstraintViolation}
  *                              object.
  */
 public function __construct($violationPath)
 {
     $path = new PropertyPath($violationPath);
     $elements = $path->getElements();
     $positions = $path->getPositions();
     $data = false;
     for ($i = 0, $l = count($elements); $i < $l; ++$i) {
         if (!$data) {
             // The element "data" has not yet been passed
             if ('children' === $elements[$i] && $path->isProperty($i)) {
                 // Skip element "children"
                 ++$i;
                 // Next element must exist and must be an index
                 // Otherwise consider this the end of the path
                 if ($i >= $l || !$path->isIndex($i)) {
                     break;
                 }
                 $this->elements[] = $elements[$i];
                 $this->positions[] = $positions[$i];
                 $this->isIndex[] = true;
                 $this->mapsForm[] = true;
             } elseif ('data' === $elements[$i] && $path->isProperty($i)) {
                 // Skip element "data"
                 ++$i;
                 // End of path
                 if ($i >= $l) {
                     break;
                 }
                 $this->elements[] = $elements[$i];
                 $this->positions[] = $positions[$i];
                 $this->isIndex[] = $path->isIndex($i);
                 $this->mapsForm[] = false;
                 $data = true;
             } else {
                 // Neither "children" nor "data" property found
                 // Consider this the end of the path
                 break;
             }
         } else {
             // Already after the "data" element
             // Pick everything as is
             $this->elements[] = $elements[$i];
             $this->positions[] = $positions[$i];
             $this->isIndex[] = $path->isIndex($i);
             $this->mapsForm[] = false;
         }
     }
     $this->length = count($this->elements);
     $this->pathAsString = $violationPath;
     $this->resizeString();
 }
Example #7
0
 private function extractLabels($choices, array &$labels)
 {
     foreach ($choices as $i => $choice) {
         if (is_array($choice) || $choice instanceof \Traversable) {
             $labels[$i] = array();
             $this->extractLabels($choice, $labels[$i]);
         } elseif ($this->labelPath) {
             $labels[$i] = $this->labelPath->getValue($choice);
         } elseif (method_exists($choice, '__toString')) {
             $labels[$i] = (string) $choice;
         } else {
             throw new StringCastException('A "__toString()" method was not found on the objects of type "' . get_class($choice) . '" passed to the choice field. To read a custom getter instead, set the argument $labelPath to the desired property path.');
         }
     }
 }
 /**
  * Renders a pagerfanta.
  *
  * @param PagerfantaInterface $pagerfanta The pagerfanta.
  * @param string              $viewName   The view name.
  * @param array               $options    An array of options (optional).
  *
  * @return string The pagerfanta rendered.
  */
 public function renderPagerfanta(PagerfantaInterface $pagerfanta, $viewName = 'default', array $options = array())
 {
     $options = array_replace(array('routeName' => null, 'routeParams' => array(), 'pageParameter' => 'page'), $options);
     $router = $this->container->get('router');
     $request = $this->container->get('request');
     if (null === $options['routeName']) {
         $options['routeName'] = $request->attributes->get('_route');
         $options['routeParams'] = $request->query->all();
         if ($options['routeName'] === '_internal') {
             throw new \Exception('PagerfantaBundle can not guess the route when used in a subrequest');
         }
         foreach ($router->getRouteCollection()->get($options['routeName'])->compile()->getVariables() as $variable) {
             $options['routeParams'][$variable] = $request->attributes->get($variable);
         }
     }
     $routeName = $options['routeName'];
     $routeParams = $options['routeParams'];
     $pagePropertyPath = new PropertyPath($options['pageParameter']);
     $routeGenerator = function ($page) use($router, $routeName, $routeParams, $pagePropertyPath) {
         $pagePropertyPath->setValue($routeParams, $page);
         return $router->generate($routeName, $routeParams);
     };
     return $this->container->get('white_october_pagerfanta.view_factory')->get($viewName)->render($pagerfanta, $routeGenerator, $options);
 }
 /**
  * @param \Symfony\Component\HttpFoundation\Request $request
  * @return \Symfony\Component\HttpFoundation\Response
  */
 public function setObjectFieldValueAction(Request $request)
 {
     $field = $request->get('field');
     $code = $request->get('code');
     $objectId = $request->get('objectId');
     $value = $request->get('value');
     $context = $request->get('context');
     $admin = $this->pool->getInstance($code);
     // alter should be done by using a post method
     if ($request->getMethod() != 'POST') {
         return new Response(json_encode(array('status' => 'KO', 'message' => 'Expected a POST Request')), 200, array('Content-Type' => 'application/json'));
     }
     $object = $admin->getObject($objectId);
     if (!$object) {
         return new Response(json_encode(array('status' => 'KO', 'message' => 'Object does not exist')), 200, array('Content-Type' => 'application/json'));
     }
     // check user permission
     if (false === $admin->isGranted('EDIT', $object)) {
         return new Response(json_encode(array('status' => 'KO', 'message' => 'Invalid permissions')), 200, array('Content-Type' => 'application/json'));
     }
     if ($context == 'list') {
         $fieldDescription = $admin->getListFieldDescription($field);
     } else {
         return new Response(json_encode(array('status' => 'KO', 'message' => 'Invalid context')), 200, array('Content-Type' => 'application/json'));
     }
     if (!$fieldDescription) {
         return new Response(json_encode(array('status' => 'KO', 'message' => 'The field does not exist')), 200, array('Content-Type' => 'application/json'));
     }
     if (!$fieldDescription->getOption('editable')) {
         return new Response(json_encode(array('status' => 'KO', 'message' => 'The field cannot be edit, editable option must be set to true')), 200, array('Content-Type' => 'application/json'));
     }
     // TODO : call the validator component ...
     $propertyPath = new PropertyPath($field);
     $propertyPath->setValue($object, $value);
     $admin->update($object);
     // render the widget
     // todo : fix this, the twig environment variable is not set inside the extension ...
     $extension = $this->twig->getExtension('sonata_admin');
     $extension->initRuntime($this->twig);
     $content = $extension->renderListElement($object, $fieldDescription);
     return new Response(json_encode(array('status' => 'OK', 'content' => $content)), 200, array('Content-Type' => 'application/json'));
 }
Example #10
0
 /**
  * @param FormInterface $root
  * @param string        $propertyPath
  */
 public function __construct(FormInterface $root, $propertyPath)
 {
     parent::__construct($propertyPath);
     $this->root = $root;
 }
 public function testGetParent_noParent()
 {
     $propertyPath = new PropertyPath('path');
     $this->assertNull($propertyPath->getParent());
 }
Example #12
0
 private function groupEntities($entities, $groupBy)
 {
     $grouped = array();
     foreach ($entities as $entity) {
         // Get group name from property path
         try {
             $path = new PropertyPath($groupBy);
             $group = (string) $path->getValue($entity);
         } catch (UnexpectedTypeException $e) {
             // PropertyPath cannot traverse entity
             $group = null;
         }
         if (empty($group)) {
             $grouped[] = $entity;
         } else {
             $grouped[$group][] = $entity;
         }
     }
     return $grouped;
 }
 public function onBindNormData(FilterDataEvent $event)
 {
     $originalData = $event->getForm()->getNormData();
     // If we are not allowed to change anything, return immediately
     if (!$this->allowAdd && !$this->allowDelete) {
         // Don't set to the snapshot as then we are switching from the
         // original object to its copy, which might break things
         $event->setData($originalData);
         return;
     }
     $form = $event->getForm();
     $data = $event->getData();
     $childPropertyPath = null;
     $parentData = null;
     $addMethod = null;
     $removeMethod = null;
     $propertyPath = null;
     $plural = null;
     if ($form->hasParent() && $form->getAttribute('property_path')) {
         $propertyPath = new PropertyPath($form->getAttribute('property_path'));
         $childPropertyPath = $propertyPath;
         $parentData = $form->getParent()->getClientData();
         $lastElement = $propertyPath->getElement($propertyPath->getLength() - 1);
         // If the property path contains more than one element, the parent
         // data is the object at the parent property path
         if ($propertyPath->getLength() > 1) {
             $parentData = $propertyPath->getParent()->getValue($parentData);
             // Property path relative to $parentData
             $childPropertyPath = new PropertyPath($lastElement);
         }
         // The plural form is the last element of the property path
         $plural = ucfirst($lastElement);
     }
     if (null === $data) {
         $data = array();
     }
     if (!is_array($data) && !($data instanceof \Traversable && $data instanceof \ArrayAccess)) {
         throw new UnexpectedTypeException($data, 'array or (\\Traversable and \\ArrayAccess)');
     }
     if (null !== $originalData && !is_array($originalData) && !($originalData instanceof \Traversable && $originalData instanceof \ArrayAccess)) {
         throw new UnexpectedTypeException($originalData, 'array or (\\Traversable and \\ArrayAccess)');
     }
     // Check if the parent has matching methods to add/remove items
     if ($this->mergeStrategy & self::MERGE_INTO_PARENT && is_object($parentData)) {
         $reflClass = new \ReflectionClass($parentData);
         $addMethodNeeded = $this->allowAdd && !$this->addMethod;
         $removeMethodNeeded = $this->allowDelete && !$this->removeMethod;
         // Any of the two methods is required, but not yet known
         if ($addMethodNeeded || $removeMethodNeeded) {
             $singulars = (array) FormUtil::singularify($plural);
             foreach ($singulars as $singular) {
                 // Try to find adder, but don't override preconfigured one
                 if ($addMethodNeeded) {
                     $addMethod = 'add' . $singular;
                     // False alert
                     if (!$this->isAccessible($reflClass, $addMethod, 1)) {
                         $addMethod = null;
                     }
                 }
                 // Try to find remover, but don't override preconfigured one
                 if ($removeMethodNeeded) {
                     $removeMethod = 'remove' . $singular;
                     // False alert
                     if (!$this->isAccessible($reflClass, $removeMethod, 1)) {
                         $removeMethod = null;
                     }
                 }
                 // Found all that we need. Abort search.
                 if ((!$addMethodNeeded || $addMethod) && (!$removeMethodNeeded || $removeMethod)) {
                     break;
                 }
                 // False alert
                 $addMethod = null;
                 $removeMethod = null;
             }
         }
         // Set preconfigured adder
         if ($this->allowAdd && $this->addMethod) {
             $addMethod = $this->addMethod;
             if (!$this->isAccessible($reflClass, $addMethod, 1)) {
                 throw new FormException(sprintf('The public method "%s" could not be found on class %s', $addMethod, $reflClass->getName()));
             }
         }
         // Set preconfigured remover
         if ($this->allowDelete && $this->removeMethod) {
             $removeMethod = $this->removeMethod;
             if (!$this->isAccessible($reflClass, $removeMethod, 1)) {
                 throw new FormException(sprintf('The public method "%s" could not be found on class %s', $removeMethod, $reflClass->getName()));
             }
         }
     }
     // Calculate delta between $data and the snapshot created in PRE_BIND
     $itemsToDelete = array();
     $itemsToAdd = is_object($data) ? clone $data : $data;
     if ($this->dataSnapshot) {
         foreach ($this->dataSnapshot as $originalItem) {
             foreach ($data as $key => $item) {
                 if ($item === $originalItem) {
                     // Item found, next original item
                     unset($itemsToAdd[$key]);
                     continue 2;
                 }
             }
             // Item not found, remember for deletion
             foreach ($originalData as $key => $item) {
                 if ($item === $originalItem) {
                     $itemsToDelete[$key] = $item;
                     continue 2;
                 }
             }
         }
     }
     if ($addMethod || $removeMethod) {
         // If methods to add and to remove exist, call them now, if allowed
         if ($removeMethod) {
             foreach ($itemsToDelete as $item) {
                 $parentData->{$removeMethod}($item);
             }
         }
         if ($addMethod) {
             foreach ($itemsToAdd as $item) {
                 $parentData->{$addMethod}($item);
             }
         }
         $event->setData($childPropertyPath->getValue($parentData));
     } elseif ($this->mergeStrategy & self::MERGE_NORMAL) {
         if (!$originalData) {
             // No original data was set. Set it if allowed
             if ($this->allowAdd) {
                 $originalData = $data;
             }
         } else {
             // Original data is an array-like structure
             // Add and remove items in the original variable
             if ($this->allowDelete) {
                 foreach ($itemsToDelete as $key => $item) {
                     unset($originalData[$key]);
                 }
             }
             if ($this->allowAdd) {
                 foreach ($itemsToAdd as $key => $item) {
                     if (!isset($originalData[$key])) {
                         $originalData[$key] = $item;
                     } else {
                         $originalData[] = $item;
                     }
                 }
             }
         }
         $event->setData($originalData);
     }
 }
Example #14
0
 protected function renderChoiceWidgetOptions(FormView $view, $blockName, array $variables = array())
 {
     $options = array();
     $valuePropertyPath = new PropertyPath('value');
     $labelPropertyPath = new PropertyPath('label');
     foreach ($variables['options'] as $groupLabel => $choice) {
         if (is_array($choice) || $choice instanceof \Traversable) {
             $options = array_merge($options, $this->renderChoiceWidgetOptions($view, $blockName, array_merge($variables, array('options' => $choice))));
         } else {
             $option = new FormRepresentations\Option();
             $option->attributes['value'] = $valuePropertyPath->getValue($choice);
             if ($this->isSelectedChoice($choice, $variables['value'])) {
                 $option['attributes']['selected'] = 'selected';
             }
             $option->value = $labelPropertyPath->getValue($choice);
             $options[] = $option;
         }
     }
     return $options;
 }
Example #15
0
 protected function getValue($object, $field)
 {
     $path = new PropertyPath($field);
     return $path->getValue($object);
 }
Example #16
0
 public function normalizeEntity($entity, $doNotExpandRelationsAndCollections = false)
 {
     // Make sure that the used is authorized to see this resource
     $canSee = $this->getConfigurationEntity()['can_see'];
     if (false === $canSee($this->securityContext, $entity)) {
         throw new AccessDeniedException();
     }
     $entityRepresentationClass = $this->getConfigurationEntity()['representation_class'];
     $entityRepresentation = new $entityRepresentationClass();
     $entityRepresentation->addLink($this->atomLinkFactory->create('self', $this->getUrlGenerator()->generateEntityUrl($entity)));
     $getEntityValue = function ($value) use($entity) {
         if ($value instanceof \Closure) {
             return $value($entity);
         }
         $propertyPath = new PropertyPath($value);
         return $propertyPath->getValue($entity);
     };
     // Properties
     $normalizeAttributes = $this->getConfigurationEntity()['normalize_attributes'];
     foreach ($normalizeAttributes as $key => $value) {
         $entityRepresentation->setAttribute($key, $getEntityValue($value));
     }
     // Elements
     $normalizeElements = $this->getConfigurationEntity()['normalize_elements'];
     foreach ($normalizeElements as $key => $value) {
         $entityRepresentation->setElement($key, $getEntityValue($value));
     }
     // Entity collections
     foreach ($this->getConfigurationEntityCollections() as $entityCollectionRel => $configurationEntityCollection) {
         if (isset($configurationEntityCollection['can_see']) && !$configurationEntityCollection['can_see']($this->securityContext, $entity)) {
             continue;
         }
         if ($doNotExpandRelationsAndCollections || !in_array($entityCollectionRel, $this->getConfigurationEntity()['expanded_collections'])) {
             $entityRepresentation->addLink($this->atomLinkFactory->create($entityCollectionRel, $this->getUrlGenerator()->generateEntityCollectionUrl($entity, $entityCollectionRel)));
         } else {
             $entityRelationSearchFormDescription = $this->createEntityCollectionSearchFormDescription($entity, $entityCollectionRel);
             $entityRelationPager = $this->getEntityCollectionPager($entity, $entityRelationSearchFormDescription->getData(), $entityCollectionRel);
             $entityRelationRepresentation = $this->normalizeEntityCollection($entity, $entityCollectionRel, $entityRelationPager, $entityRelationSearchFormDescription);
             $entityRelationRepresentation->rel = $this->atomLinkFactory->getRel($entityCollectionRel);
             $entityRepresentation->addCollection($entityRelationRepresentation);
         }
     }
     // Entity relations
     foreach ($this->getConfigurationEntityRelations() as $entityRelationRel => $entityRelationConfiguration) {
         $entityRelation = $this->getEntityRelation($entity, $entityRelationRel);
         if (null === $entityRelation) {
             continue;
         }
         $entityRelationClassName = ClassUtils::getRealClass(get_class($entityRelation));
         $entityRelationResource = $this->container->get($entityRelationConfiguration['resources'][$entityRelationClassName]);
         $canSeeEntityRelation = $entityRelationResource->getConfigurationEntity()['can_see'];
         if (!$canSeeEntityRelation($this->securityContext, $entityRelation) || $doNotExpandRelationsAndCollections || !in_array($entityRelationRel, $this->getConfigurationEntity()['expanded_relations'])) {
             $entityRepresentation->addLink($this->atomLinkFactory->create($entityRelationRel, $entityRelationResource->getUrlGenerator()->generateEntityUrl($entityRelation)));
         } else {
             $entityRelationRepresentation = $entityRelationResource->normalizeEntity($entityRelation, true);
             $entityRelationRepresentation->rel = $this->atomLinkFactory->getRel($entityRelationRel);
             $entityRepresentation->addRelation($entityRelationRepresentation);
         }
     }
     return $entityRepresentation;
 }
Example #17
0
 /**
  * Build the form FieldDescription collection
  *
  * @return void
  */
 protected function buildForm()
 {
     if ($this->form) {
         return;
     }
     // append parent object if any
     // todo : clean the way the Admin class can retrieve set the object
     if ($this->isChild() && $this->getParentAssociationMapping()) {
         $parent = $this->getParent()->getObject($this->request->get($this->getParent()->getIdParameter()));
         $propertyPath = new PropertyPath($this->getParentAssociationMapping());
         $object = $this->getSubject();
         $propertyPath->setValue($object, $parent);
     }
     $this->form = $this->getFormBuilder()->getForm();
 }
Example #18
0
    /**
     * @dataProvider provideCustomDataErrorTests
     */
    public function testCustomDataErrorMapping($target, $mapFrom, $mapTo, $childName, $childPath, $grandChildName, $grandChildPath, $violationPath)
    {
        $violation = $this->getConstraintViolation($violationPath);
        $parent = $this->getForm('parent', null, null, array($mapFrom => $mapTo));
        $child = $this->getForm($childName, $childPath);
        $grandChild = $this->getForm($grandChildName, $grandChildPath);

        $parent->add($child);
        $child->add($grandChild);

        // Add a field mapped to the first element of $mapFrom
        // to try to distract the algorithm
        // Only add it if we expect the error to come up on a different
        // level than LEVEL_0, because in this case the error would
        // (correctly) be mapped to the distraction field
        if ($target !== self::LEVEL_0) {
            $mapFromPath = new PropertyPath($mapFrom);
            $mapFromPrefix = $mapFromPath->isIndex(0)
                ? '['.$mapFromPath->getElement(0).']'
                : $mapFromPath->getElement(0);
            $distraction = $this->getForm('distraction', $mapFromPrefix);

            $parent->add($distraction);
        }

        $this->mapper->mapViolation($violation, $parent);

        if ($target !== self::LEVEL_0) {
            $this->assertFalse($distraction->hasErrors(), 'distraction should not have an error, but has one');
        }

        if (self::LEVEL_0 === $target) {
            $this->assertEquals(array($this->getFormError()), $parent->getErrors(), $parent->getName() . ' should have an error, but has none');
            $this->assertFalse($child->hasErrors(), $childName . ' should not have an error, but has one');
            $this->assertFalse($grandChild->hasErrors(), $grandChildName . ' should not have an error, but has one');
        } elseif (self::LEVEL_1 === $target) {
            $this->assertFalse($parent->hasErrors(), $parent->getName() . ' should not have an error, but has one');
            $this->assertEquals(array($this->getFormError()), $child->getErrors(), $childName . ' should have an error, but has none');
            $this->assertFalse($grandChild->hasErrors(), $grandChildName . ' should not have an error, but has one');
        } else {
            $this->assertFalse($parent->hasErrors(), $parent->getName() . ' should not have an error, but has one');
            $this->assertFalse($child->hasErrors(), $childName . ' should not have an error, but has one');
            $this->assertEquals(array($this->getFormError()), $grandChild->getErrors(), $grandChildName. ' should have an error, but has none');
        }
    }
 /**
  * @expectedException \OutOfBoundsException
  */
 public function testIsIndexDoesNotAcceptNegativeIndices()
 {
     $propertyPath = new PropertyPath('grandpa.parent[child]');
     $propertyPath->isIndex(-1);
 }
 /**
  * @expectedException Symfony\Component\Form\Exception\InvalidPropertyException
  */
 public function testMapFormToDataFailsIfOnlyRemoverFound()
 {
     $car = $this->getMock(__CLASS__ . '_CarOnlyRemover');
     $axesBefore = $this->getCollection(array(1 => 'second', 3 => 'fourth'));
     $axesAfter = $this->getCollection(array(0 => 'first', 1 => 'second', 2 => 'third'));
     $path = new PropertyPath('axes');
     $car->expects($this->any())->method('getAxes')->will($this->returnValue($axesBefore));
     $path->setValue($car, $axesAfter);
 }
Example #21
0
 public function testToString()
 {
     $path = new PropertyPath('reference.traversable[index].property');
     $this->assertEquals('reference.traversable[index].property', $path->__toString());
 }