diff --git a/Classes/UrlKeyGenerator/Base62UrlKeyGenerator.php b/Classes/UrlKeyGenerator/Base62UrlKeyGenerator.php index eafe210..2af0b7e 100644 --- a/Classes/UrlKeyGenerator/Base62UrlKeyGenerator.php +++ b/Classes/UrlKeyGenerator/Base62UrlKeyGenerator.php @@ -20,7 +20,14 @@ use TYPO3\CMS\Core\Utility\GeneralUtility; /** - * Contains utilities for creating tiny url keys and url hashes. + * Generates a key for a tinyurl using a configured dictionary. + * + * The dictionary is used as a base for encoding an integer (the UID of the tinyurl recordd) + * into a string. + * + * Opionally, a minimum length for the generated key can be configured. When the key generated from + * the dictionary is shorter than the configured minimum length, a random string is appended to the + * original key, separated by a dash. */ class Base62UrlKeyGenerator implements UrlKeyGenerator { @@ -85,21 +92,22 @@ public function injectGeneralUtility(GeneralUtilityWrapper $generalUtility): voi * Thanks to http://jeremygibbs.com/2012/01/16/how-to-make-a-url-shortener * * @param int $base10Integer The integer that will converted - * @param string $base62Dictionary the dictionary for generating the base62 integer + * @param string $baseXDictionary the dictionary for generating the baseX integer * * @return string A base62 encoded integer using a custom dictionary */ - protected function convertIntToBase62(int $base10Integer, string $base62Dictionary): string + protected function convertIntToBase62(int $base10Integer, string $baseXDictionary): string { - $base62Integer = ''; - $base = 62; + $baseXInteger = ''; + $base = mb_strlen($baseXDictionary); do { - $base62Integer = $base62Dictionary[$base10Integer % $base] . $base62Integer; + $dictionaryOffset = $base10Integer % $base; + $baseXInteger = mb_substr($baseXDictionary, $dictionaryOffset, 1) . $baseXInteger; $base10Integer = floor($base10Integer / $base); } while ($base10Integer > 0); - return $base62Integer; + return $baseXInteger; } /** diff --git a/Tests/Unit/UrlKeyGenerator/Base62UrlKeyGeneratorTest.php b/Tests/Unit/UrlKeyGenerator/Base62UrlKeyGeneratorTest.php index 73f756b..485dab6 100644 --- a/Tests/Unit/UrlKeyGenerator/Base62UrlKeyGeneratorTest.php +++ b/Tests/Unit/UrlKeyGenerator/Base62UrlKeyGeneratorTest.php @@ -26,20 +26,11 @@ */ class Base62UrlKeyGeneratorTest extends TestCase { - /** - * @var Base62UrlKeyGenerator - */ - protected $base62UrlKeyGenerator; + protected Base62UrlKeyGenerator $base62UrlKeyGenerator; - /** - * @var ExtensionConfiguration|MockObject - */ - protected $extensionConfigurationMock; + protected ExtensionConfiguration|MockObject $extensionConfigurationMock; - /** - * @var GeneralUtilityWrapper|MockObject - */ - protected $generalUtilityMock; + protected GeneralUtilityWrapper|MockObject $generalUtilityMock; protected function setUp(): void { @@ -51,7 +42,7 @@ protected function setUp(): void $this->base62UrlKeyGenerator->injectGeneralUtility($this->generalUtilityMock); } - public function testGenerateTinyurlKeyForUidEncodesIntegerIfNoMinimalLengthIsConfigured(): void + public function testGenerateTinyurlKeyForTinyUrlCreatesExpectedKey(): void { $this->extensionConfigurationMock->method('getBase62Dictionary') ->willReturn('abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'); @@ -62,6 +53,17 @@ public function testGenerateTinyurlKeyForUidEncodesIntegerIfNoMinimalLengthIsCon self::assertSame('ud', $key); } + public function testGenerateTinyurlKeyForUidEncodesIntegerIfNoMinimalLengthIsConfigured(): void + { + $this->extensionConfigurationMock->method('getBase62Dictionary') + ->willReturn('abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'); + + $tinyUrl = TinyUrl::createNew(); + $tinyUrl->persistPostProcessInsert(1243); + $key = $this->base62UrlKeyGenerator->generateTinyurlKeyForUid(1243); + self::assertSame('ud', $key); + } + public function testGenerateTinyurlKeyForUidFillsUpKeyUpToConfiguredMinimalLength(): void { $this->extensionConfigurationMock->method('getBase62Dictionary') @@ -74,9 +76,7 @@ public function testGenerateTinyurlKeyForUidFillsUpKeyUpToConfiguredMinimalLengt ->with(2) ->willReturn('ag'); - $tinyUrl = TinyUrl::createNew(); - $tinyUrl->persistPostProcessInsert(1243); - $key = $this->base62UrlKeyGenerator->generateTinyurlKeyForTinyUrl($tinyUrl); + $key = $this->base62UrlKeyGenerator->generateTinyurlKeyForUid(1243); self::assertSame('ud-ag', $key); } @@ -95,9 +95,18 @@ public function testGenerateTinyurlKeyForUidFillsUpKeyWithConfiguredMinimalRando ->with(2) ->willReturn('ag'); + $key = $this->base62UrlKeyGenerator->generateTinyurlKeyForUid(1243); + self::assertSame('ud-ag', $key); + } + + public function testGenerateTinyurlKeyForUidWorksWithShorterDictionary(): void + { + $this->extensionConfigurationMock->method('getBase62Dictionary') + ->willReturn('abcä'); + $tinyUrl = TinyUrl::createNew(); $tinyUrl->persistPostProcessInsert(1243); - $key = $this->base62UrlKeyGenerator->generateTinyurlKeyForTinyUrl($tinyUrl); - self::assertSame('ud-ag', $key); + $key = $this->base62UrlKeyGenerator->generateTinyurlKeyForUid(1243); + self::assertSame('baäbcä', $key); } }