diff --git a/src/PhpSpreadsheet/Cell/Coordinate.php b/src/PhpSpreadsheet/Cell/Coordinate.php index 6652b7adb6..6a377f2b40 100644 --- a/src/PhpSpreadsheet/Cell/Coordinate.php +++ b/src/PhpSpreadsheet/Cell/Coordinate.php @@ -4,7 +4,6 @@ use PhpOffice\PhpSpreadsheet\Exception; use PhpOffice\PhpSpreadsheet\Worksheet\Worksheet; -use Throwable; /** * Helper class to manipulate cell coordinates. @@ -15,6 +14,7 @@ abstract class Coordinate { public const A1_COORDINATE_REGEX = '/^(?\$?[A-Z]{1,3})(?\$?\d{1,7})$/i'; + public const FULL_REFERENCE_REGEX = '/^(?:(?[^!]*)!)?(?(?[$]?[A-Z]{1,3}[$]?\d{1,7})(?:\:(?[$]?[A-Z]{1,3}[$]?\d{1,7}))?)$/i'; /** * Default range variable constant. @@ -269,24 +269,24 @@ public static function getRangeBoundaries(string $range) */ private static function validateReferenceAndGetData($reference): array { - preg_match('/^(?:(?[^!]*)!)?(?(?[A-Z]{1,3}\d{1,7})(?:\:(?[A-Z]{1,3}\d{1,7}))?)$/', $reference, $matches); + preg_match(self::FULL_REFERENCE_REGEX, $reference, $matches); if (count($matches) === 0) { - throw new Exception('Invalid Cell or Range Reference'); + return ['type' => 'invalid']; } if (isset($matches['secondCoordinate'])) { $data['type'] = 'range'; - $data['firstCoordinate'] = $matches['firstCoordinate']; - $data['secondCoordinate'] = $matches['secondCoordinate']; + $data['firstCoordinate'] = str_replace('$', '', $matches['firstCoordinate']); + $data['secondCoordinate'] = str_replace('$', '', $matches['secondCoordinate']); } else { - $data['coordinate'] = $matches['firstCoordinate']; $data['type'] = 'coordinate'; + $data['coordinate'] = str_replace('$', '', $matches['firstCoordinate']); } if ($matches['worksheet'] !== '') { - $data['worksheet'] = $matches['worksheet']; + $data['worksheet'] = strtolower(str_replace('\'', '', $matches['worksheet'])); } - $data['localReference'] = $matches['localReference']; + $data['localReference'] = str_replace('$', '', $matches['localReference']); return $data; } @@ -301,21 +301,13 @@ private static function validateReferenceAndGetData($reference): array */ public static function coordinateIsInsideRange(string $range, string $coordinate): bool { - try { - $rangeData = self::validateReferenceAndGetData($range); - if ($rangeData['type'] !== 'range') { - throw new Exception(); - } - } catch (Throwable $th) { + $rangeData = self::validateReferenceAndGetData($range); + if ($rangeData['type'] === 'invalid') { throw new Exception('First argument needs to be a range'); } - try { - $coordinateData = self::validateReferenceAndGetData($coordinate); - if ($coordinateData['type'] !== 'coordinate') { - throw new Exception(); - } - } catch (Throwable $th) { + $coordinateData = self::validateReferenceAndGetData($coordinate); + if ($coordinateData['type'] === 'invalid') { throw new Exception('Second argument needs to be a single coordinate'); } @@ -336,9 +328,7 @@ public static function coordinateIsInsideRange(string $range, string $coordinate } $boundaries = self::rangeBoundaries($range); - - $coordinates = self::coordinateFromString($coordinate); - $coordinates[0] = self::columnIndexFromString($coordinates[0]); + $coordinates = self::indexesFromString($coordinate); $columnIsInside = $boundaries[0][0] <= $coordinates[0] && $coordinates[0] <= $boundaries[1][0]; if (!$columnIsInside) { diff --git a/tests/PhpSpreadsheetTests/Cell/CoordinateTest.php b/tests/PhpSpreadsheetTests/Cell/CoordinateTest.php index 5fcc1057e6..d62b2c7ca1 100644 --- a/tests/PhpSpreadsheetTests/Cell/CoordinateTest.php +++ b/tests/PhpSpreadsheetTests/Cell/CoordinateTest.php @@ -300,52 +300,39 @@ public static function providerGetRangeBoundaries(): array return require 'tests/data/CellGetRangeBoundaries.php'; } - public static function testCoordinateIsInsideRange(): void + /** + * @dataProvider providerCoordinateIsInsideRange + */ + public static function testCoordinateIsInsideRange(bool $expectedResult, string $range, string $coordinate): void { - $cellRange = 'A1:D4'; - $cellCordinate = 'B2'; - $result = Coordinate::coordinateIsInsideRange($cellRange, $cellCordinate); - self::assertTrue($result); + $result = Coordinate::coordinateIsInsideRange($range, $coordinate); + self::assertEquals($result, $expectedResult); } - public static function testCoordinateIsOutsideRange(): void + public static function providerCoordinateIsInsideRange(): array { - $cellRange = 'A1:D4'; - $cellCordinate = 'F6'; - $result = Coordinate::coordinateIsInsideRange($cellRange, $cellCordinate); - self::assertFalse($result); + return require 'tests/data/coordinateIsInsideRange.php'; } - public static function testCoordinateIsInsideRangeInvalidFirstArgument(): void + /** + * @dataProvider providerCoordinateIsInsideRangeException + */ + public static function testCoordinateIsInsideRangeException(string $expectedResult, string $range, string $coordinate): void { - $cellRange = 'inavlidRange'; - $cellCordinate = 'F6'; - try { - Coordinate::coordinateIsInsideRange($cellRange, $cellCordinate); + Coordinate::coordinateIsInsideRange($range, $coordinate); } catch (\Exception $e) { self::assertInstanceOf(Exception::class, $e); - self::assertEquals($e->getMessage(), 'First argument needs to be a range'); + self::assertEquals($e->getMessage(), $expectedResult); return; } self::fail('An expected exception has not been raised.'); } - public static function testCoordinateIsInsideRangeInvalidSecondArgument(): void + public static function providerCoordinateIsInsideRangeException(): array { - $cellRange = 'A1:D4'; - $cellCordinate = 'invalidCoordinate'; - - try { - Coordinate::coordinateIsInsideRange($cellRange, $cellCordinate); - } catch (\Exception $e) { - self::assertInstanceOf(Exception::class, $e); - self::assertEquals($e->getMessage(), 'Second argument needs to be a single coordinate'); - - return; - } - self::fail('An expected exception has not been raised.'); + return require 'tests/data/coordinateIsInsideRangeException.php'; } /** diff --git a/tests/data/Cell/coordinateIsInsideRange.php b/tests/data/Cell/coordinateIsInsideRange.php new file mode 100644 index 0000000000..7e06c5d69f --- /dev/null +++ b/tests/data/Cell/coordinateIsInsideRange.php @@ -0,0 +1,26 @@ +