diff --git a/.php_cs.dist b/.php_cs.dist index 04bf320..c055e4e 100644 --- a/.php_cs.dist +++ b/.php_cs.dist @@ -42,7 +42,6 @@ $config = PhpCsFixer\Config::create() 'simplified_null_return' => false, 'single_line_comment_style' => ['comment_types' => ['hash']], 'strict_comparison' => true, - 'void_return' => true, 'yoda_style' => ['equal' => false, 'identical' => false], ]); diff --git a/src/Spout/Writer/CSV/Writer.php b/src/Spout/Writer/CSV/Writer.php index 7f9c814..0f4d5dd 100644 --- a/src/Spout/Writer/CSV/Writer.php +++ b/src/Spout/Writer/CSV/Writer.php @@ -5,6 +5,7 @@ namespace Box\Spout\Writer\CSV; use Box\Spout\Common\Exception\IOException; use Box\Spout\Common\Helper\EncodingHelper; use Box\Spout\Writer\Common\Entity\Options; +use Box\Spout\Writer\Common\Entity\Row; use Box\Spout\Writer\WriterAbstract; /** @@ -78,20 +79,20 @@ class Writer extends WriterAbstract } /** - * Adds data to the currently opened writer. + * Adds a row to the currently opened writer. * - * @param array $dataRow Array containing data to be written. - * Example $dataRow = ['data1', 1234, null, '', 'data5']; - * @param \Box\Spout\Writer\Common\Entity\Style\Style $style Ignored here since CSV does not support styling. - * @throws \Box\Spout\Common\Exception\IOException If unable to write data + * @param Row $row The row containing cells and styles + * + * @throws IOException If unable to write data * @return void + * @internal param \Box\Spout\Writer\Common\Entity\Style\Style $style Ignored here since CSV does not support styling. */ - protected function addRowToWriter(array $dataRow, $style) + protected function addRowToWriter(Row $row) { $fieldDelimiter = $this->optionsManager->getOption(Options::FIELD_DELIMITER); $fieldEnclosure = $this->optionsManager->getOption(Options::FIELD_ENCLOSURE); - $wasWriteSuccessful = $this->globalFunctionsHelper->fputcsv($this->filePointer, $dataRow, $fieldDelimiter, $fieldEnclosure); + $wasWriteSuccessful = $this->globalFunctionsHelper->fputcsv($this->filePointer, $row->getCells(), $fieldDelimiter, $fieldEnclosure); if ($wasWriteSuccessful === false) { throw new IOException('Unable to write data'); } diff --git a/src/Spout/Writer/Common/Creator/EntityFactory.php b/src/Spout/Writer/Common/Creator/EntityFactory.php index 04324aa..b9ebef4 100644 --- a/src/Spout/Writer/Common/Creator/EntityFactory.php +++ b/src/Spout/Writer/Common/Creator/EntityFactory.php @@ -3,10 +3,14 @@ namespace Box\Spout\Writer\Common\Creator; use Box\Spout\Writer\Common\Entity\Cell; +use Box\Spout\Writer\Common\Entity\Row; use Box\Spout\Writer\Common\Entity\Sheet; +use Box\Spout\Writer\Common\Entity\Style\Style; use Box\Spout\Writer\Common\Entity\Workbook; use Box\Spout\Writer\Common\Entity\Worksheet; +use Box\Spout\Writer\Common\Manager\RowManager; use Box\Spout\Writer\Common\Manager\SheetManager; +use Box\Spout\Writer\Common\Manager\Style\StyleMerger; /** * Class EntityFactory @@ -47,7 +51,7 @@ class EntityFactory * @param mixed $cellValue * @return Cell */ - public function createCell($cellValue) + public static function createCell($cellValue) { return new Cell($cellValue); } @@ -59,4 +63,17 @@ class EntityFactory { return new \ZipArchive(); } + + /** + * @param array $cells + * @param Style|null $style + * @return Row + */ + public static function createRow(array $cells, Style $style = null) + { + $styleMerger = new StyleMerger(); + $rowManager = new RowManager($styleMerger); + + return new Row($cells, $style, $rowManager); + } } diff --git a/src/Spout/Writer/Common/Entity/Cell.php b/src/Spout/Writer/Common/Entity/Cell.php index f869e2c..9660b42 100644 --- a/src/Spout/Writer/Common/Entity/Cell.php +++ b/src/Spout/Writer/Common/Entity/Cell.php @@ -2,7 +2,9 @@ namespace Box\Spout\Writer\Common\Entity; +use Box\Spout\Writer\Common\Entity\Style\Style; use Box\Spout\Writer\Common\Helper\CellHelper; +use Box\Spout\Writer\Common\Manager\Style\StyleMerger; /** * Class Cell @@ -53,16 +55,29 @@ class Cell protected $type; /** - * Cell constructor. - * @param $value mixed + * The cell style + * @var Style */ - public function __construct($value) + protected $style; + + /** + * @var StyleMerger + */ + protected $styleMerger; + + /** + * @param $value mixed + * @param Style|null $style + */ + public function __construct($value, Style $style = null) { $this->setValue($value); + $this->setStyle($style); + $this->styleMerger = new StyleMerger(); } /** - * @param $value mixed|null + * @param mixed|null $value */ public function setValue($value) { @@ -78,6 +93,22 @@ class Cell return $this->value; } + /** + * @param Style|null $style + */ + public function setStyle($style) + { + $this->style = $style ?: new Style(); + } + + /** + * @return Style + */ + public function getStyle() + { + return $this->style; + } + /** * @return int|null */ @@ -88,6 +119,7 @@ class Cell /** * Get the current value type + * * @param mixed|null $value * @return int */ @@ -127,6 +159,7 @@ class Cell /** * Not used at the moment + * * @return bool */ public function isFormula() @@ -165,4 +198,20 @@ class Cell { return (string) $this->value; } + + /** + * @param Style|null $style + * @return Cell + */ + public function applyStyle($style) + { + if ($style === null) { + return $this; + } + + $mergedStyle = $this->styleMerger->merge($this->style, $style); + $this->setStyle($mergedStyle); + + return $this; + } } diff --git a/src/Spout/Writer/Common/Entity/Row.php b/src/Spout/Writer/Common/Entity/Row.php new file mode 100644 index 0000000..fae771f --- /dev/null +++ b/src/Spout/Writer/Common/Entity/Row.php @@ -0,0 +1,126 @@ +setCells($cells) + ->setStyle($style); + + $this->rowManager = $rowManager; + } + + /** + * @return Cell[] $cells + */ + public function getCells() + { + return $this->cells; + } + + /** + * @param Cell[] $cells + * @return $this + */ + public function setCells(array $cells) + { + $this->cells = []; + foreach ($cells as $cell) { + $this->addCell($cell); + } + + return $this; + } + + /** + * @return Style + */ + public function getStyle() + { + return $this->style; + } + + /** + * @param Style|null $style + * @return Row + */ + public function setStyle($style) + { + $this->style = $style ?: new Style(); + + return $this; + } + + /** + * @param Style $style + * @return Row + */ + public function applyStyle($style) + { + $this->rowManager->applyStyle($this, $style); + + return $this; + } + + /** + * @param Cell $cell + * @return Row + */ + public function addCell(Cell $cell) + { + $this->cells[] = $cell; + + return $this; + } + + /** + * Returns whether a row has cells + * + * @return bool + */ + public function hasCells() + { + return $this->rowManager->hasCells($this); + } + + /** + * Detect whether this row is considered empty. + * An empty row has either no cells at all - or only empty cells + * + * @return bool + */ + public function isEmpty() + { + return $this->rowManager->isEmpty($this); + } +} diff --git a/src/Spout/Writer/Common/Manager/CellManager.php b/src/Spout/Writer/Common/Manager/CellManager.php new file mode 100644 index 0000000..d320802 --- /dev/null +++ b/src/Spout/Writer/Common/Manager/CellManager.php @@ -0,0 +1,36 @@ +styleMerger = $styleMerger; + } + + /** + * Merges a Style into a cell's Style. + * + * @param Cell $cell + * @param Style $style + * @return $this + */ + public function applyStyle(Cell $cell, Style $style) + { + $mergedStyle = $this->styleMerger->merge($cell->getStyle(), $style); + $cell->setStyle($mergedStyle); + } +} diff --git a/src/Spout/Writer/Common/Manager/RowManager.php b/src/Spout/Writer/Common/Manager/RowManager.php new file mode 100644 index 0000000..109fa06 --- /dev/null +++ b/src/Spout/Writer/Common/Manager/RowManager.php @@ -0,0 +1,59 @@ +styleMerger = $styleMerger; + } + + /** + * @param Row $row + * @param Style $style + * @return $this + */ + public function applyStyle(Row $row, Style $style) + { + $mergedStyle = $this->styleMerger->merge($row->getStyle(), $style); + $row->setStyle($mergedStyle); + } + + /** + * Returns whether a row has cells + * + * @param Row $row + * @return bool + */ + public function hasCells(Row $row) + { + return count($row->getCells()) !== 0; + } + + /** + * Detect whether a row is considered empty. + * An empty row has either no cells at all - or only one empty cell + * + * @param Row $row + * @return bool + */ + public function isEmpty(Row $row) + { + $cells = $row->getCells(); + + return count($cells) === 0 || (count($cells) === 1 && $cells[0]->isEmpty()); + } +} diff --git a/src/Spout/Writer/Common/Manager/Style/StyleManager.php b/src/Spout/Writer/Common/Manager/Style/StyleManager.php index 14a4c7e..9006d02 100644 --- a/src/Spout/Writer/Common/Manager/Style/StyleManager.php +++ b/src/Spout/Writer/Common/Manager/Style/StyleManager.php @@ -2,6 +2,7 @@ namespace Box\Spout\Writer\Common\Manager\Style; +use Box\Spout\Writer\Common\Entity\Cell; use Box\Spout\Writer\Common\Entity\Style\Style; /** @@ -48,13 +49,12 @@ class StyleManager implements StyleManagerInterface * Apply additional styles if the given row needs it. * Typically, set "wrap text" if a cell contains a new line. * - * @param Style $style The original style - * @param array $dataRow The row the style will be applied to - * @return Style The updated style + * @param Cell $cell + * @return Style */ - public function applyExtraStylesIfNeeded($style, $dataRow) + public function applyExtraStylesIfNeeded(Cell $cell) { - $updatedStyle = $this->applyWrapTextIfCellContainsNewLine($style, $dataRow); + $updatedStyle = $this->applyWrapTextIfCellContainsNewLine($cell); return $updatedStyle; } @@ -68,24 +68,22 @@ class StyleManager implements StyleManagerInterface * A workaround would be to encode "\n" as "_x000D_" but it does not work * on the Windows version of Excel... * - * @param Style $style The original style - * @param array $dataRow The row the style will be applied to - * @return Style The eventually updated style + * @param Cell $cell The cell the style should be applied to + * @return \Box\Spout\Writer\Common\Entity\Style\Style The eventually updated style */ - protected function applyWrapTextIfCellContainsNewLine($style, $dataRow) + protected function applyWrapTextIfCellContainsNewLine(Cell $cell) { + $cellStyle = $cell->getStyle(); + // if the "wrap text" option is already set, no-op - if ($style->hasSetWrapText()) { - return $style; + if ($cellStyle->hasSetWrapText()) { + return $cellStyle; } - foreach ($dataRow as $cell) { - if (is_string($cell) && strpos($cell, "\n") !== false) { - $style->setShouldWrapText(); - break; - } + if ($cell->isString() && strpos($cell->getValue(), "\n") !== false) { + $cellStyle->setShouldWrapText(); } - return $style; + return $cellStyle; } } diff --git a/src/Spout/Writer/Common/Manager/Style/StyleManagerInterface.php b/src/Spout/Writer/Common/Manager/Style/StyleManagerInterface.php index 70de0ef..49ec1d7 100644 --- a/src/Spout/Writer/Common/Manager/Style/StyleManagerInterface.php +++ b/src/Spout/Writer/Common/Manager/Style/StyleManagerInterface.php @@ -2,6 +2,7 @@ namespace Box\Spout\Writer\Common\Manager\Style; +use Box\Spout\Writer\Common\Entity\Cell; use Box\Spout\Writer\Common\Entity\Style\Style; /** @@ -22,9 +23,8 @@ interface StyleManagerInterface * Apply additional styles if the given row needs it. * Typically, set "wrap text" if a cell contains a new line. * - * @param Style $style The original style - * @param array $dataRow The row the style will be applied to - * @return Style The updated style + * @param Cell $cell + * @return \Box\Spout\Writer\Common\Entity\Style\Style The updated style */ - public function applyExtraStylesIfNeeded($style, $dataRow); + public function applyExtraStylesIfNeeded(Cell $cell); } diff --git a/src/Spout/Writer/Common/Manager/WorkbookManagerAbstract.php b/src/Spout/Writer/Common/Manager/WorkbookManagerAbstract.php index b4308bb..ebf59a0 100644 --- a/src/Spout/Writer/Common/Manager/WorkbookManagerAbstract.php +++ b/src/Spout/Writer/Common/Manager/WorkbookManagerAbstract.php @@ -7,8 +7,8 @@ use Box\Spout\Common\Manager\OptionsManagerInterface; use Box\Spout\Writer\Common\Creator\EntityFactory; use Box\Spout\Writer\Common\Creator\ManagerFactoryInterface; use Box\Spout\Writer\Common\Entity\Options; +use Box\Spout\Writer\Common\Entity\Row; use Box\Spout\Writer\Common\Entity\Sheet; -use Box\Spout\Writer\Common\Entity\Style\Style; use Box\Spout\Writer\Common\Entity\Workbook; use Box\Spout\Writer\Common\Entity\Worksheet; use Box\Spout\Writer\Common\Helper\FileSystemWithRootFolderHelperInterface; @@ -198,21 +198,20 @@ abstract class WorkbookManagerAbstract implements WorkbookManagerInterface } /** - * Adds data to the current sheet. + * Adds a row to the current sheet. * If shouldCreateNewSheetsAutomatically option is set to true, it will handle pagination * with the creation of new worksheets if one worksheet has reached its maximum capicity. * - * @param array $dataRow Array containing data to be written. Cannot be empty. - * Example $dataRow = ['data1', 1234, null, '', 'data5']; - * @param Style $style Style to be applied to the row. + * @param Row $row The row to added * @throws IOException If trying to create a new sheet and unable to open the sheet for writing * @throws WriterException If unable to write data * @return void + * @return void */ - public function addRowToCurrentWorksheet($dataRow, Style $style) + public function addRowToCurrentWorksheet(Row $row) { $currentWorksheet = $this->getCurrentWorksheet(); - $hasReachedMaxRows = $this->hasCurrentWorkseetReachedMaxRows(); + $hasReachedMaxRows = $this->hasCurrentWorksheetReachedMaxRows(); // if we reached the maximum number of rows for the current sheet... if ($hasReachedMaxRows) { @@ -220,19 +219,19 @@ abstract class WorkbookManagerAbstract implements WorkbookManagerInterface if ($this->optionManager->getOption(Options::SHOULD_CREATE_NEW_SHEETS_AUTOMATICALLY)) { $currentWorksheet = $this->addNewSheetAndMakeItCurrent(); - $this->addRowWithStyleToWorksheet($currentWorksheet, $dataRow, $style); + $this->addRowToWorksheet($currentWorksheet, $row); } else { // otherwise, do nothing as the data won't be written anyways } } else { - $this->addRowWithStyleToWorksheet($currentWorksheet, $dataRow, $style); + $this->addRowToWorksheet($currentWorksheet, $row); } } /** * @return bool Whether the current worksheet has reached the maximum number of rows per sheet. */ - private function hasCurrentWorkseetReachedMaxRows() + private function hasCurrentWorksheetReachedMaxRows() { $currentWorksheet = $this->getCurrentWorksheet(); @@ -243,21 +242,18 @@ abstract class WorkbookManagerAbstract implements WorkbookManagerInterface * Adds data with the given style to the given sheet. * * @param Worksheet $worksheet Worksheet to write the row to - * @param array $dataRow Array containing data to be written. Cannot be empty. - * Example $dataRow = ['data1', 1234, null, '', 'data5']; - * @param Style $style Style to be applied to the row. + * @param Row $row The row to be added * @throws WriterException If unable to write data * @return void + * @return void */ - private function addRowWithStyleToWorksheet(Worksheet $worksheet, $dataRow, Style $style) + private function addRowToWorksheet(Worksheet $worksheet, Row $row) { - $updatedStyle = $this->styleManager->applyExtraStylesIfNeeded($style, $dataRow); - $registeredStyle = $this->styleManager->registerStyle($updatedStyle); - $this->worksheetManager->addRow($worksheet, $dataRow, $registeredStyle); + $this->worksheetManager->addRow($worksheet, $row); // update max num columns for the worksheet $currentMaxNumColumns = $worksheet->getMaxNumColumns(); - $cellsCount = count($dataRow); + $cellsCount = count($row->getCells()); $worksheet->setMaxNumColumns(max($currentMaxNumColumns, $cellsCount)); } diff --git a/src/Spout/Writer/Common/Manager/WorkbookManagerInterface.php b/src/Spout/Writer/Common/Manager/WorkbookManagerInterface.php index dbc5780..6e9221d 100644 --- a/src/Spout/Writer/Common/Manager/WorkbookManagerInterface.php +++ b/src/Spout/Writer/Common/Manager/WorkbookManagerInterface.php @@ -3,8 +3,8 @@ namespace Box\Spout\Writer\Common\Manager; use Box\Spout\Common\Exception\IOException; +use Box\Spout\Writer\Common\Entity\Row; use Box\Spout\Writer\Common\Entity\Sheet; -use Box\Spout\Writer\Common\Entity\Style\Style; use Box\Spout\Writer\Common\Entity\Workbook; use Box\Spout\Writer\Common\Entity\Worksheet; use Box\Spout\Writer\Exception\SheetNotFoundException; @@ -53,18 +53,17 @@ interface WorkbookManagerInterface public function setCurrentSheet(Sheet $sheet); /** - * Adds data to the current sheet. + * Adds a row to the current sheet. * If shouldCreateNewSheetsAutomatically option is set to true, it will handle pagination * with the creation of new worksheets if one worksheet has reached its maximum capicity. * - * @param array $dataRow Array containing data to be written. Cannot be empty. - * Example $dataRow = ['data1', 1234, null, '', 'data5']; - * @param Style $style Style to be applied to the row. + * @param Row $row The row to added * @throws IOException If trying to create a new sheet and unable to open the sheet for writing * @throws WriterException If unable to write data * @return void + * @return void */ - public function addRowToCurrentWorksheet($dataRow, Style $style); + public function addRowToCurrentWorksheet(Row $row); /** * Closes the workbook and all its associated sheets. diff --git a/src/Spout/Writer/Common/Manager/WorksheetManagerInterface.php b/src/Spout/Writer/Common/Manager/WorksheetManagerInterface.php index 70e6bd5..81e4d39 100644 --- a/src/Spout/Writer/Common/Manager/WorksheetManagerInterface.php +++ b/src/Spout/Writer/Common/Manager/WorksheetManagerInterface.php @@ -2,7 +2,7 @@ namespace Box\Spout\Writer\Common\Manager; -use Box\Spout\Writer\Common\Entity\Style\Style; +use Box\Spout\Writer\Common\Entity\Row; use Box\Spout\Writer\Common\Entity\Worksheet; /** @@ -12,17 +12,16 @@ use Box\Spout\Writer\Common\Entity\Worksheet; interface WorksheetManagerInterface { /** - * Adds data to the worksheet. + * Adds a row to the worksheet. * * @param Worksheet $worksheet The worksheet to add the row to - * @param array $dataRow Array containing data to be written. Cannot be empty. - * Example $dataRow = ['data1', 1234, null, '', 'data5']; - * @param Style $rowStyle Style to be applied to the row. NULL means use default style. + * @param Row $row The row to be added * @throws \Box\Spout\Common\Exception\IOException If the data cannot be written * @throws \Box\Spout\Common\Exception\InvalidArgumentException If a cell value's type is not supported * @return void + * @return void */ - public function addRow(Worksheet $worksheet, $dataRow, $rowStyle); + public function addRow(Worksheet $worksheet, Row $row); /** * Prepares the worksheet to accept data diff --git a/src/Spout/Writer/ODS/Creator/ManagerFactory.php b/src/Spout/Writer/ODS/Creator/ManagerFactory.php index ca84657..7624c4c 100644 --- a/src/Spout/Writer/ODS/Creator/ManagerFactory.php +++ b/src/Spout/Writer/ODS/Creator/ManagerFactory.php @@ -46,7 +46,7 @@ class ManagerFactory implements ManagerFactoryInterface $fileSystemHelper->createBaseFilesAndFolders(); $styleManager = $this->createStyleManager($optionsManager); - $worksheetManager = $this->createWorksheetManager(); + $worksheetManager = $this->createWorksheetManager($styleManager); return new WorkbookManager( $workbook, @@ -60,14 +60,15 @@ class ManagerFactory implements ManagerFactoryInterface } /** + * @param StyleManager $styleManager * @return WorksheetManager */ - private function createWorksheetManager() + private function createWorksheetManager(StyleManager $styleManager) { $stringsEscaper = $this->helperFactory->createStringsEscaper(); $stringsHelper = $this->helperFactory->createStringHelper(); - return new WorksheetManager($stringsEscaper, $stringsHelper, $this->entityFactory); + return new WorksheetManager($styleManager, $stringsEscaper, $stringsHelper); } /** diff --git a/src/Spout/Writer/ODS/Manager/WorksheetManager.php b/src/Spout/Writer/ODS/Manager/WorksheetManager.php index a0562b2..225e3a8 100644 --- a/src/Spout/Writer/ODS/Manager/WorksheetManager.php +++ b/src/Spout/Writer/ODS/Manager/WorksheetManager.php @@ -4,12 +4,13 @@ namespace Box\Spout\Writer\ODS\Manager; use Box\Spout\Common\Exception\InvalidArgumentException; use Box\Spout\Common\Exception\IOException; +use Box\Spout\Common\Helper\Escaper\ODS as ODSEscaper; use Box\Spout\Common\Helper\StringHelper; -use Box\Spout\Writer\Common\Creator\EntityFactory; use Box\Spout\Writer\Common\Entity\Cell; -use Box\Spout\Writer\Common\Entity\Style\Style; +use Box\Spout\Writer\Common\Entity\Row; use Box\Spout\Writer\Common\Entity\Worksheet; use Box\Spout\Writer\Common\Manager\WorksheetManagerInterface; +use Box\Spout\Writer\ODS\Manager\Style\StyleManager; /** * Class WorksheetManager @@ -23,24 +24,23 @@ class WorksheetManager implements WorksheetManagerInterface /** @var StringHelper String helper */ private $stringHelper; - /** @var EntityFactory Factory to create entities */ - private $entityFactory; + /** @var StyleManager Manages styles */ + private $styleManager; /** * WorksheetManager constructor. - * - * @param \Box\Spout\Common\Helper\Escaper\ODS $stringsEscaper + * @param StyleManager $styleManager + * @param ODSEscaper $stringsEscaper * @param StringHelper $stringHelper - * @param EntityFactory $entityFactory */ public function __construct( - \Box\Spout\Common\Helper\Escaper\ODS $stringsEscaper, - StringHelper $stringHelper, - EntityFactory $entityFactory + StyleManager $styleManager, + ODSEscaper $stringsEscaper, + StringHelper $stringHelper ) { $this->stringsEscaper = $stringsEscaper; $this->stringHelper = $stringHelper; - $this->entityFactory = $entityFactory; + $this->styleManager = $styleManager; } /** @@ -91,24 +91,20 @@ class WorksheetManager implements WorksheetManagerInterface } /** - * Adds data to the given worksheet. + * Adds a row to the worksheet. * * @param Worksheet $worksheet The worksheet to add the row to - * @param array $dataRow Array containing data to be written. Cannot be empty. - * Example $dataRow = ['data1', 1234, null, '', 'data5']; - * @param Style $rowStyle Style to be applied to the row. NULL means use default style. + * @param Row $row The row to be added * @throws IOException If the data cannot be written * @throws InvalidArgumentException If a cell value's type is not supported * @return void + * + * @return void */ - public function addRow(Worksheet $worksheet, $dataRow, $rowStyle) + public function addRow(Worksheet $worksheet, Row $row) { - // $dataRow can be an associative array. We need to transform - // it into a regular array, as we'll use the numeric indexes. - $dataRowWithNumericIndexes = array_values($dataRow); - - $styleIndex = ($rowStyle->getId() + 1); // 1-based - $cellsCount = count($dataRow); + $cells = $row->getCells(); + $cellsCount = count($cells); $data = ''; @@ -116,14 +112,21 @@ class WorksheetManager implements WorksheetManagerInterface $nextCellIndex = 1; for ($i = 0; $i < $cellsCount; $i++) { - $currentCellValue = $dataRowWithNumericIndexes[$currentCellIndex]; + /** @var Cell $cell */ + $cell = $cells[$currentCellIndex]; + /** @var Cell|null $nextCell */ + $nextCell = isset($cells[$nextCellIndex]) ? $cells[$nextCellIndex] : null; + + // @TODO refactoring: move this to its own method + if ($nextCell === null || $cell->getValue() !== $nextCell->getValue()) { + // Apply styles - the row style is merged at this point + $cell->applyStyle($row->getStyle()); + $this->styleManager->applyExtraStylesIfNeeded($cell); + $registeredStyle = $this->styleManager->registerStyle($cell->getStyle()); + $styleIndex = $registeredStyle->getId() + 1; // 1-based - // Using isset here because it is way faster than array_key_exists... - if (!isset($dataRowWithNumericIndexes[$nextCellIndex]) || - $currentCellValue !== $dataRowWithNumericIndexes[$nextCellIndex]) { $numTimesValueRepeated = ($nextCellIndex - $currentCellIndex); - $data .= $this->getCellXML($currentCellValue, $styleIndex, $numTimesValueRepeated); - + $data .= $this->getCellXML($cell, $styleIndex, $numTimesValueRepeated); $currentCellIndex = $nextCellIndex; } @@ -145,13 +148,13 @@ class WorksheetManager implements WorksheetManagerInterface /** * Returns the cell XML content, given its value. * - * @param mixed $cellValue The value to be written + * @param Cell $cell The cell to be written * @param int $styleIndex Index of the used style * @param int $numTimesValueRepeated Number of times the value is consecutively repeated * @throws \Box\Spout\Common\Exception\InvalidArgumentException If a cell value's type is not supported * @return string The cell XML content */ - private function getCellXML($cellValue, $styleIndex, $numTimesValueRepeated) + protected function getCellXML(Cell $cell, $styleIndex, $numTimesValueRepeated) { $data = 'entityFactory->createCell($cellValue); - } - if ($cell->isString()) { $data .= ' office:value-type="string" calcext:value-type="string">'; diff --git a/src/Spout/Writer/WriterAbstract.php b/src/Spout/Writer/WriterAbstract.php index 0cdebf4..ad9c301 100644 --- a/src/Spout/Writer/WriterAbstract.php +++ b/src/Spout/Writer/WriterAbstract.php @@ -9,6 +9,7 @@ use Box\Spout\Common\Exception\SpoutException; use Box\Spout\Common\Helper\GlobalFunctionsHelper; use Box\Spout\Common\Manager\OptionsManagerInterface; use Box\Spout\Writer\Common\Entity\Options; +use Box\Spout\Writer\Common\Entity\Row; use Box\Spout\Writer\Common\Entity\Style\Style; use Box\Spout\Writer\Common\Manager\Style\StyleMerger; use Box\Spout\Writer\Exception\WriterAlreadyOpenedException; @@ -42,9 +43,6 @@ abstract class WriterAbstract implements WriterInterface /** @var StyleMerger Helps merge styles together */ protected $styleMerger; - /** @var Style Style to be applied to the next written row(s) */ - protected $rowStyle; - /** @var string Content-Type value for the header - to be defined by child class */ protected static $headerContentType; @@ -64,8 +62,6 @@ abstract class WriterAbstract implements WriterInterface $this->styleMerger = $styleMerger; $this->globalFunctionsHelper = $globalFunctionsHelper; $this->helperFactory = $helperFactory; - - $this->resetRowStyleToDefault(); } /** @@ -77,14 +73,12 @@ abstract class WriterAbstract implements WriterInterface abstract protected function openWriter(); /** - * Adds data to the currently openned writer. + * Adds a row to the currently opened writer. * - * @param array $dataRow Array containing data to be streamed. - * Example $dataRow = ['data1', 1234, null, '', 'data5']; - * @param Style $style Style to be applied to the written row + * @param Row $row The row containing cells and styles * @return void */ - abstract protected function addRowToWriter(array $dataRow, $style); + abstract protected function addRowToWriter(Row $row); /** * Closes the streamer, preventing any additional writing. @@ -94,9 +88,7 @@ abstract class WriterAbstract implements WriterInterface abstract protected function closeWriter(); /** - * Sets the default styles for all rows added with "addRow". - * Overriding the default style instead of using "addRowWithStyle" improves performance by 20%. - * @see https://github.com/box/spout/issues/272 + * Sets the default styles for all rows added with "addRow" * * @param Style $defaultStyle * @return WriterAbstract @@ -104,19 +96,12 @@ abstract class WriterAbstract implements WriterInterface public function setDefaultRowStyle($defaultStyle) { $this->optionsManager->setOption(Options::DEFAULT_ROW_STYLE, $defaultStyle); - $this->resetRowStyleToDefault(); return $this; } /** - * Inits the writer and opens it to accept data. - * By using this method, the data will be written to a file. - * - * @api - * @param string $outputFilePath Path of the output file that will contain the data - * @throws \Box\Spout\Common\Exception\IOException If the writer cannot be opened or if the given path is not writable - * @return WriterAbstract + * {@inheritdoc} */ public function openToFile($outputFilePath) { @@ -132,15 +117,9 @@ abstract class WriterAbstract implements WriterInterface } /** - * Inits the writer and opens it to accept data. - * By using this method, the data will be outputted directly to the browser. - * * @codeCoverageIgnore * - * @api - * @param string $outputFileName Name of the output file that will contain the data. If a path is passed in, only the file name will be kept - * @throws \Box\Spout\Common\Exception\IOException If the writer cannot be opened - * @return WriterAbstract + * {@inheritdoc} */ public function openToBrowser($outputFileName) { @@ -203,24 +182,15 @@ abstract class WriterAbstract implements WriterInterface } /** - * Write given data to the output. New data will be appended to end of stream. - * - * @param array $dataRow Array containing data to be streamed. - * If empty, no data is added (i.e. not even as a blank row) - * Example: $dataRow = ['data1', 1234, null, '', 'data5', false]; - * @api - * @throws \Box\Spout\Writer\Exception\WriterNotOpenedException If this function is called before opening the writer - * @throws \Box\Spout\Common\Exception\IOException If unable to write data - * @throws \Box\Spout\Common\Exception\SpoutException If anything else goes wrong while writing data - * @return WriterAbstract + * {@inheritdoc} */ - public function addRow(array $dataRow) + public function addRow(Row $row) { if ($this->isWriterOpened) { - // empty $dataRow should not add an empty line - if (!empty($dataRow)) { + if ($row->hasCells()) { try { - $this->addRowToWriter($dataRow, $this->rowStyle); + $this->applyDefaultRowStyle($row); + $this->addRowToWriter($row); } catch (SpoutException $e) { // if an exception occurs while writing data, // close the writer and remove all files created so far. @@ -238,115 +208,43 @@ abstract class WriterAbstract implements WriterInterface } /** - * Write given data to the output and apply the given style. - * @see addRow - * - * @api - * @param array $dataRow Array of array containing data to be streamed. - * @param Style $style Style to be applied to the row. - * @throws \Box\Spout\Common\Exception\InvalidArgumentException If the input param is not valid - * @throws \Box\Spout\Writer\Exception\WriterNotOpenedException If this function is called before opening the writer - * @throws \Box\Spout\Common\Exception\IOException If unable to write data - * @return WriterAbstract - */ - public function addRowWithStyle(array $dataRow, $style) - { - if (!$style instanceof Style) { - throw new InvalidArgumentException('The "$style" argument must be a Style instance and cannot be NULL.'); - } - - $this->setRowStyle($style); - $this->addRow($dataRow); - $this->resetRowStyleToDefault(); - - return $this; - } - - /** - * Write given data to the output. New data will be appended to end of stream. - * - * @api - * @param array $dataRows Array of array containing data to be streamed. - * If a row is empty, it won't be added (i.e. not even as a blank row) - * Example: $dataRows = [ - * ['data11', 12, , '', 'data13'], - * ['data21', 'data22', null, false], - * ]; - * @throws \Box\Spout\Common\Exception\InvalidArgumentException If the input param is not valid - * @throws \Box\Spout\Writer\Exception\WriterNotOpenedException If this function is called before opening the writer - * @throws \Box\Spout\Common\Exception\IOException If unable to write data - * @return WriterAbstract + * {@inheritdoc} */ public function addRows(array $dataRows) { - if (!empty($dataRows)) { - $firstRow = reset($dataRows); - if (!is_array($firstRow)) { - throw new InvalidArgumentException('The input should be an array of arrays'); + foreach ($dataRows as $dataRow) { + if (!$dataRow instanceof Row) { + $this->closeAndAttemptToCleanupAllFiles(); + throw new InvalidArgumentException(); } - foreach ($dataRows as $dataRow) { - $this->addRow($dataRow); - } + $this->addRow($dataRow); } return $this; } /** - * Write given data to the output and apply the given style. - * @see addRows + * @TODO: Move this into styleMerger * - * @api - * @param array $dataRows Array of array containing data to be streamed. - * @param Style $style Style to be applied to the rows. - * @throws \Box\Spout\Common\Exception\InvalidArgumentException If the input param is not valid - * @throws \Box\Spout\Writer\Exception\WriterNotOpenedException If this function is called before opening the writer - * @throws \Box\Spout\Common\Exception\IOException If unable to write data - * @return WriterAbstract + * @param Row $row + * @return $this */ - public function addRowsWithStyle(array $dataRows, $style) + private function applyDefaultRowStyle(Row $row) { - if (!$style instanceof Style) { - throw new InvalidArgumentException('The "$style" argument must be a Style instance and cannot be NULL.'); - } - - $this->setRowStyle($style); - $this->addRows($dataRows); - $this->resetRowStyleToDefault(); - - return $this; - } - - /** - * Sets the style to be applied to the next written rows - * until it is changed or reset. - * - * @param Style $style - * @return void - */ - private function setRowStyle($style) - { - // Merge given style with the default one to inherit custom properties $defaultRowStyle = $this->optionsManager->getOption(Options::DEFAULT_ROW_STYLE); - $this->rowStyle = $this->styleMerger->merge($style, $defaultRowStyle); - } + if ($defaultRowStyle === null) { + return $this; + } - /** - * Resets the style to be applied to the next written rows. - * - * @return void - */ - private function resetRowStyleToDefault() - { - $this->rowStyle = $this->optionsManager->getOption(Options::DEFAULT_ROW_STYLE); + $mergedStyle = $this->styleMerger->merge($row->getStyle(), $defaultRowStyle); + $row->setStyle($mergedStyle); } /** * Closes the writer. This will close the streamer as well, preventing new data * to be written to the file. * - * @api * @return void */ public function close() diff --git a/src/Spout/Writer/WriterInterface.php b/src/Spout/Writer/WriterInterface.php index 375dbd9..fd8d145 100644 --- a/src/Spout/Writer/WriterInterface.php +++ b/src/Spout/Writer/WriterInterface.php @@ -2,7 +2,7 @@ namespace Box\Spout\Writer; -use Box\Spout\Writer\Common\Entity\Style\Style; +use Box\Spout\Writer\Common\Entity\Row; /** * Interface WriterInterface @@ -10,7 +10,7 @@ use Box\Spout\Writer\Common\Entity\Style\Style; interface WriterInterface { /** - * Inits the writer and opens it to accept data. + * Initializes the writer and opens it to accept data. * By using this method, the data will be written to a file. * * @param string $outputFilePath Path of the output file that will contain the data @@ -20,7 +20,7 @@ interface WriterInterface public function openToFile($outputFilePath); /** - * Inits the writer and opens it to accept data. + * Initializes the writer and opens it to accept data. * By using this method, the data will be outputted directly to the browser. * * @param string $outputFileName Name of the output file that will contain the data. If a path is passed in, only the file name will be kept @@ -30,56 +30,24 @@ interface WriterInterface public function openToBrowser($outputFileName); /** - * Write given data to the output. New data will be appended to end of stream. + * Append a row to the end of the stream. * - * @param array $dataRow Array containing data to be streamed. - * Example $dataRow = ['data1', 1234, null, '', 'data5']; - * @throws \Box\Spout\Writer\Exception\WriterNotOpenedException If the writer has not been opened yetthe writer - * @throws \Box\Spout\Common\Exception\IOException If unable to write data + * @param Row $row The row to be appended to the stream * @return WriterInterface */ - public function addRow(array $dataRow); + public function addRow(Row $row); /** - * Write given data to the output and apply the given style. - * @see addRow + * Write a given array of rows to the output. New data will be appended to the end of the stream. * - * @param array $dataRow Array of array containing data to be streamed. - * @param Style $style Style to be applied to the row. - * @throws \Box\Spout\Common\Exception\InvalidArgumentException If the input param is not valid - * @throws \Box\Spout\Writer\Exception\WriterNotOpenedException If this function is called before opening the writer - * @throws \Box\Spout\Common\Exception\IOException If unable to write data - * @return WriterInterface - */ - public function addRowWithStyle(array $dataRow, $style); - - /** - * Write given data to the output. New data will be appended to end of stream. - * - * @param array $dataRows Array of array containing data to be streamed. - * Example $dataRow = [ - * ['data11', 12, , '', 'data13'], - * ['data21', 'data22', null], - * ]; + * @param Row[] $rows Array of rows be appended to the stream * @throws \Box\Spout\Common\Exception\InvalidArgumentException If the input param is not valid * @throws \Box\Spout\Writer\Exception\WriterNotOpenedException If the writer has not been opened yet * @throws \Box\Spout\Common\Exception\IOException If unable to write data * @return WriterInterface - */ - public function addRows(array $dataRows); - - /** - * Write given data to the output and apply the given style. - * @see addRows - * - * @param array $dataRows Array of array containing data to be streamed. - * @param Style $style Style to be applied to the rows. - * @throws \Box\Spout\Common\Exception\InvalidArgumentException If the input param is not valid - * @throws \Box\Spout\Writer\Exception\WriterNotOpenedException If this function is called before opening the writer - * @throws \Box\Spout\Common\Exception\IOException If unable to write data * @return WriterInterface */ - public function addRowsWithStyle(array $dataRows, $style); + public function addRows(array $rows); /** * Closes the writer. This will close the streamer as well, preventing new data diff --git a/src/Spout/Writer/WriterMultiSheetsAbstract.php b/src/Spout/Writer/WriterMultiSheetsAbstract.php index 763df12..4cfae4a 100644 --- a/src/Spout/Writer/WriterMultiSheetsAbstract.php +++ b/src/Spout/Writer/WriterMultiSheetsAbstract.php @@ -7,6 +7,7 @@ use Box\Spout\Common\Helper\GlobalFunctionsHelper; use Box\Spout\Common\Manager\OptionsManagerInterface; use Box\Spout\Writer\Common\Creator\ManagerFactoryInterface; use Box\Spout\Writer\Common\Entity\Options; +use Box\Spout\Writer\Common\Entity\Row; use Box\Spout\Writer\Common\Entity\Sheet; use Box\Spout\Writer\Common\Entity\Worksheet; use Box\Spout\Writer\Common\Manager\Style\StyleMerger; @@ -163,17 +164,16 @@ abstract class WriterMultiSheetsAbstract extends WriterAbstract * If shouldCreateNewSheetsAutomatically option is set to true, it will handle pagination * with the creation of new worksheets if one worksheet has reached its maximum capicity. * - * @param array $dataRow Array containing data to be written. - * Example $dataRow = ['data1', 1234, null, '', 'data5']; - * @param \Box\Spout\Writer\Common\Entity\Style\Style $style Style to be applied to the row. + * @param Row $row * @throws WriterNotOpenedException If the book is not created yet * @throws \Box\Spout\Common\Exception\IOException If unable to write data * @return void + * @return void */ - protected function addRowToWriter(array $dataRow, $style) + protected function addRowToWriter(Row $row) { $this->throwIfWorkbookIsNotAvailable(); - $this->workbookManager->addRowToCurrentWorksheet($dataRow, $style); + $this->workbookManager->addRowToCurrentWorksheet($row); } /** diff --git a/src/Spout/Writer/XLSX/Manager/WorksheetManager.php b/src/Spout/Writer/XLSX/Manager/WorksheetManager.php index 8eb39f2..341fbf6 100644 --- a/src/Spout/Writer/XLSX/Manager/WorksheetManager.php +++ b/src/Spout/Writer/XLSX/Manager/WorksheetManager.php @@ -9,6 +9,7 @@ use Box\Spout\Common\Manager\OptionsManagerInterface; use Box\Spout\Writer\Common\Creator\EntityFactory; use Box\Spout\Writer\Common\Entity\Cell; use Box\Spout\Writer\Common\Entity\Options; +use Box\Spout\Writer\Common\Entity\Row; use Box\Spout\Writer\Common\Entity\Style\Style; use Box\Spout\Writer\Common\Entity\Worksheet; use Box\Spout\Writer\Common\Helper\CellHelper; @@ -119,60 +120,47 @@ EOD; } /** - * Adds data to the given worksheet. + * Adds a row to the worksheet. * * @param Worksheet $worksheet The worksheet to add the row to - * @param array $dataRow Array containing data to be written. Cannot be empty. - * Example $dataRow = ['data1', 1234, null, '', 'data5']; - * @param Style $rowStyle Style to be applied to the row. NULL means use default style. + * @param Row $row The row to be added * @throws IOException If the data cannot be written * @throws InvalidArgumentException If a cell value's type is not supported * @return void */ - public function addRow(Worksheet $worksheet, $dataRow, $rowStyle) + public function addRow(Worksheet $worksheet, Row $row) { - if (!$this->isEmptyRow($dataRow)) { - $this->addNonEmptyRow($worksheet, $dataRow, $rowStyle); + if (!$row->isEmpty()) { + $this->addNonEmptyRow($worksheet, $row); } $worksheet->setLastWrittenRowIndex($worksheet->getLastWrittenRowIndex() + 1); } - /** - * Returns whether the given row is empty - * - * @param array $dataRow Array containing data to be written. Cannot be empty. - * Example $dataRow = ['data1', 1234, null, '', 'data5']; - * @return bool Whether the given row is empty - */ - private function isEmptyRow($dataRow) - { - $numCells = count($dataRow); - // using "reset()" instead of "$dataRow[0]" because $dataRow can be an associative array - return ($numCells === 1 && CellHelper::isEmpty(reset($dataRow))); - } - /** * Adds non empty row to the worksheet. * - * @param Worksheet $worksheet The worksheet to add the row to - * @param array $dataRow Array containing data to be written. Cannot be empty. - * Example $dataRow = ['data1', 1234, null, '', 'data5']; - * @param \Box\Spout\Writer\Common\Entity\Style\Style $style Style to be applied to the row. NULL means use default style. + * @param Row $row The row to be written * @throws \Box\Spout\Common\Exception\IOException If the data cannot be written * @throws \Box\Spout\Common\Exception\InvalidArgumentException If a cell value's type is not supported * @return void */ - private function addNonEmptyRow(Worksheet $worksheet, $dataRow, $style) + private function addNonEmptyRow(Worksheet $worksheet, Row $row) { $cellNumber = 0; $rowIndex = $worksheet->getLastWrittenRowIndex() + 1; - $numCells = count($dataRow); + $numCells = count($row->getCells()); $rowXML = ''; - foreach ($dataRow as $cellValue) { - $rowXML .= $this->getCellXML($rowIndex, $cellNumber, $cellValue, $style->getId()); + // @TODO refactoring: move this to its own method + /** @var Cell $cell */ + foreach ($row->getCells() as $cell) { + // Apply styles - the row style is merged at this point + $cell->applyStyle($row->getStyle()); + $this->styleManager->applyExtraStylesIfNeeded($cell); + $registeredStyle = $this->styleManager->registerStyle($cell->getStyle()); + $rowXML .= $this->getCellXML($rowIndex, $cellNumber, $cell, $registeredStyle->getId()); $cellNumber++; } @@ -189,24 +177,17 @@ EOD; * * @param int $rowIndex * @param int $cellNumber - * @param mixed $cellValue + * @param Cell $cell * @param int $styleId * @throws InvalidArgumentException If the given value cannot be processed * @return string */ - private function getCellXML($rowIndex, $cellNumber, $cellValue, $styleId) + private function getCellXML($rowIndex, $cellNumber, Cell $cell, $styleId) { $columnIndex = CellHelper::getCellIndexFromColumnIndex($cellNumber); $cellXML = 'entityFactory->createCell($cellValue); - } - if ($cell->isString()) { $cellXML .= $this->getCellXMLFragmentForNonEmptyString($cell->getValue()); } elseif ($cell->isBoolean()) { diff --git a/tests/Spout/Reader/XLSX/Helper/CellValueFormatterTest.php b/tests/Spout/Reader/XLSX/Helper/CellValueFormatterTest.php index ef58574..7d2dc5c 100644 --- a/tests/Spout/Reader/XLSX/Helper/CellValueFormatterTest.php +++ b/tests/Spout/Reader/XLSX/Helper/CellValueFormatterTest.php @@ -3,6 +3,7 @@ namespace Box\Spout\Reader\XLSX\Helper; use Box\Spout\Common\Helper\Escaper; +use Box\Spout\Reader\XLSX\Manager\StyleManager; /** * Class CellValueFormatterTest @@ -39,7 +40,7 @@ class CellValueFormatterTest extends \PHPUnit_Framework_TestCase */ public function testExcelDate($cellType, $nodeValue, $expectedDateAsString) { - $nodeListMock = $this->getMockBuilder('DOMNodeList')->disableOriginalConstructor()->getMock(); + $nodeListMock = $this->createMock('DOMNodeList'); $nodeListMock ->expects($this->atLeastOnce()) @@ -47,7 +48,7 @@ class CellValueFormatterTest extends \PHPUnit_Framework_TestCase ->with(0) ->will($this->returnValue((object) ['nodeValue' => $nodeValue])); - $nodeMock = $this->getMockBuilder('DOMElement')->disableOriginalConstructor()->getMock(); + $nodeMock = $this->createMock('DOMElement'); $nodeMock ->expects($this->atLeastOnce()) @@ -64,7 +65,7 @@ class CellValueFormatterTest extends \PHPUnit_Framework_TestCase ->will($this->returnValue($nodeListMock)); /** @var \Box\Spout\Reader\XLSX\Manager\StyleManager|\PHPUnit_Framework_MockObject_MockObject $styleManagerMock */ - $styleManagerMock = $this->getMockBuilder('Box\Spout\Reader\XLSX\Manager\StyleManager')->disableOriginalConstructor()->getMock(); + $styleManagerMock = $this->createMock(StyleManager::class); $styleManagerMock ->expects($this->once()) @@ -120,7 +121,7 @@ class CellValueFormatterTest extends \PHPUnit_Framework_TestCase public function testFormatNumericCellValueWithNumbers($value, $expectedFormattedValue, $expectedType) { /** @var \Box\Spout\Reader\XLSX\Manager\StyleManager|\PHPUnit_Framework_MockObject_MockObject $styleManagerMock */ - $styleManagerMock = $this->getMockBuilder('Box\Spout\Reader\XLSX\Manager\StyleManager')->disableOriginalConstructor()->getMock(); + $styleManagerMock = $this->createMock(StyleManager::class); $styleManagerMock ->expects($this->once()) ->method('shouldFormatNumericValueAsDate') @@ -155,14 +156,14 @@ class CellValueFormatterTest extends \PHPUnit_Framework_TestCase */ public function testFormatInlineStringCellValue($value, $expectedFormattedValue) { - $nodeListMock = $this->getMockBuilder('DOMNodeList')->disableOriginalConstructor()->getMock(); + $nodeListMock = $this->createMock('DOMNodeList'); $nodeListMock ->expects($this->atLeastOnce()) ->method('item') ->with(0) ->will($this->returnValue((object) ['nodeValue' => $value])); - $nodeMock = $this->getMockBuilder('DOMElement')->disableOriginalConstructor()->getMock(); + $nodeMock = $this->createMock('DOMElement'); $nodeMock ->expects($this->atLeastOnce()) ->method('getElementsByTagName') diff --git a/tests/Spout/Writer/CSV/WriterTest.php b/tests/Spout/Writer/CSV/WriterTest.php index 4f679c0..d8e4dad 100644 --- a/tests/Spout/Writer/CSV/WriterTest.php +++ b/tests/Spout/Writer/CSV/WriterTest.php @@ -5,7 +5,7 @@ namespace Box\Spout\Writer\CSV; use Box\Spout\Common\Helper\EncodingHelper; use Box\Spout\Common\Type; use Box\Spout\TestUsingResource; -use Box\Spout\Writer\Common\Entity\Cell; +use Box\Spout\Writer\Common\Creator\EntityFactory; use Box\Spout\Writer\WriterFactory; /** @@ -26,7 +26,11 @@ class WriterTest extends \PHPUnit_Framework_TestCase $writer = WriterFactory::create(Type::CSV); @$writer->openToFile($filePath); - $writer->addRow(['csv--11', 'csv--12']); + $row = EntityFactory::createRow([ + EntityFactory::createCell('csv--11'), + EntityFactory::createCell('csv--12'), + ]); + $writer->addRow($row); $writer->close(); } @@ -36,7 +40,11 @@ class WriterTest extends \PHPUnit_Framework_TestCase public function testWriteShouldThrowExceptionIfCallAddRowBeforeOpeningWriter() { $writer = WriterFactory::create(Type::CSV); - $writer->addRow(['csv--11', 'csv--12']); + $row = EntityFactory::createRow([ + EntityFactory::createCell('csv--11'), + EntityFactory::createCell('csv--12'), + ]); + $writer->addRow($row); $writer->close(); } @@ -46,17 +54,22 @@ class WriterTest extends \PHPUnit_Framework_TestCase public function testWriteShouldThrowExceptionIfCallAddRowsBeforeOpeningWriter() { $writer = WriterFactory::create(Type::CSV); - $writer->addRows([['csv--11', 'csv--12']]); + $row = EntityFactory::createRow([ + EntityFactory::createCell('csv--11'), + EntityFactory::createCell('csv--12'), + ]); + $writer->addRows([$row]); $writer->close(); } /** * @expectedException \Box\Spout\Common\Exception\InvalidArgumentException */ - public function testAddRowsShouldThrowExceptionIfRowsAreNotArrayOfArrays() + public function testAddRowsShouldThrowExceptionIfRowsAreNotArrayOfRows() { $writer = WriterFactory::create(Type::CSV); - $writer->addRows(['csv--11', 'csv--12']); + $row = new \stdClass(); + $writer->addRows([$row]); $writer->close(); } @@ -182,7 +195,7 @@ class WriterTest extends \PHPUnit_Framework_TestCase public function testWriteShouldAcceptCellObjects() { $allRows = [ - [new Cell('String Value'), new Cell(1)], + [EntityFactory::createCell('String Value'), EntityFactory::createCell(1)], ]; $writtenContent = $this->writeToCsvFileAndReturnWrittenContent($allRows, 'csv_with_cell_objects.csv'); $writtenContent = $this->trimWrittenContent($writtenContent); @@ -190,7 +203,7 @@ class WriterTest extends \PHPUnit_Framework_TestCase } /** - * @param array $allRows + * @param array $allRows * @param string $fileName * @param string $fieldDelimiter * @param string $fieldEnclosure @@ -209,7 +222,13 @@ class WriterTest extends \PHPUnit_Framework_TestCase $writer->setShouldAddBOM($shouldAddBOM); $writer->openToFile($resourcePath); - $writer->addRows($allRows); + + $writer->addRows(array_map(function ($oneRow) { + return EntityFactory::createRow(array_map(function ($value) { + return EntityFactory::createCell($value); + }, $oneRow)); + }, $allRows)); + $writer->close(); return file_get_contents($resourcePath); diff --git a/tests/Spout/Writer/Common/Entity/CellTest.php b/tests/Spout/Writer/Common/Entity/CellTest.php new file mode 100644 index 0000000..e31a0b2 --- /dev/null +++ b/tests/Spout/Writer/Common/Entity/CellTest.php @@ -0,0 +1,68 @@ +assertInstanceOf(Cell::class, new Cell('cell')); + $this->assertInstanceOf(Cell::class, new Cell('cell-with-style', $this->createMock(Style::class))); + } + + /** + * @return void + */ + public function testCellTypeNumeric() + { + $this->assertTrue((new Cell(0))->isNumeric()); + $this->assertTrue((new Cell(1))->isNumeric()); + } + + /** + * @return void + */ + public function testCellTypeString() + { + $this->assertTrue((new Cell('String!'))->isString()); + } + + /** + * @return void + */ + public function testCellTypeEmptyString() + { + $this->assertTrue((new Cell(''))->isEmpty()); + } + + /** + * @return void + */ + public function testCellTypeEmptyNull() + { + $this->assertTrue((new Cell(null))->isEmpty()); + } + + /** + * @return void + */ + public function testCellTypeBool() + { + $this->assertTrue((new Cell(true))->isBoolean()); + $this->assertTrue((new Cell(false))->isBoolean()); + } + + /** + * @return void + */ + public function testCellTypeError() + { + $this->assertTrue((new Cell([]))->isError()); + } +} diff --git a/tests/Spout/Writer/Common/Entity/RowTest.php b/tests/Spout/Writer/Common/Entity/RowTest.php new file mode 100644 index 0000000..ff9a1c7 --- /dev/null +++ b/tests/Spout/Writer/Common/Entity/RowTest.php @@ -0,0 +1,114 @@ +createMock(Style::class); + } + + /** + * @return \PHPUnit_Framework_MockObject_MockObject|Cell + */ + private function getCellMock() + { + return $this->createMock(Cell::class); + } + + /** + * @return \PHPUnit_Framework_MockObject_MockObject|RowManager + */ + private function getRowManagerMock() + { + return $this->createMock(RowManager::class); + } + + /** + * @return void + */ + public function testValidInstance() + { + $this->assertInstanceOf( + Row::class, + new Row([], null, $this->getRowManagerMock()) + ); + } + + /** + * @return void + */ + public function testSetCells() + { + $row = new Row([], null, $this->getRowManagerMock()); + $row->setCells([$this->getCellMock(), $this->getCellMock()]); + + $this->assertEquals(2, count($row->getCells())); + } + + /** + * @return void + */ + public function testSetCellsResets() + { + $row = new Row([], null, $this->getRowManagerMock()); + $row->setCells([$this->getCellMock(), $this->getCellMock()]); + + $this->assertEquals(2, count($row->getCells())); + + $row->setCells([$this->getCellMock()]); + + $this->assertEquals(1, count($row->getCells())); + } + + /** + * @return void + */ + public function testGetCells() + { + $row = new Row([], null, $this->getRowManagerMock()); + + $this->assertEquals(0, count($row->getCells())); + + $row->setCells([$this->getCellMock(), $this->getCellMock()]); + + $this->assertEquals(2, count($row->getCells())); + } + + /** + * @return void + */ + public function testAddCell() + { + $row = new Row([], null, $this->getRowManagerMock()); + $row->setCells([$this->getCellMock(), $this->getCellMock()]); + + $this->assertEquals(2, count($row->getCells())); + + $row->addCell($this->getCellMock()); + + $this->assertEquals(3, count($row->getCells())); + } + + /** + * @return void + */ + public function testFluentInterface() + { + $row = new Row([], null, $this->getRowManagerMock()); + $row + ->addCell($this->getCellMock()) + ->setStyle($this->getStyleMock()) + ->setCells([]); + + $this->assertTrue(is_object($row)); + } +} diff --git a/tests/Spout/Writer/Common/Manager/CellManagerTest.php b/tests/Spout/Writer/Common/Manager/CellManagerTest.php new file mode 100644 index 0000000..f10eefd --- /dev/null +++ b/tests/Spout/Writer/Common/Manager/CellManagerTest.php @@ -0,0 +1,28 @@ +assertFalse($cell->getStyle()->isFontBold()); + + $style = (new StyleBuilder())->setFontBold()->build(); + $cellManager->applyStyle($cell, $style); + + $this->assertTrue($cell->getStyle()->isFontBold()); + } +} diff --git a/tests/Spout/Writer/Common/Manager/RowManagerTest.php b/tests/Spout/Writer/Common/Manager/RowManagerTest.php new file mode 100644 index 0000000..93c6844 --- /dev/null +++ b/tests/Spout/Writer/Common/Manager/RowManagerTest.php @@ -0,0 +1,86 @@ +assertFalse($row->getStyle()->isFontBold()); + + $style = (new StyleBuilder())->setFontBold()->build(); + $rowManager->applyStyle($row, $style); + + $this->assertTrue($row->getStyle()->isFontBold()); + } + + /** + * @return array + */ + public function dataProviderForTestHasCells() + { + return [ + // cells, expected hasCells + [[], false], + [[new Cell('')], true], + [[new Cell(null)], true], + [[new Cell('test')], true], + ]; + } + + /** + * @dataProvider dataProviderForTestHasCells + * + * @param array $cells + * @param bool $expectedHasCells + * @return void + */ + public function testHasCells(array $cells, $expectedHasCells) + { + $rowManager = new RowManager(new StyleMerger()); + + $row = new Row($cells, null, $rowManager); + $this->assertEquals($expectedHasCells, $rowManager->hasCells($row)); + } + + /** + * @return array + */ + public function dataProviderForTestIsEmptyRow() + { + return [ + // cells, expected isEmpty + [[], true], + [[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(new StyleMerger()); + + $row = new Row($cells, null, $rowManager); + $this->assertEquals($expectedIsEmpty, $rowManager->isEmpty($row)); + } +} diff --git a/tests/Spout/Writer/Common/Manager/Style/StyleManagerTest.php b/tests/Spout/Writer/Common/Manager/Style/StyleManagerTest.php index 7e2a117..4f4341e 100644 --- a/tests/Spout/Writer/Common/Manager/Style/StyleManagerTest.php +++ b/tests/Spout/Writer/Common/Manager/Style/StyleManagerTest.php @@ -3,6 +3,7 @@ namespace Box\Spout\Writer\Common\Manager\Style; use Box\Spout\Writer\Common\Creator\Style\StyleBuilder; +use Box\Spout\Writer\Common\Entity\Cell; /** * Class StyleManagerTest @@ -29,7 +30,7 @@ class StyleManagerTest extends \PHPUnit_Framework_TestCase $this->assertFalse($style->shouldWrapText()); $styleManager = $this->getStyleManager(); - $updatedStyle = $styleManager->applyExtraStylesIfNeeded($style, [12, 'single line', "multi\nlines", null]); + $updatedStyle = $styleManager->applyExtraStylesIfNeeded(new Cell("multi\nlines", $style)); $this->assertTrue($updatedStyle->shouldWrapText()); } @@ -43,7 +44,7 @@ class StyleManagerTest extends \PHPUnit_Framework_TestCase $this->assertTrue($style->shouldWrapText()); $styleManager = $this->getStyleManager(); - $updatedStyle = $styleManager->applyExtraStylesIfNeeded($style, ["multi\nlines"]); + $updatedStyle = $styleManager->applyExtraStylesIfNeeded(new Cell("multi\nlines")); $this->assertTrue($updatedStyle->shouldWrapText()); } diff --git a/tests/Spout/Writer/ODS/SheetTest.php b/tests/Spout/Writer/ODS/SheetTest.php index 685fddb..4401915 100644 --- a/tests/Spout/Writer/ODS/SheetTest.php +++ b/tests/Spout/Writer/ODS/SheetTest.php @@ -4,6 +4,7 @@ namespace Box\Spout\Writer\ODS; use Box\Spout\Common\Type; use Box\Spout\TestUsingResource; +use Box\Spout\Writer\Common\Creator\EntityFactory; use Box\Spout\Writer\Common\Entity\Sheet; use Box\Spout\Writer\WriterFactory; @@ -91,7 +92,11 @@ class SheetTest extends \PHPUnit_Framework_TestCase $sheet = $writer->getCurrentSheet(); $sheet->setName($sheetName); - $writer->addRow(['ods--11', 'ods--12']); + $row = EntityFactory::createRow([ + EntityFactory::createCell('ods--11'), + EntityFactory::createCell('ods--12'), + ]); + $writer->addRow($row); $writer->close(); } @@ -108,9 +113,20 @@ class SheetTest extends \PHPUnit_Framework_TestCase $writer = WriterFactory::create(Type::ODS); $writer->openToFile($resourcePath); - $writer->addRow(['ods--sheet1--11', 'ods--sheet1--12']); + $row = EntityFactory::createRow([ + EntityFactory::createCell('ods--sheet1--11'), + EntityFactory::createCell('ods--sheet1--12'), + ]); + $writer->addRow($row); + $writer->addNewSheetAndMakeItCurrent(); - $writer->addRow(['ods--sheet2--11', 'ods--sheet2--12', 'ods--sheet2--13']); + + $row = EntityFactory::createRow([ + EntityFactory::createCell('ods--sheet2--11'), + EntityFactory::createCell('ods--sheet2--12'), + EntityFactory::createCell('ods--sheet2--13'), + ]); + $writer->addRow($row); $writer->close(); diff --git a/tests/Spout/Writer/ODS/WriterTest.php b/tests/Spout/Writer/ODS/WriterTest.php index e42226b..19e1d08 100644 --- a/tests/Spout/Writer/ODS/WriterTest.php +++ b/tests/Spout/Writer/ODS/WriterTest.php @@ -6,6 +6,7 @@ use Box\Spout\Common\Exception\SpoutException; use Box\Spout\Common\Type; use Box\Spout\Reader\Wrapper\XMLReader; use Box\Spout\TestUsingResource; +use Box\Spout\Writer\Common\Creator\EntityFactory; use Box\Spout\Writer\Common\Entity\Cell; use Box\Spout\Writer\Common\Helper\ZipHelper; use Box\Spout\Writer\WriterFactory; @@ -17,6 +18,20 @@ class WriterTest extends \PHPUnit_Framework_TestCase { use TestUsingResource; + /** + * @var EntityFactory + */ + protected $entityFactory; + + /** + * @return void + */ + protected function setUp() + { + $this->entityFactory = new EntityFactory(); + parent::setUp(); + } + /** * @expectedException \Box\Spout\Common\Exception\IOException */ @@ -36,7 +51,11 @@ class WriterTest extends \PHPUnit_Framework_TestCase public function testAddRowShouldThrowExceptionIfCallAddRowBeforeOpeningWriter() { $writer = WriterFactory::create(Type::ODS); - $writer->addRow(['ods--11', 'ods--12']); + $row = $this->entityFactory->createRow([ + EntityFactory::createCell('csv--11'), + EntityFactory::createCell('csv--12'), + ]); + $writer->addRow($row); } /** @@ -45,7 +64,11 @@ class WriterTest extends \PHPUnit_Framework_TestCase public function testAddRowShouldThrowExceptionIfCalledBeforeOpeningWriter() { $writer = WriterFactory::create(Type::ODS); - $writer->addRows([['ods--11', 'ods--12']]); + $row = $this->entityFactory->createRow([ + EntityFactory::createCell('csv--11'), + EntityFactory::createCell('csv--12'), + ]); + $writer->addRows([$row]); } /** @@ -98,8 +121,8 @@ class WriterTest extends \PHPUnit_Framework_TestCase { $fileName = 'test_add_row_should_cleanup_all_files_if_exception_thrown.ods'; $dataRows = [ - ['wrong'], - [new \stdClass()], + $this->entityFactory->createRow([]), + new \stdClass(), ]; $this->createGeneratedFolderIfNeeded($fileName); @@ -191,6 +214,7 @@ class WriterTest extends \PHPUnit_Framework_TestCase public function testAddRowShouldWriteGivenDataToSheet() { $fileName = 'test_add_row_should_write_given_data_to_sheet.ods'; + $dataRows = [ ['ods--11', 'ods--12'], ['ods--21', 'ods--22', 'ods--23'], @@ -313,6 +337,14 @@ class WriterTest extends \PHPUnit_Framework_TestCase */ public function testAddRowShouldWriteGivenDataToTheCorrectSheet() { + $arrayToRows = function (array $allRows) { + return array_map(function ($oneRow) { + return $this->entityFactory->createRow(array_map(function ($value) { + return EntityFactory::createCell($value); + }, $oneRow)); + }, $allRows); + }; + $fileName = 'test_add_row_should_write_given_data_to_the_correct_sheet.ods'; $dataRowsSheet1 = [ ['ods--sheet1--11', 'ods--sheet1--12'], @@ -334,15 +366,15 @@ class WriterTest extends \PHPUnit_Framework_TestCase $writer = WriterFactory::create(Type::ODS); $writer->openToFile($resourcePath); - $writer->addRows($dataRowsSheet1); + $writer->addRows($arrayToRows($dataRowsSheet1)); $writer->addNewSheetAndMakeItCurrent(); - $writer->addRows($dataRowsSheet2); + $writer->addRows($arrayToRows($dataRowsSheet2)); $firstSheet = $writer->getSheets()[0]; $writer->setCurrentSheet($firstSheet); - $writer->addRows($dataRowsSheet1Again); + $writer->addRows($arrayToRows($dataRowsSheet1Again)); $writer->close(); @@ -471,8 +503,8 @@ class WriterTest extends \PHPUnit_Framework_TestCase { $fileName = 'test_writer_should_accept_cell_objects.ods'; $dataRows = [ - [new Cell('ods--11'), new Cell('ods--12')], - [new Cell('ods--21'), new Cell('ods--22'), new Cell('ods--23')], + [EntityFactory::createCell('ods--11'), EntityFactory::createCell('ods--12')], + [EntityFactory::createCell('ods--21'), EntityFactory::createCell('ods--22'), EntityFactory::createCell('ods--23')], ]; $this->writeToODSFile($dataRows, $fileName); @@ -492,7 +524,7 @@ class WriterTest extends \PHPUnit_Framework_TestCase { $fileName = 'test_writer_should_accept_cell_objects_with_types.ods'; $dataRows = [ - [new Cell('i am a string'), new Cell(51465), new Cell(true), new Cell(51465.5)], + [EntityFactory::createCell('i am a string'), EntityFactory::createCell(51465), EntityFactory::createCell(true), EntityFactory::createCell(51465.5)], ]; $this->writeToODSFile($dataRows, $fileName); @@ -521,7 +553,16 @@ class WriterTest extends \PHPUnit_Framework_TestCase $writer->setShouldCreateNewSheetsAutomatically($shouldCreateSheetsAutomatically); $writer->openToFile($resourcePath); - $writer->addRows($allRows); + $writer->addRows(array_map(function ($oneRow) { + return $this->entityFactory->createRow(array_map(function ($value) { + // @TODO: always pass a Cell instance! + if (!$value instanceof Cell) { + return EntityFactory::createCell($value); + } else { + return $value; + } + }, $oneRow)); + }, $allRows)); $writer->close(); return $writer; @@ -544,11 +585,19 @@ class WriterTest extends \PHPUnit_Framework_TestCase $writer->setShouldCreateNewSheetsAutomatically($shouldCreateSheetsAutomatically); $writer->openToFile($resourcePath); - $writer->addRows($allRows); + $writer->addRows(array_map(function ($oneRow) { + return $this->entityFactory->createRow(array_map(function ($value) { + return EntityFactory::createCell($value); + }, $oneRow)); + }, $allRows)); for ($i = 1; $i < $numSheets; $i++) { $writer->addNewSheetAndMakeItCurrent(); - $writer->addRows($allRows); + $writer->addRows(array_map(function ($oneRow) { + return $this->entityFactory->createRow(array_map(function ($value) { + return EntityFactory::createCell($value); + }, $oneRow)); + }, $allRows)); } $writer->close(); diff --git a/tests/Spout/Writer/ODS/WriterWithStyleTest.php b/tests/Spout/Writer/ODS/WriterWithStyleTest.php index cd6e21e..01aec50 100644 --- a/tests/Spout/Writer/ODS/WriterWithStyleTest.php +++ b/tests/Spout/Writer/ODS/WriterWithStyleTest.php @@ -5,8 +5,10 @@ namespace Box\Spout\Writer\ODS; use Box\Spout\Common\Type; use Box\Spout\Reader\Wrapper\XMLReader; use Box\Spout\TestUsingResource; +use Box\Spout\Writer\Common\Creator\EntityFactory; use Box\Spout\Writer\Common\Creator\Style\BorderBuilder; use Box\Spout\Writer\Common\Creator\Style\StyleBuilder; +use Box\Spout\Writer\Common\Entity\Cell; use Box\Spout\Writer\Common\Entity\Style\Border; use Box\Spout\Writer\Common\Entity\Style\Color; use Box\Spout\Writer\Common\Entity\Style\Style; @@ -36,16 +38,24 @@ class WriterWithStyleTest extends \PHPUnit_Framework_TestCase public function testAddRowWithStyleShouldThrowExceptionIfCallAddRowBeforeOpeningWriter() { $writer = WriterFactory::create(Type::ODS); - $writer->addRowWithStyle(['ods--11', 'ods--12'], $this->defaultStyle); + $row = EntityFactory::createRow([ + EntityFactory::createCell('ods--11'), + EntityFactory::createCell('ods--12'), + ], $this->defaultStyle); + $writer->addRow($row); } /** * @expectedException \Box\Spout\Writer\Exception\WriterNotOpenedException */ - public function testAddRowWithStyleShouldThrowExceptionIfCalledBeforeOpeningWriter() + public function testAddRowsWithStyleShouldThrowExceptionIfCalledBeforeOpeningWriter() { $writer = WriterFactory::create(Type::ODS); - $writer->addRowWithStyle(['ods--11', 'ods--12'], $this->defaultStyle); + $row = EntityFactory::createRow([ + EntityFactory::createCell('ods--11'), + EntityFactory::createCell('ods--12'), + ], $this->defaultStyle); + $writer->addRows([$row]); } /** @@ -56,42 +66,53 @@ class WriterWithStyleTest extends \PHPUnit_Framework_TestCase return [ ['style'], [new \stdClass()], - [null], ]; } /** + * @requires PHP 7 * @dataProvider dataProviderForInvalidStyle - * @expectedException \Box\Spout\Common\Exception\InvalidArgumentException * * @param \Box\Spout\Writer\Common\Entity\Style\Style $style */ public function testAddRowWithStyleShouldThrowExceptionIfInvalidStyleGiven($style) { + $this->expectException(\TypeError::class); + $fileName = 'test_add_row_with_style_should_throw_exception.ods'; $this->createGeneratedFolderIfNeeded($fileName); $resourcePath = $this->getGeneratedResourcePath($fileName); $writer = WriterFactory::create(Type::ODS); $writer->openToFile($resourcePath); - $writer->addRowWithStyle(['ods--11', 'ods--12'], $style); + $row = EntityFactory::createRow([ + EntityFactory::createCell('ods--11'), + EntityFactory::createCell('ods--12'), + ], $style); + $writer->addRow($row); } /** + * @requires PHP 7 * @dataProvider dataProviderForInvalidStyle - * @expectedException \Box\Spout\Common\Exception\InvalidArgumentException * * @param \Box\Spout\Writer\Common\Entity\Style\Style $style */ public function testAddRowsWithStyleShouldThrowExceptionIfInvalidStyleGiven($style) { + $this->expectException(\TypeError::class); + $fileName = 'test_add_row_with_style_should_throw_exception.ods'; $this->createGeneratedFolderIfNeeded($fileName); $resourcePath = $this->getGeneratedResourcePath($fileName); $writer = WriterFactory::create(Type::ODS); $writer->openToFile($resourcePath); - $writer->addRowsWithStyle([['ods--11', 'ods--12']], $style); + $row = EntityFactory::createRow([ + EntityFactory::createCell('ods--11'), + EntityFactory::createCell('ods--12'), + ], $style); + $writer->addRows([[$row]]); } /** @@ -277,7 +298,7 @@ class WriterWithStyleTest extends \PHPUnit_Framework_TestCase $borderTopRedThinDashed = (new BorderBuilder()) ->setBorderTop(Color::RED, Border::WIDTH_THIN, Border::STYLE_DASHED)->build(); - $styles = [ + $styles = [ (new StyleBuilder())->setBorder($borderBottomGreenThickSolid)->build(), (new StyleBuilder())->build(), (new StyleBuilder())->setBorder($borderTopRedThinDashed)->build(), @@ -328,7 +349,10 @@ class WriterWithStyleTest extends \PHPUnit_Framework_TestCase public function testSetDefaultRowStyle() { $fileName = 'test_set_default_row_style.ods'; - $dataRows = [['ods--11']]; + $row = EntityFactory::createRow([ + EntityFactory::createCell('ods--11'), + ]); + $dataRows = [$row]; $defaultFontSize = 50; $defaultStyle = (new StyleBuilder())->setFontSize($defaultFontSize)->build(); @@ -347,6 +371,14 @@ class WriterWithStyleTest extends \PHPUnit_Framework_TestCase */ private function writeToODSFile($allRows, $fileName, $style) { + $arrayToRows = function (array $allRows) use ($style) { + return array_map(function ($oneRow) use ($style) { + return EntityFactory::createRow(array_map(function ($value) { + return EntityFactory::createCell($value); + }, $oneRow), $style); + }, $allRows); + }; + $this->createGeneratedFolderIfNeeded($fileName); $resourcePath = $this->getGeneratedResourcePath($fileName); @@ -354,7 +386,7 @@ class WriterWithStyleTest extends \PHPUnit_Framework_TestCase $writer = WriterFactory::create(Type::ODS); $writer->openToFile($resourcePath); - $writer->addRowsWithStyle($allRows, $style); + $writer->addRows($arrayToRows($allRows)); $writer->close(); return $writer; @@ -401,11 +433,12 @@ class WriterWithStyleTest extends \PHPUnit_Framework_TestCase $writer->openToFile($resourcePath); for ($i = 0; $i < count($allRows); $i++) { - if ($styles[$i] === null) { - $writer->addRow($allRows[$i]); - } else { - $writer->addRowWithStyle($allRows[$i], $styles[$i]); - } + $currentRow = $allRows[$i]; + $currentStyle = $styles[$i]; + $row = EntityFactory::createRow(array_map(function ($value) { + return EntityFactory::createCell($value); + }, $currentRow), $currentStyle); + $writer->addRow($row); } $writer->close(); diff --git a/tests/Spout/Writer/XLSX/SheetTest.php b/tests/Spout/Writer/XLSX/SheetTest.php index 5df4d57..6e0c435 100644 --- a/tests/Spout/Writer/XLSX/SheetTest.php +++ b/tests/Spout/Writer/XLSX/SheetTest.php @@ -4,6 +4,7 @@ namespace Box\Spout\Writer\XLSX; use Box\Spout\Common\Type; use Box\Spout\TestUsingResource; +use Box\Spout\Writer\Common\Creator\EntityFactory; use Box\Spout\Writer\Common\Entity\Sheet; use Box\Spout\Writer\WriterFactory; @@ -91,7 +92,11 @@ class SheetTest extends \PHPUnit_Framework_TestCase $sheet = $writer->getCurrentSheet(); $sheet->setName($sheetName); - $writer->addRow(['xlsx--11', 'xlsx--12']); + $row = EntityFactory::createRow([ + EntityFactory::createCell('xlsx--11'), + EntityFactory::createCell('xlsx--12'), + ]); + $writer->addRow($row); $writer->close(); return $sheet; @@ -110,9 +115,20 @@ class SheetTest extends \PHPUnit_Framework_TestCase $writer = WriterFactory::create(Type::XLSX); $writer->openToFile($resourcePath); - $writer->addRow(['xlsx--sheet1--11', 'xlsx--sheet1--12']); + $row = EntityFactory::createRow([ + EntityFactory::createCell('xlsx--sheet1--11'), + EntityFactory::createCell('xlsx--sheet1--12'), + ]); + $writer->addRow($row); + $writer->addNewSheetAndMakeItCurrent(); - $writer->addRow(['xlsx--sheet2--11', 'xlsx--sheet2--12', 'xlsx--sheet2--13']); + + $row = EntityFactory::createRow([ + EntityFactory::createCell('xlsx--sheet2--11'), + EntityFactory::createCell('xlsx--sheet2--12'), + EntityFactory::createCell('xlsx--sheet2--13'), + ]); + $writer->addRow($row); $writer->close(); diff --git a/tests/Spout/Writer/XLSX/WriterTest.php b/tests/Spout/Writer/XLSX/WriterTest.php index 18dfd70..ebf04c1 100644 --- a/tests/Spout/Writer/XLSX/WriterTest.php +++ b/tests/Spout/Writer/XLSX/WriterTest.php @@ -5,6 +5,7 @@ namespace Box\Spout\Writer\XLSX; use Box\Spout\Common\Exception\SpoutException; use Box\Spout\Common\Type; use Box\Spout\TestUsingResource; +use Box\Spout\Writer\Common\Creator\EntityFactory; use Box\Spout\Writer\Common\Entity\Cell; use Box\Spout\Writer\WriterFactory; use Box\Spout\Writer\XLSX\Manager\WorksheetManager; @@ -16,6 +17,20 @@ class WriterTest extends \PHPUnit_Framework_TestCase { use TestUsingResource; + /** + * @var EntityFactory + */ + protected $entityFactory; + + /** + * @return void + */ + protected function setUp() + { + $this->entityFactory = new EntityFactory(); + parent::setUp(); + } + /** * @expectedException \Box\Spout\Common\Exception\IOException */ @@ -35,7 +50,12 @@ class WriterTest extends \PHPUnit_Framework_TestCase public function testAddRowShouldThrowExceptionIfCallAddRowBeforeOpeningWriter() { $writer = WriterFactory::create(Type::XLSX); - $writer->addRow(['xlsx--11', 'xlsx--12']); + + $row = EntityFactory::createRow([ + EntityFactory::createCell('xlsx--11'), + EntityFactory::createCell('xlsx--12'), + ]); + $writer->addRow($row); } /** @@ -44,7 +64,11 @@ class WriterTest extends \PHPUnit_Framework_TestCase public function testAddRowShouldThrowExceptionIfCalledBeforeOpeningWriter() { $writer = WriterFactory::create(Type::XLSX); - $writer->addRows([['xlsx--11', 'xlsx--12']]); + $row = EntityFactory::createRow([ + EntityFactory::createCell('xlsx--11'), + EntityFactory::createCell('xlsx--12'), + ]); + $writer->addRows([$row]); } /** @@ -361,6 +385,14 @@ class WriterTest extends \PHPUnit_Framework_TestCase */ public function testAddRowShouldWriteGivenDataToTheCorrectSheet() { + $arrayToRows = function (array $allRows) { + return array_map(function ($oneRow) { + return EntityFactory::createRow(array_map(function ($value) { + return EntityFactory::createCell($value); + }, $oneRow)); + }, $allRows); + }; + $fileName = 'test_add_row_should_write_given_data_to_the_correct_sheet.xlsx'; $dataRowsSheet1 = [ ['xlsx--sheet1--11', 'xlsx--sheet1--12'], @@ -384,15 +416,15 @@ class WriterTest extends \PHPUnit_Framework_TestCase $writer->openToFile($resourcePath); - $writer->addRows($dataRowsSheet1); + $writer->addRows($arrayToRows($dataRowsSheet1)); $writer->addNewSheetAndMakeItCurrent(); - $writer->addRows($dataRowsSheet2); + $writer->addRows($arrayToRows($dataRowsSheet2)); $firstSheet = $writer->getSheets()[0]; $writer->setCurrentSheet($firstSheet); - $writer->addRows($dataRowsSheet1Again); + $writer->addRows($arrayToRows($dataRowsSheet1Again)); $writer->close(); @@ -513,8 +545,8 @@ class WriterTest extends \PHPUnit_Framework_TestCase { $fileName = 'test_writer_should_accept_cell_objects.xlsx'; $dataRows = [ - [new Cell('xlsx--11'), new Cell('xlsx--12')], - [new Cell('xlsx--21'), new Cell('xlsx--22'), new Cell('xlsx--23')], + [EntityFactory::createCell('xlsx--11'), EntityFactory::createCell('xlsx--12')], + [EntityFactory::createCell('xlsx--21'), EntityFactory::createCell('xlsx--22'), EntityFactory::createCell('xlsx--23')], ]; $this->writeToXLSXFile($dataRows, $fileName, $shouldUseInlineStrings = false); @@ -535,10 +567,10 @@ class WriterTest extends \PHPUnit_Framework_TestCase $fileName = 'test_writer_should_accept_cell_objects_with_types.xlsx'; $dataRowsShared = [ - [new Cell('i am a string')], + [EntityFactory::createCell('i am a string')], ]; $dataRowsInline = [ - [new Cell(51465), new Cell(true), new Cell(51465.5)], + [EntityFactory::createCell(51465), EntityFactory::createCell(true), EntityFactory::createCell(51465.5)], ]; $dataRows = array_merge($dataRowsShared, $dataRowsInline); @@ -578,7 +610,15 @@ class WriterTest extends \PHPUnit_Framework_TestCase $writer->setShouldCreateNewSheetsAutomatically($shouldCreateSheetsAutomatically); $writer->openToFile($resourcePath); - $writer->addRows($allRows); + $writer->addRows(array_map(function ($oneRow) { + return EntityFactory::createRow(array_map(function ($value) { + if (!$value instanceof Cell) { + return EntityFactory::createCell($value); + } else { + return $value; + } + }, $oneRow)); + }, $allRows)); $writer->close(); return $writer; @@ -603,11 +643,19 @@ class WriterTest extends \PHPUnit_Framework_TestCase $writer->setShouldCreateNewSheetsAutomatically($shouldCreateSheetsAutomatically); $writer->openToFile($resourcePath); - $writer->addRows($allRows); + $writer->addRows(array_map(function ($oneRow) { + return EntityFactory::createRow(array_map(function ($value) { + return EntityFactory::createCell($value); + }, $oneRow)); + }, $allRows)); for ($i = 1; $i < $numSheets; $i++) { $writer->addNewSheetAndMakeItCurrent(); - $writer->addRows($allRows); + $writer->addRows(array_map(function ($oneRow) { + return EntityFactory::createRow(array_map(function ($value) { + return EntityFactory::createCell($value); + }, $oneRow)); + }, $allRows)); } $writer->close(); diff --git a/tests/Spout/Writer/XLSX/WriterWithStyleTest.php b/tests/Spout/Writer/XLSX/WriterWithStyleTest.php index 84b8440..d321bbb 100644 --- a/tests/Spout/Writer/XLSX/WriterWithStyleTest.php +++ b/tests/Spout/Writer/XLSX/WriterWithStyleTest.php @@ -5,8 +5,10 @@ namespace Box\Spout\Writer\XLSX; use Box\Spout\Common\Type; use Box\Spout\Reader\Wrapper\XMLReader; use Box\Spout\TestUsingResource; +use Box\Spout\Writer\Common\Creator\EntityFactory; use Box\Spout\Writer\Common\Creator\Style\BorderBuilder; use Box\Spout\Writer\Common\Creator\Style\StyleBuilder; +use Box\Spout\Writer\Common\Entity\Cell; use Box\Spout\Writer\Common\Entity\Style\Border; use Box\Spout\Writer\Common\Entity\Style\Color; use Box\Spout\Writer\Common\Entity\Style\Style; @@ -38,16 +40,24 @@ class WriterWithStyleTest extends \PHPUnit_Framework_TestCase public function testAddRowWithStyleShouldThrowExceptionIfCallAddRowBeforeOpeningWriter() { $writer = WriterFactory::create(Type::XLSX); - $writer->addRowWithStyle(['xlsx--11', 'xlsx--12'], $this->defaultStyle); + $row = EntityFactory::createRow([ + EntityFactory::createCell('xlsx--11'), + EntityFactory::createCell('xlsx--12'), + ], $this->defaultStyle); + $writer->addRow($row); } /** * @expectedException \Box\Spout\Writer\Exception\WriterNotOpenedException */ - public function testAddRowWithStyleShouldThrowExceptionIfCalledBeforeOpeningWriter() + public function testAddRowsWithStyleShouldThrowExceptionIfCalledBeforeOpeningWriter() { $writer = WriterFactory::create(Type::XLSX); - $writer->addRowWithStyle(['xlsx--11', 'xlsx--12'], $this->defaultStyle); + $row = EntityFactory::createRow([ + EntityFactory::createCell('xlsx--11'), + EntityFactory::createCell('xlsx--12'), + ], $this->defaultStyle); + $writer->addRows([$row]); } /** @@ -58,42 +68,53 @@ class WriterWithStyleTest extends \PHPUnit_Framework_TestCase return [ ['style'], [new \stdClass()], - [null], ]; } /** + * @requires PHP 7 * @dataProvider dataProviderForInvalidStyle - * @expectedException \Box\Spout\Common\Exception\InvalidArgumentException * * @param \Box\Spout\Writer\Common\Entity\Style\Style $style */ public function testAddRowWithStyleShouldThrowExceptionIfInvalidStyleGiven($style) { + $this->expectException(\TypeError::class); + $fileName = 'test_add_row_with_style_should_throw_exception.xlsx'; $this->createGeneratedFolderIfNeeded($fileName); $resourcePath = $this->getGeneratedResourcePath($fileName); $writer = WriterFactory::create(Type::XLSX); $writer->openToFile($resourcePath); - $writer->addRowWithStyle(['xlsx--11', 'xlsx--12'], $style); + $row = EntityFactory::createRow([ + EntityFactory::createCell('xlsx--11'), + EntityFactory::createCell('xlsx--12'), + ], $style); + $writer->addRow($row); } /** + * @requires PHP 7 * @dataProvider dataProviderForInvalidStyle - * @expectedException \Box\Spout\Common\Exception\InvalidArgumentException * * @param \Box\Spout\Writer\Common\Entity\Style\Style $style */ public function testAddRowsWithStyleShouldThrowExceptionIfInvalidStyleGiven($style) { + $this->expectException(\TypeError::class); + $fileName = 'test_add_row_with_style_should_throw_exception.xlsx'; $this->createGeneratedFolderIfNeeded($fileName); $resourcePath = $this->getGeneratedResourcePath($fileName); $writer = WriterFactory::create(Type::XLSX); $writer->openToFile($resourcePath); - $writer->addRowsWithStyle([['xlsx--11', 'xlsx--12']], $style); + $row = EntityFactory::createRow([ + EntityFactory::createCell('xlsx--11'), + EntityFactory::createCell('xlsx--12'), + ], $style); + $writer->addRows([$row]); } /** @@ -429,7 +450,11 @@ class WriterWithStyleTest extends \PHPUnit_Framework_TestCase public function testSetDefaultRowStyle() { $fileName = 'test_set_default_row_style.xlsx'; - $dataRows = [['xlsx--11']]; + + $row = EntityFactory::createRow([ + EntityFactory::createCell('xlsx--11'), + ]); + $dataRows = [$row]; $defaultFontSize = 50; $defaultStyle = (new StyleBuilder())->setFontSize($defaultFontSize)->build(); @@ -521,6 +546,14 @@ class WriterWithStyleTest extends \PHPUnit_Framework_TestCase */ private function writeToXLSXFile($allRows, $fileName, $style) { + $arrayToRows = function (array $allRows) use ($style) { + return array_map(function ($oneRow) use ($style) { + return EntityFactory::createRow(array_map(function ($value) { + return EntityFactory::createCell($value); + }, $oneRow), $style); + }, $allRows); + }; + $this->createGeneratedFolderIfNeeded($fileName); $resourcePath = $this->getGeneratedResourcePath($fileName); @@ -529,7 +562,7 @@ class WriterWithStyleTest extends \PHPUnit_Framework_TestCase $writer->setShouldUseInlineStrings(true); $writer->openToFile($resourcePath); - $writer->addRowsWithStyle($allRows, $style); + $writer->addRows(($arrayToRows($allRows))); $writer->close(); return $writer; @@ -578,11 +611,12 @@ class WriterWithStyleTest extends \PHPUnit_Framework_TestCase $writer->openToFile($resourcePath); for ($i = 0; $i < count($allRows); $i++) { - if ($styles[$i] === null) { - $writer->addRow($allRows[$i]); - } else { - $writer->addRowWithStyle($allRows[$i], $styles[$i]); - } + $currentRow = $allRows[$i]; + $currentStyle = $styles[$i]; + $row = EntityFactory::createRow(array_map(function ($value) { + return EntityFactory::createCell($value); + }, $currentRow), $currentStyle); + $writer->addRow($row); } $writer->close();