1<?php 2 3declare(strict_types=1); 4 5namespace JMS\Serializer\Handler; 6 7use JMS\Serializer\GraphNavigatorInterface; 8use JMS\Serializer\JsonSerializationVisitor; 9use JMS\Serializer\SerializationContext; 10use JMS\Serializer\XmlSerializationVisitor; 11use Symfony\Component\Validator\ConstraintViolation; 12use Symfony\Component\Validator\ConstraintViolationList; 13 14final class ConstraintViolationHandler implements SubscribingHandlerInterface 15{ 16 /** 17 * {@inheritdoc} 18 */ 19 public static function getSubscribingMethods() 20 { 21 $methods = []; 22 $formats = ['xml', 'json']; 23 $types = ['Symfony\Component\Validator\ConstraintViolationList' => 'serializeList', 'Symfony\Component\Validator\ConstraintViolation' => 'serializeViolation']; 24 25 foreach ($types as $type => $method) { 26 foreach ($formats as $format) { 27 $methods[] = [ 28 'direction' => GraphNavigatorInterface::DIRECTION_SERIALIZATION, 29 'type' => $type, 30 'format' => $format, 31 'method' => $method . 'To' . $format, 32 ]; 33 } 34 } 35 36 return $methods; 37 } 38 39 public function serializeListToXml(XmlSerializationVisitor $visitor, ConstraintViolationList $list, array $type): void 40 { 41 $currentNode = $visitor->getCurrentNode(); 42 if (!$currentNode) { 43 $visitor->createRoot(); 44 } 45 46 foreach ($list as $violation) { 47 $this->serializeViolationToXml($visitor, $violation); 48 } 49 } 50 51 /** 52 * @return array|\ArrayObject 53 */ 54 public function serializeListToJson(JsonSerializationVisitor $visitor, ConstraintViolationList $list, array $type, SerializationContext $context) 55 { 56 return $visitor->visitArray(iterator_to_array($list), $type); 57 } 58 59 public function serializeViolationToXml(XmlSerializationVisitor $visitor, ConstraintViolation $violation, ?array $type = null): void 60 { 61 $violationNode = $visitor->getDocument()->createElement('violation'); 62 63 $parent = $visitor->getCurrentNode(); 64 if (!$parent) { 65 $visitor->setCurrentAndRootNode($violationNode); 66 } else { 67 $parent->appendChild($violationNode); 68 } 69 70 $violationNode->setAttribute('property_path', $violation->getPropertyPath()); 71 $violationNode->appendChild($messageNode = $visitor->getDocument()->createElement('message')); 72 73 $messageNode->appendChild($visitor->getDocument()->createCDATASection($violation->getMessage())); 74 } 75 76 public function serializeViolationToJson(JsonSerializationVisitor $visitor, ConstraintViolation $violation, ?array $type = null): array 77 { 78 return [ 79 'property_path' => $violation->getPropertyPath(), 80 'message' => $violation->getMessage(), 81 ]; 82 } 83} 84