From f96d9cedba8ce6f0b63bfed96823c295e295258c Mon Sep 17 00:00:00 2001 From: MarkBaker Date: Sat, 25 Apr 2015 21:49:30 +0100 Subject: [PATCH] Added RowIterator support for end row, and throws exceptions for invalid arguments --- Classes/PHPExcel/Worksheet.php | 8 +- Classes/PHPExcel/Worksheet/RowIterator.php | 40 +++++++-- .../PHPExcel/Worksheet/RowIteratorTest.php | 87 +++++++++++++++++++ 3 files changed, 127 insertions(+), 8 deletions(-) create mode 100644 unitTests/Classes/PHPExcel/Worksheet/RowIteratorTest.php diff --git a/Classes/PHPExcel/Worksheet.php b/Classes/PHPExcel/Worksheet.php index 51edf4ab..bb6a22fd 100644 --- a/Classes/PHPExcel/Worksheet.php +++ b/Classes/PHPExcel/Worksheet.php @@ -2559,11 +2559,13 @@ class PHPExcel_Worksheet implements PHPExcel_IComparable /** * Get row iterator * - * @param integer $startRow The row number at which to start iterating + * @param integer $startRow The row number at which to start iterating + * @param integer $endRow The row number at which to stop iterating + * * @return PHPExcel_Worksheet_RowIterator */ - public function getRowIterator($startRow = 1) { - return new PHPExcel_Worksheet_RowIterator($this,$startRow); + public function getRowIterator($startRow = 1, $endRow = null) { + return new PHPExcel_Worksheet_RowIterator($this, $startRow, $endRow); } /** diff --git a/Classes/PHPExcel/Worksheet/RowIterator.php b/Classes/PHPExcel/Worksheet/RowIterator.php index 642ec763..295ed60e 100644 --- a/Classes/PHPExcel/Worksheet/RowIterator.php +++ b/Classes/PHPExcel/Worksheet/RowIterator.php @@ -59,15 +59,25 @@ class PHPExcel_Worksheet_RowIterator implements Iterator private $_startRow = 1; + /** + * End position + * + * @var int + */ + private $_endRow = 1; + + /** * Create a new row iterator * * @param PHPExcel_Worksheet $subject The worksheet to iterate over * @param integer $startRow The row number at which to start iterating + * @param integer $endRow Optionally, the row number at which to stop iterating */ - public function __construct(PHPExcel_Worksheet $subject = null, $startRow = 1) { + public function __construct(PHPExcel_Worksheet $subject = null, $startRow = 1, $endRow = null) { // Set subject $this->_subject = $subject; + $this->resetEnd($endRow); $this->resetStart($startRow); } @@ -86,6 +96,19 @@ class PHPExcel_Worksheet_RowIterator implements Iterator public function resetStart($startRow = 1) { $this->_startRow = $startRow; $this->seek($startRow); + + return $this; + } + + /** + * (Re)Set the end row + * + * @param integer $endRow The row number at which to stop iterating + */ + public function resetEnd($endRow = null) { + $this->_endRow = ($endRow) ? $endRow : $this->_subject->getHighestRow(); + + return $this; } /** @@ -94,6 +117,10 @@ class PHPExcel_Worksheet_RowIterator implements Iterator * @param integer $row The row number to set the current pointer at */ public function seek($row = 1) { + if (($row < $this->_startRow) || ($row > $this->_endRow)) { + throw new PHPExcel_Exception("Row $row is out of range ({$this->_startRow} - {$this->_endRow})"); + } + $this->_position = $row; } @@ -133,16 +160,19 @@ class PHPExcel_Worksheet_RowIterator implements Iterator * Set the iterator to its previous value */ public function prev() { - if ($this->_position > 1) - --$this->_position; + if ($this->_position <= $this->_startRow) { + throw new PHPExcel_Exception("Row is already at the beginning of range ({$this->_startRow} - {$this->_endRow})"); + } + + --$this->_position; } /** - * Indicate if more rows exist in the worksheet + * Indicate if more rows exist in the worksheet range of rows that we're iterating * * @return boolean */ public function valid() { - return $this->_position <= $this->_subject->getHighestRow(); + return $this->_position <= $this->_endRow; } } diff --git a/unitTests/Classes/PHPExcel/Worksheet/RowIteratorTest.php b/unitTests/Classes/PHPExcel/Worksheet/RowIteratorTest.php new file mode 100644 index 00000000..f39f33d5 --- /dev/null +++ b/unitTests/Classes/PHPExcel/Worksheet/RowIteratorTest.php @@ -0,0 +1,87 @@ +mockRow = $this->getMockBuilder('PHPExcel_Worksheet_Row') + ->disableOriginalConstructor() + ->getMock(); + + $this->mockWorksheet = $this->getMockBuilder('PHPExcel_Worksheet') + ->disableOriginalConstructor() + ->getMock(); + + $this->mockWorksheet->expects($this->any()) + ->method('getHighestRow') + ->will($this->returnValue(5)); + $this->mockWorksheet->expects($this->any()) + ->method('current') + ->will($this->returnValue($this->mockRow)); + } + + + public function testIteratorFullRange() + { + $iterator = new PHPExcel_Worksheet_RowIterator($this->mockWorksheet); + $rowIndexResult = 1; + $this->assertEquals($rowIndexResult, $iterator->key()); + + foreach($iterator as $key => $row) { + $this->assertEquals($rowIndexResult++, $key); + $this->assertInstanceOf('PHPExcel_Worksheet_Row', $row); + } + } + + public function testIteratorStartEndRange() + { + $iterator = new PHPExcel_Worksheet_RowIterator($this->mockWorksheet, 2, 4); + $rowIndexResult = 2; + $this->assertEquals($rowIndexResult, $iterator->key()); + + foreach($iterator as $key => $row) { + $this->assertEquals($rowIndexResult++, $key); + $this->assertInstanceOf('PHPExcel_Worksheet_Row', $row); + } + } + + public function testIteratorSeekAndPrev() + { + $iterator = new PHPExcel_Worksheet_RowIterator($this->mockWorksheet); + $columnIndexResult = 4; + $iterator->seek(4); + $this->assertEquals($columnIndexResult, $iterator->key(), 2, 4); + + for($i = 1; $i < $columnIndexResult; $i++) { + $iterator->prev(); + $this->assertEquals($columnIndexResult - $i, $iterator->key()); + } + } + + /** + * @expectedException PHPExcel_Exception + */ + public function testSeekOutOfRange() + { + $iterator = new PHPExcel_Worksheet_RowIterator($this->mockWorksheet, 2, 4); + $iterator->seek(1); + } + + /** + * @expectedException PHPExcel_Exception + */ + public function testPrevOutOfRange() + { + $iterator = new PHPExcel_Worksheet_RowIterator($this->mockWorksheet, 2, 4); + $iterator->prev(); + } + +}