src/module-elasticsuite-core/Model/Search/Request/RelevanceConfig/Initial/Converter.php
<?php
/**
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade Smile ElasticSuite to newer
* versions in the future.
*
* @category Smile
* @package Smile\ElasticsuiteCore
* @author Romain Ruaud <romain.ruaud@smile.fr>
* @copyright 2020 Smile
* @license Open Software License ("OSL") v. 3.0
*/
namespace Smile\ElasticsuiteCore\Model\Search\Request\RelevanceConfig\Initial;
use Magento\Framework\Config\ConverterInterface;
/**
* Default Configuration converter
*
* @category Smile
* @package Smile\ElasticsuiteCore
* @author Romain Ruaud <romain.ruaud@smile.fr>
*/
class Converter implements ConverterInterface
{
/**
* Node paths to process
*
* @var array
*/
protected $nodeMap = [];
/**
* @var array
*/
protected $metadata = [];
/**
* @param array $nodeMap The node map
*/
public function __construct(array $nodeMap = [])
{
$this->nodeMap = $nodeMap;
}
/**
* Convert config
*
* @param \DOMDocument $source The source document
*
* @return array
*/
public function convert($source)
{
$output = [];
$xpath = new \DOMXPath($source);
$this->metadata = [];
/** @var $node \DOMNode */
foreach ($xpath->query(implode(' | ', $this->nodeMap)) as $node) {
$output = array_merge($output, $this->convertNode($node));
}
$result = ['data' => $output, 'metadata' => $this->metadata];
return $result;
}
/**
* Convert node oto array
*
* @param \DOMNode $node The Configuration DOM node to parse
* @param string $path The path for DOM navigation
*
* @return array|string|null
*/
protected function convertNode(\DOMNode $node, $path = '')
{
$output = [];
if ($node->nodeType == XML_ELEMENT_NODE) {
$nodeName = $this->parseNodeName($node);
$output[$nodeName] = $this->parseNodeData($node, $path);
} elseif ($node->nodeType == XML_CDATA_SECTION_NODE
|| $node->nodeType == XML_TEXT_NODE && trim($node->nodeValue) != '') {
return $node->nodeValue;
}
return $output;
}
/**
* Retrieve proper node name
*
* @param \DOMNode $node The configuration XML node to parse
*
* @return string
*/
protected function parseNodeName($node)
{
$nodeName = $node->nodeName;
if ($node->hasAttributes()) {
$storeCodeNode = $node->attributes->getNamedItem('store_code');
$containerNameNode = $node->attributes->getNamedItem('name');
if ($containerNameNode) {
$nodeName = $containerNameNode->nodeValue;
if ($storeCodeNode) {
$nodeName = $nodeName . "|" . $storeCodeNode->nodeValue;
}
}
}
return $nodeName;
}
/**
* Convert node onto array
*
* @param \DOMNode $node The Configuration DOM node to parse
* @param string $path The path for DOM navigation
*
* @return array|string|null
*/
private function parseNodeData(\DOMNode $node, $path)
{
$nodeData = [];
foreach ($node->childNodes as $childNode) {
$childrenData = $this->convertNode($childNode, ($path ? $path . '/' : '') . $childNode->nodeName);
if ($childrenData === null) {
continue;
}
$nodeData = $this->mergeChildData($nodeData, $childrenData);
}
if (is_array($nodeData) && empty($nodeData)) {
$nodeData = null;
}
return $nodeData;
}
/**
* Merge child node data into current node
*
* @param array $nodeData Current node data
* @param array $childrenData The child node data
*
* @return array
*/
private function mergeChildData($nodeData, $childrenData)
{
if (is_array($childrenData)) {
$nodeData = array_merge($nodeData, $childrenData);
return $nodeData;
}
$nodeData = $childrenData;
return $nodeData;
}
}