Drupal investigation

XmlFileLoader.php 6.3KB

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