Magento 2 Documentation  2.3
Documentation for Magento 2 CMS v2.3 (December 2018)
Public Member Functions | Static Public Member Functions | Data Fields | Protected Member Functions | Protected Attributes
Dom Class Reference
Inheritance diagram for Dom:
Dom Dom

Public Member Functions

 __construct ( $xml, \Magento\Framework\Config\ValidationStateInterface $validationState, array $idAttributes=[], $typeAttributeName=null, $schemaFile=null, $errorFormat=self::ERROR_FORMAT_DEFAULT)
 
 merge ($xml)
 
 getDom ()
 
 validate ($schemaFileName, &$errors=[])
 
 setSchemaFile ($schemaFile)
 

Static Public Member Functions

static validateDomDocument (\DOMDocument $dom, $schema, $errorFormat=self::ERROR_FORMAT_DEFAULT)
 

Data Fields

const ROOT_NAMESPACE_PREFIX = 'x'
 
const ERROR_FORMAT_DEFAULT = "%message%\nLine: %line%\n"
 

Protected Member Functions

 _mergeNode (\DOMElement $node, $parentPath)
 
 _isTextNode ($node)
 
 _mergeAttributes ($baseNode, $mergeNode)
 
 _getNodePathByParent (\DOMElement $node, $parentPath)
 
 _getMatchedNode ($nodePath)
 
 _initDom ($xml)
 

Protected Attributes

 $dom
 
 $nodeMergingConfig
 
 $typeAttributeName
 
 $schema
 
 $errorFormat
 
 $rootNamespace
 

Detailed Description

Class Dom

@SuppressWarnings(PHPMD.CouplingBetweenObjects) @api

Since
100.0.2

Definition at line 23 of file Dom.php.

Constructor & Destructor Documentation

◆ __construct()

__construct (   $xml,
\Magento\Framework\Config\ValidationStateInterface  $validationState,
array  $idAttributes = [],
  $typeAttributeName = null,
  $schemaFile = null,
  $errorFormat = self::ERROR_FORMAT_DEFAULT 
)

Build DOM with initial XML contents and specifying identifier attributes for merging

Format of $idAttributes: array('/xpath/to/some/node' => 'id_attribute_name') The path to ID attribute name should not include any attribute notations or modifiers – only node names

Parameters
string$xml
\Magento\Framework\Config\ValidationStateInterface$validationState
array$idAttributes
string$typeAttributeName
string$schemaFile
string$errorFormat

Definition at line 104 of file Dom.php.

111  {
112  $this->validationState = $validationState;
113  $this->schema = $schemaFile;
114  $this->nodeMergingConfig = new Dom\NodeMergingConfig(new Dom\NodePathMatcher(), $idAttributes);
115  $this->typeAttributeName = $typeAttributeName;
116  $this->errorFormat = $errorFormat;
117  $this->dom = $this->_initDom($xml);
118  $this->rootNamespace = $this->dom->lookupNamespaceUri($this->dom->namespaceURI);
119  }

Member Function Documentation

◆ _getMatchedNode()

_getMatchedNode (   $nodePath)
protected

Getter for node by path

Parameters
string$nodePath
Exceptions

Definition at line 271 of file Dom.php.

272  {
273  $xPath = new \DOMXPath($this->dom);
274  if ($this->rootNamespace) {
275  $xPath->registerNamespace(self::ROOT_NAMESPACE_PREFIX, $this->rootNamespace);
276  }
277  $matchedNodes = $xPath->query($nodePath);
278  $node = null;
279  if ($matchedNodes->length > 1) {
280  throw new \Magento\Framework\Exception\LocalizedException(
281  new \Magento\Framework\Phrase(
282  "More than one node matching the query: %1, Xml is: %2",
283  [$nodePath, $this->dom->saveXML()]
284  )
285  );
286  } elseif ($matchedNodes->length == 1) {
287  $node = $matchedNodes->item(0);
288  }
289  return $node;
290  }
elseif(isset( $params[ 'redirect_parent']))
Definition: iframe.phtml:17

◆ _getNodePathByParent()

_getNodePathByParent ( \DOMElement  $node,
  $parentPath 
)
protected

Identify node path based on parent path and node attributes

Parameters
\DOMElement$node
string$parentPath
Returns
string

Definition at line 245 of file Dom.php.

246  {
247  $prefix = $this->rootNamespace === null ? '' : self::ROOT_NAMESPACE_PREFIX . ':';
248  $path = $parentPath . '/' . $prefix . $node->tagName;
249  $idAttribute = $this->nodeMergingConfig->getIdAttribute($path);
250  if (is_array($idAttribute)) {
251  $constraints = [];
252  foreach ($idAttribute as $attribute) {
253  $value = $node->getAttribute($attribute);
254  $constraints[] = "@{$attribute}='{$value}'";
255  }
256  $path .= '[' . implode(' and ', $constraints) . ']';
257  } elseif ($idAttribute && ($value = $node->getAttribute($idAttribute))) {
258  $path .= "[@{$idAttribute}='{$value}']";
259  }
260  return $path;
261  }
elseif(isset( $params[ 'redirect_parent']))
Definition: iframe.phtml:17
$prefix
Definition: name.phtml:25
$value
Definition: gender.phtml:16

◆ _initDom()

_initDom (   $xml)
protected

Create DOM document based on $xml parameter

Parameters
string$xml
Returns
\DOMDocument
Exceptions

Definition at line 388 of file Dom.php.

389  {
390  $dom = new \DOMDocument();
391  $useErrors = libxml_use_internal_errors(true);
392  $res = $dom->loadXML($xml);
393  if (!$res) {
394  $errors = self::getXmlErrors($this->errorFormat);
395  libxml_use_internal_errors($useErrors);
396  throw new \Magento\Framework\Config\Dom\ValidationException(implode("\n", $errors));
397  }
398  libxml_use_internal_errors($useErrors);
399  if ($this->validationState->isValidationRequired() && $this->schema) {
400  $errors = $this->validateDomDocument($dom, $this->schema, $this->errorFormat);
401  if (count($errors)) {
402  throw new \Magento\Framework\Config\Dom\ValidationException(implode("\n", $errors));
403  }
404  }
405  return $dom;
406  }
static validateDomDocument(\DOMDocument $dom, $schema, $errorFormat=self::ERROR_FORMAT_DEFAULT)
Definition: Dom.php:301
$errors
Definition: overview.phtml:9

◆ _isTextNode()

_isTextNode (   $node)
protected

Check if the node content is text

Parameters
\DOMElement$node
Returns
bool

Definition at line 219 of file Dom.php.

220  {
221  return $node->childNodes->length == 1 && $node->childNodes->item(0) instanceof \DOMText;
222  }

◆ _mergeAttributes()

_mergeAttributes (   $baseNode,
  $mergeNode 
)
protected

Merges attributes of the merge node to the base node

Parameters
\DOMElement$baseNode
\DOMNode$mergeNode
Returns
void

Definition at line 231 of file Dom.php.

232  {
233  foreach ($mergeNode->attributes as $attribute) {
234  $baseNode->setAttribute($this->_getAttributeName($attribute), $attribute->value);
235  }
236  }

◆ _mergeNode()

_mergeNode ( \DOMElement  $node,
  $parentPath 
)
protected

Recursive merging of the \DOMElement into the original document

Algorithm:

  1. Find the same node in original document
  2. Extend and override original document node attributes and scalar value if found
  3. Append new node if original document doesn't have the same node
Parameters
\DOMElement$node
string$parentPathpath to parent node
Returns
void @SuppressWarnings(PHPMD.CyclomaticComplexity)

Definition at line 167 of file Dom.php.

168  {
169  $path = $this->_getNodePathByParent($node, $parentPath);
170 
171  $matchedNode = $this->_getMatchedNode($path);
172 
173  /* Update matched node attributes and value */
174  if ($matchedNode) {
175  //different node type
176  if ($this->typeAttributeName &&
177  $node->hasAttribute($this->typeAttributeName) &&
178  $matchedNode->hasAttribute($this->typeAttributeName) &&
179  $node->getAttribute($this->typeAttributeName) !== $matchedNode->getAttribute($this->typeAttributeName)
180  ) {
181  $parentMatchedNode = $this->_getMatchedNode($parentPath);
182  $newNode = $this->dom->importNode($node, true);
183  $parentMatchedNode->replaceChild($newNode, $matchedNode);
184  return;
185  }
186 
187  $this->_mergeAttributes($matchedNode, $node);
188  if (!$node->hasChildNodes()) {
189  return;
190  }
191  /* override node value */
192  if ($this->_isTextNode($node)) {
193  /* skip the case when the matched node has children, otherwise they get overridden */
194  if (!$matchedNode->hasChildNodes() || $this->_isTextNode($matchedNode)) {
195  $matchedNode->nodeValue = $node->childNodes->item(0)->nodeValue;
196  }
197  } else {
198  /* recursive merge for all child nodes */
199  foreach ($node->childNodes as $childNode) {
200  if ($childNode instanceof \DOMElement) {
201  $this->_mergeNode($childNode, $path);
202  }
203  }
204  }
205  } else {
206  /* Add node as is to the document under the same parent element */
207  $parentMatchedNode = $this->_getMatchedNode($parentPath);
208  $newNode = $this->dom->importNode($node, true);
209  $parentMatchedNode->appendChild($newNode);
210  }
211  }
_getNodePathByParent(\DOMElement $node, $parentPath)
Definition: Dom.php:245
_mergeNode(\DOMElement $node, $parentPath)
Definition: Dom.php:167
_mergeAttributes($baseNode, $mergeNode)
Definition: Dom.php:231
_getMatchedNode($nodePath)
Definition: Dom.php:271

◆ getDom()

getDom ( )

DOM document getter

Returns
\DOMDocument

Definition at line 376 of file Dom.php.

377  {
378  return $this->dom;
379  }

◆ merge()

merge (   $xml)

Merge $xml into DOM document

Parameters
string$xml
Returns
void

Definition at line 148 of file Dom.php.

149  {
150  $dom = $this->_initDom($xml);
151  $this->_mergeNode($dom->documentElement, '');
152  }
_mergeNode(\DOMElement $node, $parentPath)
Definition: Dom.php:167

◆ setSchemaFile()

setSchemaFile (   $schemaFile)

Set schema file

Parameters
string$schemaFile
Returns
$this

Definition at line 430 of file Dom.php.

431  {
432  $this->schema = $schemaFile;
433  return $this;
434  }

◆ validate()

validate (   $schemaFileName,
$errors = [] 
)

Validate self contents towards to specified schema

Parameters
string$schemaFileNameabsolute path to schema file
array&$errors
Returns
bool

Definition at line 415 of file Dom.php.

416  {
417  if ($this->validationState->isValidationRequired()) {
418  $errors = $this->validateDomDocument($this->dom, $schemaFileName, $this->errorFormat);
419  return !count($errors);
420  }
421  return true;
422  }
static validateDomDocument(\DOMDocument $dom, $schema, $errorFormat=self::ERROR_FORMAT_DEFAULT)
Definition: Dom.php:301
$errors
Definition: overview.phtml:9

◆ validateDomDocument()

static validateDomDocument ( \DOMDocument  $dom,
  $schema,
  $errorFormat = self::ERROR_FORMAT_DEFAULT 
)
static

Validate dom document

Parameters
\DOMDocument$dom
string$schemaAbsolute schema file path or URN
string$errorFormat
Returns
array of errors
Exceptions

Definition at line 301 of file Dom.php.

305  {
306  if (!function_exists('libxml_set_external_entity_loader')) {
307  return [];
308  }
309 
310  if (!self::$urnResolver) {
311  self::$urnResolver = new UrnResolver();
312  }
313  if (!isset(self::$resolvedSchemaPaths[$schema])) {
314  self::$resolvedSchemaPaths[$schema] = self::$urnResolver->getRealPath($schema);
315  }
316  $schema = self::$resolvedSchemaPaths[$schema];
317 
318  libxml_use_internal_errors(true);
319  libxml_set_external_entity_loader([self::$urnResolver, 'registerEntityLoader']);
320  $errors = [];
321  try {
322  $result = $dom->schemaValidate($schema);
323  if (!$result) {
324  $errors = self::getXmlErrors($errorFormat);
325  }
326  } catch (\Exception $exception) {
327  $errors = self::getXmlErrors($errorFormat);
328  libxml_use_internal_errors(false);
329  array_unshift($errors, new Phrase('Processed schema file: %1', [$schema]));
330  throw new ValidationSchemaException(new Phrase(implode("\n", $errors)));
331  }
332  libxml_set_external_entity_loader(null);
333  libxml_use_internal_errors(false);
334  return $errors;
335  }
$errors
Definition: overview.phtml:9

Field Documentation

◆ $dom

$dom
protected

Definition at line 45 of file Dom.php.

◆ $errorFormat

$errorFormat
protected

Definition at line 71 of file Dom.php.

◆ $nodeMergingConfig

$nodeMergingConfig
protected

Definition at line 50 of file Dom.php.

◆ $rootNamespace

$rootNamespace
protected

Definition at line 78 of file Dom.php.

◆ $schema

$schema
protected

Definition at line 64 of file Dom.php.

◆ $typeAttributeName

$typeAttributeName
protected

Definition at line 57 of file Dom.php.

◆ ERROR_FORMAT_DEFAULT

const ERROR_FORMAT_DEFAULT = "%message%\nLine: %line%\n"

Format of items in errors array to be used by default. Available placeholders - fields of \LibXMLError.

Definition at line 33 of file Dom.php.

◆ ROOT_NAMESPACE_PREFIX

const ROOT_NAMESPACE_PREFIX = 'x'

Prefix which will be used for root namespace

Definition at line 28 of file Dom.php.


The documentation for this class was generated from the following file: