Files
pathfinder/app/main/data/mapper/abstractiterator.php
Mark Friedrich efd768974f - New "Intel module" for Citadel tracking, closed #246
- updated "Select2" js lib `4.0.3` -> `4.0.6-rc.1`
- fixed some login Issues
- fixed broken `map/*` reroute URL wildcard replacement
- fixed broken cache layer for Universe models
2018-05-01 19:51:17 +02:00

123 lines
3.7 KiB
PHP

<?php
/**
* Created by PhpStorm.
* User: Exodus
* Date: 31.01.2016
* Time: 04:06
*/
namespace data\mapper;
use lib\Util;
class AbstractIterator extends \RecursiveArrayIterator {
/**
* iterator mapping
* -> overwrite in child classes (late static binding)
* @var array
*/
protected static $map = [];
/**
* remove unmapped values from Array
* -> see $map
* @var bool
*/
protected static $removeUnmapped = true;
function __construct($data){
parent::__construct($data, \RecursiveIteratorIterator::SELF_FIRST);
}
/**
* map iterator
* @return array
*/
public function getData(){
iterator_apply($this, 'self::recursiveIterator', [$this]);
return iterator_to_array($this, true);
}
/**
* convert array keys to camelCase
* @param $array
* @return array
*/
protected function camelCaseKeys($array){
return Util::arrayChangeKeys($array, [\Base::instance(), 'camelcase']);
}
/**
* recursive iterator function called on every node
* @param $iterator
* @return mixed
*/
static function recursiveIterator($iterator){
$keyWhitelist = array_keys(static::$map);
while($iterator->valid()){
if( isset(static::$map[$iterator->key()]) ){
$mapValue = static::$map[$iterator->key()];
// check for mapping key
if(
$iterator->hasChildren() &&
Util::is_assoc($iterator->current())
){
// recursive call for child elements
$iterator->offsetSet($iterator->key(), forward_static_call(array('self', __METHOD__), $iterator->getChildren())->getArrayCopy());
$iterator->next();
}elseif(is_array($mapValue)){
// a -> array mapping
$parentKey = array_keys($mapValue)[0];
$entryKey = array_values($mapValue)[0];
// check if key already exists
if($iterator->offsetExists($parentKey)){
$currentValue = $iterator->offsetGet($parentKey);
// add new array entry
$currentValue[$entryKey] = $iterator->current();
$iterator->offsetSet($parentKey, $currentValue);
}else{
$iterator->offsetSet($parentKey, [$entryKey => $iterator->current()]);
$keyWhitelist[] = $parentKey;
}
$iterator->offsetUnset($iterator->key());
}elseif(is_object($mapValue)){
// a -> a (format by function)
$formatFunction = $mapValue;
$iterator->offsetSet($iterator->key(), call_user_func($formatFunction, $iterator));
// just value change no key change
$iterator->next();
}elseif($mapValue !== $iterator->key()){
// a -> b mapping (key changed)
$iterator->offsetSet($mapValue, $iterator->current());
$iterator->offsetUnset($iterator->key());
$keyWhitelist[] = $mapValue;
}else{
// a -> a (no changes)
$iterator->next();
}
}elseif(
static::$removeUnmapped &&
!in_array($iterator->key(), $keyWhitelist)
){
$iterator->offsetUnset($iterator->key());
}else{
$iterator->next();
}
}
return $iterator;
}
}