AbstractSource.php 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182
  1. <?php
  2. /**
  3. * Copyright © Magento, Inc. All rights reserved.
  4. * See COPYING.txt for license details.
  5. */
  6. namespace Magento\ImportExport\Model\Import;
  7. use Magento\ImportExport\Model\Import\AbstractEntity;
  8. /**
  9. * Data source with columns for Magento_ImportExport
  10. *
  11. * @api
  12. * @since 100.0.2
  13. */
  14. abstract class AbstractSource implements \SeekableIterator
  15. {
  16. /**
  17. * @var array
  18. */
  19. protected $_colNames = [];
  20. /**
  21. * Quantity of columns
  22. *
  23. * @var int
  24. */
  25. protected $_colQty;
  26. /**
  27. * Current row
  28. *
  29. * @var array
  30. */
  31. protected $_row = [];
  32. /**
  33. * Current row number
  34. *
  35. * -1 means "out of bounds"
  36. *
  37. * @var int
  38. */
  39. protected $_key = -1;
  40. /**
  41. * @var bool
  42. */
  43. protected $_foundWrongQuoteFlag = false;
  44. /**
  45. * Get and validate column names
  46. *
  47. * @param array $colNames
  48. * @throws \InvalidArgumentException
  49. */
  50. public function __construct(array $colNames)
  51. {
  52. if (empty($colNames)) {
  53. throw new \InvalidArgumentException('Empty column names');
  54. }
  55. if (count(array_unique($colNames)) != count($colNames)) {
  56. throw new \InvalidArgumentException('Duplicates found in column names: ' . var_export($colNames, 1));
  57. }
  58. $this->_colNames = $colNames;
  59. $this->_colQty = count($colNames);
  60. }
  61. /**
  62. * Column names getter.
  63. *
  64. * @return array
  65. */
  66. public function getColNames()
  67. {
  68. return $this->_colNames;
  69. }
  70. /**
  71. * Return the current element
  72. *
  73. * Returns the row in associative array format: array(<col_name> => <value>, ...)
  74. *
  75. * @return array
  76. */
  77. public function current()
  78. {
  79. $row = $this->_row;
  80. if (count($row) != $this->_colQty) {
  81. if ($this->_foundWrongQuoteFlag) {
  82. throw new \InvalidArgumentException(AbstractEntity::ERROR_CODE_WRONG_QUOTES);
  83. } else {
  84. throw new \InvalidArgumentException(AbstractEntity::ERROR_CODE_COLUMNS_NUMBER);
  85. }
  86. }
  87. return array_combine($this->_colNames, $row);
  88. }
  89. /**
  90. * Move forward to next element (\Iterator interface)
  91. *
  92. * @return void
  93. */
  94. public function next()
  95. {
  96. $this->_key++;
  97. $row = $this->_getNextRow();
  98. if (false === $row || [] === $row) {
  99. $this->_row = [];
  100. $this->_key = -1;
  101. } else {
  102. $this->_row = $row;
  103. }
  104. }
  105. /**
  106. * Render next row
  107. *
  108. * Return array or false on error
  109. *
  110. * @return array|false
  111. */
  112. abstract protected function _getNextRow();
  113. /**
  114. * Return the key of the current element (\Iterator interface)
  115. *
  116. * @return int -1 if out of bounds, 0 or more otherwise
  117. */
  118. public function key()
  119. {
  120. return $this->_key;
  121. }
  122. /**
  123. * Checks if current position is valid (\Iterator interface)
  124. *
  125. * @return bool
  126. */
  127. public function valid()
  128. {
  129. return -1 !== $this->_key;
  130. }
  131. /**
  132. * Rewind the \Iterator to the first element (\Iterator interface)
  133. *
  134. * @return void
  135. */
  136. public function rewind()
  137. {
  138. $this->_key = -1;
  139. $this->_row = [];
  140. $this->next();
  141. }
  142. /**
  143. * Seeks to a position (Seekable interface)
  144. *
  145. * @param int $position The position to seek to 0 or more
  146. * @return void
  147. * @throws \OutOfBoundsException
  148. */
  149. public function seek($position)
  150. {
  151. if ($position == $this->_key) {
  152. return;
  153. }
  154. if (0 == $position || $position < $this->_key) {
  155. $this->rewind();
  156. }
  157. if ($position > 0) {
  158. do {
  159. $this->next();
  160. if ($this->_key == $position) {
  161. return;
  162. }
  163. } while ($this->_key != -1);
  164. }
  165. throw new \OutOfBoundsException('Please correct the seek position.');
  166. }
  167. }