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

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

No files matched your search

@@ -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;
}
}
@@ -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);
}
@@ -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
@@ -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;
}
}
@@ -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