diff --git a/ruleset.xml b/ruleset.xml
index bf502b2..c5eeec1 100644
--- a/ruleset.xml
+++ b/ruleset.xml
@@ -6,7 +6,7 @@
-
+
diff --git a/src/Personnummer.php b/src/Personnummer.php
index 604f385..7d3d7e8 100644
--- a/src/Personnummer.php
+++ b/src/Personnummer.php
@@ -21,18 +21,12 @@
*/
final class Personnummer implements PersonnummerInterface
{
- private $parts;
+ private array $parts;
- private $options;
+ private array $options;
/**
- *
- * @param string $ssn
- * @param array $options
- *
- * @return PersonnummerInterface
- *
- * @throws PersonnummerException
+ * @inheritDoc
*/
public static function parse(string $ssn, array $options = []): PersonnummerInterface
{
@@ -40,22 +34,19 @@ public static function parse(string $ssn, array $options = []): PersonnummerInte
}
/**
- * Check if a Swedish social security number is for a male.
- *
- * @return bool
+ * @inheritDoc
*/
public function isMale(): bool
{
$parts = $this->parts;
$genderDigit = substr($parts['num'], -1);
- return boolval($genderDigit % 2);
+ return (bool)($genderDigit % 2);
}
+
/**
- * Check if a Swedish social security number is for a female.
- *
- * @return bool
+ * @inheritDoc
*/
public function isFemale(): bool
{
@@ -63,14 +54,7 @@ public function isFemale(): bool
}
/**
- * Format a Swedish social security/coordination number as one of the official formats,
- * A long format or a short format.
- *
- * If the input number could not be parsed an empty string will be returned.
- *
- * @param bool $longFormat short format YYMMDD-XXXX or long YYYYMMDDXXXX since the tax office says both are official
- *
- * @return string
+ * @inheritDoc
*/
public function format(bool $longFormat = false): string
{
@@ -94,18 +78,24 @@ public function format(bool $longFormat = false): string
);
}
+ /**
+ * @inheritDoc
+ */
public function isCoordinationNumber(): bool
{
$parts = $this->parts;
- return checkdate(intval($parts['month']), $parts['day'] - 60, $parts['fullYear']);
+ return checkdate((int)$parts['month'], $parts['day'] - 60, $parts['fullYear']);
}
+ /**
+ * @inheritDoc
+ */
public static function valid(string $ssn, array $options = []): bool
{
try {
return self::parse($ssn, $options)->isValid();
- } catch (PersonnummerException $exception) {
+ } catch (PersonnummerException) {
return false;
}
}
@@ -132,7 +122,7 @@ private static function getParts(string $ssn): array
$parts = array_filter($match, 'is_string', ARRAY_FILTER_USE_KEY);
if (!empty($parts['century'])) {
- if (date('Y') - intval(strval($parts['century']) . strval($parts['year'])) < 100) {
+ if (date('Y') - (int)((string)$parts['century'] . (string)$parts['year']) < 100) {
$parts['sep'] = '-';
} else {
$parts['sep'] = '+';
@@ -163,8 +153,9 @@ private static function luhn(string $str): int
{
$sum = 0;
- for ($i = 0; $i < strlen($str); $i++) {
- $v = intval($str[$i]);
+ $len = strlen($str);
+ for ($i = 0; $i < $len; $i++) {
+ $v = (int)$str[$i];
$v *= 2 - ($i % 2);
if ($v > 9) {
@@ -174,7 +165,7 @@ private static function luhn(string $str): int
$sum += $v;
}
- return intval(ceil($sum / 10) * 10 - $sum);
+ return (int)(ceil($sum / 10) * 10 - $sum);
}
/**
@@ -206,7 +197,7 @@ public function getAge(): int
{
$parts = $this->parts;
- $day = intval($parts['day']);
+ $day = (int)$parts['day'];
if ($this->isCoordinationNumber()) {
$day -= 60;
}
@@ -257,7 +248,7 @@ private function isValid(): bool
}
$checkStr = $parts['year'] . $parts['month'] . $parts['day'] . $parts['num'];
- $validCheck = self::luhn($checkStr) === intval($parts['check']);
+ $validCheck = self::luhn($checkStr) === (int)$parts['check'];
return $validDate && $validCheck;
}
diff --git a/src/PersonnummerException.php b/src/PersonnummerException.php
index 347d859..dcfa786 100644
--- a/src/PersonnummerException.php
+++ b/src/PersonnummerException.php
@@ -14,9 +14,9 @@ class PersonnummerException extends Exception
* @param null|Exception $previous
*/
public function __construct(
- $message = 'Invalid swedish social security number',
- $code = 400,
- $previous = null
+ string $message = 'Invalid swedish social security number',
+ int $code = 400,
+ ?Exception $previous = null
) {
parent::__construct($message, $code, $previous);
}
diff --git a/src/PersonnummerInterface.php b/src/PersonnummerInterface.php
index 7e1822e..c41a3d6 100644
--- a/src/PersonnummerInterface.php
+++ b/src/PersonnummerInterface.php
@@ -2,6 +2,8 @@
namespace Personnummer;
+use Exception;
+
/**
* Interface PersonnummerInterface
*
@@ -18,17 +20,66 @@
*/
interface PersonnummerInterface
{
+ /**
+ * Parse a string representation of a Swedish social security number.
+ *
+ * @param string $ssn Social Security number to parse.
+ * @param array $options Parse options.
+ * @return PersonnummerInterface
+ * @throws PersonnummerException
+ */
public static function parse(string $ssn, array $options = []): self;
+ /**
+ * Test a string representation of a Swedish social security number to see
+ * if it's valid.
+ *
+ * @param string $ssn Social Security number to parse.
+ * @param array $options Parse options.
+ * @return bool
+ */
public static function valid(string $ssn, array $options = []): bool;
+ /**
+ * Format a Swedish social security/coordination number as one of the official formats,
+ * A long format or a short format.
+ *
+ * If the input number could not be parsed an empty string will be returned.
+ *
+ * @param bool $longFormat short format YYMMDD-XXXX or long YYYYMMDDXXXX since the tax office says both are official
+ * @return string
+ */
public function format(bool $longFormat = false): string;
+ /**
+ * Check if a Swedish social security number is for a female.
+ *
+ * @return bool
+ */
public function isFemale(): bool;
+ /**
+ * Check if a Swedish social security number is for a male.
+ *
+ * @return bool
+ */
public function isMale(): bool;
+ /**
+ * Check if the Swedish social security number is a coordination number.
+ *
+ * @return bool
+ */
public function isCoordinationNumber(): bool;
public function __construct(string $ssn, array $options = []);
+
+ /**
+ * Get age from a Swedish social security/coordination number.
+ *
+ * @return int
+ *
+ * @throws Exception When date is invalid or problems with DateTime library
+ */
+ public function getAge(): int;
}
diff --git a/tests/AssertError.php b/tests/AssertError.php
index 7fdcff7..61e158f 100644
--- a/tests/AssertError.php
+++ b/tests/AssertError.php
@@ -6,7 +6,7 @@
trait AssertError
{
- private $errors;
+ private array $errors;
/**
* AssertError.
@@ -37,9 +37,10 @@ public function assertError(
$callable();
restore_error_handler();
- $comparisons = array_filter(compact('error_type', 'error_msg', 'error_file', 'error_line'), function ($value) {
- return !is_null($value);
- });
+ $comparisons = array_filter(
+ compact('error_type', 'error_msg', 'error_file', 'error_line'),
+ static fn ($value) => !is_null($value),
+ );
$matchingErrors = [];
foreach ($this->errors as $error) {
@@ -51,7 +52,7 @@ public function assertError(
if (empty($matchingErrors)) {
$failMessage = 'Expected error was not found';
$failMessage .= $comparisons ? ': ' : '';
- $failMessage .= implode(', ', array_map(function ($value, $key) {
+ $failMessage .= implode(', ', array_map(static function ($value, $key) {
return $key . ': ' . $value;
}, $comparisons, array_keys($comparisons)));
diff --git a/tests/PersonnummerTest.php b/tests/PersonnummerTest.php
index d804751..29fcba3 100644
--- a/tests/PersonnummerTest.php
+++ b/tests/PersonnummerTest.php
@@ -15,11 +15,11 @@ class PersonnummerTest extends TestCase
use AssertThrows;
use AssertError;
- private static $testdataList;
+ private static array $testdataList;
- private static $testdataStructured;
+ private static array $testdataStructured;
- private static $availableListFormats = [
+ private static array $availableListFormats = [
'integer',
'long_format',
'short_format',
@@ -29,17 +29,17 @@ class PersonnummerTest extends TestCase
public static function setUpBeforeClass(): void
{
- self::$testdataList = json_decode(file_get_contents('https://raw.githubusercontent.com/personnummer/meta/master/testdata/list.json'), true); // phpcs:ignore
- self::$testdataStructured = json_decode(file_get_contents('https://raw.githubusercontent.com/personnummer/meta/master/testdata/structured.json'), true); // phpcs:ignore
+ self::$testdataList = json_decode(file_get_contents('https://raw.githubusercontent.com/personnummer/meta/master/testdata/list.json'), true, 512, JSON_THROW_ON_ERROR); // phpcs:ignore
+ self::$testdataStructured = json_decode(file_get_contents('https://raw.githubusercontent.com/personnummer/meta/master/testdata/structured.json'), true, 512, JSON_THROW_ON_ERROR); // phpcs:ignore
}
- public function testParse()
+ public function testParse(): void
{
$this->assertSame(Personnummer::class, get_class(Personnummer::parse('1212121212')));
$this->assertEquals(new Personnummer('1212121212'), Personnummer::parse('1212121212'));
}
- public function testOptions()
+ public function testOptions(): void
{
new Personnummer('1212621211');
@@ -51,7 +51,7 @@ public function testOptions()
}, E_USER_WARNING);
}
- public function testPersonnummerData()
+ public function testPersonnummerData(): void
{
foreach (self::$testdataList as $testdata) {
foreach (self::$availableListFormats as $format) {
@@ -69,7 +69,7 @@ public function testPersonnummerData()
}
foreach (self::$testdataStructured as $ssnType => $testdataInputs) {
- foreach ($testdataInputs as $testdataType => $testdata) {
+ foreach ($testdataInputs as $testdata) {
foreach ($testdata as $valid => $ssns) {
foreach ($ssns as $ssn) {
$this->assertSame(
@@ -87,12 +87,12 @@ public function testPersonnummerData()
}
}
- public function testFormat()
+ public function testFormat(): void
{
foreach (self::$testdataList as $testdata) {
if ($testdata['valid']) {
foreach (self::$availableListFormats as $format) {
- if ($format === 'short_format' && strpos($testdata['separated_format'], '+') !== false) {
+ if ($format === 'short_format' && str_contains($testdata['separated_format'], '+')) {
continue;
}
@@ -104,7 +104,7 @@ public function testFormat()
}
}
- public function testThrowsErrorOnInvalid()
+ public function testThrowsErrorOnInvalid(): void
{
foreach (self::$testdataList as $testdata) {
if (!$testdata['valid']) {
@@ -144,20 +144,20 @@ public function testThrowsErrorOnInvalid()
}
}
- public function testAge()
+ public function testAge(): void
{
foreach (self::$testdataList as $testdata) {
if ($testdata['valid']) {
$birthdate = substr($testdata['separated_long'], 0, 8);
if ($testdata['type'] === 'con') {
$birthdate = substr($birthdate, 0, 6) .
- str_pad(intval(substr($birthdate, -2)) - 60, 2, "0", STR_PAD_LEFT);
+ str_pad((int)substr($birthdate, -2) - 60, 2, "0", STR_PAD_LEFT);
}
- $expected = intval((new DateTime($birthdate))->diff(new DateTime())->format('%y'));
+ $expected = (int)(new DateTime($birthdate))->diff(new DateTime())->format('%y');
foreach (self::$availableListFormats as $format) {
- if ($format === 'short_format' && strpos($testdata['separated_format'], '+') !== false) {
+ if ($format === 'short_format' && str_contains($testdata['separated_format'], '+')) {
continue;
}
@@ -167,10 +167,10 @@ public function testAge()
}
}
- public function testAgeOnBirthday()
+ public function testAgeOnBirthday(): void
{
$date = (new DateTime())->modify('-30 years midnight');
- $expected = intval($date->diff(new DateTime())->format('%y'));
+ $expected = (int)$date->diff(new DateTime())->format('%y');
$ssn = $date->format('Ymd') . '999';
@@ -183,7 +183,7 @@ public function testAgeOnBirthday()
$this->assertSame($expected, Personnummer::parse($ssn)->getAge());
}
- public function testSex()
+ public function testSex(): void
{
foreach (self::$testdataList as $testdata) {
if ($testdata['valid']) {
@@ -195,7 +195,7 @@ public function testSex()
}
}
- public function testProperties()
+ public function testProperties(): void
{
// Parts, as position and length
$separatedLongParts = [
@@ -220,7 +220,7 @@ public function testProperties()
}
}
- public function testMissingProperties()
+ public function testMissingProperties(): void
{
$this->assertError(function () {
Personnummer::parse('1212121212')->missingProperty;