Refactory Writer Styles to match new code organization (#433)

Decomposed old StyleHelper into StyleManager, StyleRegistry and StyleMerger.
This commit is contained in:
Adrien Loison 2017-05-30 13:05:18 +02:00 committed by GitHub
parent 238756ab6e
commit cc9a0b526b
34 changed files with 1005 additions and 762 deletions

View File

@ -1,147 +0,0 @@
<?php
namespace Box\Spout\Writer\Common\Helper;
use Box\Spout\Writer\Common\Entity\Style\Style;
use Box\Spout\Writer\Common\Manager\StyleManager;
/**
* Class StyleHelperAbstract
* This class provides helper functions to manage styles
*
* @package Box\Spout\Writer\Common\Helper
*/
abstract class StyleHelperAbstract implements StyleHelperInterface
{
/** @var StyleManager Style manager */
private $styleManager;
/** @var array [SERIALIZED_STYLE] => [STYLE_ID] mapping table, keeping track of the registered styles */
protected $serializedStyleToStyleIdMappingTable = [];
/** @var array [STYLE_ID] => [STYLE] mapping table, keeping track of the registered styles */
protected $styleIdToStyleMappingTable = [];
/**
* @param Style $defaultStyle
* @param StyleManager $styleManager
*/
public function __construct(Style $defaultStyle, StyleManager $styleManager)
{
$this->styleManager = $styleManager;
// This ensures that the default style is the first one to be registered
$this->registerStyle($defaultStyle);
}
/**
* Registers the given style as a used style.
* Duplicate styles won't be registered more than once.
*
* @param Style $style The style to be registered
* @return Style The registered style, updated with an internal ID.
*/
public function registerStyle($style)
{
$serializedStyle = $this->styleManager->serialize($style);
if (!$this->hasStyleAlreadyBeenRegistered($style)) {
$nextStyleId = count($this->serializedStyleToStyleIdMappingTable);
$style->setId($nextStyleId);
$this->serializedStyleToStyleIdMappingTable[$serializedStyle] = $nextStyleId;
$this->styleIdToStyleMappingTable[$nextStyleId] = $style;
}
return $this->getStyleFromSerializedStyle($serializedStyle);
}
/**
* Returns whether the given style has already been registered.
*
* @param Style $style
* @return bool
*/
protected function hasStyleAlreadyBeenRegistered($style)
{
$serializedStyle = $this->styleManager->serialize($style);
// Using isset here because it is way faster than array_key_exists...
return isset($this->serializedStyleToStyleIdMappingTable[$serializedStyle]);
}
/**
* Returns the registered style associated to the given serialization.
*
* @param string $serializedStyle The serialized style from which the actual style should be fetched from
* @return Style
*/
protected function getStyleFromSerializedStyle($serializedStyle)
{
$styleId = $this->serializedStyleToStyleIdMappingTable[$serializedStyle];
return $this->styleIdToStyleMappingTable[$styleId];
}
/**
* @return Style[] List of registered styles
*/
protected function getRegisteredStyles()
{
return array_values($this->styleIdToStyleMappingTable);
}
/**
* Returns the default style
*
* @return Style Default style
*/
protected function getDefaultStyle()
{
// By construction, the default style has ID 0
return $this->styleIdToStyleMappingTable[0];
}
/**
* 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
*/
public function applyExtraStylesIfNeeded($style, $dataRow)
{
$updatedStyle = $this->applyWrapTextIfCellContainsNewLine($style, $dataRow);
return $updatedStyle;
}
/**
* Set the "wrap text" option if a cell of the given row contains a new line.
*
* @NOTE: There is a bug on the Mac version of Excel (2011 and below) where new lines
* are ignored even when the "wrap text" option is set. This only occurs with
* inline strings (shared strings do work fine).
* 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
*/
protected function applyWrapTextIfCellContainsNewLine($style, $dataRow)
{
// if the "wrap text" option is already set, no-op
if ($style->hasSetWrapText()) {
return $style;
}
foreach ($dataRow as $cell) {
if (is_string($cell) && strpos($cell, "\n") !== false) {
$style->setShouldWrapText();
break;
}
}
return $style;
}
}

View File

@ -1,30 +0,0 @@
<?php
namespace Box\Spout\Writer\Common\Helper;
/**
* Interface StyleHelperInterface
*
* @package Box\Spout\Writer\Common\Helper
*/
interface StyleHelperInterface
{
/**
* Registers the given style as a used style.
* Duplicate styles won't be registered more than once.
*
* @param \Box\Spout\Writer\Common\Entity\Style\Style $style The style to be registered
* @return \Box\Spout\Writer\Common\Entity\Style\Style The registered style, updated with an internal ID.
*/
public function registerStyle($style);
/**
* Apply additional styles if the given row needs it.
* Typically, set "wrap text" if a cell contains a new line.
*
* @param \Box\Spout\Writer\Common\Entity\Style\Style $style The original style
* @param array $dataRow The row the style will be applied to
* @return \Box\Spout\Writer\Common\Entity\Style\Style The updated style
*/
public function applyExtraStylesIfNeeded($style, $dataRow);
}

View File

@ -0,0 +1,92 @@
<?php
namespace Box\Spout\Writer\Common\Manager\Style;
use Box\Spout\Writer\Common\Entity\Style\Style;
/**
* Class StyleManager
* Manages styles to be applied to a cell
*
* @package Box\Spout\Writer\Common\Manager\Style
*/
class StyleManager implements StyleManagerInterface
{
/** @var StyleRegistry Registry for all used styles */
protected $styleRegistry;
/**
* @param StyleRegistry $styleRegistry
*/
public function __construct(StyleRegistry $styleRegistry)
{
$this->styleRegistry = $styleRegistry;
}
/**
* Returns the default style
*
* @return Style Default style
*/
protected function getDefaultStyle()
{
// By construction, the default style has ID 0
return $this->styleRegistry->getRegisteredStyles()[0];
}
/**
* Registers the given style as a used style.
* Duplicate styles won't be registered more than once.
*
* @param Style $style The style to be registered
* @return Style The registered style, updated with an internal ID.
*/
public function registerStyle($style)
{
return $this->styleRegistry->registerStyle($style);
}
/**
* 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
*/
public function applyExtraStylesIfNeeded($style, $dataRow)
{
$updatedStyle = $this->applyWrapTextIfCellContainsNewLine($style, $dataRow);
return $updatedStyle;
}
/**
* Set the "wrap text" option if a cell of the given row contains a new line.
*
* @NOTE: There is a bug on the Mac version of Excel (2011 and below) where new lines
* are ignored even when the "wrap text" option is set. This only occurs with
* inline strings (shared strings do work fine).
* 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
*/
protected function applyWrapTextIfCellContainsNewLine($style, $dataRow)
{
// if the "wrap text" option is already set, no-op
if ($style->hasSetWrapText()) {
return $style;
}
foreach ($dataRow as $cell) {
if (is_string($cell) && strpos($cell, "\n") !== false) {
$style->setShouldWrapText();
break;
}
}
return $style;
}
}

View File

@ -0,0 +1,32 @@
<?php
namespace Box\Spout\Writer\Common\Manager\Style;
use Box\Spout\Writer\Common\Entity\Style\Style;
/**
* Interface StyleHManagernterface
*
* @package Box\Spout\Writer\Common\Manager\Style
*/
interface StyleManagerInterface
{
/**
* Registers the given style as a used style.
* Duplicate styles won't be registered more than once.
*
* @param Style $style The style to be registered
* @return Style The registered style, updated with an internal ID.
*/
public function registerStyle($style);
/**
* 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
*/
public function applyExtraStylesIfNeeded($style, $dataRow);
}

View File

@ -1,38 +1,19 @@
<?php
namespace Box\Spout\Writer\Common\Manager;
namespace Box\Spout\Writer\Common\Manager\Style;
use Box\Spout\Writer\Common\Entity\Style\Color;
use Box\Spout\Writer\Common\Entity\Style\Style;
use Box\Spout\Writer\XLSX\Helper\BorderHelper;
/**
* Class StyleManager
* Manages styles to be applied to a cell
* Class StyleMerger
* Takes care of merging styles together
*
* @package Box\Spout\Writer\Common\Manager\Style
*/
class StyleManager
class StyleMerger
{
/**
* Serializes the style for future comparison with other styles.
* The ID is excluded from the comparison, as we only care about
* actual style properties.
*
* @param Style $style
* @return string The serialized style
*/
public function serialize(Style $style)
{
// In order to be able to properly compare style, set static ID value
$currentId = $style->getId();
$style->setId(0);
$serializedStyle = serialize($style);
$style->setId($currentId);
return $serializedStyle;
}
/**
* Merges the current style with the given style, using the given style as a base. This means that:
* - if current style and base style both have property A set, use current style property's value

View File

@ -0,0 +1,115 @@
<?php
namespace Box\Spout\Writer\Common\Manager\Style;
use Box\Spout\Writer\Common\Entity\Style\Style;
/**
* Class StyleRegistry
* Registry for all used styles
*
* @package Box\Spout\Writer\Common\Manager\Style
*/
class StyleRegistry
{
/** @var array [SERIALIZED_STYLE] => [STYLE_ID] mapping table, keeping track of the registered styles */
protected $serializedStyleToStyleIdMappingTable = [];
/** @var array [STYLE_ID] => [STYLE] mapping table, keeping track of the registered styles */
protected $styleIdToStyleMappingTable = [];
/**
* @param Style $defaultStyle
*/
public function __construct(Style $defaultStyle)
{
// This ensures that the default style is the first one to be registered
$this->registerStyle($defaultStyle);
}
/**
* Registers the given style as a used style.
* Duplicate styles won't be registered more than once.
*
* @param Style $style The style to be registered
* @return Style The registered style, updated with an internal ID.
*/
public function registerStyle(Style $style)
{
$serializedStyle = $this->serialize($style);
if (!$this->hasStyleAlreadyBeenRegistered($style)) {
$nextStyleId = count($this->serializedStyleToStyleIdMappingTable);
$style->setId($nextStyleId);
$this->serializedStyleToStyleIdMappingTable[$serializedStyle] = $nextStyleId;
$this->styleIdToStyleMappingTable[$nextStyleId] = $style;
}
return $this->getStyleFromSerializedStyle($serializedStyle);
}
/**
* Returns whether the given style has already been registered.
*
* @param Style $style
* @return bool
*/
protected function hasStyleAlreadyBeenRegistered(Style $style)
{
$serializedStyle = $this->serialize($style);
// Using isset here because it is way faster than array_key_exists...
return isset($this->serializedStyleToStyleIdMappingTable[$serializedStyle]);
}
/**
* Returns the registered style associated to the given serialization.
*
* @param string $serializedStyle The serialized style from which the actual style should be fetched from
* @return Style
*/
protected function getStyleFromSerializedStyle($serializedStyle)
{
$styleId = $this->serializedStyleToStyleIdMappingTable[$serializedStyle];
return $this->styleIdToStyleMappingTable[$styleId];
}
/**
* @return Style[] List of registered styles
*/
public function getRegisteredStyles()
{
return array_values($this->styleIdToStyleMappingTable);
}
/**
* @param int $styleId
* @return Style
*/
public function getStyleFromStyleId($styleId)
{
return $this->styleIdToStyleMappingTable[$styleId];
}
/**
* Serializes the style for future comparison with other styles.
* The ID is excluded from the comparison, as we only care about
* actual style properties.
*
* @param Style $style
* @return string The serialized style
*/
public function serialize(Style $style)
{
// In order to be able to properly compare style, set static ID value
$currentId = $style->getId();
$style->setId(0);
$serializedStyle = serialize($style);
$style->setId($currentId);
return $serializedStyle;
}
}

View File

@ -4,8 +4,8 @@ namespace Box\Spout\Writer\Common\Manager;
use Box\Spout\Common\Exception\IOException;
use Box\Spout\Writer\Common\Helper\FileSystemWithRootFolderHelperInterface;
use Box\Spout\Writer\Common\Helper\StyleHelperInterface;
use Box\Spout\Writer\Common\Entity\Options;
use Box\Spout\Writer\Common\Manager\Style\StyleManagerInterface;
use Box\Spout\Writer\Common\Sheet;
use Box\Spout\Writer\Common\Entity\Workbook;
use Box\Spout\Writer\Common\Entity\Worksheet;
@ -31,14 +31,14 @@ abstract class WorkbookManagerAbstract implements WorkbookManagerInterface
/** @var WorksheetManagerInterface */
protected $worksheetManager;
/** @var StyleHelperInterface */
protected $styleHelper;
/** @var StyleManagerInterface Manages styles */
protected $styleManager;
/** @var FileSystemWithRootFolderHelperInterface Helper to perform file system operations */
protected $fileSystemHelper;
/** @var EntityFactory Factory to create entities */
private $entityFactory;
protected $entityFactory;
/** @var Worksheet The worksheet where data will be written to */
protected $currentWorksheet;
@ -48,7 +48,7 @@ abstract class WorkbookManagerAbstract implements WorkbookManagerInterface
* @param Workbook $workbook
* @param OptionsManagerInterface $optionsManager
* @param WorksheetManagerInterface $worksheetManager
* @param StyleHelperInterface $styleHelper
* @param StyleManagerInterface $styleManager
* @param FileSystemWithRootFolderHelperInterface $fileSystemHelper
* @param EntityFactory $entityFactory
*/
@ -56,14 +56,14 @@ abstract class WorkbookManagerAbstract implements WorkbookManagerInterface
Workbook $workbook,
OptionsManagerInterface $optionsManager,
WorksheetManagerInterface $worksheetManager,
StyleHelperInterface $styleHelper,
StyleManagerInterface $styleManager,
FileSystemWithRootFolderHelperInterface $fileSystemHelper,
EntityFactory $entityFactory)
{
$this->workbook = $workbook;
$this->optionManager = $optionsManager;
$this->worksheetManager = $worksheetManager;
$this->styleHelper = $styleHelper;
$this->styleManager = $styleManager;
$this->fileSystemHelper = $fileSystemHelper;
$this->entityFactory = $entityFactory;
}
@ -244,8 +244,8 @@ abstract class WorkbookManagerAbstract implements WorkbookManagerInterface
*/
private function addRowWithStyleToWorksheet(Worksheet $worksheet, $dataRow, Style $style)
{
$updatedStyle = $this->styleHelper->applyExtraStylesIfNeeded($style, $dataRow);
$registeredStyle = $this->styleHelper->registerStyle($updatedStyle);
$updatedStyle = $this->styleManager->applyExtraStylesIfNeeded($style, $dataRow);
$registeredStyle = $this->styleManager->registerStyle($updatedStyle);
$this->worksheetManager->addRow($worksheet, $dataRow, $registeredStyle);
// update max num columns for the worksheet

View File

@ -7,9 +7,9 @@ use Box\Spout\Writer\Common\Manager\OptionsManagerInterface;
use Box\Spout\Writer\Common\Entity\Options;
use Box\Spout\Writer\Common\Creator\EntityFactory;
use Box\Spout\Writer\Common\Creator\InternalFactoryInterface;
use Box\Spout\Writer\Common\Manager\StyleManager;
use Box\Spout\Writer\ODS\Helper\FileSystemHelper;
use Box\Spout\Writer\ODS\Helper\StyleHelper;
use Box\Spout\Writer\ODS\Manager\Style\StyleManager;
use Box\Spout\Writer\ODS\Manager\Style\StyleRegistry;
use Box\Spout\Writer\ODS\Manager\WorkbookManager;
use Box\Spout\Writer\ODS\Manager\WorksheetManager;
use \Box\Spout\Common\Escaper;
@ -46,22 +46,41 @@ class InternalFactory implements InternalFactoryInterface
$fileSystemHelper = $this->createFileSystemHelper($optionsManager);
$fileSystemHelper->createBaseFilesAndFolders();
$styleHelper = $this->createStyleHelper($optionsManager);
$worksheetManager = $this->createWorksheetManager($styleHelper);
$styleManager = $this->createStyleManager($optionsManager);
$worksheetManager = $this->createWorksheetManager();
return new WorkbookManager($workbook, $optionsManager, $worksheetManager, $styleHelper, $fileSystemHelper, $this->entityFactory);
return new WorkbookManager($workbook, $optionsManager, $worksheetManager, $styleManager, $fileSystemHelper, $this->entityFactory);
}
/**
* @param StyleHelper $styleHelper
* @return WorksheetManager
*/
private function createWorksheetManager(StyleHelper $styleHelper)
private function createWorksheetManager()
{
$stringsEscaper = $this->createStringsEscaper();
$stringsHelper = $this->createStringHelper();
return new WorksheetManager($styleHelper, $stringsEscaper, $stringsHelper);
return new WorksheetManager($stringsEscaper, $stringsHelper);
}
/**
* @param OptionsManagerInterface $optionsManager
* @return StyleManager
*/
private function createStyleManager(OptionsManagerInterface $optionsManager)
{
$styleRegistry = $this->createStyleRegistry($optionsManager);
return new StyleManager($styleRegistry);
}
/**
* @param OptionsManagerInterface $optionsManager
* @return StyleRegistry
*/
private function createStyleRegistry(OptionsManagerInterface $optionsManager)
{
$defaultRowStyle = $optionsManager->getOption(Options::DEFAULT_ROW_STYLE);
return new StyleRegistry($defaultRowStyle);
}
/**
@ -74,26 +93,6 @@ class InternalFactory implements InternalFactoryInterface
return new FileSystemHelper($tempFolder);
}
/**
* @param OptionsManagerInterface $optionsManager
* @return StyleHelper
*/
private function createStyleHelper(OptionsManagerInterface $optionsManager)
{
$defaultRowStyle = $optionsManager->getOption(Options::DEFAULT_ROW_STYLE);
$styleManager = $this->createStyleManager();
return new StyleHelper($defaultRowStyle, $styleManager);
}
/**
* @return StyleManager
*/
private function createStyleManager()
{
return new StyleManager();
}
/**
* @return Escaper\ODS
*/

View File

@ -5,6 +5,7 @@ namespace Box\Spout\Writer\ODS\Helper;
use Box\Spout\Writer\Common\Helper\FileSystemWithRootFolderHelperInterface;
use Box\Spout\Writer\Common\Helper\ZipHelper;
use Box\Spout\Writer\Common\Entity\Worksheet;
use Box\Spout\Writer\ODS\Manager\Style\StyleManager;
use Box\Spout\Writer\ODS\Manager\WorksheetManager;
/**
@ -175,19 +176,19 @@ EOD;
* Creates the "content.xml" file under the root folder
*
* @param WorksheetManager $worksheetManager
* @param StyleManager $styleManager
* @param Worksheet[] $worksheets
* @param StyleHelper $styleHelper
* @return FileSystemHelper
*/
public function createContentFile($worksheetManager, $worksheets, $styleHelper)
public function createContentFile($worksheetManager, $styleManager, $worksheets)
{
$contentXmlFileContents = <<<EOD
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<office:document-content office:version="1.2" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:calcext="urn:org:documentfoundation:names:experimental:calc:xmlns:calcext:1.0" xmlns:draw="urn:oasis:names:tc:opendocument:xmlns:drawing:1.0" xmlns:fo="urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0" xmlns:msoxl="http://schemas.microsoft.com/office/excel/formula" xmlns:number="urn:oasis:names:tc:opendocument:xmlns:datastyle:1.0" xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office:1.0" xmlns:style="urn:oasis:names:tc:opendocument:xmlns:style:1.0" xmlns:svg="urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0" xmlns:table="urn:oasis:names:tc:opendocument:xmlns:table:1.0" xmlns:text="urn:oasis:names:tc:opendocument:xmlns:text:1.0" xmlns:xlink="http://www.w3.org/1999/xlink">
EOD;
$contentXmlFileContents .= $styleHelper->getContentXmlFontFaceSectionContent();
$contentXmlFileContents .= $styleHelper->getContentXmlAutomaticStylesSectionContent(count($worksheets));
$contentXmlFileContents .= $styleManager->getContentXmlFontFaceSectionContent();
$contentXmlFileContents .= $styleManager->getContentXmlAutomaticStylesSectionContent(count($worksheets));
$contentXmlFileContents .= '<office:body><office:spreadsheet>';
@ -246,13 +247,13 @@ EOD;
/**
* Creates the "styles.xml" file under the root folder
*
* @param StyleHelper $styleHelper
* @param StyleManager $styleManager
* @param int $numWorksheets Number of created worksheets
* @return FileSystemHelper
*/
public function createStylesFile($styleHelper, $numWorksheets)
public function createStylesFile($styleManager, $numWorksheets)
{
$stylesXmlFileContents = $styleHelper->getStylesXMLFileContent($numWorksheets);
$stylesXmlFileContents = $styleManager->getStylesXMLFileContent($numWorksheets);
$this->createFileWithContents($this->rootFolder, self::STYLES_XML_FILE_NAME, $stylesXmlFileContents);
return $this;

View File

@ -1,41 +1,20 @@
<?php
namespace Box\Spout\Writer\ODS\Helper;
namespace Box\Spout\Writer\ODS\Manager\Style;
use Box\Spout\Writer\Common\Helper\StyleHelperAbstract;
use Box\Spout\Writer\Common\Entity\Style\BorderPart;
use Box\Spout\Writer\ODS\Helper\BorderHelper;
/**
* Class StyleHelper
* This class provides helper functions to manage styles
* Class StyleManager
* Manages styles to be applied to a cell
*
* @package Box\Spout\Writer\ODS\Helper
* @package Box\Spout\Writer\ODS\Manager\Style
*/
class StyleHelper extends StyleHelperAbstract
class StyleManager extends \Box\Spout\Writer\Common\Manager\Style\StyleManager
{
/** @var string[] [FONT_NAME] => [] Map whose keys contain all the fonts used */
protected $usedFontsSet = [];
/**
* Registers the given style as a used style.
* Duplicate styles won't be registered more than once.
*
* @param \Box\Spout\Writer\Common\Entity\Style\Style $style The style to be registered
* @return \Box\Spout\Writer\Common\Entity\Style\Style The registered style, updated with an internal ID.
*/
public function registerStyle($style)
{
$this->usedFontsSet[$style->getFontName()] = true;
return parent::registerStyle($style);
}
/**
* @return string[] List of used fonts name
*/
protected function getUsedFonts()
{
return array_keys($this->usedFontsSet);
}
/** @var StyleRegistry */
protected $styleRegistry;
/**
* Returns the content of the "styles.xml" file, given a list of styles.
@ -70,7 +49,7 @@ EOD;
protected function getFontFaceSectionContent()
{
$content = '<office:font-face-decls>';
foreach ($this->getUsedFonts() as $fontName) {
foreach ($this->styleRegistry->getUsedFonts() as $fontName) {
$content .= '<style:font-face style:name="' . $fontName . '" svg:font-family="' . $fontName . '"/>';
}
$content .= '</office:font-face-decls>';
@ -162,7 +141,7 @@ EOD;
public function getContentXmlFontFaceSectionContent()
{
$content = '<office:font-face-decls>';
foreach ($this->getUsedFonts() as $fontName) {
foreach ($this->styleRegistry->getUsedFonts() as $fontName) {
$content .= '<style:font-face style:name="' . $fontName . '" svg:font-family="' . $fontName . '"/>';
}
$content .= '</office:font-face-decls>';
@ -180,7 +159,7 @@ EOD;
{
$content = '<office:automatic-styles>';
foreach ($this->getRegisteredStyles() as $style) {
foreach ($this->styleRegistry->getRegisteredStyles() as $style) {
$content .= $this->getStyleSectionContent($style);
}

View File

@ -0,0 +1,40 @@
<?php
namespace Box\Spout\Writer\ODS\Manager\Style;
use Box\Spout\Writer\Common\Entity\Style\Style;
/**
* Class StyleRegistry
* Registry for all used styles
*
* @package Box\Spout\Writer\ODS\Manager\Style
*/
class StyleRegistry extends \Box\Spout\Writer\Common\Manager\Style\StyleRegistry
{
/** @var array [FONT_NAME] => [] Map whose keys contain all the fonts used */
protected $usedFontsSet = [];
/**
* Registers the given style as a used style.
* Duplicate styles won't be registered more than once.
*
* @param Style $style The style to be registered
* @return Style The registered style, updated with an internal ID.
*/
public function registerStyle(Style $style)
{
$registeredStyle = parent::registerStyle($style);
$this->usedFontsSet[$style->getFontName()] = true;
return $registeredStyle;
}
/**
* @return string[] List of used fonts name
*/
public function getUsedFonts()
{
return array_keys($this->usedFontsSet);
}
}

View File

@ -6,6 +6,7 @@ use Box\Spout\Writer\Common\Sheet;
use Box\Spout\Writer\Common\Manager\WorkbookManagerAbstract;
use Box\Spout\Writer\ODS\Helper\FileSystemHelper;
use Box\Spout\Writer\ODS\Helper\StyleHelper;
use Box\Spout\Writer\ODS\Manager\Style\StyleManager;
/**
* Class WorkbookManager
@ -27,11 +28,8 @@ class WorkbookManager extends WorkbookManagerAbstract
/** @var FileSystemHelper Helper to perform file system operations */
protected $fileSystemHelper;
/** @var StyleHelper Helper to apply styles */
protected $styleHelper;
/** @var int Maximum number of columns among all the written rows */
protected $maxNumColumns = 1;
/** @var StyleManager Manages styles */
protected $styleManager;
/**
* @return int Maximum number of rows/columns a sheet can contain
@ -63,9 +61,9 @@ class WorkbookManager extends WorkbookManagerAbstract
$numWorksheets = count($worksheets);
$this->fileSystemHelper
->createContentFile($this->worksheetManager, $worksheets, $this->styleHelper)
->createContentFile($this->worksheetManager, $this->styleManager, $worksheets)
->deleteWorksheetTempFolder()
->createStylesFile($this->styleHelper, $numWorksheets)
->createStylesFile($this->styleManager, $numWorksheets)
->zipRootFolderAndCopyToStream($finalFilePointer);
}
}

View File

@ -8,8 +8,8 @@ use Box\Spout\Common\Helper\StringHelper;
use Box\Spout\Writer\Common\Entity\Cell;
use Box\Spout\Writer\Common\Entity\Worksheet;
use Box\Spout\Writer\Common\Manager\WorksheetManagerInterface;
use Box\Spout\Writer\ODS\Helper\StyleHelper;
use Box\Spout\Writer\Common\Entity\Style\Style;
use Box\Spout\Writer\ODS\Manager\Style\StyleManager;
/**
* Class WorksheetManager
@ -19,9 +19,6 @@ use Box\Spout\Writer\Common\Entity\Style\Style;
*/
class WorksheetManager implements WorksheetManagerInterface
{
/** @var StyleHelper Helper to work with styles */
private $styleHelper;
/** @var \Box\Spout\Common\Escaper\ODS Strings escaper */
private $stringsEscaper;
@ -31,16 +28,13 @@ class WorksheetManager implements WorksheetManagerInterface
/**
* WorksheetManager constructor.
*
* @param StyleHelper $styleHelper
* @param \Box\Spout\Common\Escaper\ODS $stringsEscaper
* @param StringHelper $stringHelper
*/
public function __construct(
StyleHelper $styleHelper,
\Box\Spout\Common\Escaper\ODS $stringsEscaper,
StringHelper $stringHelper)
{
$this->styleHelper = $styleHelper;
$this->stringsEscaper = $stringsEscaper;
$this->stringHelper = $stringHelper;
}

View File

@ -10,7 +10,7 @@ use Box\Spout\Common\Helper\GlobalFunctionsHelper;
use Box\Spout\Writer\Common\Entity\Options;
use Box\Spout\Writer\Common\Entity\Style\Style;
use Box\Spout\Writer\Common\Manager\OptionsManagerInterface;
use Box\Spout\Writer\Common\Manager\StyleManager;
use Box\Spout\Writer\Common\Manager\Style\StyleMerger;
use Box\Spout\Writer\Exception\WriterAlreadyOpenedException;
use Box\Spout\Writer\Exception\WriterNotOpenedException;
@ -37,8 +37,8 @@ abstract class WriterAbstract implements WriterInterface
/** @var OptionsManagerInterface Writer options manager */
protected $optionsManager;
/** @var StyleManager Style manager */
protected $styleManager;
/** @var StyleMerger Helps merge styles together */
protected $styleMerger;
/** @var Style Style to be applied to the next written row(s) */
protected $rowStyle;
@ -46,6 +46,17 @@ abstract class WriterAbstract implements WriterInterface
/** @var string Content-Type value for the header - to be defined by child class */
protected static $headerContentType;
/**
* @param OptionsManagerInterface $optionsManager
* @param StyleMerger $styleMerger
*/
public function __construct(OptionsManagerInterface $optionsManager, StyleMerger $styleMerger)
{
$this->optionsManager = $optionsManager;
$this->styleMerger = $styleMerger;
$this->resetRowStyleToDefault();
}
/**
* Opens the streamer and makes it ready to accept data.
*
@ -71,17 +82,6 @@ abstract class WriterAbstract implements WriterInterface
*/
abstract protected function closeWriter();
/**
* @param OptionsManagerInterface $optionsManager
* @param StyleManager $styleManager
*/
public function __construct(OptionsManagerInterface $optionsManager, StyleManager $styleManager)
{
$this->optionsManager = $optionsManager;
$this->styleManager = $styleManager;
$this->resetRowStyleToDefault();
}
/**
* Sets the default styles for all rows added with "addRow".
* Overriding the default style instead of using "addRowWithStyle" improves performance by 20%.
@ -327,7 +327,7 @@ abstract class WriterAbstract implements WriterInterface
{
// Merge given style with the default one to inherit custom properties
$defaultRowStyle = $this->optionsManager->getOption(Options::DEFAULT_ROW_STYLE);
$this->rowStyle = $this->styleManager->merge($style, $defaultRowStyle);
$this->rowStyle = $this->styleMerger->merge($style, $defaultRowStyle);
}
/**

View File

@ -7,7 +7,7 @@ use Box\Spout\Common\Helper\GlobalFunctionsHelper;
use Box\Spout\Common\Type;
use Box\Spout\Writer\Common\Creator\EntityFactory;
use Box\Spout\Writer\Common\Creator\Style\StyleBuilder;
use Box\Spout\Writer\Common\Manager\StyleManager;
use Box\Spout\Writer\Common\Manager\Style\StyleMerger;
/**
* Class WriterFactory
@ -55,9 +55,9 @@ class WriterFactory
private static function getCSVWriter()
{
$optionsManager = new CSV\Manager\OptionsManager();
$styleManager = new StyleManager();
$styleMerger = new StyleMerger();
return new CSV\Writer($optionsManager, $styleManager);
return new CSV\Writer($optionsManager, $styleMerger);
}
/**
@ -67,10 +67,10 @@ class WriterFactory
{
$styleBuilder = new StyleBuilder();
$optionsManager = new XLSX\Manager\OptionsManager($styleBuilder);
$styleManager = new StyleManager();
$styleMerger = new StyleMerger();
$generalFactory = new XLSX\Creator\InternalFactory(new EntityFactory());
return new XLSX\Writer($optionsManager, $styleManager, $generalFactory);
return new XLSX\Writer($optionsManager, $styleMerger, $generalFactory);
}
/**
@ -80,9 +80,9 @@ class WriterFactory
{
$styleBuilder = new StyleBuilder();
$optionsManager = new ODS\Manager\OptionsManager($styleBuilder);
$styleManager = new StyleManager();
$styleMerger = new StyleMerger();
$generalFactory = new ODS\Creator\InternalFactory(new EntityFactory());
return new ODS\Writer($optionsManager, $styleManager, $generalFactory);
return new ODS\Writer($optionsManager, $styleMerger, $generalFactory);
}
}

View File

@ -5,7 +5,7 @@ namespace Box\Spout\Writer;
use Box\Spout\Writer\Common\Manager\OptionsManagerInterface;
use Box\Spout\Writer\Common\Entity\Options;
use Box\Spout\Writer\Common\Entity\Worksheet;
use Box\Spout\Writer\Common\Manager\StyleManager;
use Box\Spout\Writer\Common\Manager\Style\StyleMerger;
use Box\Spout\Writer\Exception\WriterNotOpenedException;
use Box\Spout\Writer\Common\Creator\InternalFactoryInterface;
use Box\Spout\Writer\Common\Manager\WorkbookManagerInterface;
@ -27,12 +27,12 @@ abstract class WriterMultiSheetsAbstract extends WriterAbstract
/**
* @param OptionsManagerInterface $optionsManager
* @param StyleManager $styleManager
* @param StyleMerger $styleMerger
* @param InternalFactoryInterface $internalFactory
*/
public function __construct(OptionsManagerInterface $optionsManager, StyleManager $styleManager, InternalFactoryInterface $internalFactory)
public function __construct(OptionsManagerInterface $optionsManager, StyleMerger $styleMerger, InternalFactoryInterface $internalFactory)
{
parent::__construct($optionsManager, $styleManager);
parent::__construct($optionsManager, $styleMerger);
$this->internalFactory = $internalFactory;
}

View File

@ -4,16 +4,14 @@ namespace Box\Spout\Writer\XLSX\Creator;
use Box\Spout\Common\Escaper;
use Box\Spout\Common\Helper\StringHelper;
use Box\Spout\Writer\Common\Manager\OptionsManagerInterface;
use Box\Spout\Writer\Common\Entity\Options;
use Box\Spout\Writer\Common\Creator\EntityFactory;
use Box\Spout\Writer\Common\Creator\InternalFactoryInterface;
use Box\Spout\Writer\Common\Creator\WorkbookFactory;
use Box\Spout\Writer\Common\Creator\WorksheetFactory;
use Box\Spout\Writer\Common\Manager\StyleManager;
use Box\Spout\Writer\Common\Entity\Options;
use Box\Spout\Writer\Common\Manager\OptionsManagerInterface;
use Box\Spout\Writer\XLSX\Helper\FileSystemHelper;
use Box\Spout\Writer\XLSX\Helper\SharedStringsHelper;
use Box\Spout\Writer\XLSX\Helper\StyleHelper;
use Box\Spout\Writer\XLSX\Manager\Style\StyleManager;
use Box\Spout\Writer\XLSX\Manager\Style\StyleRegistry;
use Box\Spout\Writer\XLSX\Manager\WorkbookManager;
use Box\Spout\Writer\XLSX\Manager\WorksheetManager;
@ -52,29 +50,48 @@ class InternalFactory implements InternalFactoryInterface
$xlFolder = $fileSystemHelper->getXlFolder();
$sharedStringsHelper = $this->createSharedStringsHelper($xlFolder);
$styleHelper = $this->createStyleHelper($optionsManager);
$styleManager = $this->createStyleManager($optionsManager);
$worksheetManager = $this->createWorksheetManager($optionsManager, $styleManager, $sharedStringsHelper);
$worksheetManager = $this->createWorksheetManager($optionsManager, $sharedStringsHelper, $styleHelper);
return new WorkbookManager($workbook, $optionsManager, $worksheetManager, $styleHelper, $fileSystemHelper, $this->entityFactory);
return new WorkbookManager($workbook, $optionsManager, $worksheetManager, $styleManager, $fileSystemHelper, $this->entityFactory);
}
/**
* @param OptionsManagerInterface $optionsManager
* @param StyleManager $styleManager
* @param SharedStringsHelper $sharedStringsHelper
* @param StyleHelper $styleHelper
* @return WorksheetManager
*/
private function createWorksheetManager(
OptionsManagerInterface $optionsManager,
SharedStringsHelper $sharedStringsHelper,
StyleHelper $styleHelper
StyleManager $styleManager,
SharedStringsHelper $sharedStringsHelper
)
{
$stringsEscaper = $this->createStringsEscaper();
$stringsHelper = $this->createStringHelper();
return new WorksheetManager($optionsManager, $sharedStringsHelper, $styleHelper, $stringsEscaper, $stringsHelper);
return new WorksheetManager($optionsManager, $styleManager, $sharedStringsHelper, $stringsEscaper, $stringsHelper);
}
/**
* @param OptionsManagerInterface $optionsManager
* @return StyleManager
*/
private function createStyleManager(OptionsManagerInterface $optionsManager)
{
$styleRegistry = $this->createStyleRegistry($optionsManager);
return new StyleManager($styleRegistry);
}
/**
* @param OptionsManagerInterface $optionsManager
* @return StyleRegistry
*/
private function createStyleRegistry(OptionsManagerInterface $optionsManager)
{
$defaultRowStyle = $optionsManager->getOption(Options::DEFAULT_ROW_STYLE);
return new StyleRegistry($defaultRowStyle);
}
/**
@ -96,26 +113,6 @@ class InternalFactory implements InternalFactoryInterface
return new FileSystemHelper($tempFolder);
}
/**
* @param OptionsManagerInterface $optionsManager
* @return StyleHelper
*/
private function createStyleHelper(OptionsManagerInterface $optionsManager)
{
$defaultRowStyle = $optionsManager->getOption(Options::DEFAULT_ROW_STYLE);
$styleManager = $this->createStyleManager();
return new StyleHelper($defaultRowStyle, $styleManager);
}
/**
* @return StyleManager
*/
private function createStyleManager()
{
return new StyleManager();
}
/**
* @return Escaper\XLSX
*/

View File

@ -2,9 +2,10 @@
namespace Box\Spout\Writer\XLSX\Helper;
use Box\Spout\Writer\Common\Entity\Worksheet;
use Box\Spout\Writer\Common\Helper\FileSystemWithRootFolderHelperInterface;
use Box\Spout\Writer\Common\Helper\ZipHelper;
use Box\Spout\Writer\Common\Entity\Worksheet;
use Box\Spout\Writer\XLSX\Manager\Style\StyleManager;
/**
* Class FileSystemHelper
@ -335,12 +336,12 @@ EOD;
/**
* Creates the "styles.xml" file under the "xl" folder
*
* @param StyleHelper $styleHelper
* @param StyleManager $styleManager
* @return FileSystemHelper
*/
public function createStylesFile($styleHelper)
public function createStylesFile($styleManager)
{
$stylesXmlFileContents = $styleHelper->getStylesXMLFileContent();
$stylesXmlFileContents = $styleManager->getStylesXMLFileContent();
$this->createFileWithContents($this->xlFolder, self::STYLES_XML_FILE_NAME, $stylesXmlFileContents);
return $this;

View File

@ -1,124 +1,21 @@
<?php
namespace Box\Spout\Writer\XLSX\Helper;
namespace Box\Spout\Writer\XLSX\Manager\Style;
use Box\Spout\Writer\Common\Helper\StyleHelperAbstract;
use Box\Spout\Writer\Common\Entity\Style\Color;
use Box\Spout\Writer\Common\Entity\Style\Style;
use Box\Spout\Writer\XLSX\Helper\BorderHelper;
/**
* Class StyleHelper
* This class provides helper functions to manage styles
* Class StyleManager
* Manages styles to be applied to a cell
*
* @package Box\Spout\Writer\XLSX\Helper
* @package Box\Spout\Writer\XLSX\Manager\Style
*/
class StyleHelper extends StyleHelperAbstract
class StyleManager extends \Box\Spout\Writer\Common\Manager\Style\StyleManager
{
/**
* @var array
*/
protected $registeredFills = [];
/**
* @var array [STYLE_ID] => [FILL_ID] maps a style to a fill declaration
*/
protected $styleIdToFillMappingTable = [];
/**
* Excel preserves two default fills with index 0 and 1
* Since Excel is the dominant vendor - we play along here
*
* @var int The fill index counter for custom fills.
*/
protected $fillIndex = 2;
/**
* @var array
*/
protected $registeredBorders = [];
/**
* @var array [STYLE_ID] => [BORDER_ID] maps a style to a border declaration
*/
protected $styleIdToBorderMappingTable = [];
/**
* XLSX specific operations on the registered styles
*
* @param \Box\Spout\Writer\Common\Entity\Style\Style $style
* @return \Box\Spout\Writer\Common\Entity\Style\Style
*/
public function registerStyle($style)
{
$registeredStyle = parent::registerStyle($style);
$this->registerFill($registeredStyle);
$this->registerBorder($registeredStyle);
return $registeredStyle;
}
/**
* Register a fill definition
*
* @param \Box\Spout\Writer\Common\Entity\Style\Style $style
*/
protected function registerFill($style)
{
$styleId = $style->getId();
// Currently - only solid backgrounds are supported
// so $backgroundColor is a scalar value (RGB Color)
$backgroundColor = $style->getBackgroundColor();
if ($backgroundColor) {
$isBackgroundColorRegistered = isset($this->registeredFills[$backgroundColor]);
// We need to track the already registered background definitions
if ($isBackgroundColorRegistered) {
$registeredStyleId = $this->registeredFills[$backgroundColor];
$registeredFillId = $this->styleIdToFillMappingTable[$registeredStyleId];
$this->styleIdToFillMappingTable[$styleId] = $registeredFillId;
} else {
$this->registeredFills[$backgroundColor] = $styleId;
$this->styleIdToFillMappingTable[$styleId] = $this->fillIndex++;
}
} else {
// The fillId maps a style to a fill declaration
// When there is no background color definition - we default to 0
$this->styleIdToFillMappingTable[$styleId] = 0;
}
}
/**
* Register a border definition
*
* @param \Box\Spout\Writer\Common\Entity\Style\Style $style
*/
protected function registerBorder($style)
{
$styleId = $style->getId();
if ($style->shouldApplyBorder()) {
$border = $style->getBorder();
$serializedBorder = serialize($border);
$isBorderAlreadyRegistered = isset($this->registeredBorders[$serializedBorder]);
if ($isBorderAlreadyRegistered) {
$registeredStyleId = $this->registeredBorders[$serializedBorder];
$registeredBorderId = $this->styleIdToBorderMappingTable[$registeredStyleId];
$this->styleIdToBorderMappingTable[$styleId] = $registeredBorderId;
} else {
$this->registeredBorders[$serializedBorder] = $styleId;
$this->styleIdToBorderMappingTable[$styleId] = count($this->registeredBorders);
}
} else {
// If no border should be applied - the mapping is the default border: 0
$this->styleIdToBorderMappingTable[$styleId] = 0;
}
}
/** @var StyleRegistry */
protected $styleRegistry;
/**
* For empty cells, we can specify a style or not. If no style are specified,
@ -132,8 +29,11 @@ class StyleHelper extends StyleHelperAbstract
*/
public function shouldApplyStyleOnEmptyCell($styleId)
{
$hasStyleCustomFill = (isset($this->styleIdToFillMappingTable[$styleId]) && $this->styleIdToFillMappingTable[$styleId] !== 0);
$hasStyleCustomBorders = (isset($this->styleIdToBorderMappingTable[$styleId]) && $this->styleIdToBorderMappingTable[$styleId] !== 0);
$associatedFillId = $this->styleRegistry->getFillIdForStyleId($styleId);
$hasStyleCustomFill = ($associatedFillId !== null && $associatedFillId !== 0);
$associatedBorderId = $this->styleRegistry->getBorderIdForStyleId($styleId);
$hasStyleCustomBorders = ($associatedBorderId !== null && $associatedBorderId !== 0);
return ($hasStyleCustomFill || $hasStyleCustomBorders);
}
@ -172,10 +72,12 @@ EOD;
*/
protected function getFontsSectionContent()
{
$content = '<fonts count="' . count($this->styleIdToStyleMappingTable) . '">';
$registeredStyles = $this->styleRegistry->getRegisteredStyles();
/** @var \Box\Spout\Writer\Common\Entity\Style\Style $style */
foreach ($this->getRegisteredStyles() as $style) {
$content = '<fonts count="' . count($registeredStyles) . '">';
/** @var Style $style */
foreach ($registeredStyles as $style) {
$content .= '<font>';
$content .= '<sz val="' . $style->getFontSize() . '"/>';
@ -210,17 +112,19 @@ EOD;
*/
protected function getFillsSectionContent()
{
$registeredFills = $this->styleRegistry->getRegisteredFills();
// Excel reserves two default fills
$fillsCount = count($this->registeredFills) + 2;
$fillsCount = count($registeredFills) + 2;
$content = sprintf('<fills count="%d">', $fillsCount);
$content .= '<fill><patternFill patternType="none"/></fill>';
$content .= '<fill><patternFill patternType="gray125"/></fill>';
// The other fills are actually registered by setting a background color
foreach ($this->registeredFills as $styleId) {
foreach ($registeredFills as $styleId) {
/** @var Style $style */
$style = $this->styleIdToStyleMappingTable[$styleId];
$style = $this->styleRegistry->getStyleFromStyleId($styleId);
$backgroundColor = $style->getBackgroundColor();
$content .= sprintf(
@ -241,18 +145,19 @@ EOD;
*/
protected function getBordersSectionContent()
{
$registeredBorders = $this->styleRegistry->getRegisteredBorders();
// There is one default border with index 0
$borderCount = count($this->registeredBorders) + 1;
$borderCount = count($registeredBorders) + 1;
$content = '<borders count="' . $borderCount . '">';
// Default border starting at index 0
$content .= '<border><left/><right/><top/><bottom/></border>';
foreach ($this->registeredBorders as $styleId) {
foreach ($registeredBorders as $styleId) {
/** @var \Box\Spout\Writer\Common\Entity\Style\Style $style */
$style = $this->styleIdToStyleMappingTable[$styleId];
$style = $this->styleRegistry->getStyleFromStyleId($styleId);
$border = $style->getBorder();
$content .= '<border>';
@ -265,7 +170,6 @@ EOD;
$part = $border->getPart($partName);
$content .= BorderHelper::serializeBorderPart($part);
}
}
$content .= '</border>';
@ -297,14 +201,14 @@ EOD;
*/
protected function getCellXfsSectionContent()
{
$registeredStyles = $this->getRegisteredStyles();
$registeredStyles = $this->styleRegistry->getRegisteredStyles();
$content = '<cellXfs count="' . count($registeredStyles) . '">';
foreach ($registeredStyles as $style) {
$styleId = $style->getId();
$fillId = $this->styleIdToFillMappingTable[$styleId];
$borderId = $this->styleIdToBorderMappingTable[$styleId];
$fillId = $this->styleRegistry->getFillIdForStyleId($styleId);
$borderId = $this->styleRegistry->getBorderIdForStyleId($styleId);
$content .= '<xf numFmtId="0" fontId="' . $styleId . '" fillId="' . $fillId . '" borderId="' . $borderId . '" xfId="0"';

View File

@ -0,0 +1,158 @@
<?php
namespace Box\Spout\Writer\XLSX\Manager\Style;
use Box\Spout\Writer\Common\Entity\Style\Style;
/**
* Class StyleRegistry
* Registry for all used styles
*
* @package Box\Spout\Writer\XLSX\Manager\Style
*/
class StyleRegistry extends \Box\Spout\Writer\Common\Manager\Style\StyleRegistry
{
/**
* @var array
*/
protected $registeredFills = [];
/**
* @var array [STYLE_ID] => [FILL_ID] maps a style to a fill declaration
*/
protected $styleIdToFillMappingTable = [];
/**
* Excel preserves two default fills with index 0 and 1
* Since Excel is the dominant vendor - we play along here
*
* @var int The fill index counter for custom fills.
*/
protected $fillIndex = 2;
/**
* @var array
*/
protected $registeredBorders = [];
/**
* @var array [STYLE_ID] => [BORDER_ID] maps a style to a border declaration
*/
protected $styleIdToBorderMappingTable = [];
/**
* XLSX specific operations on the registered styles
*
* @param Style $style
* @return Style
*/
public function registerStyle(Style $style)
{
$registeredStyle = parent::registerStyle($style);
$this->registerFill($registeredStyle);
$this->registerBorder($registeredStyle);
return $registeredStyle;
}
/**
* Register a fill definition
*
* @param Style $style
*/
private function registerFill(Style $style)
{
$styleId = $style->getId();
// Currently - only solid backgrounds are supported
// so $backgroundColor is a scalar value (RGB Color)
$backgroundColor = $style->getBackgroundColor();
if ($backgroundColor) {
$isBackgroundColorRegistered = isset($this->registeredFills[$backgroundColor]);
// We need to track the already registered background definitions
if ($isBackgroundColorRegistered) {
$registeredStyleId = $this->registeredFills[$backgroundColor];
$registeredFillId = $this->styleIdToFillMappingTable[$registeredStyleId];
$this->styleIdToFillMappingTable[$styleId] = $registeredFillId;
} else {
$this->registeredFills[$backgroundColor] = $styleId;
$this->styleIdToFillMappingTable[$styleId] = $this->fillIndex++;
}
} else {
// The fillId maps a style to a fill declaration
// When there is no background color definition - we default to 0
$this->styleIdToFillMappingTable[$styleId] = 0;
}
}
/**
* @param int $styleId
* @return int|null Fill ID associated to the given style ID
*/
public function getFillIdForStyleId($styleId)
{
return (isset($this->styleIdToFillMappingTable[$styleId])) ?
$this->styleIdToFillMappingTable[$styleId] :
null;
}
/**
* Register a border definition
*
* @param Style $style
*/
private function registerBorder(Style $style)
{
$styleId = $style->getId();
if ($style->shouldApplyBorder()) {
$border = $style->getBorder();
$serializedBorder = serialize($border);
$isBorderAlreadyRegistered = isset($this->registeredBorders[$serializedBorder]);
if ($isBorderAlreadyRegistered) {
$registeredStyleId = $this->registeredBorders[$serializedBorder];
$registeredBorderId = $this->styleIdToBorderMappingTable[$registeredStyleId];
$this->styleIdToBorderMappingTable[$styleId] = $registeredBorderId;
} else {
$this->registeredBorders[$serializedBorder] = $styleId;
$this->styleIdToBorderMappingTable[$styleId] = count($this->registeredBorders);
}
} else {
// If no border should be applied - the mapping is the default border: 0
$this->styleIdToBorderMappingTable[$styleId] = 0;
}
}
/**
* @param int $styleId
* @return int|null Fill ID associated to the given style ID
*/
public function getBorderIdForStyleId($styleId)
{
return (isset($this->styleIdToBorderMappingTable[$styleId])) ?
$this->styleIdToBorderMappingTable[$styleId] :
null;
}
/**
* @return array
*/
public function getRegisteredFills()
{
return $this->registeredFills;
}
/**
* @return array
*/
public function getRegisteredBorders()
{
return $this->registeredBorders;
}
}

View File

@ -5,7 +5,7 @@ namespace Box\Spout\Writer\XLSX\Manager;
use Box\Spout\Writer\Common\Sheet;
use Box\Spout\Writer\Common\Manager\WorkbookManagerAbstract;
use Box\Spout\Writer\XLSX\Helper\FileSystemHelper;
use Box\Spout\Writer\XLSX\Helper\StyleHelper;
use Box\Spout\Writer\XLSX\Manager\Style\StyleManager;
/**
* Class WorkbookManager
@ -24,12 +24,12 @@ class WorkbookManager extends WorkbookManagerAbstract
/** @var WorksheetManager Object used to manage worksheets */
protected $worksheetManager;
/** @var StyleManager Manages styles */
protected $styleManager;
/** @var FileSystemHelper Helper to perform file system operations */
protected $fileSystemHelper;
/** @var StyleHelper Helper to apply styles */
protected $styleHelper;
/**
* @return int Maximum number of rows/columns a sheet can contain
*/
@ -72,7 +72,7 @@ class WorkbookManager extends WorkbookManagerAbstract
->createContentTypesFile($worksheets)
->createWorkbookFile($worksheets)
->createWorkbookRelsFile($worksheets)
->createStylesFile($this->styleHelper)
->createStylesFile($this->styleManager)
->zipRootFolderAndCopyToStream($finalFilePointer);
}
}

View File

@ -13,7 +13,7 @@ use Box\Spout\Writer\Common\Entity\Worksheet;
use Box\Spout\Writer\Common\Manager\WorksheetManagerInterface;
use Box\Spout\Writer\Common\Entity\Style\Style;
use Box\Spout\Writer\XLSX\Helper\SharedStringsHelper;
use Box\Spout\Writer\XLSX\Helper\StyleHelper;
use Box\Spout\Writer\XLSX\Manager\Style\StyleManager;
/**
* Class WorksheetManager
@ -39,12 +39,12 @@ EOD;
/** @var bool Whether inline or shared strings should be used */
protected $shouldUseInlineStrings;
/** @var StyleManager Manages styles */
private $styleManager;
/** @var SharedStringsHelper Helper to write shared strings */
private $sharedStringsHelper;
/** @var StyleHelper Helper to work with styles */
private $styleHelper;
/** @var \Box\Spout\Common\Escaper\XLSX Strings escaper */
private $stringsEscaper;
@ -55,21 +55,21 @@ EOD;
* WorksheetManager constructor.
*
* @param OptionsManagerInterface $optionsManager
* @param StyleManager $styleManager
* @param SharedStringsHelper $sharedStringsHelper
* @param StyleHelper $styleHelper
* @param \Box\Spout\Common\Escaper\XLSX $stringsEscaper
* @param StringHelper $stringHelper
*/
public function __construct(
OptionsManagerInterface $optionsManager,
StyleManager $styleManager,
SharedStringsHelper $sharedStringsHelper,
StyleHelper $styleHelper,
\Box\Spout\Common\Escaper\XLSX $stringsEscaper,
StringHelper $stringHelper)
{
$this->shouldUseInlineStrings = $optionsManager->getOption(Options::SHOULD_USE_INLINE_STRINGS);
$this->styleManager = $styleManager;
$this->sharedStringsHelper = $sharedStringsHelper;
$this->styleHelper = $styleHelper;
$this->stringsEscaper = $stringsEscaper;
$this->stringHelper = $stringHelper;
}
@ -211,7 +211,7 @@ EOD;
} else if ($cell->isNumeric()) {
$cellXML .= '><v>' . $cell->getValue() . '</v></c>';
} else if ($cell->isEmpty()) {
if ($this->styleHelper->shouldApplyStyleOnEmptyCell($styleId)) {
if ($this->styleManager->shouldApplyStyleOnEmptyCell($styleId)) {
$cellXML .= '/>';
} else {
// don't write empty cells that do no need styling

View File

@ -3,7 +3,7 @@
namespace Box\Spout\Reader\XLSX\Helper;
/**
* Class StyleHelperTest
* Class StyleManagerTest
*
* @package Box\Spout\Reader\XLSX\Helper
*/

View File

@ -0,0 +1,45 @@
<?php
namespace Box\Spout\Writer\Common\Creator\Style;
use Box\Spout\Writer\Common\Entity\Style\Border;
use Box\Spout\Writer\Common\Entity\Style\Color;
use Box\Spout\Writer\Common\Manager\Style\StyleMerger;
/**
* Class StyleManagerTest
*
* @package Box\Spout\Writer\Common\Creator\Style
*/
class StyleBuilderTest extends \PHPUnit_Framework_TestCase
{
/**
* @return void
*/
public function testStyleBuilderShouldApplyBorders()
{
$border = (new BorderBuilder())
->setBorderBottom()
->build();
$style = (new StyleBuilder())->setBorder($border)->build();
$this->assertTrue($style->shouldApplyBorder());
}
/**
* @return void
*/
public function testStyleBuilderShouldMergeBorders()
{
$border = (new BorderBuilder())->setBorderBottom(Color::RED, Border::WIDTH_THIN, Border::STYLE_DASHED)->build();
$baseStyle = (new StyleBuilder())->setBorder($border)->build();
$currentStyle = (new StyleBuilder())->build();
$styleMerger = new StyleMerger();
$mergedStyle = $styleMerger->merge($currentStyle, $baseStyle);
$this->assertEquals(null, $currentStyle->getBorder(), 'Current style has no border');
$this->assertInstanceOf('Box\Spout\Writer\Common\Entity\Style\Border', $baseStyle->getBorder(), 'Base style has a border');
$this->assertInstanceOf('Box\Spout\Writer\Common\Entity\Style\Border', $mergedStyle->getBorder(), 'Merged style has a border');
}
}

View File

@ -0,0 +1,52 @@
<?php
namespace Box\Spout\Writer\Common\Manager\Style;
use Box\Spout\Writer\Common\Creator\Style\StyleBuilder;
/**
* Class StyleManagerTest
*
* @package Box\Spout\Writer\Common\Manager\Style
*/
class StyleManagerTest extends \PHPUnit_Framework_TestCase
{
/**
* @return StyleManager
*/
private function getStyleManager()
{
$style = (new StyleBuilder())->build();
$styleRegistry = new StyleRegistry($style);
return new StyleManager($styleRegistry);
}
/**
* @return void
*/
public function testApplyExtraStylesIfNeededShouldApplyWrapTextIfCellContainsNewLine()
{
$style = (new StyleBuilder())->build();
$this->assertFalse($style->shouldWrapText());
$styleManager = $this->getStyleManager();
$updatedStyle = $styleManager->applyExtraStylesIfNeeded($style, [12, 'single line', "multi\nlines", null]);
$this->assertTrue($updatedStyle->shouldWrapText());
}
/**
* @return void
*/
public function testApplyExtraStylesIfNeededShouldDoNothingIfWrapTextAlreadyApplied()
{
$style = (new StyleBuilder())->setShouldWrapText()->build();
$this->assertTrue($style->shouldWrapText());
$styleManager = $this->getStyleManager();
$updatedStyle = $styleManager->applyExtraStylesIfNeeded($style, ["multi\nlines"]);
$this->assertTrue($updatedStyle->shouldWrapText());
}
}

View File

@ -1,43 +1,27 @@
<?php
namespace Box\Spout\Writer\Common\Manager;
namespace Box\Spout\Writer\Common\Manager\Style;
use Box\Spout\Writer\Common\Creator\Style\BorderBuilder;
use Box\Spout\Writer\Common\Creator\Style\StyleBuilder;
use Box\Spout\Writer\Common\Entity\Style\Border;
use Box\Spout\Writer\Common\Entity\Style\Color;
use Box\Spout\Writer\Common\Entity\Style\Style;
/**
* Class StyleManagerTest
* Class StyleMergerTest
*
* @package Box\Spout\Writer\Common\Manager
* @package Box\Spout\Writer\Common\Manager\Style
*/
class StyleManagerTest extends \PHPUnit_Framework_TestCase
class StyleMergerTest extends \PHPUnit_Framework_TestCase
{
/** @var StyleManager */
private $styleManager;
/** @var StyleMerger */
private $styleMerger;
/**
* @return void
*/
public function setUp()
{
$this->styleManager = new StyleManager();
}
/**
* @return void
*/
public function testSerializeShouldNotTakeIntoAccountId()
{
$style1 = (new StyleBuilder())->setFontBold()->build();
$style1->setId(1);
$style2 = (new StyleBuilder())->setFontBold()->build();
$style2->setId(2);
$this->assertEquals($this->styleManager->serialize($style1), $this->styleManager->serialize($style2));
$this->styleMerger = new StyleMerger();
}
/**
@ -47,7 +31,7 @@ class StyleManagerTest extends \PHPUnit_Framework_TestCase
{
$baseStyle = (new StyleBuilder())->build();
$currentStyle = (new StyleBuilder())->build();
$mergedStyle = $this->styleManager->merge($currentStyle, $baseStyle);
$mergedStyle = $this->styleMerger->merge($currentStyle, $baseStyle);
$this->assertNotSame($mergedStyle, $currentStyle);
}
@ -57,17 +41,26 @@ class StyleManagerTest extends \PHPUnit_Framework_TestCase
*/
public function testMergeWithShouldMergeSetProperties()
{
$baseStyle = (new StyleBuilder())->setFontSize(99)->setFontBold()->build();
$baseStyle = (new StyleBuilder())
->setFontSize(99)
->setFontBold()
->setFontColor(Color::YELLOW)
->setBackgroundColor(Color::BLUE)
->build();
$currentStyle = (new StyleBuilder())->setFontName('Font')->setFontUnderline()->build();
$mergedStyle = $this->styleManager->merge($currentStyle, $baseStyle);
$mergedStyle = $this->styleMerger->merge($currentStyle, $baseStyle);
$this->assertNotEquals(99, $currentStyle->getFontSize());
$this->assertFalse($currentStyle->isFontBold());
$this->assertEquals(Style::DEFAULT_FONT_COLOR, $currentStyle->getFontColor());
$this->assertEquals(null, $currentStyle->getBackgroundColor());
$this->assertEquals(99, $mergedStyle->getFontSize());
$this->assertTrue($mergedStyle->isFontBold());
$this->assertEquals('Font', $mergedStyle->getFontName());
$this->assertTrue($mergedStyle->isFontUnderline());
$this->assertEquals(Color::YELLOW, $mergedStyle->getFontColor());
$this->assertEquals(Color::BLUE, $mergedStyle->getBackgroundColor());
}
/**
@ -77,7 +70,7 @@ class StyleManagerTest extends \PHPUnit_Framework_TestCase
{
$baseStyle = (new StyleBuilder())->setFontSize(10)->build();
$currentStyle = (new StyleBuilder())->setFontSize(99)->build();
$mergedStyle = $this->styleManager->merge($currentStyle, $baseStyle);
$mergedStyle = $this->styleMerger->merge($currentStyle, $baseStyle);
$this->assertEquals(99, $mergedStyle->getFontSize());
}
@ -88,8 +81,12 @@ class StyleManagerTest extends \PHPUnit_Framework_TestCase
public function testMergeWithShouldPreferCurrentStylePropertyIfSetOnCurrentButNotOnBase()
{
$baseStyle = (new StyleBuilder())->build();
$currentStyle = (new StyleBuilder())->setFontItalic()->setFontStrikethrough()->build();
$mergedStyle = $this->styleManager->merge($currentStyle, $baseStyle);
$currentStyle = (new StyleBuilder())
->setFontItalic()
->setFontStrikethrough()
->build();
$mergedStyle = $this->styleMerger->merge($currentStyle, $baseStyle);
$this->assertFalse($baseStyle->isFontItalic());
$this->assertFalse($baseStyle->isFontStrikethrough());
@ -110,7 +107,7 @@ class StyleManagerTest extends \PHPUnit_Framework_TestCase
->setShouldWrapText()
->build();
$currentStyle = (new StyleBuilder())->build();
$mergedStyle = $this->styleManager->merge($currentStyle, $baseStyle);
$mergedStyle = $this->styleMerger->merge($currentStyle, $baseStyle);
$this->assertFalse($currentStyle->isFontUnderline());
$this->assertTrue($mergedStyle->isFontUnderline());
@ -126,10 +123,10 @@ class StyleManagerTest extends \PHPUnit_Framework_TestCase
{
$baseStyle = (new StyleBuilder())->build();
$currentStyle = (new StyleBuilder())->build();
$mergedStyle = $this->styleManager->merge($currentStyle, $baseStyle);
$mergedStyle = $this->styleMerger->merge($currentStyle, $baseStyle);
$this->assertTrue($this->styleManager->serialize($baseStyle) === $this->styleManager->serialize($currentStyle));
$this->assertTrue($this->styleManager->serialize($currentStyle) === $this->styleManager->serialize($mergedStyle));
$this->assertSameStyles($baseStyle, $currentStyle);
$this->assertSameStyles($currentStyle, $mergedStyle);
}
/**
@ -142,36 +139,21 @@ class StyleManagerTest extends \PHPUnit_Framework_TestCase
->setFontSize(Style::DEFAULT_FONT_SIZE)
->build();
$currentStyle = (new StyleBuilder())->build();
$mergedStyle = $this->styleManager->merge($currentStyle, $baseStyle);
$mergedStyle = $this->styleMerger->merge($currentStyle, $baseStyle);
$this->assertTrue($this->styleManager->serialize($currentStyle) === $this->styleManager->serialize($mergedStyle));
$this->assertSameStyles($currentStyle, $mergedStyle);
}
/**
* @param Style $style1
* @param Style $style2
* @return void
*/
public function testStyleBuilderShouldApplyBorders()
private function assertSameStyles(Style $style1, Style $style2)
{
$border = (new BorderBuilder())
->setBorderBottom()
->build();
$style = (new StyleBuilder())->setBorder($border)->build();
$this->assertTrue($style->shouldApplyBorder());
}
$fakeStyle = (new StyleBuilder())->build();
$styleRegistry = new StyleRegistry($fakeStyle);
/**
* @return void
*/
public function testStyleBuilderShouldMergeBorders()
{
$border = (new BorderBuilder())->setBorderBottom(Color::RED, Border::WIDTH_THIN, Border::STYLE_DASHED)->build();
$baseStyle = (new StyleBuilder())->setBorder($border)->build();
$currentStyle = (new StyleBuilder())->build();
$mergedStyle = $this->styleManager->merge($currentStyle, $baseStyle);
$this->assertEquals(null, $currentStyle->getBorder(), 'Current style has no border');
$this->assertInstanceOf('Box\Spout\Writer\Common\Entity\Style\Border', $baseStyle->getBorder(), 'Base style has a border');
$this->assertInstanceOf('Box\Spout\Writer\Common\Entity\Style\Border', $mergedStyle->getBorder(), 'Merged style has a border');
$this->assertTrue($styleRegistry->serialize($style1) === $styleRegistry->serialize($style2));
}
}

View File

@ -0,0 +1,79 @@
<?php
namespace Box\Spout\Writer\Common\Manager\Style;
use Box\Spout\Writer\Common\Creator\Style\BorderBuilder;
use Box\Spout\Writer\Common\Creator\Style\StyleBuilder;
use Box\Spout\Writer\Common\Entity\Style\Border;
use Box\Spout\Writer\Common\Entity\Style\Color;
use Box\Spout\Writer\Common\Entity\Style\Style;
/**
* Class StyleRegistryTest
*
* @package Box\Spout\Writer\Common\Manager\Style
*/
class StyleRegistryTest extends \PHPUnit_Framework_TestCase
{
/** @var Style */
private $defaultStyle;
/** @var StyleRegistry */
private $styleRegistry;
/**
* @return void
*/
public function setUp()
{
$this->defaultStyle = (new StyleBuilder())->build();
$this->styleRegistry = new StyleRegistry($this->defaultStyle);
}
/**
* @return void
*/
public function testSerializeShouldNotTakeIntoAccountId()
{
$style1 = (new StyleBuilder())->setFontBold()->build();
$style1->setId(1);
$style2 = (new StyleBuilder())->setFontBold()->build();
$style2->setId(2);
$this->assertEquals($this->styleRegistry->serialize($style1), $this->styleRegistry->serialize($style2));
}
/**
* @return void
*/
public function testRegisterStyleShouldUpdateId()
{
$style1 = (new StyleBuilder())->setFontBold()->build();
$style2 = (new StyleBuilder())->setFontUnderline()->build();
$this->assertEquals(0, $this->defaultStyle->getId(), 'Default style ID should be 0');
$this->assertNull($style1->getId());
$this->assertNull($style2->getId());
$registeredStyle1 = $this->styleRegistry->registerStyle($style1);
$registeredStyle2 = $this->styleRegistry->registerStyle($style2);
$this->assertEquals(1, $registeredStyle1->getId());
$this->assertEquals(2, $registeredStyle2->getId());
}
/**
* @return void
*/
public function testRegisterStyleShouldReuseAlreadyRegisteredStyles()
{
$style = (new StyleBuilder())->setFontBold()->build();
$registeredStyle1 = $this->styleRegistry->registerStyle($style);
$registeredStyle2 = $this->styleRegistry->registerStyle($style);
$this->assertEquals(1, $registeredStyle1->getId());
$this->assertEquals(1, $registeredStyle2->getId());
}
}

View File

@ -1,91 +0,0 @@
<?php
namespace Box\Spout\Writer\ODS\Helper;
use Box\Spout\Writer\Common\Creator\Style\StyleBuilder;
use Box\Spout\Writer\Common\Entity\Style\Style;
use Box\Spout\Writer\Common\Manager\StyleManager;
/**
* Class StyleHelperTest
*
* @package Box\Spout\Writer\ODS\Helper
*/
class StyleHelperTest extends \PHPUnit_Framework_TestCase
{
/** @var Style */
protected $defaultStyle;
/** @var StyleHelper */
private $styleHelper;
/**
* @return void
*/
public function setUp()
{
$this->defaultStyle = (new StyleBuilder())->build();
$this->styleHelper = new StyleHelper($this->defaultStyle, new StyleManager());
}
/**
* @return void
*/
public function testRegisterStyleShouldUpdateId()
{
$style1 = (new StyleBuilder())->setFontBold()->build();
$style2 = (new StyleBuilder())->setFontUnderline()->build();
$this->assertEquals(0, $this->defaultStyle->getId(), 'Default style ID should be 0');
$this->assertNull($style1->getId());
$this->assertNull($style2->getId());
$registeredStyle1 = $this->styleHelper->registerStyle($style1);
$registeredStyle2 = $this->styleHelper->registerStyle($style2);
$this->assertEquals(1, $registeredStyle1->getId());
$this->assertEquals(2, $registeredStyle2->getId());
}
/**
* @return void
*/
public function testRegisterStyleShouldReuseAlreadyRegisteredStyles()
{
$style = (new StyleBuilder())->setFontBold()->build();
$registeredStyle1 = $this->styleHelper->registerStyle($style);
$registeredStyle2 = $this->styleHelper->registerStyle($style);
$this->assertEquals(1, $registeredStyle1->getId());
$this->assertEquals(1, $registeredStyle2->getId());
}
/**
* @return void
*/
public function testApplyExtraStylesIfNeededShouldApplyWrapTextIfCellContainsNewLine()
{
$style = clone $this->defaultStyle;
$this->assertFalse($style->shouldWrapText());
$updatedStyle = $this->styleHelper->applyExtraStylesIfNeeded($style, [12, 'single line', "multi\nlines", null]);
$this->assertTrue($updatedStyle->shouldWrapText());
}
/**
* @return void
*/
public function testApplyExtraStylesIfNeededShouldDoNothingIfWrapTextAlreadyApplied()
{
$style = (new StyleBuilder())->setShouldWrapText()->build();
$this->assertTrue($style->shouldWrapText());
$updatedStyle = $this->styleHelper->applyExtraStylesIfNeeded($style, ["multi\nlines"]);
$this->assertTrue($updatedStyle->shouldWrapText());
}
}

View File

@ -0,0 +1,40 @@
<?php
namespace Box\Spout\Writer\ODS\Manager\Style;
use Box\Spout\Writer\Common\Creator\Style\StyleBuilder;
/**
* Class StyleRegistryTest
*
* @package Box\Spout\Writer\ODS\Manager\Style
*/
class StyleRegistryTest extends \PHPUnit_Framework_TestCase
{
/**
* @return StyleRegistry
*/
private function getStyleRegistry()
{
$defaultStyle = (new StyleBuilder())->build();
return new StyleRegistry($defaultStyle);
}
/**
* @return void
*/
public function testRegisterStyleKeepsTrackOfUsedFonts()
{
$styleRegistry = $this->getStyleRegistry();
$this->assertEquals(1, count($styleRegistry->getUsedFonts()), 'There should only be the default font name');
$style1 = (new StyleBuilder())->setFontName("MyFont1")->build();
$styleRegistry->registerStyle($style1);
$style2 = (new StyleBuilder())->setFontName("MyFont2")->build();
$styleRegistry->registerStyle($style2);
$this->assertEquals(3, count($styleRegistry->getUsedFonts()), 'There should be 3 fonts registered');
}
}

View File

@ -22,8 +22,8 @@ class WriterWithStyleTest extends \PHPUnit_Framework_TestCase
{
use TestUsingResource;
/** @var \Box\Spout\Writer\Common\Entity\Style\Style */
protected $defaultStyle;
/** @var Style */
private $defaultStyle;
/**
* @return void

View File

@ -1,114 +0,0 @@
<?php
namespace Box\Spout\Writer\XLSX\Helper;
use Box\Spout\Writer\Common\Entity\Style\Border;
use Box\Spout\Writer\Common\Creator\Style\BorderBuilder;
use Box\Spout\Writer\Common\Entity\Style\Color;
use Box\Spout\Writer\Common\Creator\Style\StyleBuilder;
use Box\Spout\Writer\Common\Entity\Style\Style;
use Box\Spout\Writer\Common\Manager\StyleManager;
/**
* Class StyleHelperTest
*
* @package Box\Spout\Writer\XLSX\Helper
*/
class StyleHelperTest extends \PHPUnit_Framework_TestCase
{
/** @var Style */
protected $defaultStyle;
/** @var StyleHelper */
private $styleHelper;
/**
* @return void
*/
public function setUp()
{
$this->defaultStyle = (new StyleBuilder())->build();
$this->styleHelper = new StyleHelper($this->defaultStyle, new StyleManager());
}
/**
* @return void
*/
public function testRegisterStyleShouldUpdateId()
{
$style1 = (new StyleBuilder())->setFontBold()->build();
$style2 = (new StyleBuilder())->setFontUnderline()->build();
$this->assertEquals(0, $this->defaultStyle->getId(), 'Default style ID should be 0');
$this->assertNull($style1->getId());
$this->assertNull($style2->getId());
$registeredStyle1 = $this->styleHelper->registerStyle($style1);
$registeredStyle2 = $this->styleHelper->registerStyle($style2);
$this->assertEquals(1, $registeredStyle1->getId());
$this->assertEquals(2, $registeredStyle2->getId());
}
/**
* @return void
*/
public function testRegisterStyleShouldReuseAlreadyRegisteredStyles()
{
$style = (new StyleBuilder())->setFontBold()->build();
$registeredStyle1 = $this->styleHelper->registerStyle($style);
$registeredStyle2 = $this->styleHelper->registerStyle($style);
$this->assertEquals(1, $registeredStyle1->getId());
$this->assertEquals(1, $registeredStyle2->getId());
}
/**
* @return void
*/
public function testShouldApplyStyleOnEmptyCell()
{
$styleWithFont = (new StyleBuilder())->setFontBold()->build();
$styleWithBackground = (new StyleBuilder())->setBackgroundColor(Color::BLUE)->build();
$border = (new BorderBuilder())->setBorderBottom(Color::GREEN)->build();
$styleWithBorder = (new StyleBuilder())->setBorder($border)->build();
$this->styleHelper->registerStyle($styleWithFont);
$this->styleHelper->registerStyle($styleWithBackground);
$this->styleHelper->registerStyle($styleWithBorder);
$this->assertFalse($this->styleHelper->shouldApplyStyleOnEmptyCell($styleWithFont->getId()));
$this->assertTrue($this->styleHelper->shouldApplyStyleOnEmptyCell($styleWithBackground->getId()));
$this->assertTrue($this->styleHelper->shouldApplyStyleOnEmptyCell($styleWithBorder->getId()));
}
/**
* @return void
*/
public function testApplyExtraStylesIfNeededShouldApplyWrapTextIfCellContainsNewLine()
{
$style = clone $this->defaultStyle;
$this->assertFalse($style->shouldWrapText());
$updatedStyle = $this->styleHelper->applyExtraStylesIfNeeded($style, [12, 'single line', "multi\nlines", null]);
$this->assertTrue($updatedStyle->shouldWrapText());
}
/**
* @return void
*/
public function testApplyExtraStylesIfNeededShouldDoNothingIfWrapTextAlreadyApplied()
{
$style = (new StyleBuilder())->setShouldWrapText()->build();
$this->assertTrue($style->shouldWrapText());
$updatedStyle = $this->styleHelper->applyExtraStylesIfNeeded($style, ["multi\nlines"]);
$this->assertTrue($updatedStyle->shouldWrapText());
}
}

View File

@ -0,0 +1,59 @@
<?php
namespace Box\Spout\Writer\XLSX\Manager\Style;
/**
* Class StyleManagerTest
*
* @package Box\Spout\Writer\XLSX\Manager\Style
*/
class StyleManagerTest extends \PHPUnit_Framework_TestCase
{
/**
* @return array
*/
public function dataProviderForTestShouldApplyStyleOnEmptyCell()
{
return [
// fillId, borderId, expected result
[null, null, false],
[0, null, false],
[null, 0, false],
[0, 0, false],
[12, null, true],
[null, 12, true],
[12, 0, true],
[0, 12, true],
[12, 13, true],
];
}
/**
* @dataProvider dataProviderForTestShouldApplyStyleOnEmptyCell
*
* @param int|null $fillId
* @param int|null $borderId
* @param bool $expectedResult
* @return void
*/
public function testShouldApplyStyleOnEmptyCell($fillId, $borderId, $expectedResult)
{
$styleRegistryMock = $this->getMockBuilder(StyleRegistry::class)
->disableOriginalConstructor()
->setMethods(['getFillIdForStyleId', 'getBorderIdForStyleId'])
->getMock();
$styleRegistryMock
->method('getFillIdForStyleId')
->willReturn($fillId);
$styleRegistryMock
->method('getBorderIdForStyleId')
->willReturn($borderId);
$styleManager = new StyleManager($styleRegistryMock);
$shouldApply = $styleManager->shouldApplyStyleOnEmptyCell(99);
$this->assertEquals($expectedResult, $shouldApply);
}
}

View File

@ -0,0 +1,77 @@
<?php
namespace Box\Spout\Writer\XLSX\Manager\Style;
use Box\Spout\Writer\Common\Creator\Style\BorderBuilder;
use Box\Spout\Writer\Common\Creator\Style\StyleBuilder;
use Box\Spout\Writer\Common\Entity\Style\Color;
/**
* Class StyleRegistryTest
*
* @package Box\Spout\Writer\XLSX\Manager\Style
*/
class StyleRegistryTest extends \PHPUnit_Framework_TestCase
{
/**
* @return StyleRegistry
*/
private function getStyleRegistry()
{
$defaultStyle = (new StyleBuilder())->build();
return new StyleRegistry($defaultStyle);
}
/**
* @return void
*/
public function testRegisterStyleAlsoRegistersFills()
{
$styleRegistry = $this->getStyleRegistry();
$styleBlack = (new StyleBuilder())->setBackgroundColor(Color::BLACK)->build();
$styleOrange = (new StyleBuilder())->setBackgroundColor(Color::ORANGE)->build();
$styleOrangeBold = (new StyleBuilder())->setBackgroundColor(Color::ORANGE)->setFontBold()->build();
$styleNoBackgroundColor = (new StyleBuilder())->setFontItalic()->build();
$styleRegistry->registerStyle($styleBlack);
$styleRegistry->registerStyle($styleOrange);
$styleRegistry->registerStyle($styleOrangeBold);
$styleRegistry->registerStyle($styleNoBackgroundColor);
$this->assertEquals(2, count($styleRegistry->getRegisteredFills()), 'There should be 2 registered fills');
$this->assertEquals(2, $styleRegistry->getFillIdForStyleId($styleBlack->getId()), 'First style with background color set should have index 2 (0 and 1 being reserved)');
$this->assertEquals(3, $styleRegistry->getFillIdForStyleId($styleOrange->getId()), 'Second style with background color set - different from first style - should have index 3');
$this->assertEquals(3, $styleRegistry->getFillIdForStyleId($styleOrangeBold->getId()), 'Style with background color already set should have the same index');
$this->assertEquals(0, $styleRegistry->getFillIdForStyleId($styleNoBackgroundColor->getId()), 'Style with no background color should have index 0');
}
/**
* @return void
*/
public function testRegisterStyleAlsoRegistersBorders()
{
$styleRegistry = $this->getStyleRegistry();
$borderLeft = (new BorderBuilder())->setBorderLeft()->build();
$borderRight = (new BorderBuilder())->setBorderRight()->build();
$styleBorderLeft = (new StyleBuilder())->setBorder($borderLeft)->build();
$styleBoderRight = (new StyleBuilder())->setBorder($borderRight)->build();
$styleBoderRightBold = (new StyleBuilder())->setBorder($borderRight)->setFontBold()->build();
$styleNoBorder = (new StyleBuilder())->setFontItalic()->build();
$styleRegistry->registerStyle($styleBorderLeft);
$styleRegistry->registerStyle($styleBoderRight);
$styleRegistry->registerStyle($styleBoderRightBold);
$styleRegistry->registerStyle($styleNoBorder);
$this->assertEquals(2, count($styleRegistry->getRegisteredBorders()), 'There should be 2 registered borders');
$this->assertEquals(1, $styleRegistry->getBorderIdForStyleId($styleBorderLeft->getId()), 'First style with border set should have index 1 (0 is for the default style)');
$this->assertEquals(2, $styleRegistry->getBorderIdForStyleId($styleBoderRight->getId()), 'Second style with border set - different from first style - should have index 2');
$this->assertEquals(2, $styleRegistry->getBorderIdForStyleId($styleBoderRightBold->getId()), 'Style with border already set should have the same index');
$this->assertEquals(0, $styleRegistry->getBorderIdForStyleId($styleNoBorder->getId()), 'Style with no border should have index 0');
}
}

View File

@ -10,7 +10,7 @@ use Box\Spout\Writer\Common\Creator\Style\BorderBuilder;
use Box\Spout\Writer\Common\Entity\Style\Color;
use Box\Spout\Writer\Common\Entity\Style\Style;
use Box\Spout\Writer\Common\Creator\Style\StyleBuilder;
use Box\Spout\Writer\Common\Manager\StyleManager;
use Box\Spout\Writer\Common\Manager\Style\StyleMerger;
use Box\Spout\Writer\WriterFactory;
use Box\Spout\Writer\XLSX\Manager\OptionsManager;
@ -24,7 +24,7 @@ class WriterWithStyleTest extends \PHPUnit_Framework_TestCase
use TestUsingResource;
/** @var \Box\Spout\Writer\Common\Entity\Style\Style */
protected $defaultStyle;
private $defaultStyle;
/**
* @return void
@ -463,7 +463,7 @@ class WriterWithStyleTest extends \PHPUnit_Framework_TestCase
$fontStyle = (new StyleBuilder())->setFontBold()->build();
$emptyStyle = (new StyleBuilder())->build();
$borderRightFontBoldStyle = (new StyleManager())->merge($borderRightStyle, $fontStyle);
$borderRightFontBoldStyle = (new StyleMerger())->merge($borderRightStyle, $fontStyle);
$dataRows = [
['Border-Left'],