various improvements

This commit is contained in:
Adrien Loison 2017-11-19 02:11:03 +01:00
parent 102e17159c
commit 4d1d1c1e87
19 changed files with 90 additions and 112 deletions

View File

@ -65,6 +65,24 @@ class InternalEntityFactory implements InternalEntityFactoryInterface
return new RowIterator($filePointer, $optionsManager, $encodingHelper, $this, $globalFunctionsHelper); return new RowIterator($filePointer, $optionsManager, $encodingHelper, $this, $globalFunctionsHelper);
} }
/**
* @param Cell[] $cells
* @return Row
*/
public function createRow(array $cells = [])
{
return new Row($cells);
}
/**
* @param mixed $cellValue
* @return Cell
*/
public function createCell($cellValue)
{
return new Cell($cellValue);
}
/** /**
* @param array $cellValues * @param array $cellValues
* @return Row * @return Row
@ -72,9 +90,9 @@ class InternalEntityFactory implements InternalEntityFactoryInterface
public function createRowFromArray(array $cellValues = []) public function createRowFromArray(array $cellValues = [])
{ {
$cells = array_map(function ($cellValue) { $cells = array_map(function ($cellValue) {
return new Cell($cellValue); return $this->createCell($cellValue);
}, $cellValues); }, $cellValues);
return new Row($cells); return $this->createRow($cells);
} }
} }

View File

@ -2,9 +2,23 @@
namespace Box\Spout\Reader\Common\Creator; namespace Box\Spout\Reader\Common\Creator;
use Box\Spout\Reader\Common\Entity\Cell;
use Box\Spout\Reader\Common\Entity\Row;
/** /**
* Interface EntityFactoryInterface * Interface EntityFactoryInterface
*/ */
interface InternalEntityFactoryInterface interface InternalEntityFactoryInterface
{ {
/**
* @param Cell[] $cells
* @return Row
*/
public function createRow(array $cells = []);
/**
* @param mixed $cellValue
* @return Cell
*/
public function createCell($cellValue);
} }

View File

@ -65,6 +65,14 @@ class Row
return $this; return $this;
} }
/**
* @return int
*/
public function getNumCells()
{
return count($this->cells);
}
/** /**
* @return array The row values, as array * @return array The row values, as array
*/ */

View File

@ -1,22 +1,22 @@
<?php <?php
namespace Box\Spout\Reader\XLSX\Manager; namespace Box\Spout\Reader\Common\Manager;
use Box\Spout\Reader\Common\Creator\InternalEntityFactoryInterface;
use Box\Spout\Reader\Common\Entity\Row; use Box\Spout\Reader\Common\Entity\Row;
use Box\Spout\Reader\XLSX\Creator\InternalEntityFactory;
/** /**
* Class RowManager * Class RowManager
*/ */
class RowManager class RowManager
{ {
/** @var InternalEntityFactory Factory to create entities */ /** @var InternalEntityFactoryInterface Factory to create entities */
private $entityFactory; private $entityFactory;
/** /**
* @param InternalEntityFactory $entityFactory Factory to create entities * @param InternalEntityFactoryInterface $entityFactory Factory to create entities
*/ */
public function __construct(InternalEntityFactory $entityFactory) public function __construct(InternalEntityFactoryInterface $entityFactory)
{ {
$this->entityFactory = $entityFactory; $this->entityFactory = $entityFactory;
} }
@ -47,11 +47,11 @@ class RowManager
*/ */
public function fillMissingIndexesWithEmptyCells(Row $row) public function fillMissingIndexesWithEmptyCells(Row $row)
{ {
$rowCells = $row->getCells(); if ($row->getNumCells() === 0) {
if (count($rowCells) === 0) {
return $row; return $row;
} }
$rowCells = $row->getCells();
$maxCellIndex = max(array_keys($rowCells)); $maxCellIndex = max(array_keys($rowCells));
for ($cellIndex = 0; $cellIndex < $maxCellIndex; $cellIndex++) { for ($cellIndex = 0; $cellIndex < $maxCellIndex; $cellIndex++) {

View File

@ -73,7 +73,7 @@ class InternalEntityFactory implements InternalEntityFactoryInterface
$shouldFormatDates = $optionsManager->getOption(Options::SHOULD_FORMAT_DATES); $shouldFormatDates = $optionsManager->getOption(Options::SHOULD_FORMAT_DATES);
$cellValueFormatter = $this->helperFactory->createCellValueFormatter($shouldFormatDates); $cellValueFormatter = $this->helperFactory->createCellValueFormatter($shouldFormatDates);
$xmlProcessor = $this->createXMLProcessor($xmlReader); $xmlProcessor = $this->createXMLProcessor($xmlReader);
$rowManager = $this->managerFactory->createRowManager(); $rowManager = $this->managerFactory->createRowManager($this);
return new RowIterator($xmlReader, $optionsManager, $cellValueFormatter, $xmlProcessor, $rowManager, $this); return new RowIterator($xmlReader, $optionsManager, $cellValueFormatter, $xmlProcessor, $rowManager, $this);
} }
@ -82,7 +82,7 @@ class InternalEntityFactory implements InternalEntityFactoryInterface
* @param Cell[] $cells * @param Cell[] $cells
* @return Row * @return Row
*/ */
public function createRow(array $cells) public function createRow(array $cells = [])
{ {
return new Row($cells); return new Row($cells);
} }

View File

@ -2,7 +2,7 @@
namespace Box\Spout\Reader\ODS\Creator; namespace Box\Spout\Reader\ODS\Creator;
use Box\Spout\Reader\ODS\Manager\RowManager; use Box\Spout\Reader\Common\Manager\RowManager;
/** /**
* Class ManagerFactory * Class ManagerFactory
@ -11,10 +11,11 @@ use Box\Spout\Reader\ODS\Manager\RowManager;
class ManagerFactory class ManagerFactory
{ {
/** /**
* @param InternalEntityFactory $entityFactory Factory to create entities
* @return RowManager * @return RowManager
*/ */
public function createRowManager() public function createRowManager($entityFactory)
{ {
return new RowManager(); return new RowManager($entityFactory);
} }
} }

View File

@ -1,29 +0,0 @@
<?php
namespace Box\Spout\Reader\ODS\Manager;
use Box\Spout\Reader\Common\Entity\Row;
/**
* Class RowManager
*/
class RowManager
{
/**
* Detect whether a row is considered empty.
* An empty row has all of its cells empty.
*
* @param Row $row
* @return bool
*/
public function isEmpty(Row $row)
{
foreach ($row->getCells() as $cell) {
if (!$cell->isEmpty()) {
return false;
}
}
return true;
}
}

View File

@ -7,6 +7,7 @@ use Box\Spout\Common\Manager\OptionsManagerInterface;
use Box\Spout\Reader\Common\Entity\Cell; use Box\Spout\Reader\Common\Entity\Cell;
use Box\Spout\Reader\Common\Entity\Options; use Box\Spout\Reader\Common\Entity\Options;
use Box\Spout\Reader\Common\Entity\Row; use Box\Spout\Reader\Common\Entity\Row;
use Box\Spout\Reader\Common\Manager\RowManager;
use Box\Spout\Reader\Common\XMLProcessor; use Box\Spout\Reader\Common\XMLProcessor;
use Box\Spout\Reader\Exception\InvalidValueException; use Box\Spout\Reader\Exception\InvalidValueException;
use Box\Spout\Reader\Exception\IteratorNotRewindableException; use Box\Spout\Reader\Exception\IteratorNotRewindableException;
@ -14,7 +15,6 @@ use Box\Spout\Reader\Exception\XMLProcessingException;
use Box\Spout\Reader\IteratorInterface; use Box\Spout\Reader\IteratorInterface;
use Box\Spout\Reader\ODS\Creator\InternalEntityFactory; use Box\Spout\Reader\ODS\Creator\InternalEntityFactory;
use Box\Spout\Reader\ODS\Helper\CellValueFormatter; use Box\Spout\Reader\ODS\Helper\CellValueFormatter;
use Box\Spout\Reader\ODS\Manager\RowManager;
use Box\Spout\Reader\Wrapper\XMLReader; use Box\Spout\Reader\Wrapper\XMLReader;
/** /**
@ -190,7 +190,7 @@ class RowIterator implements IteratorInterface
*/ */
protected function readDataForNextRow() protected function readDataForNextRow()
{ {
$this->currentlyProcessedRow = $this->entityFactory->createRow([]); $this->currentlyProcessedRow = $this->entityFactory->createRow();
try { try {
$this->xmlProcessor->readUntilStopped(); $this->xmlProcessor->readUntilStopped();
@ -257,7 +257,7 @@ class RowIterator implements IteratorInterface
// if the row is empty, we don't want to return more than one cell // if the row is empty, we don't want to return more than one cell
$actualNumColumnsRepeated = (!$isEmptyRow) ? $this->numColumnsRepeated : 1; $actualNumColumnsRepeated = (!$isEmptyRow) ? $this->numColumnsRepeated : 1;
$numCellsInCurrentlyProcessedRow = count($this->currentlyProcessedRow->getCells()); $numCellsInCurrentlyProcessedRow = $this->currentlyProcessedRow->getNumCells();
// Only add the value if the last read cell is not a trailing empty cell repeater in Excel. // Only add the value if the last read cell is not a trailing empty cell repeater in Excel.
// The current count of read columns is determined by counting the values in "$this->currentlyProcessedRowData". // The current count of read columns is determined by counting the values in "$this->currentlyProcessedRowData".

View File

@ -116,7 +116,7 @@ class InternalEntityFactory implements InternalEntityFactoryInterface
* @param Cell[] $cells * @param Cell[] $cells
* @return Row * @return Row
*/ */
public function createRow(array $cells) public function createRow(array $cells = [])
{ {
return new Row($cells); return new Row($cells);
} }

View File

@ -2,7 +2,7 @@
namespace Box\Spout\Reader\XLSX\Creator; namespace Box\Spout\Reader\XLSX\Creator;
use Box\Spout\Reader\XLSX\Manager\RowManager; use Box\Spout\Reader\Common\Manager\RowManager;
use Box\Spout\Reader\XLSX\Manager\SharedStringsCaching\CachingStrategyFactory; use Box\Spout\Reader\XLSX\Manager\SharedStringsCaching\CachingStrategyFactory;
use Box\Spout\Reader\XLSX\Manager\SharedStringsManager; use Box\Spout\Reader\XLSX\Manager\SharedStringsManager;
use Box\Spout\Reader\XLSX\Manager\SheetManager; use Box\Spout\Reader\XLSX\Manager\SheetManager;

View File

@ -5,6 +5,7 @@ namespace Box\Spout\Reader\XLSX;
use Box\Spout\Common\Exception\IOException; use Box\Spout\Common\Exception\IOException;
use Box\Spout\Reader\Common\Entity\Cell; use Box\Spout\Reader\Common\Entity\Cell;
use Box\Spout\Reader\Common\Entity\Row; use Box\Spout\Reader\Common\Entity\Row;
use Box\Spout\Reader\Common\Manager\RowManager;
use Box\Spout\Reader\Common\XMLProcessor; use Box\Spout\Reader\Common\XMLProcessor;
use Box\Spout\Reader\Exception\InvalidValueException; use Box\Spout\Reader\Exception\InvalidValueException;
use Box\Spout\Reader\Exception\XMLProcessingException; use Box\Spout\Reader\Exception\XMLProcessingException;
@ -13,7 +14,6 @@ use Box\Spout\Reader\Wrapper\XMLReader;
use Box\Spout\Reader\XLSX\Creator\InternalEntityFactory; use Box\Spout\Reader\XLSX\Creator\InternalEntityFactory;
use Box\Spout\Reader\XLSX\Helper\CellHelper; use Box\Spout\Reader\XLSX\Helper\CellHelper;
use Box\Spout\Reader\XLSX\Helper\CellValueFormatter; use Box\Spout\Reader\XLSX\Helper\CellValueFormatter;
use Box\Spout\Reader\XLSX\Manager\RowManager;
/** /**
* Class RowIterator * Class RowIterator
@ -47,7 +47,7 @@ class RowIterator implements IteratorInterface
/** @var Helper\CellValueFormatter Helper to format cell values */ /** @var Helper\CellValueFormatter Helper to format cell values */
protected $cellValueFormatter; protected $cellValueFormatter;
/** @var \Box\Spout\Reader\XLSX\Manager\RowManager Manages rows */ /** @var \Box\Spout\Reader\Common\Manager\RowManager Manages rows */
protected $rowManager; protected $rowManager;
/** @var \Box\Spout\Reader\XLSX\Creator\InternalEntityFactory Factory to create entities */ /** @var \Box\Spout\Reader\XLSX\Creator\InternalEntityFactory Factory to create entities */
@ -215,7 +215,7 @@ class RowIterator implements IteratorInterface
*/ */
protected function readDataForNextRow() protected function readDataForNextRow()
{ {
$this->currentlyProcessedRow = $this->entityFactory->createRow([]); $this->currentlyProcessedRow = $this->entityFactory->createRow();
try { try {
$this->xmlProcessor->readUntilStopped(); $this->xmlProcessor->readUntilStopped();
@ -386,7 +386,7 @@ class RowIterator implements IteratorInterface
if ($this->lastRowIndexProcessed !== $this->nextRowIndexToBeProcessed) { if ($this->lastRowIndexProcessed !== $this->nextRowIndexToBeProcessed) {
// return empty row if mismatch between last processed row // return empty row if mismatch between last processed row
// and the row that needs to be returned // and the row that needs to be returned
$rowToBeProcessed = $this->entityFactory->createRow([]); $rowToBeProcessed = $this->entityFactory->createRow();
} }
} }

View File

@ -81,4 +81,12 @@ class Row
return $this; return $this;
} }
/**
* @return int
*/
public function getNumCells()
{
return count($this->cells);
}
} }

View File

@ -259,7 +259,7 @@ abstract class WorkbookManagerAbstract implements WorkbookManagerInterface
// update max num columns for the worksheet // update max num columns for the worksheet
$currentMaxNumColumns = $worksheet->getMaxNumColumns(); $currentMaxNumColumns = $worksheet->getMaxNumColumns();
$cellsCount = count($row->getCells()); $cellsCount = $row->getNumCells();
$worksheet->setMaxNumColumns(max($currentMaxNumColumns, $cellsCount)); $worksheet->setMaxNumColumns(max($currentMaxNumColumns, $cellsCount));
} }

View File

@ -111,7 +111,6 @@ class WorksheetManager implements WorksheetManagerInterface
public function addRow(Worksheet $worksheet, Row $row) public function addRow(Worksheet $worksheet, Row $row)
{ {
$cells = $row->getCells(); $cells = $row->getCells();
$cellsCount = count($cells);
$rowStyle = $row->getStyle(); $rowStyle = $row->getStyle();
$data = '<table:table-row table:style-name="ro1">'; $data = '<table:table-row table:style-name="ro1">';
@ -119,7 +118,7 @@ class WorksheetManager implements WorksheetManagerInterface
$currentCellIndex = 0; $currentCellIndex = 0;
$nextCellIndex = 1; $nextCellIndex = 1;
for ($i = 0; $i < $cellsCount; $i++) { for ($i = 0; $i < $row->getNumCells(); $i++) {
/** @var Cell $cell */ /** @var Cell $cell */
$cell = $cells[$currentCellIndex]; $cell = $cells[$currentCellIndex];
/** @var Cell|null $nextCell */ /** @var Cell|null $nextCell */

View File

@ -156,7 +156,7 @@ EOD;
$cellIndex = 0; $cellIndex = 0;
$rowStyle = $row->getStyle(); $rowStyle = $row->getStyle();
$rowIndex = $worksheet->getLastWrittenRowIndex() + 1; $rowIndex = $worksheet->getLastWrittenRowIndex() + 1;
$numCells = count($row->getCells()); $numCells = $row->getNumCells();
$rowXML = '<row r="' . $rowIndex . '" spans="1:' . $numCells . '">'; $rowXML = '<row r="' . $rowIndex . '" spans="1:' . $numCells . '">';

View File

@ -28,7 +28,7 @@ class RowTest extends \PHPUnit\Framework\TestCase
$row = new Row([], null); $row = new Row([], null);
$row->setCells([$this->getCellMock(), $this->getCellMock()]); $row->setCells([$this->getCellMock(), $this->getCellMock()]);
$this->assertEquals(2, count($row->getCells())); $this->assertEquals(2, $row->getNumCells());
} }
/** /**
@ -39,11 +39,11 @@ class RowTest extends \PHPUnit\Framework\TestCase
$row = new Row([], null); $row = new Row([], null);
$row->setCells([$this->getCellMock(), $this->getCellMock()]); $row->setCells([$this->getCellMock(), $this->getCellMock()]);
$this->assertEquals(2, count($row->getCells())); $this->assertEquals(2, $row->getNumCells());
$row->setCells([$this->getCellMock()]); $row->setCells([$this->getCellMock()]);
$this->assertEquals(1, count($row->getCells())); $this->assertEquals(1, $row->getNumCells());
} }
/** /**
@ -53,11 +53,11 @@ class RowTest extends \PHPUnit\Framework\TestCase
{ {
$row = new Row([], null); $row = new Row([], null);
$this->assertEquals(0, count($row->getCells())); $this->assertEquals(0, $row->getNumCells());
$row->setCells([$this->getCellMock(), $this->getCellMock()]); $row->setCells([$this->getCellMock(), $this->getCellMock()]);
$this->assertEquals(2, count($row->getCells())); $this->assertEquals(2, $row->getNumCells());
} }
/** /**
@ -68,11 +68,11 @@ class RowTest extends \PHPUnit\Framework\TestCase
$row = new Row([], null); $row = new Row([], null);
$row->setCells([$this->getCellMock(), $this->getCellMock()]); $row->setCells([$this->getCellMock(), $this->getCellMock()]);
$this->assertEquals(2, count($row->getCells())); $this->assertEquals(2, $row->getNumCells());
$row->addCell($this->getCellMock()); $row->addCell($this->getCellMock());
$this->assertEquals(3, count($row->getCells())); $this->assertEquals(3, $row->getNumCells());
} }
/** /**

View File

@ -1,6 +1,6 @@
<?php <?php
namespace Box\Spout\Reader\XLSX\Manager; namespace Box\Spout\Reader\Common\Manager;
use Box\Spout\Reader\Common\Entity\Cell; use Box\Spout\Reader\Common\Entity\Cell;
use Box\Spout\Reader\Common\Entity\Row; use Box\Spout\Reader\Common\Entity\Row;

View File

@ -1,41 +0,0 @@
<?php
namespace Box\Spout\Reader\ODS\Manager;
use Box\Spout\Reader\Common\Entity\Cell;
use Box\Spout\Reader\Common\Entity\Row;
/**
* Class RowManagerTest
*/
class RowManagerTest extends \PHPUnit_Framework_TestCase
{
/**
* @return array
*/
public function dataProviderForTestIsEmptyRow()
{
return [
// cells, expected isEmpty
[[], true],
[[new Cell('')], true],
[[new Cell(''), new Cell('')], true],
[[new Cell(''), new Cell(''), new Cell('Okay')], false],
];
}
/**
* @dataProvider dataProviderForTestIsEmptyRow
*
* @param array $cells
* @param bool $expectedIsEmpty
* @return void
*/
public function testIsEmptyRow(array $cells, $expectedIsEmpty)
{
$rowManager = new RowManager();
$row = new Row($cells);
$this->assertEquals($expectedIsEmpty, $rowManager->isEmpty($row));
}
}

View File

@ -39,7 +39,7 @@ class RowTest extends TestCase
$row = new Row([], null); $row = new Row([], null);
$row->setCells([$this->getCellMock(), $this->getCellMock()]); $row->setCells([$this->getCellMock(), $this->getCellMock()]);
$this->assertEquals(2, count($row->getCells())); $this->assertEquals(2, $row->getNumCells());
} }
/** /**
@ -50,11 +50,11 @@ class RowTest extends TestCase
$row = new Row([], null); $row = new Row([], null);
$row->setCells([$this->getCellMock(), $this->getCellMock()]); $row->setCells([$this->getCellMock(), $this->getCellMock()]);
$this->assertEquals(2, count($row->getCells())); $this->assertEquals(2, $row->getNumCells());
$row->setCells([$this->getCellMock()]); $row->setCells([$this->getCellMock()]);
$this->assertEquals(1, count($row->getCells())); $this->assertEquals(1, $row->getNumCells());
} }
/** /**
@ -64,11 +64,11 @@ class RowTest extends TestCase
{ {
$row = new Row([], null); $row = new Row([], null);
$this->assertEquals(0, count($row->getCells())); $this->assertEquals(0, $row->getNumCells());
$row->setCells([$this->getCellMock(), $this->getCellMock()]); $row->setCells([$this->getCellMock(), $this->getCellMock()]);
$this->assertEquals(2, count($row->getCells())); $this->assertEquals(2, $row->getNumCells());
} }
/** /**
@ -79,11 +79,11 @@ class RowTest extends TestCase
$row = new Row([], null); $row = new Row([], null);
$row->setCells([$this->getCellMock(), $this->getCellMock()]); $row->setCells([$this->getCellMock(), $this->getCellMock()]);
$this->assertEquals(2, count($row->getCells())); $this->assertEquals(2, $row->getNumCells());
$row->addCell($this->getCellMock()); $row->addCell($this->getCellMock());
$this->assertEquals(3, count($row->getCells())); $this->assertEquals(3, $row->getNumCells());
} }
/** /**