Enforce sheet name uniqueness per workbook (#397)

Instead of across all workbooks (in case of multiple spreadsheets being created at the same time).
This commit is contained in:
Adrien Loison authored and GitHub committed 2017-03-27 17:58:06 +02:00
1 parent 36d3596f83
commit 33c9d2f2ed
5 files changed
+43 -13

No files matched your search

@@ -16,6 +16,9 @@ abstract class AbstractWorkbook implements WorkbookInterface
/** @var bool Whether new sheets should be automatically created when the max rows limit per sheet is reached */ /** @var bool Whether new sheets should be automatically created when the max rows limit per sheet is reached */
protected $shouldCreateNewSheetsAutomatically; protected $shouldCreateNewSheetsAutomatically;
/** @var string Timestamp based unique ID identifying the workbook */
protected $internalId;
/** @var WorksheetInterface[] Array containing the workbook's sheets */ /** @var WorksheetInterface[] Array containing the workbook's sheets */
protected $worksheets = []; protected $worksheets = [];
@@ -30,6 +33,7 @@ abstract class AbstractWorkbook implements WorkbookInterface
public function __construct($shouldCreateNewSheetsAutomatically, $defaultRowStyle) public function __construct($shouldCreateNewSheetsAutomatically, $defaultRowStyle)
{ {
$this->shouldCreateNewSheetsAutomatically = $shouldCreateNewSheetsAutomatically; $this->shouldCreateNewSheetsAutomatically = $shouldCreateNewSheetsAutomatically;
$this->internalId = uniqid();
} }
/** /**
+14 -5
View File
@@ -7,7 +7,7 @@ use Box\Spout\Writer\Exception\InvalidSheetNameException;
/** /**
* Class Sheet * Class Sheet
* External representation of a worksheet within a ODS file * External representation of a worksheet
* *
* @package Box\Spout\Writer\Common * @package Box\Spout\Writer\Common
*/ */
@@ -21,12 +21,15 @@ class Sheet
/** @var array Invalid characters that cannot be contained in the sheet name */ /** @var array Invalid characters that cannot be contained in the sheet name */
private static $INVALID_CHARACTERS_IN_SHEET_NAME = ['\\', '/', '?', '*', ':', '[', ']']; private static $INVALID_CHARACTERS_IN_SHEET_NAME = ['\\', '/', '?', '*', ':', '[', ']'];
/** @var array Associative array [SHEET_INDEX] => [SHEET_NAME] keeping track of sheets' name to enforce uniqueness */ /** @var array Associative array [WORKBOOK_ID] => [[SHEET_INDEX] => [SHEET_NAME]] keeping track of sheets' name to enforce uniqueness per workbook */
protected static $SHEETS_NAME_USED = []; protected static $SHEETS_NAME_USED = [];
/** @var int Index of the sheet, based on order in the workbook (zero-based) */ /** @var int Index of the sheet, based on order in the workbook (zero-based) */
protected $index; protected $index;
/** @var string ID of the sheet's associated workbook. Used to restrict sheet name uniqueness enforcement to a single workbook */
protected $associatedWorkbookId;
/** @var string Name of the sheet */ /** @var string Name of the sheet */
protected $name; protected $name;
@@ -35,10 +38,16 @@ class Sheet
/** /**
* @param int $sheetIndex Index of the sheet, based on order in the workbook (zero-based) * @param int $sheetIndex Index of the sheet, based on order in the workbook (zero-based)
* @param string $associatedWorkbookId ID of the sheet's associated workbook
*/ */
public function __construct($sheetIndex) public function __construct($sheetIndex, $associatedWorkbookId)
{ {
$this->index = $sheetIndex; $this->index = $sheetIndex;
$this->associatedWorkbookId = $associatedWorkbookId;
if (!isset(self::$SHEETS_NAME_USED[$associatedWorkbookId])) {
self::$SHEETS_NAME_USED[$associatedWorkbookId] = [];
}
$this->stringHelper = new StringHelper(); $this->stringHelper = new StringHelper();
$this->setName(self::DEFAULT_SHEET_NAME_PREFIX . ($sheetIndex + 1)); $this->setName(self::DEFAULT_SHEET_NAME_PREFIX . ($sheetIndex + 1));
} }
@@ -78,7 +87,7 @@ class Sheet
$this->throwIfNameIsInvalid($name); $this->throwIfNameIsInvalid($name);
$this->name = $name; $this->name = $name;
self::$SHEETS_NAME_USED[$this->index] = $name; self::$SHEETS_NAME_USED[$this->associatedWorkbookId][$this->index] = $name;
return $this; return $this;
} }
@@ -163,7 +172,7 @@ class Sheet
*/ */
protected function isNameUnique($name) protected function isNameUnique($name)
{ {
foreach (self::$SHEETS_NAME_USED as $sheetIndex => $sheetName) { foreach (self::$SHEETS_NAME_USED[$this->associatedWorkbookId] as $sheetIndex => $sheetName) {
if ($sheetIndex !== $this->index && $sheetName === $name) { if ($sheetIndex !== $this->index && $sheetName === $name) {
return false; return false;
} }
+1 -1
View File
@@ -69,7 +69,7 @@ class Workbook extends AbstractWorkbook
public function addNewSheet() public function addNewSheet()
{ {
$newSheetIndex = count($this->worksheets); $newSheetIndex = count($this->worksheets);
$sheet = new Sheet($newSheetIndex); $sheet = new Sheet($newSheetIndex, $this->internalId);
$sheetsContentTempFolder = $this->fileSystemHelper->getSheetsContentTempFolder(); $sheetsContentTempFolder = $this->fileSystemHelper->getSheetsContentTempFolder();
$worksheet = new Worksheet($sheet, $sheetsContentTempFolder); $worksheet = new Worksheet($sheet, $sheetsContentTempFolder);
+1 -1
View File
@@ -83,7 +83,7 @@ class Workbook extends AbstractWorkbook
public function addNewSheet() public function addNewSheet()
{ {
$newSheetIndex = count($this->worksheets); $newSheetIndex = count($this->worksheets);
$sheet = new Sheet($newSheetIndex); $sheet = new Sheet($newSheetIndex, $this->internalId);
$worksheetFilesFolder = $this->fileSystemHelper->getXlWorksheetsFolder(); $worksheetFilesFolder = $this->fileSystemHelper->getXlWorksheetsFolder();
$worksheet = new Worksheet($sheet, $worksheetFilesFolder, $this->sharedStringsHelper, $this->styleHelper, $this->shouldUseInlineStrings); $worksheet = new Worksheet($sheet, $worksheetFilesFolder, $this->sharedStringsHelper, $this->styleHelper, $this->shouldUseInlineStrings);
+23 -6
View File
@@ -14,7 +14,7 @@ class SheetTest extends \PHPUnit_Framework_TestCase
*/ */
public function testGetSheetName() public function testGetSheetName()
{ {
$sheets = [new Sheet(0), new Sheet(1)]; $sheets = [new Sheet(0, 'workbookId1'), new Sheet(1, 'workbookId1')];
$this->assertEquals('Sheet1', $sheets[0]->getName(), 'Invalid name for the first sheet'); $this->assertEquals('Sheet1', $sheets[0]->getName(), 'Invalid name for the first sheet');
$this->assertEquals('Sheet2', $sheets[1]->getName(), 'Invalid name for the second sheet'); $this->assertEquals('Sheet2', $sheets[1]->getName(), 'Invalid name for the second sheet');
@@ -26,7 +26,7 @@ class SheetTest extends \PHPUnit_Framework_TestCase
public function testSetSheetNameShouldCreateSheetWithCustomName() public function testSetSheetNameShouldCreateSheetWithCustomName()
{ {
$customSheetName = 'CustomName'; $customSheetName = 'CustomName';
$sheet = new Sheet(0); $sheet = new Sheet(0, 'workbookId1');
$sheet->setName($customSheetName); $sheet->setName($customSheetName);
$this->assertEquals($customSheetName, $sheet->getName(), "The sheet name should have been changed to '$customSheetName'"); $this->assertEquals($customSheetName, $sheet->getName(), "The sheet name should have been changed to '$customSheetName'");
@@ -63,7 +63,7 @@ class SheetTest extends \PHPUnit_Framework_TestCase
*/ */
public function testSetSheetNameShouldThrowOnInvalidName($customSheetName) public function testSetSheetNameShouldThrowOnInvalidName($customSheetName)
{ {
(new Sheet(0))->setName($customSheetName); (new Sheet(0, 'workbookId1'))->setName($customSheetName);
} }
/** /**
@@ -72,7 +72,7 @@ class SheetTest extends \PHPUnit_Framework_TestCase
public function testSetSheetNameShouldNotThrowWhenSettingSameNameAsCurrentOne() public function testSetSheetNameShouldNotThrowWhenSettingSameNameAsCurrentOne()
{ {
$customSheetName = 'Sheet name'; $customSheetName = 'Sheet name';
$sheet = new Sheet(0); $sheet = new Sheet(0, 'workbookId1');
$sheet->setName($customSheetName); $sheet->setName($customSheetName);
$sheet->setName($customSheetName); $sheet->setName($customSheetName);
} }
@@ -85,10 +85,27 @@ class SheetTest extends \PHPUnit_Framework_TestCase
{ {
$customSheetName = 'Sheet name'; $customSheetName = 'Sheet name';
$sheet = new Sheet(0); $sheet = new Sheet(0, 'workbookId1');
$sheet->setName($customSheetName); $sheet->setName($customSheetName);
$sheet = new Sheet(1); $sheet = new Sheet(1, 'workbookId1');
$sheet->setName($customSheetName);
}
/**
* @return void
*/
public function testSetSheetNameShouldNotThrowWhenSameNameUsedInDifferentWorkbooks()
{
$customSheetName = 'Sheet name';
$sheet = new Sheet(0, 'workbookId1');
$sheet->setName($customSheetName);
$sheet = new Sheet(0, 'workbookId2');
$sheet->setName($customSheetName);
$sheet = new Sheet(1, 'workbookId3');
$sheet->setName($customSheetName); $sheet->setName($customSheetName);
} }
} }