protected function getConstraintViolation(ConstraintViolation $constraintViolation, array &$messages) { $path = new PropertyPath($constraintViolation->getPropertyPath()); $elements = $path->getElements(); $elements[] = $constraintViolation->getConstraint()->validatedBy(); $this->propertyAccessor->setValue($messages, $this->buildPath($elements), $constraintViolation->getMessage()); }
/** * 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(); $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; } // All the following index items (regardless if .children is // explicitly used) are children and grand-children for (; $i < $l && $path->isIndex($i); ++$i) { $this->elements[] = $elements[$i]; $this->isIndex[] = true; $this->mapsForm[] = true; } // Rewind the pointer as the last element above didn't match // (even if the pointer was moved forward) --$i; } elseif ('data' === $elements[$i] && $path->isProperty($i)) { // Skip element "data" ++$i; // End of path if ($i >= $l) { break; } $this->elements[] = $elements[$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->isIndex[] = $path->isIndex($i); $this->mapsForm[] = false; } } $this->length = count($this->elements); $this->buildString(); }
/** * Enables object validation. * * @param Mapping $mapping The mapping object * * @return Mapping */ public function enableObjectValidation(Mapping $mapping) { $emitter = $mapping->getEmitter(); $emitter->on(Events::APPLIED, function (Data $data) { $vios = $this->validator->validate($data->getResult()); foreach ($vios as $vio) { $propertyPath = new PropertyPath($vio->getPropertyPath()); $data->addError(new Error($vio->getMessage(), $propertyPath->getElements())); } }); return $mapping; }
/** * 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(); $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->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->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->isIndex[] = $path->isIndex($i); $this->mapsForm[] = false; } } $this->length = count($this->elements); $this->buildString(); }
/** * @param string $rootClass * @param string|PropertyPathInterface $propertyPath * @return array|null */ public function guessMetadataAndField($rootClass, $propertyPath) { if (!$propertyPath instanceof PropertyPathInterface) { $propertyPath = new PropertyPath($propertyPath); } $pathElements = array_values($propertyPath->getElements()); $elementsCount = count($pathElements); if ($elementsCount < 2) { return null; } $metadata = $this->getMetadataForClass($rootClass); $field = null; for ($i = 1; $i < $elementsCount; $i++) { $field = $pathElements[$i]; $hasAssociation = $metadata->hasAssociation($field) || $this->entityConfigProvider->hasConfig($rootClass, $field); if ($hasAssociation && $i < $elementsCount - 1) { $className = $metadata->hasAssociation($field) ? $metadata->getAssociationTargetClass($field) : $this->entityConfigProvider->getConfig($rootClass, $field)->getId()->getClassName(); $metadata = $this->getMetadataForClass($className); } elseif (!$hasAssociation && !$metadata->hasField($field)) { return null; } } return array('metadata' => $metadata, 'field' => $field); }
/** * @param Request $request * * @return 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); $admin->setRequest($request); // alter should be done by using a post method if (!$request->isXmlHttpRequest()) { return new JsonResponse(array('status' => 'KO', 'message' => 'Expected a XmlHttpRequest request header')); } if ($request->getMethod() != 'POST') { return new JsonResponse(array('status' => 'KO', 'message' => 'Expected a POST Request')); } $rootObject = $object = $admin->getObject($objectId); if (!$object) { return new JsonResponse(array('status' => 'KO', 'message' => 'Object does not exist')); } // check user permission if (false === $admin->isGranted('EDIT', $object)) { return new JsonResponse(array('status' => 'KO', 'message' => 'Invalid permissions')); } if ($context == 'list') { $fieldDescription = $admin->getListFieldDescription($field); } else { return new JsonResponse(array('status' => 'KO', 'message' => 'Invalid context')); } if (!$fieldDescription) { return new JsonResponse(array('status' => 'KO', 'message' => 'The field does not exist')); } if (!$fieldDescription->getOption('editable')) { return new JsonResponse(array('status' => 'KO', 'message' => 'The field cannot be edit, editable option must be set to true')); } $propertyPath = new PropertyPath($field); // If property path has more than 1 element, take the last object in order to validate it if ($propertyPath->getLength() > 1) { $object = $this->pool->getPropertyAccessor()->getValue($object, $propertyPath->getParent()); $elements = $propertyPath->getElements(); $field = end($elements); $propertyPath = new PropertyPath($field); } // Handle date type has setter expect a DateTime object if ('' !== $value && $fieldDescription->getType() == 'date') { $value = new \DateTime($value); } $this->pool->getPropertyAccessor()->setValue($object, $propertyPath, '' !== $value ? $value : null); $violations = $this->validator->validate($object); if (count($violations)) { $messages = array(); foreach ($violations as $violation) { $messages[] = $violation->getMessage(); } return new JsonResponse(array('status' => 'KO', 'message' => implode("\n", $messages))); } $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($rootObject, $fieldDescription); return new JsonResponse(array('status' => 'OK', 'content' => $content)); }
/** * @param $path * @return string */ private function transformPropertyPath($path) { $path = new PropertyPath($path); return '/' . implode('/', $path->getElements()); }
/** * @param string $path * @return string */ private function mapPropertyPath($path) { $propertyPath = new PropertyPath($path); $pathElements = $propertyPath->getElements(); return '/' . implode('/', $pathElements); }