mirror of
https://github.com/shlinkio/shlink.git
synced 2025-01-12 09:02:23 -06:00
Added max_visits field to short_urls
This commit is contained in:
parent
7f4678261e
commit
af7c11665c
38
data/migrations/Version20171022064541.php
Normal file
38
data/migrations/Version20171022064541.php
Normal file
@ -0,0 +1,38 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace ShlinkMigrations;
|
||||
|
||||
use Doctrine\DBAL\Migrations\AbstractMigration;
|
||||
use Doctrine\DBAL\Schema\Schema;
|
||||
use Doctrine\DBAL\Schema\SchemaException;
|
||||
use Doctrine\DBAL\Types\Type;
|
||||
|
||||
/**
|
||||
* Auto-generated Migration: Please modify to your needs!
|
||||
*/
|
||||
class Version20171022064541 extends AbstractMigration
|
||||
{
|
||||
/**
|
||||
* @param Schema $schema
|
||||
* @throws SchemaException
|
||||
*/
|
||||
public function up(Schema $schema)
|
||||
{
|
||||
$shortUrls = $schema->getTable('short_urls');
|
||||
$shortUrls->addColumn('max_visits', Type::INTEGER, [
|
||||
'unsigned' => true,
|
||||
'notnull' => false,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Schema $schema
|
||||
* @throws SchemaException
|
||||
*/
|
||||
public function down(Schema $schema)
|
||||
{
|
||||
$shortUrls = $schema->getTable('short_urls');
|
||||
$shortUrls->dropColumn('max_visits');
|
||||
}
|
||||
}
|
@ -64,6 +64,11 @@ class ShortUrl extends AbstractEntity implements \JsonSerializable
|
||||
* @ORM\Column(name="valid_until", type="datetime", nullable=true)
|
||||
*/
|
||||
protected $validUntil;
|
||||
/**
|
||||
* @var integer
|
||||
* @ORM\Column(name="max_visits", type="integer", nullable=true)
|
||||
*/
|
||||
protected $maxVisits;
|
||||
|
||||
/**
|
||||
* ShortUrl constructor.
|
||||
@ -194,6 +199,34 @@ class ShortUrl extends AbstractEntity implements \JsonSerializable
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getVisitsCount(): int
|
||||
{
|
||||
return count($this->visits);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function getMaxVisits(): int
|
||||
{
|
||||
return $this->maxVisits;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $maxVisits
|
||||
* @return $this|self
|
||||
*/
|
||||
public function setMaxVisits(int $maxVisits): self
|
||||
{
|
||||
$this->maxVisits = $maxVisits;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function maxVisitsReached(): bool
|
||||
{
|
||||
return $this->maxVisits !== null && $this->maxVisits >= $this->getVisitsCount();
|
||||
}
|
||||
|
||||
/**
|
||||
* Specify data which should be serialized to JSON
|
||||
* @link http://php.net/manual/en/jsonserializable.jsonserialize.php
|
||||
@ -206,8 +239,8 @@ class ShortUrl extends AbstractEntity implements \JsonSerializable
|
||||
return [
|
||||
'shortCode' => $this->shortCode,
|
||||
'originalUrl' => $this->originalUrl,
|
||||
'dateCreated' => isset($this->dateCreated) ? $this->dateCreated->format(\DateTime::ATOM) : null,
|
||||
'visitsCount' => count($this->visits),
|
||||
'dateCreated' => $this->dateCreated !== null ? $this->dateCreated->format(\DateTime::ATOM) : null,
|
||||
'visitsCount' => $this->getVisitsCount(),
|
||||
'tags' => $this->tags->toArray(),
|
||||
];
|
||||
}
|
||||
|
@ -3,6 +3,7 @@ declare(strict_types=1);
|
||||
|
||||
namespace Shlinkio\Shlink\Core\Service;
|
||||
|
||||
use Doctrine\ORM\EntityManager;
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
use Psr\Http\Message\ServerRequestInterface;
|
||||
use Shlinkio\Shlink\Common\Exception\InvalidArgumentException;
|
||||
@ -14,7 +15,7 @@ use Shlinkio\Shlink\Core\Repository\VisitRepository;
|
||||
class VisitsTracker implements VisitsTrackerInterface
|
||||
{
|
||||
/**
|
||||
* @var EntityManagerInterface
|
||||
* @var EntityManagerInterface|EntityManager
|
||||
*/
|
||||
private $em;
|
||||
|
||||
@ -41,24 +42,25 @@ class VisitsTracker implements VisitsTrackerInterface
|
||||
->setUserAgent($request->getHeaderLine('User-Agent'))
|
||||
->setReferer($request->getHeaderLine('Referer'))
|
||||
->setRemoteAddr($this->findOutRemoteAddr($request));
|
||||
|
||||
$this->em->persist($visit);
|
||||
$this->em->flush();
|
||||
$this->em->flush($visit);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ServerRequestInterface $request
|
||||
* @return string
|
||||
* @return string|null
|
||||
*/
|
||||
protected function findOutRemoteAddr(ServerRequestInterface $request)
|
||||
private function findOutRemoteAddr(ServerRequestInterface $request)
|
||||
{
|
||||
$forwardedFor = $request->getHeaderLine('X-Forwarded-For');
|
||||
if (empty($forwardedFor)) {
|
||||
$serverParams = $request->getServerParams();
|
||||
return isset($serverParams['REMOTE_ADDR']) ? $serverParams['REMOTE_ADDR'] : null;
|
||||
return $serverParams['REMOTE_ADDR'] ?? null;
|
||||
}
|
||||
|
||||
$ips = explode(',', $forwardedFor);
|
||||
return $ips[0];
|
||||
return $ips[0] ?? null;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -67,14 +69,15 @@ class VisitsTracker implements VisitsTrackerInterface
|
||||
* @param $shortCode
|
||||
* @param DateRange $dateRange
|
||||
* @return Visit[]
|
||||
* @throws InvalidArgumentException
|
||||
*/
|
||||
public function info($shortCode, DateRange $dateRange = null)
|
||||
public function info($shortCode, DateRange $dateRange = null): array
|
||||
{
|
||||
/** @var ShortUrl $shortUrl */
|
||||
$shortUrl = $this->em->getRepository(ShortUrl::class)->findOneBy([
|
||||
'shortCode' => $shortCode,
|
||||
]);
|
||||
if (! isset($shortUrl)) {
|
||||
if ($shortUrl === null) {
|
||||
throw new InvalidArgumentException(sprintf('Short code "%s" not found', $shortCode));
|
||||
}
|
||||
|
||||
|
@ -4,6 +4,7 @@ declare(strict_types=1);
|
||||
namespace Shlinkio\Shlink\Core\Service;
|
||||
|
||||
use Psr\Http\Message\ServerRequestInterface;
|
||||
use Shlinkio\Shlink\Common\Exception\InvalidArgumentException;
|
||||
use Shlinkio\Shlink\Common\Util\DateRange;
|
||||
use Shlinkio\Shlink\Core\Entity\Visit;
|
||||
|
||||
@ -14,7 +15,6 @@ interface VisitsTrackerInterface
|
||||
*
|
||||
* @param string $shortCode
|
||||
* @param ServerRequestInterface $request
|
||||
* @return
|
||||
*/
|
||||
public function track($shortCode, ServerRequestInterface $request);
|
||||
|
||||
@ -24,6 +24,7 @@ interface VisitsTrackerInterface
|
||||
* @param $shortCode
|
||||
* @param DateRange $dateRange
|
||||
* @return Visit[]
|
||||
* @throws InvalidArgumentException
|
||||
*/
|
||||
public function info($shortCode, DateRange $dateRange = null);
|
||||
public function info($shortCode, DateRange $dateRange = null): array;
|
||||
}
|
||||
|
@ -42,7 +42,7 @@ class VisitsTrackerTest extends TestCase
|
||||
|
||||
$this->em->getRepository(ShortUrl::class)->willReturn($repo->reveal())->shouldBeCalledTimes(1);
|
||||
$this->em->persist(Argument::any())->shouldBeCalledTimes(1);
|
||||
$this->em->flush()->shouldBeCalledTimes(1);
|
||||
$this->em->flush(Argument::type(Visit::class))->shouldBeCalledTimes(1);
|
||||
|
||||
$this->visitsTracker->track($shortCode, ServerRequestFactory::fromGlobals());
|
||||
}
|
||||
@ -63,7 +63,7 @@ class VisitsTrackerTest extends TestCase
|
||||
$visit = $args[0];
|
||||
$test->assertEquals('4.3.2.1', $visit->getRemoteAddr());
|
||||
})->shouldBeCalledTimes(1);
|
||||
$this->em->flush()->shouldBeCalledTimes(1);
|
||||
$this->em->flush(Argument::type(Visit::class))->shouldBeCalledTimes(1);
|
||||
|
||||
$this->visitsTracker->track($shortCode, ServerRequestFactory::fromGlobals(
|
||||
['REMOTE_ADDR' => '1.2.3.4']
|
||||
|
Loading…
Reference in New Issue
Block a user