Skip to content

Commit 2864afb

Browse files
author
MarkBaker
committed
Add functionality to adjust CellRange by "modifying" the from/to CellAddress Value objects
1 parent 1849737 commit 2864afb

File tree

5 files changed

+94
-5
lines changed

5 files changed

+94
-5
lines changed

.php-cs-fixer.dist.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
'braces' => true,
2222
'cast_spaces' => true,
2323
'class_attributes_separation' => ['elements' => ['method' => 'one', 'property' => 'one']], // const are often grouped with other related const
24-
'class_definition' => true,
24+
'class_definition' => false,
2525
'class_keyword_remove' => false, // ::class keyword gives us better support in IDE
2626
'combine_consecutive_issets' => true,
2727
'combine_consecutive_unsets' => true,

CHANGELOG.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,8 @@ and this project adheres to [Semantic Versioning](https://semver.org).
99

1010
### Added
1111

12-
- Implementation of the FILTER(), SORT(), SORTBY() and UNIQUE() Lookup/Reference (array) functions
12+
- Introduced CellAddress, CellRange, RowRange and ColumnRange value objects that can be used as an alternative to a string value (e.g. `'C5'`, `'B2:D4'`, `'2:2'` or `'B:C'`) in appropriate contexts.
13+
- Implementation of the FILTER(), SORT(), SORTBY() and UNIQUE() Lookup/Reference (array) functions.
1314
- Implementation of the ISREF() Information function.
1415
- Added support for reading "formatted" numeric values from Csv files; although default behaviour of reading these values as strings is preserved.
1516

src/PhpSpreadsheet/Cell/CellAddress.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ class CellAddress
3232
*/
3333
protected $rowId;
3434

35-
protected function __construct(string $cellAddress, ?Worksheet $worksheet)
35+
public function __construct(string $cellAddress, ?Worksheet $worksheet)
3636
{
3737
$this->cellAddress = str_replace('$', '', $cellAddress);
3838
[$this->columnName, $rowId] = Coordinate::coordinateFromString($cellAddress);

src/PhpSpreadsheet/Cell/CellRange.php

Lines changed: 60 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,8 @@ private function validateFromTo(CellAddress $from, CellAddress $to): void
3434
$toWorksheet = $to->worksheet();
3535
$this->validateWorksheets($fromWorksheet, $toWorksheet);
3636

37-
$this->from = CellAddress::fromColumnAndRow($firstColumn, $firstRow, $fromWorksheet);
38-
$this->to = CellAddress::fromColumnAndRow($lastColumn, $lastRow, $toWorksheet);
37+
$this->from = $this->cellAddressWrapper($firstColumn, $firstRow, $fromWorksheet);
38+
$this->to = $this->cellAddressWrapper($lastColumn, $lastRow, $toWorksheet);
3939
}
4040

4141
private function validateWorksheets(?Worksheet $fromWorksheet, ?Worksheet $toWorksheet): void
@@ -54,18 +54,76 @@ private function validateWorksheets(?Worksheet $fromWorksheet, ?Worksheet $toWor
5454
}
5555
}
5656

57+
private function cellAddressWrapper(int $column, int $row, ?Worksheet $worksheet = null): CellAddress
58+
{
59+
$cellAddress = Coordinate::stringFromColumnIndex($column) . (string) $row;
60+
61+
return new class ($cellAddress, $worksheet) extends CellAddress {
62+
public function nextRow(int $offset = 1): CellAddress
63+
{
64+
/** @var CellAddress $result */
65+
$result = parent::nextRow($offset);
66+
$this->rowId = $result->rowId;
67+
$this->cellAddress = $result->cellAddress;
68+
69+
return $this;
70+
}
71+
72+
public function previousRow(int $offset = 1): CellAddress
73+
{
74+
/** @var CellAddress $result */
75+
$result = parent::previousRow($offset);
76+
$this->rowId = $result->rowId;
77+
$this->cellAddress = $result->cellAddress;
78+
79+
return $this;
80+
}
81+
82+
public function nextColumn(int $offset = 1): CellAddress
83+
{
84+
/** @var CellAddress $result */
85+
$result = parent::nextColumn($offset);
86+
$this->columnId = $result->columnId;
87+
$this->columnName = $result->columnName;
88+
$this->cellAddress = $result->cellAddress;
89+
90+
return $this;
91+
}
92+
93+
public function previousColumn(int $offset = 1): CellAddress
94+
{
95+
/** @var CellAddress $result */
96+
$result = parent::previousColumn($offset);
97+
$this->columnId = $result->columnId;
98+
$this->columnName = $result->columnName;
99+
$this->cellAddress = $result->cellAddress;
100+
101+
return $this;
102+
}
103+
};
104+
}
105+
57106
public function from(): CellAddress
58107
{
108+
// Re-order from/to in case the cell addresses have been modified
109+
$this->validateFromTo($this->from, $this->to);
110+
59111
return $this->from;
60112
}
61113

62114
public function to(): CellAddress
63115
{
116+
// Re-order from/to in case the cell addresses have been modified
117+
$this->validateFromTo($this->from, $this->to);
118+
64119
return $this->to;
65120
}
66121

67122
public function __toString(): string
68123
{
124+
// Re-order from/to in case the cell addresses have been modified
125+
$this->validateFromTo($this->from, $this->to);
126+
69127
if ($this->from->cellAddress() === $this->to->cellAddress()) {
70128
return "{$this->from->fullCellAddress()}";
71129
}

tests/PhpSpreadsheetTests/Cell/CellRangeTest.php

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,4 +110,34 @@ public function testCreateCellRangeWithMismatchedSpreadsheets(): void
110110
$to = CellAddress::fromCellAddress('E2', $worksheet2);
111111
new CellRange($from, $to);
112112
}
113+
114+
public function testShiftRangeTo(): void
115+
{
116+
$from = CellAddress::fromCellAddress('B5');
117+
$to = CellAddress::fromCellAddress('E2');
118+
$cellRange = new CellRange($from, $to);
119+
self::assertSame('B2:E5', (string) $cellRange);
120+
121+
$cellRange->to()->nextColumn(2);
122+
$cellRange->to()->nextRow(2);
123+
124+
self::assertSame('B2', (string) $cellRange->from());
125+
self::assertSame('G7', (string) $cellRange->to());
126+
self::assertSame('B2:G7', (string) $cellRange);
127+
}
128+
129+
public function testShiftRangeFrom(): void
130+
{
131+
$from = CellAddress::fromCellAddress('B5');
132+
$to = CellAddress::fromCellAddress('E2');
133+
$cellRange = new CellRange($from, $to);
134+
self::assertSame('B2:E5', (string) $cellRange);
135+
136+
$cellRange->from()->nextColumn(5);
137+
$cellRange->from()->nextRow(5);
138+
139+
self::assertSame('E5', (string) $cellRange->from());
140+
self::assertSame('G7', (string) $cellRange->to());
141+
self::assertSame('E5:G7', (string) $cellRange);
142+
}
113143
}

0 commit comments

Comments
 (0)