TrackManiaControl/core/Utils/DataUtil.php

185 lines
4.8 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, $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);
}
}
}
/**
* Checks, if a string ends with the given substring.
* @param string $haystack
* @param string $needle
* @return bool
*/
public static function endsWith($haystack, $needle) {
$length = strlen($needle);
if ($length == 0) {
return true;
}
return (substr($haystack, -$length) === $needle);
}
/**
* Checks, if a string starts with the given substring.
* @param string $haystack
* @param string $needle
* @return bool
*/
public static function startsWith($haystack, $needle) {
$length = strlen($needle);
return (substr($haystack, 0, $length) === $needle);
}
/**
* Implodes sub-arrays with position properties.
*
* @param array $a
* @param bool $recurse
* @return array
*/
public static function implodePositions(array $a, $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, $delimiter = '.', $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, $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;
}
}