vendor/symfony/validator/Mapping/Loader/XmlFileLoader.php line 215

Open in your IDE?
  1. <?php
  2. /*
  3.  * This file is part of the Symfony package.
  4.  *
  5.  * (c) Fabien Potencier <fabien@symfony.com>
  6.  *
  7.  * For the full copyright and license information, please view the LICENSE
  8.  * file that was distributed with this source code.
  9.  */
  10. namespace Symfony\Component\Validator\Mapping\Loader;
  11. use Symfony\Component\Config\Util\XmlUtils;
  12. use Symfony\Component\Validator\Constraint;
  13. use Symfony\Component\Validator\Exception\MappingException;
  14. use Symfony\Component\Validator\Mapping\ClassMetadata;
  15. /**
  16.  * Loads validation metadata from an XML file.
  17.  *
  18.  * @author Bernhard Schussek <bschussek@gmail.com>
  19.  */
  20. class XmlFileLoader extends FileLoader
  21. {
  22.     /**
  23.      * The XML nodes of the mapping file.
  24.      *
  25.      * @var \SimpleXMLElement[]|null
  26.      */
  27.     protected $classes;
  28.     /**
  29.      * {@inheritdoc}
  30.      */
  31.     public function loadClassMetadata(ClassMetadata $metadata)
  32.     {
  33.         if (null === $this->classes) {
  34.             $this->loadClassesFromXml();
  35.         }
  36.         if (isset($this->classes[$metadata->getClassName()])) {
  37.             $classDescription $this->classes[$metadata->getClassName()];
  38.             $this->loadClassMetadataFromXml($metadata$classDescription);
  39.             return true;
  40.         }
  41.         return false;
  42.     }
  43.     /**
  44.      * Return the names of the classes mapped in this file.
  45.      *
  46.      * @return string[]
  47.      */
  48.     public function getMappedClasses()
  49.     {
  50.         if (null === $this->classes) {
  51.             $this->loadClassesFromXml();
  52.         }
  53.         return array_keys($this->classes);
  54.     }
  55.     /**
  56.      * Parses a collection of "constraint" XML nodes.
  57.      *
  58.      * @param \SimpleXMLElement $nodes The XML nodes
  59.      *
  60.      * @return Constraint[]
  61.      */
  62.     protected function parseConstraints(\SimpleXMLElement $nodes)
  63.     {
  64.         $constraints = [];
  65.         foreach ($nodes as $node) {
  66.             if (\count($node) > 0) {
  67.                 if (\count($node->value) > 0) {
  68.                     $options $this->parseValues($node->value);
  69.                 } elseif (\count($node->constraint) > 0) {
  70.                     $options $this->parseConstraints($node->constraint);
  71.                 } elseif (\count($node->option) > 0) {
  72.                     $options $this->parseOptions($node->option);
  73.                 } else {
  74.                     $options = [];
  75.                 }
  76.             } elseif ('' !== (string) $node) {
  77.                 $options XmlUtils::phpize(trim($node));
  78.             } else {
  79.                 $options null;
  80.             }
  81.             $constraints[] = $this->newConstraint((string) $node['name'], $options);
  82.         }
  83.         return $constraints;
  84.     }
  85.     /**
  86.      * Parses a collection of "value" XML nodes.
  87.      *
  88.      * @param \SimpleXMLElement $nodes The XML nodes
  89.      *
  90.      * @return array
  91.      */
  92.     protected function parseValues(\SimpleXMLElement $nodes)
  93.     {
  94.         $values = [];
  95.         foreach ($nodes as $node) {
  96.             if (\count($node) > 0) {
  97.                 if (\count($node->value) > 0) {
  98.                     $value $this->parseValues($node->value);
  99.                 } elseif (\count($node->constraint) > 0) {
  100.                     $value $this->parseConstraints($node->constraint);
  101.                 } else {
  102.                     $value = [];
  103.                 }
  104.             } else {
  105.                 $value trim($node);
  106.             }
  107.             if (isset($node['key'])) {
  108.                 $values[(string) $node['key']] = $value;
  109.             } else {
  110.                 $values[] = $value;
  111.             }
  112.         }
  113.         return $values;
  114.     }
  115.     /**
  116.      * Parses a collection of "option" XML nodes.
  117.      *
  118.      * @param \SimpleXMLElement $nodes The XML nodes
  119.      *
  120.      * @return array
  121.      */
  122.     protected function parseOptions(\SimpleXMLElement $nodes)
  123.     {
  124.         $options = [];
  125.         foreach ($nodes as $node) {
  126.             if (\count($node) > 0) {
  127.                 if (\count($node->value) > 0) {
  128.                     $value $this->parseValues($node->value);
  129.                 } elseif (\count($node->constraint) > 0) {
  130.                     $value $this->parseConstraints($node->constraint);
  131.                 } else {
  132.                     $value = [];
  133.                 }
  134.             } else {
  135.                 $value XmlUtils::phpize($node);
  136.                 if (\is_string($value)) {
  137.                     $value trim($value);
  138.                 }
  139.             }
  140.             $options[(string) $node['name']] = $value;
  141.         }
  142.         return $options;
  143.     }
  144.     /**
  145.      * Loads the XML class descriptions from the given file.
  146.      *
  147.      * @return \SimpleXMLElement
  148.      *
  149.      * @throws MappingException If the file could not be loaded
  150.      */
  151.     protected function parseFile(string $path)
  152.     {
  153.         try {
  154.             $dom XmlUtils::loadFile($path__DIR__.'/schema/dic/constraint-mapping/constraint-mapping-1.0.xsd');
  155.         } catch (\Exception $e) {
  156.             throw new MappingException($e->getMessage(), $e->getCode(), $e);
  157.         }
  158.         return simplexml_import_dom($dom);
  159.     }
  160.     private function loadClassesFromXml()
  161.     {
  162.         // This method may throw an exception. Do not modify the class'
  163.         // state before it completes
  164.         $xml $this->parseFile($this->file);
  165.         $this->classes = [];
  166.         foreach ($xml->namespace as $namespace) {
  167.             $this->addNamespaceAlias((string) $namespace['prefix'], trim((string) $namespace));
  168.         }
  169.         foreach ($xml->class as $class) {
  170.             $this->classes[(string) $class['name']] = $class;
  171.         }
  172.     }
  173.     private function loadClassMetadataFromXml(ClassMetadata $metadata\SimpleXMLElement $classDescription)
  174.     {
  175.         if (\count($classDescription->{'group-sequence-provider'}) > 0) {
  176.             $metadata->setGroupSequenceProvider(true);
  177.         }
  178.         foreach ($classDescription->{'group-sequence'} as $groupSequence) {
  179.             if (\count($groupSequence->value) > 0) {
  180.                 $metadata->setGroupSequence($this->parseValues($groupSequence[0]->value));
  181.             }
  182.         }
  183.         foreach ($this->parseConstraints($classDescription->constraint) as $constraint) {
  184.             $metadata->addConstraint($constraint);
  185.         }
  186.         foreach ($classDescription->property as $property) {
  187.             foreach ($this->parseConstraints($property->constraint) as $constraint) {
  188.                 $metadata->addPropertyConstraint((string) $property['name'], $constraint);
  189.             }
  190.         }
  191.         foreach ($classDescription->getter as $getter) {
  192.             foreach ($this->parseConstraints($getter->constraint) as $constraint) {
  193.                 $metadata->addGetterConstraint((string) $getter['property'], $constraint);
  194.             }
  195.         }
  196.     }
  197. }