1<?php 2 3 4namespace ComboStrap; 5 6 7use ArrayAccess; 8use ArrayObject; 9use Traversable; 10 11/** 12 * Class ArrayCaseInsensitive 13 * @package ComboStrap 14 * 15 * Wrapper around an array to make it case access insensitive 16 */ 17class ArrayCaseInsensitive implements ArrayAccess, \Iterator 18{ 19 20 /** 21 * A mapping between lower key and original key (ie offset) 22 * @var array 23 */ 24 private $_keyMapping = array(); 25 /** 26 * @var array 27 */ 28 private $sourceArray; 29 /** 30 * @var false|mixed 31 */ 32 private $valid; 33 private $iteratorIndex = 0; 34 /** 35 * @var \ArrayIterator 36 */ 37 private $iterator; 38 39 40 public function __construct(array &$source = array()) 41 { 42 $this->sourceArray = &$source; 43 array_walk($source, function ($value, &$key) { 44 $this->_keyMapping[strtolower($key)] = $key; 45 }); 46 47 /** 48 * Iterator 49 */ 50 $this->rewind(); 51 } 52 53 public function offsetSet($offset, $value) 54 { 55 56 if (is_null($offset)) { 57 LogUtility::msg("The offset (key) is null and this is not supported"); 58 } else { 59 if (is_string($offset)) { 60 $lowerCaseOffset = strtolower($offset); 61 $this->_keyMapping[$lowerCaseOffset] = $offset; 62 $this->sourceArray[$offset] = $value; 63 } else { 64 LogUtility::msg("The offset should be a string", LogUtility::LVL_MSG_ERROR); 65 } 66 67 } 68 } 69 70 public function offsetExists($offset) 71 { 72 if (is_string($offset)) $offset = strtolower($offset); 73 return isset($this->_keyMapping[$offset]); 74 } 75 76 public function offsetUnset($offset) 77 { 78 if (is_string($offset)) $offset = strtolower($offset); 79 $originalOffset = $this->_keyMapping[$offset]; 80 unset($this->sourceArray[$originalOffset]); 81 unset($this->_keyMapping[$offset]); 82 83 } 84 85 public function offsetGet($offset) 86 { 87 if (is_string($offset)) $offset = strtolower($offset); 88 $sourceOffset = $this->_keyMapping[$offset]; 89 return $this->sourceArray[$sourceOffset] ?? null; 90 } 91 92 function getOriginalArray() 93 { 94 return $this->sourceArray; 95 } 96 97 98 public function current() 99 { 100 return $this->iterator->current(); 101 } 102 103 public function next() 104 { 105 $this->iterator->next(); 106 } 107 108 public function key() 109 { 110 return $this->iterator->key(); 111 } 112 113 public function valid() 114 { 115 return $this->iterator->valid(); 116 } 117 118 public function rewind() 119 { 120 $obj = new ArrayObject( $this->sourceArray ); 121 $this->iterator = $obj->getIterator(); 122 } 123} 124