mirror of
https://github.com/shlinkio/shlink.git
synced 2026-03-11 01:33:11 +08:00
Updated resolve short url action to return all data for that short url
This commit is contained in:
@@ -42,7 +42,6 @@ return [
|
||||
Service\UrlShortener::class => [
|
||||
'httpClient',
|
||||
'em',
|
||||
Cache::class,
|
||||
'config.url_shortener.validate_url',
|
||||
'config.url_shortener.shortcode_chars',
|
||||
],
|
||||
|
||||
@@ -65,14 +65,14 @@ abstract class AbstractTrackingAction implements MiddlewareInterface
|
||||
$disableTrackParam = $this->appOptions->getDisableTrackParam();
|
||||
|
||||
try {
|
||||
$longUrl = $this->urlShortener->shortCodeToUrl($shortCode);
|
||||
$url = $this->urlShortener->shortCodeToUrl($shortCode);
|
||||
|
||||
// Track visit to this short code
|
||||
if ($disableTrackParam === null || ! \array_key_exists($disableTrackParam, $query)) {
|
||||
$this->visitTracker->track($shortCode, $request);
|
||||
}
|
||||
|
||||
return $this->createResp($longUrl);
|
||||
return $this->createResp($url->getLongUrl());
|
||||
} catch (InvalidShortCodeException | EntityDoesNotExistException $e) {
|
||||
$this->logger->warning('An error occurred while tracking short code.' . PHP_EOL . $e);
|
||||
return $this->buildErrorResponse($request, $handler);
|
||||
|
||||
@@ -60,7 +60,7 @@ class PreviewAction implements MiddlewareInterface
|
||||
|
||||
try {
|
||||
$url = $this->urlShortener->shortCodeToUrl($shortCode);
|
||||
$imagePath = $this->previewGenerator->generatePreview($url);
|
||||
$imagePath = $this->previewGenerator->generatePreview($url->getLongUrl());
|
||||
return $this->generateImageResponse($imagePath);
|
||||
} catch (InvalidShortCodeException | EntityDoesNotExistException | PreviewGenerationException $e) {
|
||||
$this->logger->warning('An error occurred while generating preview image.' . PHP_EOL . $e);
|
||||
|
||||
@@ -5,7 +5,6 @@ namespace Shlinkio\Shlink\Core\Service;
|
||||
|
||||
use Cocur\Slugify\Slugify;
|
||||
use Cocur\Slugify\SlugifyInterface;
|
||||
use Doctrine\Common\Cache\Cache;
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
use GuzzleHttp\ClientInterface;
|
||||
use GuzzleHttp\Exception\GuzzleException;
|
||||
@@ -37,10 +36,6 @@ class UrlShortener implements UrlShortenerInterface
|
||||
* @var string
|
||||
*/
|
||||
private $chars;
|
||||
/**
|
||||
* @var Cache
|
||||
*/
|
||||
private $cache;
|
||||
/**
|
||||
* @var SlugifyInterface
|
||||
*/
|
||||
@@ -53,14 +48,12 @@ class UrlShortener implements UrlShortenerInterface
|
||||
public function __construct(
|
||||
ClientInterface $httpClient,
|
||||
EntityManagerInterface $em,
|
||||
Cache $cache,
|
||||
$urlValidationEnabled,
|
||||
$chars = self::DEFAULT_CHARS,
|
||||
SlugifyInterface $slugger = null
|
||||
) {
|
||||
$this->httpClient = $httpClient;
|
||||
$this->em = $em;
|
||||
$this->cache = $cache;
|
||||
$this->urlValidationEnabled = $urlValidationEnabled;
|
||||
$this->chars = empty($chars) ? self::DEFAULT_CHARS : $chars;
|
||||
$this->slugger = $slugger ?: new Slugify();
|
||||
@@ -192,19 +185,11 @@ class UrlShortener implements UrlShortenerInterface
|
||||
/**
|
||||
* Tries to find the mapped URL for provided short code. Returns null if not found
|
||||
*
|
||||
* @param string $shortCode
|
||||
* @return string
|
||||
* @throws InvalidShortCodeException
|
||||
* @throws EntityDoesNotExistException
|
||||
*/
|
||||
public function shortCodeToUrl(string $shortCode): string
|
||||
public function shortCodeToUrl(string $shortCode): ShortUrl
|
||||
{
|
||||
$cacheKey = sprintf('%s_longUrl', $shortCode);
|
||||
// Check if the short code => URL map is already cached
|
||||
if ($this->cache->contains($cacheKey)) {
|
||||
return $this->cache->fetch($cacheKey);
|
||||
}
|
||||
|
||||
// Validate short code format
|
||||
if (! preg_match('|[' . $this->chars . ']+|', $shortCode)) {
|
||||
throw InvalidShortCodeException::fromCharset($shortCode, $this->chars);
|
||||
@@ -219,9 +204,6 @@ class UrlShortener implements UrlShortenerInterface
|
||||
]);
|
||||
}
|
||||
|
||||
// Cache the shortcode
|
||||
$url = $shortUrl->getOriginalUrl();
|
||||
$this->cache->save($cacheKey, $url);
|
||||
return $url;
|
||||
return $shortUrl;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ declare(strict_types=1);
|
||||
namespace Shlinkio\Shlink\Core\Service;
|
||||
|
||||
use Psr\Http\Message\UriInterface;
|
||||
use Shlinkio\Shlink\Core\Entity\ShortUrl;
|
||||
use Shlinkio\Shlink\Core\Exception\EntityDoesNotExistException;
|
||||
use Shlinkio\Shlink\Core\Exception\InvalidShortCodeException;
|
||||
use Shlinkio\Shlink\Core\Exception\InvalidUrlException;
|
||||
@@ -21,7 +22,6 @@ interface UrlShortenerInterface
|
||||
* @param \DateTime|null $validUntil
|
||||
* @param string|null $customSlug
|
||||
* @param int|null $maxVisits
|
||||
* @return string
|
||||
* @throws NonUniqueSlugException
|
||||
* @throws InvalidUrlException
|
||||
* @throws RuntimeException
|
||||
@@ -38,10 +38,8 @@ interface UrlShortenerInterface
|
||||
/**
|
||||
* Tries to find the mapped URL for provided short code. Returns null if not found
|
||||
*
|
||||
* @param string $shortCode
|
||||
* @return string
|
||||
* @throws InvalidShortCodeException
|
||||
* @throws EntityDoesNotExistException
|
||||
*/
|
||||
public function shortCodeToUrl(string $shortCode): string;
|
||||
public function shortCodeToUrl(string $shortCode): ShortUrl;
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@ use Prophecy\Prophecy\ObjectProphecy;
|
||||
use Shlinkio\Shlink\Common\Response\PixelResponse;
|
||||
use Shlinkio\Shlink\Core\Action\PixelAction;
|
||||
use Shlinkio\Shlink\Core\Action\RedirectAction;
|
||||
use Shlinkio\Shlink\Core\Entity\ShortUrl;
|
||||
use Shlinkio\Shlink\Core\Options\AppOptions;
|
||||
use Shlinkio\Shlink\Core\Service\UrlShortener;
|
||||
use Shlinkio\Shlink\Core\Service\VisitsTracker;
|
||||
@@ -48,8 +49,9 @@ class PixelActionTest extends TestCase
|
||||
public function imageIsReturned()
|
||||
{
|
||||
$shortCode = 'abc123';
|
||||
$this->urlShortener->shortCodeToUrl($shortCode)->willReturn('http://domain.com/foo/bar')
|
||||
->shouldBeCalledTimes(1);
|
||||
$this->urlShortener->shortCodeToUrl($shortCode)->willReturn(
|
||||
(new ShortUrl())->setLongUrl('http://domain.com/foo/bar')
|
||||
)->shouldBeCalledTimes(1);
|
||||
$this->visitTracker->track(Argument::cetera())->willReturn(null)
|
||||
->shouldBeCalledTimes(1);
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@ use Prophecy\Prophecy\ObjectProphecy;
|
||||
use Psr\Http\Server\RequestHandlerInterface;
|
||||
use Shlinkio\Shlink\Common\Service\PreviewGenerator;
|
||||
use Shlinkio\Shlink\Core\Action\PreviewAction;
|
||||
use Shlinkio\Shlink\Core\Entity\ShortUrl;
|
||||
use Shlinkio\Shlink\Core\Exception\EntityDoesNotExistException;
|
||||
use Shlinkio\Shlink\Core\Exception\InvalidShortCodeException;
|
||||
use Shlinkio\Shlink\Core\Service\UrlShortener;
|
||||
@@ -64,8 +65,9 @@ class PreviewActionTest extends TestCase
|
||||
{
|
||||
$shortCode = 'abc123';
|
||||
$url = 'foobar.com';
|
||||
$shortUrl = (new ShortUrl())->setLongUrl($url);
|
||||
$path = __FILE__;
|
||||
$this->urlShortener->shortCodeToUrl($shortCode)->willReturn($url)->shouldBeCalledTimes(1);
|
||||
$this->urlShortener->shortCodeToUrl($shortCode)->willReturn($shortUrl)->shouldBeCalledTimes(1);
|
||||
$this->previewGenerator->generatePreview($url)->willReturn($path)->shouldBeCalledTimes(1);
|
||||
|
||||
$resp = $this->action->process(
|
||||
|
||||
@@ -10,6 +10,7 @@ use Prophecy\Prophecy\ObjectProphecy;
|
||||
use Psr\Http\Server\RequestHandlerInterface;
|
||||
use Shlinkio\Shlink\Common\Response\QrCodeResponse;
|
||||
use Shlinkio\Shlink\Core\Action\QrCodeAction;
|
||||
use Shlinkio\Shlink\Core\Entity\ShortUrl;
|
||||
use Shlinkio\Shlink\Core\Exception\EntityDoesNotExistException;
|
||||
use Shlinkio\Shlink\Core\Exception\InvalidShortCodeException;
|
||||
use Shlinkio\Shlink\Core\Service\UrlShortener;
|
||||
@@ -83,7 +84,8 @@ class QrCodeActionTest extends TestCase
|
||||
public function aCorrectRequestReturnsTheQrCodeResponse()
|
||||
{
|
||||
$shortCode = 'abc123';
|
||||
$this->urlShortener->shortCodeToUrl($shortCode)->willReturn('')->shouldBeCalledTimes(1);
|
||||
$this->urlShortener->shortCodeToUrl($shortCode)->willReturn((new ShortUrl())->setLongUrl(''))
|
||||
->shouldBeCalledTimes(1);
|
||||
$delegate = $this->prophesize(RequestHandlerInterface::class);
|
||||
|
||||
$resp = $this->action->process(
|
||||
|
||||
@@ -9,6 +9,7 @@ use Prophecy\Prophecy\MethodProphecy;
|
||||
use Prophecy\Prophecy\ObjectProphecy;
|
||||
use Psr\Http\Server\RequestHandlerInterface;
|
||||
use Shlinkio\Shlink\Core\Action\RedirectAction;
|
||||
use Shlinkio\Shlink\Core\Entity\ShortUrl;
|
||||
use Shlinkio\Shlink\Core\Exception\EntityDoesNotExistException;
|
||||
use Shlinkio\Shlink\Core\Options\AppOptions;
|
||||
use Shlinkio\Shlink\Core\Service\UrlShortener;
|
||||
@@ -51,7 +52,8 @@ class RedirectActionTest extends TestCase
|
||||
{
|
||||
$shortCode = 'abc123';
|
||||
$expectedUrl = 'http://domain.com/foo/bar';
|
||||
$this->urlShortener->shortCodeToUrl($shortCode)->willReturn($expectedUrl)
|
||||
$shortUrl = (new ShortUrl())->setLongUrl($expectedUrl);
|
||||
$this->urlShortener->shortCodeToUrl($shortCode)->willReturn($shortUrl)
|
||||
->shouldBeCalledTimes(1);
|
||||
$this->visitTracker->track(Argument::cetera())->willReturn(null)
|
||||
->shouldBeCalledTimes(1);
|
||||
@@ -93,7 +95,8 @@ class RedirectActionTest extends TestCase
|
||||
{
|
||||
$shortCode = 'abc123';
|
||||
$expectedUrl = 'http://domain.com/foo/bar';
|
||||
$this->urlShortener->shortCodeToUrl($shortCode)->willReturn($expectedUrl)
|
||||
$shortUrl = (new ShortUrl())->setLongUrl($expectedUrl);
|
||||
$this->urlShortener->shortCodeToUrl($shortCode)->willReturn($shortUrl)
|
||||
->shouldBeCalledTimes(1);
|
||||
$this->visitTracker->track(Argument::cetera())->willReturn(null)
|
||||
->shouldNotBeCalled();
|
||||
|
||||
@@ -4,8 +4,6 @@ declare(strict_types=1);
|
||||
namespace ShlinkioTest\Shlink\Core\Service;
|
||||
|
||||
use Cocur\Slugify\SlugifyInterface;
|
||||
use Doctrine\Common\Cache\ArrayCache;
|
||||
use Doctrine\Common\Cache\Cache;
|
||||
use Doctrine\Common\Persistence\ObjectRepository;
|
||||
use Doctrine\DBAL\Connection;
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
@@ -37,10 +35,6 @@ class UrlShortenerTest extends TestCase
|
||||
* @var ObjectProphecy
|
||||
*/
|
||||
protected $httpClient;
|
||||
/**
|
||||
* @var Cache
|
||||
*/
|
||||
protected $cache;
|
||||
/**
|
||||
* @var ObjectProphecy
|
||||
*/
|
||||
@@ -66,7 +60,6 @@ class UrlShortenerTest extends TestCase
|
||||
$repo->findOneBy(Argument::any())->willReturn(null);
|
||||
$this->em->getRepository(ShortUrl::class)->willReturn($repo->reveal());
|
||||
|
||||
$this->cache = new ArrayCache();
|
||||
$this->slugger = $this->prophesize(SlugifyInterface::class);
|
||||
|
||||
$this->setUrlShortener(false);
|
||||
@@ -80,7 +73,6 @@ class UrlShortenerTest extends TestCase
|
||||
$this->urlShortener = new UrlShortener(
|
||||
$this->httpClient->reveal(),
|
||||
$this->em->reveal(),
|
||||
$this->cache,
|
||||
$urlValidationEnabled,
|
||||
UrlShortener::DEFAULT_CHARS,
|
||||
$this->slugger->reveal()
|
||||
@@ -205,10 +197,8 @@ class UrlShortenerTest extends TestCase
|
||||
$repo->findOneByShortCode($shortCode)->willReturn($shortUrl);
|
||||
$this->em->getRepository(ShortUrl::class)->willReturn($repo->reveal());
|
||||
|
||||
$this->assertFalse($this->cache->contains($shortCode . '_longUrl'));
|
||||
$url = $this->urlShortener->shortCodeToUrl($shortCode);
|
||||
$this->assertEquals($shortUrl->getOriginalUrl(), $url);
|
||||
$this->assertTrue($this->cache->contains($shortCode . '_longUrl'));
|
||||
$this->assertSame($shortUrl, $url);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -219,18 +209,4 @@ class UrlShortenerTest extends TestCase
|
||||
{
|
||||
$this->urlShortener->shortCodeToUrl('&/(');
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function cachedShortCodeDoesNotHitDatabase()
|
||||
{
|
||||
$shortCode = '12C1c';
|
||||
$expectedUrl = 'expected_url';
|
||||
$this->cache->save($shortCode . '_longUrl', $expectedUrl);
|
||||
$this->em->getRepository(ShortUrl::class)->willReturn(null)->shouldBeCalledTimes(0);
|
||||
|
||||
$url = $this->urlShortener->shortCodeToUrl($shortCode);
|
||||
$this->assertEquals($expectedUrl, $url);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user