mirror of
https://github.com/shlinkio/shlink.git
synced 2024-11-27 16:26:37 +03:00
Updated UrlShortener so that it does not match a short code which is out of the validity dat erange
This commit is contained in:
parent
68b4cfbae0
commit
a3bbd06fe3
6 changed files with 116 additions and 42 deletions
|
@ -15,14 +15,20 @@ interface PaginableRepositoryInterface
|
|||
* @param string|array|null $orderBy
|
||||
* @return array
|
||||
*/
|
||||
public function findList($limit = null, $offset = null, $searchTerm = null, array $tags = [], $orderBy = null);
|
||||
public function findList(
|
||||
int $limit = null,
|
||||
int $offset = null,
|
||||
string $searchTerm = null,
|
||||
array $tags = [],
|
||||
$orderBy = null
|
||||
): array;
|
||||
|
||||
/**
|
||||
* Counts the number of elements in a list using provided filtering data
|
||||
*
|
||||
* @param null $searchTerm
|
||||
* @param string|null $searchTerm
|
||||
* @param array $tags
|
||||
* @return int
|
||||
*/
|
||||
public function countList($searchTerm = null, array $tags = []);
|
||||
public function countList(string $searchTerm = null, array $tags = []): int;
|
||||
}
|
||||
|
|
|
@ -54,22 +54,32 @@ class ShortUrl extends AbstractEntity implements \JsonSerializable
|
|||
* })
|
||||
*/
|
||||
protected $tags;
|
||||
/**
|
||||
* @var \DateTime
|
||||
* @ORM\Column(name="valid_since", type="datetime", nullable=true)
|
||||
*/
|
||||
protected $validSince;
|
||||
/**
|
||||
* @var \DateTime
|
||||
* @ORM\Column(name="valid_until", type="datetime", nullable=true)
|
||||
*/
|
||||
protected $validUntil;
|
||||
|
||||
/**
|
||||
* ShortUrl constructor.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->setDateCreated(new \DateTime());
|
||||
$this->setVisits(new ArrayCollection());
|
||||
$this->setShortCode('');
|
||||
$this->dateCreated = new \DateTime();
|
||||
$this->visits = new ArrayCollection();
|
||||
$this->shortCode = '';
|
||||
$this->tags = new ArrayCollection();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getOriginalUrl()
|
||||
public function getOriginalUrl(): string
|
||||
{
|
||||
return $this->originalUrl;
|
||||
}
|
||||
|
@ -78,7 +88,7 @@ class ShortUrl extends AbstractEntity implements \JsonSerializable
|
|||
* @param string $originalUrl
|
||||
* @return $this
|
||||
*/
|
||||
public function setOriginalUrl($originalUrl)
|
||||
public function setOriginalUrl(string $originalUrl)
|
||||
{
|
||||
$this->originalUrl = (string) $originalUrl;
|
||||
return $this;
|
||||
|
@ -87,7 +97,7 @@ class ShortUrl extends AbstractEntity implements \JsonSerializable
|
|||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getShortCode()
|
||||
public function getShortCode(): string
|
||||
{
|
||||
return $this->shortCode;
|
||||
}
|
||||
|
@ -96,7 +106,7 @@ class ShortUrl extends AbstractEntity implements \JsonSerializable
|
|||
* @param string $shortCode
|
||||
* @return $this
|
||||
*/
|
||||
public function setShortCode($shortCode)
|
||||
public function setShortCode(string $shortCode)
|
||||
{
|
||||
$this->shortCode = $shortCode;
|
||||
return $this;
|
||||
|
@ -105,7 +115,7 @@ class ShortUrl extends AbstractEntity implements \JsonSerializable
|
|||
/**
|
||||
* @return \DateTime
|
||||
*/
|
||||
public function getDateCreated()
|
||||
public function getDateCreated(): \DateTime
|
||||
{
|
||||
return $this->dateCreated;
|
||||
}
|
||||
|
@ -114,34 +124,16 @@ class ShortUrl extends AbstractEntity implements \JsonSerializable
|
|||
* @param \DateTime $dateCreated
|
||||
* @return $this
|
||||
*/
|
||||
public function setDateCreated($dateCreated)
|
||||
public function setDateCreated(\DateTime $dateCreated)
|
||||
{
|
||||
$this->dateCreated = $dateCreated;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Visit[]|Collection
|
||||
*/
|
||||
public function getVisits()
|
||||
{
|
||||
return $this->visits;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Visit[]|Collection $visits
|
||||
* @return $this
|
||||
*/
|
||||
public function setVisits($visits)
|
||||
{
|
||||
$this->visits = $visits;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Collection|Tag[]
|
||||
*/
|
||||
public function getTags()
|
||||
public function getTags(): Collection
|
||||
{
|
||||
return $this->tags;
|
||||
}
|
||||
|
@ -150,7 +142,7 @@ class ShortUrl extends AbstractEntity implements \JsonSerializable
|
|||
* @param Collection|Tag[] $tags
|
||||
* @return $this
|
||||
*/
|
||||
public function setTags($tags)
|
||||
public function setTags(Collection $tags)
|
||||
{
|
||||
$this->tags = $tags;
|
||||
return $this;
|
||||
|
@ -166,6 +158,42 @@ class ShortUrl extends AbstractEntity implements \JsonSerializable
|
|||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \DateTime|null
|
||||
*/
|
||||
public function getValidSince()
|
||||
{
|
||||
return $this->validSince;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \DateTime|null $validSince
|
||||
* @return $this|self
|
||||
*/
|
||||
public function setValidSince($validSince): self
|
||||
{
|
||||
$this->validSince = $validSince;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \DateTime|null
|
||||
*/
|
||||
public function getValidUntil()
|
||||
{
|
||||
return $this->validUntil;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \DateTime|null $validUntil
|
||||
* @return $this|self
|
||||
*/
|
||||
public function setValidUntil($validUntil): self
|
||||
{
|
||||
$this->validUntil = $validUntil;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Specify data which should be serialized to JSON
|
||||
* @link http://php.net/manual/en/jsonserializable.jsonserialize.php
|
||||
|
|
|
@ -17,8 +17,13 @@ class ShortUrlRepository extends EntityRepository implements ShortUrlRepositoryI
|
|||
* @param string|array|null $orderBy
|
||||
* @return \Shlinkio\Shlink\Core\Entity\ShortUrl[]
|
||||
*/
|
||||
public function findList($limit = null, $offset = null, $searchTerm = null, array $tags = [], $orderBy = null)
|
||||
{
|
||||
public function findList(
|
||||
int $limit = null,
|
||||
int $offset = null,
|
||||
string $searchTerm = null,
|
||||
array $tags = [],
|
||||
$orderBy = null
|
||||
): array {
|
||||
$qb = $this->createListQueryBuilder($searchTerm, $tags);
|
||||
$qb->select('s');
|
||||
|
||||
|
@ -74,7 +79,7 @@ class ShortUrlRepository extends EntityRepository implements ShortUrlRepositoryI
|
|||
* @param array $tags
|
||||
* @return int
|
||||
*/
|
||||
public function countList($searchTerm = null, array $tags = [])
|
||||
public function countList(string $searchTerm = null, array $tags = []): int
|
||||
{
|
||||
$qb = $this->createListQueryBuilder($searchTerm, $tags);
|
||||
$qb->select('COUNT(s)');
|
||||
|
@ -87,7 +92,7 @@ class ShortUrlRepository extends EntityRepository implements ShortUrlRepositoryI
|
|||
* @param array $tags
|
||||
* @return QueryBuilder
|
||||
*/
|
||||
protected function createListQueryBuilder($searchTerm = null, array $tags = [])
|
||||
protected function createListQueryBuilder(string $searchTerm = null, array $tags = []): QueryBuilder
|
||||
{
|
||||
$qb = $this->getEntityManager()->createQueryBuilder();
|
||||
$qb->from(ShortUrl::class, 's');
|
||||
|
@ -117,4 +122,29 @@ class ShortUrlRepository extends EntityRepository implements ShortUrlRepositoryI
|
|||
|
||||
return $qb;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $shortCode
|
||||
* @return ShortUrl|null
|
||||
*/
|
||||
public function findOneByShortCode(string $shortCode)
|
||||
{
|
||||
$now = new \DateTimeImmutable();
|
||||
|
||||
$qb = $this->createQueryBuilder('s');
|
||||
$qb->where($qb->expr()->eq('s.shortCode', ':shortCode'))
|
||||
->setParameter('shortCode', $shortCode)
|
||||
->andWhere($qb->expr()->orX(
|
||||
$qb->expr()->lte('s.validSince', ':now'),
|
||||
$qb->expr()->isNull('s.validSince')
|
||||
))
|
||||
->andWhere($qb->expr()->orX(
|
||||
$qb->expr()->gte('s.validUntil', ':now'),
|
||||
$qb->expr()->isNull('s.validUntil')
|
||||
))
|
||||
->setParameter('now', $now)
|
||||
->setMaxResults(1);
|
||||
|
||||
return $qb->getQuery()->getOneOrNullResult();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,7 +5,13 @@ namespace Shlinkio\Shlink\Core\Repository;
|
|||
|
||||
use Doctrine\Common\Persistence\ObjectRepository;
|
||||
use Shlinkio\Shlink\Common\Repository\PaginableRepositoryInterface;
|
||||
use Shlinkio\Shlink\Core\Entity\ShortUrl;
|
||||
|
||||
interface ShortUrlRepositoryInterface extends ObjectRepository, PaginableRepositoryInterface
|
||||
{
|
||||
/**
|
||||
* @param string $shortCode
|
||||
* @return ShortUrl|null
|
||||
*/
|
||||
public function findOneByShortCode(string $shortCode);
|
||||
}
|
||||
|
|
|
@ -14,6 +14,7 @@ use Shlinkio\Shlink\Core\Entity\ShortUrl;
|
|||
use Shlinkio\Shlink\Core\Exception\EntityDoesNotExistException;
|
||||
use Shlinkio\Shlink\Core\Exception\InvalidShortCodeException;
|
||||
use Shlinkio\Shlink\Core\Exception\InvalidUrlException;
|
||||
use Shlinkio\Shlink\Core\Repository\ShortUrlRepository;
|
||||
use Shlinkio\Shlink\Core\Util\TagManagerTrait;
|
||||
|
||||
class UrlShortener implements UrlShortenerInterface
|
||||
|
@ -160,11 +161,13 @@ class UrlShortener implements UrlShortenerInterface
|
|||
throw InvalidShortCodeException::fromCharset($shortCode, $this->chars);
|
||||
}
|
||||
|
||||
$criteria = ['shortCode' => $shortCode];
|
||||
/** @var ShortUrl|null $shortUrl */
|
||||
$shortUrl = $this->em->getRepository(ShortUrl::class)->findOneBy($criteria);
|
||||
/** @var ShortUrlRepository $shortUrlRepo */
|
||||
$shortUrlRepo = $this->em->getRepository(ShortUrl::class);
|
||||
$shortUrl = $shortUrlRepo->findOneByShortCode($shortCode);
|
||||
if ($shortUrl === null) {
|
||||
throw EntityDoesNotExistException::createFromEntityAndConditions(ShortUrl::class, $criteria);
|
||||
throw EntityDoesNotExistException::createFromEntityAndConditions(ShortUrl::class, [
|
||||
'shortCode' => $shortCode,
|
||||
]);
|
||||
}
|
||||
|
||||
// Cache the shortcode
|
||||
|
|
|
@ -16,6 +16,7 @@ use PHPUnit\Framework\TestCase;
|
|||
use Prophecy\Argument;
|
||||
use Prophecy\Prophecy\ObjectProphecy;
|
||||
use Shlinkio\Shlink\Core\Entity\ShortUrl;
|
||||
use Shlinkio\Shlink\Core\Repository\ShortUrlRepositoryInterface;
|
||||
use Shlinkio\Shlink\Core\Service\UrlShortener;
|
||||
use Zend\Diactoros\Uri;
|
||||
|
||||
|
@ -127,8 +128,8 @@ class UrlShortenerTest extends TestCase
|
|||
$shortUrl->setShortCode($shortCode)
|
||||
->setOriginalUrl('expected_url');
|
||||
|
||||
$repo = $this->prophesize(ObjectRepository::class);
|
||||
$repo->findOneBy(['shortCode' => $shortCode])->willReturn($shortUrl);
|
||||
$repo = $this->prophesize(ShortUrlRepositoryInterface::class);
|
||||
$repo->findOneByShortCode($shortCode)->willReturn($shortUrl);
|
||||
$this->em->getRepository(ShortUrl::class)->willReturn($repo->reveal());
|
||||
|
||||
$this->assertFalse($this->cache->contains($shortCode . '_longUrl'));
|
||||
|
|
Loading…
Reference in a new issue