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