/magmi/plugins/5b5/general/attributesetimport/multi_dim_array.php

https://gitlab.com/myurd/magmi-git · PHP · 247 lines · 164 code · 13 blank · 70 comment · 45 complexity · d7b8fb375622c38212bde0f396db8790 MD5 · raw file

  1. <?php
  2. /**
  3. * <p>An array class which allows to use (one-dimensional, primitive-type arrays) as keys.<p>
  4. * <p>Acts very much like you would expect (in most cases ):
  5. * <code><br/>
  6. * $mda = new MultiDimArray();<br/>
  7. * <br/>
  8. * // Setting values:<br/>
  9. * $mda->offsetSet(array(1,2,3),"Test");<br/>
  10. * $mda->offsetSet(array(3,2),"Test2");<br/>
  11. * $mda[array(1,2,3)] = "Test" DOES NOT WORK because arrays are not allowed as index in this notation :(<br/>
  12. * <br/>
  13. * // Getting values:<br/>
  14. * $mda[array(1,2,3)] -> "Test"<br/>
  15. * $mda[array(1,2)] -> MultiDimArray() [ 3 => "Test" ]<br/>
  16. * $mda[array(1)] -> MultiDimArray() [ 2 => MultiDimArray () [3 => "Test" ]]<br/>
  17. * $mda[1] -> MultiDimArray() [ 2 => MultiDimArray () [3 => "Test" ]]<br/>
  18. * $mda[1][2][3] -> "Test"<br/>
  19. * <br/>
  20. * // isset / offsetExists<br/>
  21. * isset($mda[array(1,2,3)]) -> true<br/>
  22. * isset($mda[array(1,2,3,4)]) -> false<br/>
  23. * isset($mda[array(1,2)]) -> true (because $mda[array(1,2)]) also returns a value)<br/>
  24. * isset($mda[array(1)]) -> true (same as above)<br/>
  25. * isset($mda[1]) -> true (see above)
  26. * isset($mda[1][2][3]) -> true
  27. * isset($mda[array(2)]) -> false (keys are ordered!)<br/>
  28. *
  29. * $mda->offsetExistsPartly(array(1,2,3,4)) -> true (part of the offset exists)<br/>
  30. * $mda->offsetExistsPartly(array(1,2,4)) -> false<br/>
  31. * <br/>
  32. * // iterating:<br/>
  33. * // "foreach" does not allow arrays as keys :(<br/>
  34. * $mda->rewind();<br/>
  35. * while($mda->valid()) {<br/>
  36. * $key = $mda->key(); // -> 1. iteration: array (1,2,3), 2. iteration: array (3,2)<br/>
  37. * $value = $mda->current(); // -> 1. iteration:"Test", 2. iteration: "Test2"<br/>
  38. * $mda->next();<br/>
  39. * }<br/>
  40. * </code></p>
  41. */
  42. class MultiDimArray extends ArrayIterator
  43. {
  44. private $_inner;
  45. private $_current;
  46. private $_currentKey;
  47. /**
  48. * (non-PHPdoc)
  49. * @see ArrayIterator::offsetGet()
  50. */
  51. public function offsetGet($name)
  52. {
  53. if (!is_array($name)) {
  54. return parent::offsetGet($name);
  55. } else {
  56. $key = array_shift($name);
  57. if (!parent::offsetExists($key)) {
  58. return null;
  59. }
  60. $element = parent::offsetGet($key);
  61. if (sizeof($name) == 0) {
  62. return $element;
  63. } else {
  64. if (is_a($element, 'MultiDimArray')) {
  65. return $element->offsetGet($name);
  66. } else {
  67. return $element;
  68. }
  69. }
  70. }
  71. }
  72. /**
  73. * (non-PHPdoc)
  74. * @see ArrayIterator::offsetSet()
  75. */
  76. public function offsetSet($name, $value)
  77. {
  78. if (!is_array($name)) {
  79. return parent::offsetSet($name, $value);
  80. } else {
  81. $key = array_shift($name);
  82. if (sizeof($name) == 0) {
  83. parent::offsetSet($key, $value);
  84. } else {
  85. $childArray = parent::offsetExists($key)?parent::offsetGet($key):new MultiDimArray();
  86. if (!is_a($childArray, 'MultiDimArray')) {
  87. $childArray = new MultiDimArray();
  88. }
  89. parent::offsetSet($key, $childArray);
  90. $childArray->offsetSet($name, $value);
  91. }
  92. }
  93. }
  94. /**
  95. * Returns true, if the given offset exists. Offsets can also be given
  96. * partly e.g.:<br/>
  97. * <code>
  98. * offsetExists(array(1,2)) will return true, too, if offset array(1,2,3) is set to a value<br/>
  99. * but<br/>
  100. * offsetExists(array(1,2,3,4)) will return false<br/></code>
  101. * (non-PHPdoc)
  102. * @see ArrayIterator::offsetExists()
  103. */
  104. public function offsetExists($name)
  105. {
  106. return $this->offsetExistsPartly($name, false);
  107. }
  108. /**
  109. * If $partlyOk is set to false, works exactly like offsetExists().
  110. * If $partlyOk is set to true, it also returns true, if
  111. * only a part of the given $name array exists e.g.:<br/>
  112. * <code>
  113. * offsetExistsPartly(array(1,2,3,4),true) will additionally return true if one of the following offsets exists: array(1), array(1,2), array(1,2,3)<br/></code>
  114. *
  115. * @param unknown $name
  116. * @param string $partlyOk
  117. * @return void|boolean|string
  118. */
  119. public function offsetExistsPartly($name, $partlyOk=true)
  120. {
  121. if (!is_array($name)) {
  122. return parent::offsetExists($name);
  123. } else {
  124. $key = array_shift($name);
  125. if (sizeof($name) == 0) {
  126. return parent::offsetExists($key);
  127. } else {
  128. if (!parent::offsetExists($key)) {
  129. return false;
  130. } else {
  131. $object = parent::offsetGet($key);
  132. if (is_a($object, 'MultiDimArray')) {
  133. return $object->offsetExists($name);
  134. } else {
  135. return $partlyOk;
  136. }
  137. }
  138. }
  139. }
  140. }
  141. public function offsetUnset($name)
  142. {
  143. if (!is_array($name)) {
  144. return parent::offsetUnset($name);
  145. } else {
  146. $key = array_shift($name);
  147. if (sizeof($name) == 0) {
  148. return parent::offsetUnset($key);
  149. } else {
  150. if (parent::offsetExists($key)) {
  151. $object = parent::offsetGet($key);
  152. if (is_a($object, 'MutliDimArray')) {
  153. $object->offsetUnset($name);
  154. if ($object->sizeof()==0) {
  155. parent::offsetUnset($key);
  156. }
  157. } else {
  158. parent::offsetUnset($key);
  159. }
  160. }
  161. }
  162. }
  163. }
  164. public function rewind()
  165. {
  166. $this->_iterator = null;
  167. parent::rewind();
  168. $this->setInner();
  169. }
  170. public function current()
  171. {
  172. if (isset($this->_inner)) {
  173. return $this->_inner->current();
  174. } else {
  175. return parent::current();
  176. }
  177. }
  178. private function setInner()
  179. {
  180. if (parent::valid() && is_a(parent::current(), 'MultiDimArray')) {
  181. $this->_inner = parent::current();
  182. $this->_inner->rewind();
  183. }
  184. }
  185. private function doNext()
  186. {
  187. $this->inner = null;
  188. parent::next();
  189. $this->setInner();
  190. }
  191. public function next()
  192. {
  193. if (isset($this->_inner)) {
  194. $this->_inner->next();
  195. if (!$this->_inner->valid()) {
  196. $this->doNext();
  197. }
  198. } else {
  199. $this->doNext();
  200. }
  201. }
  202. public function key()
  203. {
  204. if (isset($this->_inner)) {
  205. $innerKey = $this->_inner->key();
  206. array_unshift($innerKey, parent::key());
  207. return $innerKey;
  208. } else {
  209. return array(parent::key());
  210. }
  211. }
  212. public function valid()
  213. {
  214. return parent::valid();
  215. }
  216. public function multiSet($keyArrays, $value)
  217. {
  218. foreach ($keyArrays as $keyArray) {
  219. if (is_array($keyArray) && sizeof($keyArray) == 0) {
  220. // ignore
  221. } else {
  222. $this->offsetSet($keyArray, $value);
  223. }
  224. }
  225. }
  226. public function count($mode = null)
  227. {
  228. $count = 0;
  229. foreach ($this as $item) {
  230. $count++;
  231. }
  232. return $count;
  233. }
  234. }