159 lines
4.2 KiB
PHP
159 lines
4.2 KiB
PHP
|
<?php
|
||
|
|
||
|
namespace ManiaControl\Utils;
|
||
|
|
||
|
use InvalidArgumentException;
|
||
|
|
||
|
/**
|
||
|
* Utility Class offering Methods related to Data Structures
|
||
|
*
|
||
|
* @author axelalex2
|
||
|
* @copyright
|
||
|
* @license http://www.gnu.org/licenses/ GNU General Public License, Version 3
|
||
|
*/
|
||
|
abstract class DataUtil {
|
||
|
|
||
|
/**
|
||
|
* Build a multi-dimensional array into XML-String.
|
||
|
*
|
||
|
* @param array $a
|
||
|
* @param string $root
|
||
|
* @return string
|
||
|
*/
|
||
|
public static function buildXmlStandaloneFromArray(array $a, string $root = '') {
|
||
|
$domDocument = new \DOMDocument("1.0", "utf-8");
|
||
|
$domDocument->xmlStandalone = true;
|
||
|
|
||
|
if ($root === '') {
|
||
|
if (count($a) != 1) {
|
||
|
throw new InvalidArgumentException('Array needs to have a single root!');
|
||
|
}
|
||
|
|
||
|
reset($a);
|
||
|
$root = key($a);
|
||
|
if (!is_string($root)) {
|
||
|
throw new InvalidArgumentException('All keys have to be strings!');
|
||
|
}
|
||
|
$a = $a[$root];
|
||
|
}
|
||
|
|
||
|
$domRootElement = $domDocument->createElement($root);
|
||
|
$domDocument->appendChild($domRootElement);
|
||
|
self::buildXmlChildFromArray($domDocument, $domRootElement, $a);
|
||
|
return $domDocument->saveXML();
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Build a multi-dimensional array into XML-String (recursion for children).
|
||
|
*
|
||
|
* @param \DOMDocument $domDocument
|
||
|
* @param \DOMElement &$domElement
|
||
|
* @param array $a
|
||
|
*/
|
||
|
private static function buildXmlChildFromArray(\DOMDocument $domDocument, \DOMElement &$domElement, array $a) {
|
||
|
foreach ($a as $key => $value) {
|
||
|
if (is_array($value)) {
|
||
|
$domSubElement = $domDocument->createElement($key);
|
||
|
$domElement->appendChild($domSubElement);
|
||
|
self::buildXmlChildFromArray($domDocument, $domSubElement, $a[$key]);
|
||
|
} else {
|
||
|
$valueString = (is_string($value) ? $value : var_export($value, true));
|
||
|
$domElement->setAttribute($key, $valueString);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Implodes sub-arrays with position properties.
|
||
|
*
|
||
|
* @param array $a
|
||
|
* @param bool $recurse
|
||
|
* @return array
|
||
|
*/
|
||
|
public static function implodePositions(array $a, bool $recurse = true) {
|
||
|
$result = array();
|
||
|
foreach ($a as $key => $value) {
|
||
|
if (is_array($value)) {
|
||
|
$arrayKeys = array_keys($value);
|
||
|
if (in_array('x', $arrayKeys) && in_array('y', $arrayKeys)) {
|
||
|
$value = $value['x'].' '.$value['y'].(in_array('z', $arrayKeys) ? ' '.$value['z'] : '');
|
||
|
} elseif ($recurse) {
|
||
|
$value = self::implodePositions($value, $recurse);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
$result[$key] = $value;
|
||
|
}
|
||
|
return $result;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Transforms a multidimensional-array into a 1-dimensional with concatenated keys.
|
||
|
*
|
||
|
* @param array $a
|
||
|
* @param string $delimiter
|
||
|
* @param string $prefix (used for recursion)
|
||
|
* @return array
|
||
|
*/
|
||
|
public static function flattenArray(array $a, string $delimiter = '.', string $prefix = '') {
|
||
|
$result = array();
|
||
|
foreach ($a as $key => $value)
|
||
|
{
|
||
|
if (!is_string($key)) {
|
||
|
throw new InvalidArgumentException('All keys have to be strings!');
|
||
|
}
|
||
|
|
||
|
$new_key = $prefix . (empty($prefix) ? '' : $delimiter) . $key;
|
||
|
if (is_array($value)) {
|
||
|
$result = array_merge($result, self::flattenArray($value, $delimiter, $new_key));
|
||
|
} else {
|
||
|
$result[$new_key] = $value;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return $result;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Transforms a 1-dimensional array into a multi-dimensional by splitting the keys by a given delimiter.
|
||
|
*
|
||
|
* @param array $a
|
||
|
* @param string $delimiter
|
||
|
* @return array
|
||
|
*/
|
||
|
public static function unflattenArray(array $a, string $delimiter = '.') {
|
||
|
$result = array();
|
||
|
foreach ($a as $key => $value) {
|
||
|
if (!is_string($key)) {
|
||
|
throw new InvalidArgumentException('All keys have to be strings!');
|
||
|
}
|
||
|
|
||
|
$keySplits = explode($delimiter, $key);
|
||
|
$numSplits = count($keySplits);
|
||
|
$subResult = &$result;
|
||
|
for ($i = 0; $i < $numSplits; $i++) {
|
||
|
$keySplit = $keySplits[$i];
|
||
|
if ($i < $numSplits-1) {
|
||
|
// subarray
|
||
|
if (!array_key_exists($keySplit, $subResult)) {
|
||
|
$subResult[$keySplit] = array();
|
||
|
}
|
||
|
if (!is_array($subResult[$keySplit])) {
|
||
|
throw new InvalidArgumentException('');
|
||
|
} else {
|
||
|
$subResult = &$subResult[$keySplit];
|
||
|
}
|
||
|
} else {
|
||
|
// insert value
|
||
|
if (array_key_exists($keySplit, $subResult)) {
|
||
|
throw new InvalidArgumentException('Found duplicated key!');
|
||
|
} else {
|
||
|
$subResult[$keySplit] = $value;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
return $result;
|
||
|
}
|
||
|
}
|