Added table name validation

Validation added for
- invalid characters
- invalid names ("C", "c", "R", or "r")
- cell references
- space separate words
- maxlength of 255 characters
- unique table names across worksheet
This commit is contained in:
aswinkumar863 2022-04-03 18:23:13 +05:30
parent 0e3dbb7e03
commit 3c3d949a5d
No known key found for this signature in database
GPG Key ID: 8A69BFA6AEF8FA3E
3 changed files with 103 additions and 6 deletions

View File

@ -53,7 +53,7 @@ $spreadsheet->getActiveSheet()->fromArray($dataArray, null, 'A2');
// Create Table
$helper->log('Create Table');
$table = new Table();
$table->setName('Sales Data');
$table->setName('Sales_Data');
$table->setRange('A1:D17');
// Create Columns

View File

@ -88,7 +88,29 @@ class Table
*/
public function setName(string $name)
{
$this->name = preg_replace('/\s+/', '_', trim($name)) ?? '';
$name = trim($name);
if (strlen($name) == 1 && in_array($name, ['C', 'c', 'R', 'r'])) {
throw new PhpSpreadsheetException('The table name is invalid');
}
if (strlen($name) > 255) {
throw new PhpSpreadsheetException('The table name cannot be longer than 255 characters');
}
// Check for A1 or R1C1 cell reference notation
if (
preg_match(Coordinate::A1_COORDINATE_REGEX, $name) ||
preg_match('/^R\[?\-?[0-9]*\]?C\[?\-?[0-9]*\]?$/i', $name)
) {
throw new PhpSpreadsheetException('The table name can\'t be the same as a cell reference');
}
if (!preg_match('/^[A-Z_\\\\]/i', $name)) {
throw new PhpSpreadsheetException('The table name must begin a name with a letter, an underscore character (_), or a backslash (\)');
}
if (!preg_match('/^[A-Z_\\\\][A-Z0-9\._]+$/i', $name)) {
throw new PhpSpreadsheetException('The table name contains invalid characters');
}
$this->name = $name;
return $this;
}
@ -216,6 +238,18 @@ class Table
*/
public function setWorksheet(?Worksheet $worksheet = null)
{
if ($this->name != '' && $worksheet != null) {
$spreadsheet = $worksheet->getParent();
foreach ($spreadsheet->getWorksheetIterator() as $sheet) {
foreach ($sheet->getTableCollection() as $table) {
if ($table->getName() == $this->name) {
throw new PhpSpreadsheetException("Workbook already contains a table named '{$this->name}'");
}
}
}
}
$this->workSheet = $worksheet;
return $this;

View File

@ -22,15 +22,78 @@ class TableTest extends SetupTeardown
self::assertEquals($expectedResult, $result);
}
public function testVariousSets(): void
/**
* @dataProvider validTableNamesProvider
*/
public function testValidTableNames(string $name, string $expected): void
{
$sheet = $this->getSheet();
$table = new Table(self::INITIAL_RANGE, $sheet);
$result = $table->setName('Table 1');
$result = $table->setName($name);
self::assertInstanceOf(Table::class, $result);
// Spaces will be converted to underscore
self::assertEquals('Table_1', $table->getName());
self::assertEquals($expected, $table->getName());
}
public function validTableNamesProvider(): array
{
return [
['Table_1', 'Table_1'],
['_table_2', '_table_2'],
['\table_3', '\table_3'],
[" Table_4 \n", 'Table_4'],
];
}
/**
* @dataProvider invalidTableNamesProvider
*/
public function testInvalidTableNames(string $name): void
{
$sheet = $this->getSheet();
$table = new Table(self::INITIAL_RANGE, $sheet);
$this->expectException(PhpSpreadsheetException::class);
$table->setName($name);
}
public function invalidTableNamesProvider(): array
{
return [
['C'],
['c'],
['R'],
['r'],
['Z100'],
['Z$100'],
['R1C1'],
['R1C'],
['R11C11'],
['123'],
['=Table'],
[bin2hex(random_bytes(255))], // random string with length greater than 255
];
}
public function testUniqueTableName(): void
{
$this->expectException(PhpSpreadsheetException::class);
$sheet = $this->getSheet();
$table1 = new Table();
$table1->setName('Table_1');
$sheet->addTable($table1);
$table2 = new Table();
$table2->setName('Table_1');
$sheet->addTable($table2);
}
public function testVariousSets(): void
{
$sheet = $this->getSheet();
$table = new Table(self::INITIAL_RANGE, $sheet);
$result = $table->setShowHeaderRow(false);
self::assertInstanceOf(Table::class, $result);