. */ declare(strict_types=1); namespace Fisharebest\Webtrees\Factories; use Fisharebest\Webtrees\Contracts\IdFactoryInterface; use Ramsey\Uuid\Uuid; use Throwable; use function hexdec; use function sprintf; use function str_split; use function strtoupper; /** * Create a unique identifier. */ class IdFactory implements IdFactoryInterface { /** * @return string */ public function uuid(): string { try { return strtolower(Uuid::uuid7()->toString()); } catch (Throwable) { // uuid7() can fail for various reasons. return ''; } } /** * An identifier for use in CSS/HTML * * @param string $prefix * * @return string */ public function id(string $prefix = 'id-'): string { return $prefix . $this->uuid(); } /** * A value for _UID fields, as created by PAF * * @return string */ public function pafUid(): string { $uid = strtoupper(strtr($this->uuid(), ['-' => ''])); if ($uid === '') { return ''; } return $uid . $this->pafUidChecksum($uid); } /** * Based on the C implementation in "GEDCOM Unique Identifiers" by Gordon Clarke, dated 2007-06-08 */ public function pafUidChecksum(string $uid): string { $checksum_a = 0; // a sum of the bytes $checksum_b = 0; // a sum of the incremental values of $checksum_a foreach (str_split($uid, 2) as $byte) { $checksum_a += hexdec($byte); $checksum_b += $checksum_a; } return sprintf('%02X%02X', $checksum_a & 0xff, $checksum_b & 0xff); } }