Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Interface fixes and php8 recommendations #59

Merged
merged 2 commits into from
Jan 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion ruleset.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

<!-- Run against the PHPCompatibility ruleset -->
<rule ref="PHPCompatibility"/>
<config name="testVersion" value="8.1-"/>
<config name="testVersion" value="8.1"/>

<!-- Run against a second ruleset -->
<rule ref="PSR12"/>
Expand Down
55 changes: 23 additions & 32 deletions src/Personnummer.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,56 +21,40 @@
*/
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
{
return new self($ssn, $options);
}

/**
* 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
{
return !$this->isMale();
}

/**
* 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
{
Expand All @@ -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;
}
}
Expand All @@ -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'] = '+';
Expand Down Expand Up @@ -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) {
Expand All @@ -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);
}

/**
Expand Down Expand Up @@ -206,7 +197,7 @@ public function getAge(): int
{
$parts = $this->parts;

$day = intval($parts['day']);
$day = (int)$parts['day'];
if ($this->isCoordinationNumber()) {
$day -= 60;
}
Expand Down Expand Up @@ -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;
}
Expand Down
6 changes: 3 additions & 3 deletions src/PersonnummerException.php
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
Expand Down
51 changes: 51 additions & 0 deletions src/PersonnummerInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

namespace Personnummer;

use Exception;

/**
* Interface PersonnummerInterface
*
Expand All @@ -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;
}
11 changes: 6 additions & 5 deletions tests/AssertError.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

trait AssertError
{
private $errors;
private array $errors;

/**
* AssertError.
Expand Down Expand Up @@ -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) {
Expand All @@ -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)));

Expand Down
Loading