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 isset($this->sourceArray[$sourceOffset]) 90 ? $this->sourceArray[$sourceOffset] 91 : null; 92 } 93 94 function getOriginalArray() 95 { 96 return $this->sourceArray; 97 } 98 99 100 public function current() 101 { 102 return $this->iterator->current(); 103 } 104 105 public function next() 106 { 107 $this->iterator->next(); 108 } 109 110 public function key() 111 { 112 return $this->iterator->key(); 113 } 114 115 public function valid() 116 { 117 return $this->iterator->valid(); 118 } 119 120 public function rewind() 121 { 122 $obj = new ArrayObject( $this->sourceArray ); 123 $this->iterator = $obj->getIterator(); 124 } 125} 126