mirror of
https://github.com/shlinkio/shlink.git
synced 2024-12-29 02:11:10 -06:00
Merge branch 'feature/22' into develop
This commit is contained in:
commit
84c4021b24
@ -9,6 +9,7 @@ return [
|
||||
Command\ResolveUrlCommand::class,
|
||||
Command\ListShortcodesCommand::class,
|
||||
Command\GetVisitsCommand::class,
|
||||
Command\ProcessVisitsCommand::class,
|
||||
]
|
||||
],
|
||||
|
||||
|
@ -13,6 +13,7 @@ return [
|
||||
CLI\Command\ResolveUrlCommand::class => AnnotatedFactory::class,
|
||||
CLI\Command\ListShortcodesCommand::class => AnnotatedFactory::class,
|
||||
CLI\Command\GetVisitsCommand::class => AnnotatedFactory::class,
|
||||
CLI\Command\ProcessVisitsCommand::class => AnnotatedFactory::class,
|
||||
],
|
||||
],
|
||||
|
||||
|
74
module/CLI/src/Command/ProcessVisitsCommand.php
Normal file
74
module/CLI/src/Command/ProcessVisitsCommand.php
Normal file
@ -0,0 +1,74 @@
|
||||
<?php
|
||||
namespace Shlinkio\Shlink\CLI\Command;
|
||||
|
||||
use Acelaya\ZsmAnnotatedServices\Annotation\Inject;
|
||||
use Shlinkio\Shlink\Common\Exception\WrongIpException;
|
||||
use Shlinkio\Shlink\Common\Service\IpLocationResolver;
|
||||
use Shlinkio\Shlink\Common\Service\IpLocationResolverInterface;
|
||||
use Shlinkio\Shlink\Core\Entity\VisitLocation;
|
||||
use Shlinkio\Shlink\Core\Service\VisitService;
|
||||
use Shlinkio\Shlink\Core\Service\VisitServiceInterface;
|
||||
use Symfony\Component\Console\Command\Command;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
|
||||
class ProcessVisitsCommand extends Command
|
||||
{
|
||||
const LOCALHOST = '127.0.0.1';
|
||||
|
||||
/**
|
||||
* @var VisitServiceInterface
|
||||
*/
|
||||
private $visitService;
|
||||
/**
|
||||
* @var IpLocationResolverInterface
|
||||
*/
|
||||
private $ipLocationResolver;
|
||||
|
||||
/**
|
||||
* ProcessVisitsCommand constructor.
|
||||
* @param VisitServiceInterface|VisitService $visitService
|
||||
* @param IpLocationResolverInterface|IpLocationResolver $ipLocationResolver
|
||||
*
|
||||
* @Inject({VisitService::class, IpLocationResolver::class})
|
||||
*/
|
||||
public function __construct(VisitServiceInterface $visitService, IpLocationResolverInterface $ipLocationResolver)
|
||||
{
|
||||
parent::__construct(null);
|
||||
$this->visitService = $visitService;
|
||||
$this->ipLocationResolver = $ipLocationResolver;
|
||||
}
|
||||
|
||||
public function configure()
|
||||
{
|
||||
$this->setName('visit:process')
|
||||
->setDescription('Processes visits where location is not set already');
|
||||
}
|
||||
|
||||
public function execute(InputInterface $input, OutputInterface $output)
|
||||
{
|
||||
$visits = $this->visitService->getUnlocatedVisits();
|
||||
|
||||
foreach ($visits as $visit) {
|
||||
$ipAddr = $visit->getRemoteAddr();
|
||||
$output->write(sprintf('Processing IP <info>%s</info>', $ipAddr));
|
||||
if ($ipAddr === self::LOCALHOST) {
|
||||
$output->writeln(' (<comment>Ignored localhost address</comment>)');
|
||||
continue;
|
||||
}
|
||||
|
||||
try {
|
||||
$result = $this->ipLocationResolver->resolveIpLocation($ipAddr);
|
||||
$location = new VisitLocation();
|
||||
$location->exchangeArray($result);
|
||||
$visit->setVisitLocation($location);
|
||||
$this->visitService->saveVisit($visit);
|
||||
$output->writeln(sprintf(' (Address located at "%s")', $location->getCityName()));
|
||||
} catch (WrongIpException $e) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
$output->writeln('Finished processing all IPs');
|
||||
}
|
||||
}
|
@ -4,6 +4,7 @@ use Doctrine\Common\Cache\Cache;
|
||||
use Doctrine\ORM\EntityManager;
|
||||
use Shlinkio\Shlink\Common\Factory\CacheFactory;
|
||||
use Shlinkio\Shlink\Common\Factory\EntityManagerFactory;
|
||||
use Shlinkio\Shlink\Common\Service\IpLocationResolver;
|
||||
use Zend\ServiceManager\Factory\InvokableFactory;
|
||||
|
||||
return [
|
||||
@ -13,6 +14,7 @@ return [
|
||||
EntityManager::class => EntityManagerFactory::class,
|
||||
GuzzleHttp\Client::class => InvokableFactory::class,
|
||||
Cache::class => CacheFactory::class,
|
||||
IpLocationResolver::class => AnnotatedFactory::class,
|
||||
],
|
||||
'aliases' => [
|
||||
'em' => EntityManager::class,
|
||||
|
6
module/Common/src/Exception/ExceptionInterface.php
Normal file
6
module/Common/src/Exception/ExceptionInterface.php
Normal file
@ -0,0 +1,6 @@
|
||||
<?php
|
||||
namespace Shlinkio\Shlink\Common\Exception;
|
||||
|
||||
interface ExceptionInterface
|
||||
{
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
<?php
|
||||
namespace Shlinkio\Shlink\Core\Exception;
|
||||
namespace Shlinkio\Shlink\Common\Exception;
|
||||
|
||||
class InvalidArgumentException extends \InvalidArgumentException implements ExceptionInterface
|
||||
{
|
@ -1,5 +1,5 @@
|
||||
<?php
|
||||
namespace Shlinkio\Shlink\Core\Exception;
|
||||
namespace Shlinkio\Shlink\Common\Exception;
|
||||
|
||||
class RuntimeException extends \RuntimeException implements ExceptionInterface
|
||||
{
|
10
module/Common/src/Exception/WrongIpException.php
Normal file
10
module/Common/src/Exception/WrongIpException.php
Normal file
@ -0,0 +1,10 @@
|
||||
<?php
|
||||
namespace Shlinkio\Shlink\Common\Exception;
|
||||
|
||||
class WrongIpException extends RuntimeException
|
||||
{
|
||||
public static function fromIpAddress($ipAddress, \Exception $prev = null)
|
||||
{
|
||||
return new self(sprintf('Provided IP "%s" is invalid', $ipAddress), 0, $prev);
|
||||
}
|
||||
}
|
42
module/Common/src/Service/IpLocationResolver.php
Normal file
42
module/Common/src/Service/IpLocationResolver.php
Normal file
@ -0,0 +1,42 @@
|
||||
<?php
|
||||
namespace Shlinkio\Shlink\Common\Service;
|
||||
|
||||
use Acelaya\ZsmAnnotatedServices\Annotation\Inject;
|
||||
use GuzzleHttp\Client;
|
||||
use GuzzleHttp\Exception\GuzzleException;
|
||||
use Shlinkio\Shlink\Common\Exception\WrongIpException;
|
||||
|
||||
class IpLocationResolver implements IpLocationResolverInterface
|
||||
{
|
||||
const SERVICE_PATTERN = 'http://freegeoip.net/json/%s';
|
||||
|
||||
/**
|
||||
* @var Client
|
||||
*/
|
||||
private $httpClient;
|
||||
|
||||
/**
|
||||
* IpLocationResolver constructor.
|
||||
* @param Client $httpClient
|
||||
*
|
||||
* @Inject({"httpClient"})
|
||||
*/
|
||||
public function __construct(Client $httpClient)
|
||||
{
|
||||
$this->httpClient = $httpClient;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $ipAddress
|
||||
* @return array
|
||||
*/
|
||||
public function resolveIpLocation($ipAddress)
|
||||
{
|
||||
try {
|
||||
$response = $this->httpClient->get(sprintf(self::SERVICE_PATTERN, $ipAddress));
|
||||
return json_decode($response->getBody(), true);
|
||||
} catch (GuzzleException $e) {
|
||||
throw WrongIpException::fromIpAddress($ipAddress, $e);
|
||||
}
|
||||
}
|
||||
}
|
11
module/Common/src/Service/IpLocationResolverInterface.php
Normal file
11
module/Common/src/Service/IpLocationResolverInterface.php
Normal file
@ -0,0 +1,11 @@
|
||||
<?php
|
||||
namespace Shlinkio\Shlink\Common\Service;
|
||||
|
||||
interface IpLocationResolverInterface
|
||||
{
|
||||
/**
|
||||
* @param $ipAddress
|
||||
* @return array
|
||||
*/
|
||||
public function resolveIpLocation($ipAddress);
|
||||
}
|
@ -11,6 +11,7 @@ return [
|
||||
Service\UrlShortener::class => AnnotatedFactory::class,
|
||||
Service\VisitsTracker::class => AnnotatedFactory::class,
|
||||
Service\ShortUrlService::class => AnnotatedFactory::class,
|
||||
Service\VisitService::class => AnnotatedFactory::class,
|
||||
|
||||
// Middleware
|
||||
RedirectMiddleware::class => AnnotatedFactory::class,
|
||||
|
@ -9,7 +9,7 @@ use Shlinkio\Shlink\Common\Entity\AbstractEntity;
|
||||
* @author
|
||||
* @link
|
||||
*
|
||||
* @ORM\Entity
|
||||
* @ORM\Entity(repositoryClass="Shlinkio\Shlink\Core\Repository\VisitRepository")
|
||||
* @ORM\Table(name="visits")
|
||||
*/
|
||||
class Visit extends AbstractEntity implements \JsonSerializable
|
||||
@ -40,6 +40,12 @@ class Visit extends AbstractEntity implements \JsonSerializable
|
||||
* @ORM\JoinColumn(name="short_url_id", referencedColumnName="id")
|
||||
*/
|
||||
protected $shortUrl;
|
||||
/**
|
||||
* @var VisitLocation
|
||||
* @ORM\ManyToOne(targetEntity=VisitLocation::class, cascade={"persist"})
|
||||
* @ORM\JoinColumn(name="visit_location_id", referencedColumnName="id", nullable=true)
|
||||
*/
|
||||
protected $visitLocation;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
@ -136,6 +142,24 @@ class Visit extends AbstractEntity implements \JsonSerializable
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return VisitLocation
|
||||
*/
|
||||
public function getVisitLocation()
|
||||
{
|
||||
return $this->visitLocation;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param VisitLocation $visitLocation
|
||||
* @return $this
|
||||
*/
|
||||
public function setVisitLocation($visitLocation)
|
||||
{
|
||||
$this->visitLocation = $visitLocation;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Specify data which should be serialized to JSON
|
||||
* @link http://php.net/manual/en/jsonserializable.jsonserialize.php
|
||||
@ -150,6 +174,7 @@ class Visit extends AbstractEntity implements \JsonSerializable
|
||||
'date' => isset($this->date) ? $this->date->format(\DateTime::ISO8601) : null,
|
||||
'remoteAddr' => $this->remoteAddr,
|
||||
'userAgent' => $this->userAgent,
|
||||
'visitLocation' => $this->visitLocation,
|
||||
];
|
||||
}
|
||||
}
|
||||
|
240
module/Core/src/Entity/VisitLocation.php
Normal file
240
module/Core/src/Entity/VisitLocation.php
Normal file
@ -0,0 +1,240 @@
|
||||
<?php
|
||||
namespace Shlinkio\Shlink\Core\Entity;
|
||||
|
||||
use Shlinkio\Shlink\Common\Entity\AbstractEntity;
|
||||
use Doctrine\ORM\Mapping as ORM;
|
||||
use Zend\Stdlib\ArraySerializableInterface;
|
||||
|
||||
/**
|
||||
* Class VisitLocation
|
||||
* @author
|
||||
* @link
|
||||
*
|
||||
* @ORM\Entity()
|
||||
* @ORM\Table(name="visit_locations")
|
||||
*/
|
||||
class VisitLocation extends AbstractEntity implements ArraySerializableInterface, \JsonSerializable
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
* @ORM\Column(nullable=true)
|
||||
*/
|
||||
protected $countryCode;
|
||||
/**
|
||||
* @var string
|
||||
* @ORM\Column(nullable=true)
|
||||
*/
|
||||
protected $countryName;
|
||||
/**
|
||||
* @var string
|
||||
* @ORM\Column(nullable=true)
|
||||
*/
|
||||
protected $regionName;
|
||||
/**
|
||||
* @var string
|
||||
* @ORM\Column(nullable=true)
|
||||
*/
|
||||
protected $cityName;
|
||||
/**
|
||||
* @var string
|
||||
* @ORM\Column(nullable=true)
|
||||
*/
|
||||
protected $latitude;
|
||||
/**
|
||||
* @var string
|
||||
* @ORM\Column(nullable=true)
|
||||
*/
|
||||
protected $longitude;
|
||||
/**
|
||||
* @var string
|
||||
* @ORM\Column(nullable=true)
|
||||
*/
|
||||
protected $timezone;
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getCountryCode()
|
||||
{
|
||||
return $this->countryCode;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $countryCode
|
||||
* @return $this
|
||||
*/
|
||||
public function setCountryCode($countryCode)
|
||||
{
|
||||
$this->countryCode = $countryCode;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getCountryName()
|
||||
{
|
||||
return $this->countryName;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $countryName
|
||||
* @return $this
|
||||
*/
|
||||
public function setCountryName($countryName)
|
||||
{
|
||||
$this->countryName = $countryName;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getRegionName()
|
||||
{
|
||||
return $this->regionName;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $regionName
|
||||
* @return $this
|
||||
*/
|
||||
public function setRegionName($regionName)
|
||||
{
|
||||
$this->regionName = $regionName;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getCityName()
|
||||
{
|
||||
return $this->cityName;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $cityName
|
||||
* @return $this
|
||||
*/
|
||||
public function setCityName($cityName)
|
||||
{
|
||||
$this->cityName = $cityName;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getLatitude()
|
||||
{
|
||||
return $this->latitude;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $latitude
|
||||
* @return $this
|
||||
*/
|
||||
public function setLatitude($latitude)
|
||||
{
|
||||
$this->latitude = $latitude;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getLongitude()
|
||||
{
|
||||
return $this->longitude;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $longitude
|
||||
* @return $this
|
||||
*/
|
||||
public function setLongitude($longitude)
|
||||
{
|
||||
$this->longitude = $longitude;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getTimezone()
|
||||
{
|
||||
return $this->timezone;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $timezone
|
||||
* @return $this
|
||||
*/
|
||||
public function setTimezone($timezone)
|
||||
{
|
||||
$this->timezone = $timezone;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Exchange internal values from provided array
|
||||
*
|
||||
* @param array $array
|
||||
* @return void
|
||||
*/
|
||||
public function exchangeArray(array $array)
|
||||
{
|
||||
if (array_key_exists('country_code', $array)) {
|
||||
$this->setCountryCode($array['country_code']);
|
||||
}
|
||||
if (array_key_exists('country_name', $array)) {
|
||||
$this->setCountryName($array['country_name']);
|
||||
}
|
||||
if (array_key_exists('region_name', $array)) {
|
||||
$this->setRegionName($array['region_name']);
|
||||
}
|
||||
if (array_key_exists('city', $array)) {
|
||||
$this->setCityName($array['city']);
|
||||
}
|
||||
if (array_key_exists('latitude', $array)) {
|
||||
$this->setLatitude($array['latitude']);
|
||||
}
|
||||
if (array_key_exists('longitude', $array)) {
|
||||
$this->setLongitude($array['longitude']);
|
||||
}
|
||||
if (array_key_exists('time_zone', $array)) {
|
||||
$this->setTimezone($array['time_zone']);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return an array representation of the object
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getArrayCopy()
|
||||
{
|
||||
return [
|
||||
'countryCode' => $this->countryCode,
|
||||
'countryName' => $this->countryName,
|
||||
'regionName' => $this->regionName,
|
||||
'cityName' => $this->cityName,
|
||||
'latitude' => $this->latitude,
|
||||
'longitude' => $this->longitude,
|
||||
'timezone' => $this->timezone,
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Specify data which should be serialized to JSON
|
||||
* @link http://php.net/manual/en/jsonserializable.jsonserialize.php
|
||||
* @return mixed data which can be serialized by <b>json_encode</b>,
|
||||
* which is a value of any type other than a resource.
|
||||
* @since 5.4.0
|
||||
*/
|
||||
public function jsonSerialize()
|
||||
{
|
||||
return $this->getArrayCopy();
|
||||
}
|
||||
}
|
@ -1,6 +0,0 @@
|
||||
<?php
|
||||
namespace Shlinkio\Shlink\Core\Exception;
|
||||
|
||||
interface ExceptionInterface
|
||||
{
|
||||
}
|
@ -1,6 +1,8 @@
|
||||
<?php
|
||||
namespace Shlinkio\Shlink\Core\Exception;
|
||||
|
||||
use Shlinkio\Shlink\Common\Exception\RuntimeException;
|
||||
|
||||
class InvalidShortCodeException extends RuntimeException
|
||||
{
|
||||
public static function fromShortCode($shortCode, $charSet, \Exception $previous = null)
|
||||
|
@ -1,6 +1,8 @@
|
||||
<?php
|
||||
namespace Shlinkio\Shlink\Core\Exception;
|
||||
|
||||
use Shlinkio\Shlink\Common\Exception\RuntimeException;
|
||||
|
||||
class InvalidUrlException extends RuntimeException
|
||||
{
|
||||
public static function fromUrl($url, \Exception $previous = null)
|
||||
|
19
module/Core/src/Repository/VisitRepository.php
Normal file
19
module/Core/src/Repository/VisitRepository.php
Normal file
@ -0,0 +1,19 @@
|
||||
<?php
|
||||
namespace Shlinkio\Shlink\Core\Repository;
|
||||
|
||||
use Doctrine\ORM\EntityRepository;
|
||||
use Shlinkio\Shlink\Core\Entity\Visit;
|
||||
|
||||
class VisitRepository extends EntityRepository implements VisitRepositoryInterface
|
||||
{
|
||||
/**
|
||||
* @return Visit[]
|
||||
*/
|
||||
public function findUnlocatedVisits()
|
||||
{
|
||||
$qb = $this->createQueryBuilder('v');
|
||||
$qb->where($qb->expr()->isNull('v.visitLocation'));
|
||||
|
||||
return $qb->getQuery()->getResult();
|
||||
}
|
||||
}
|
13
module/Core/src/Repository/VisitRepositoryInterface.php
Normal file
13
module/Core/src/Repository/VisitRepositoryInterface.php
Normal file
@ -0,0 +1,13 @@
|
||||
<?php
|
||||
namespace Shlinkio\Shlink\Core\Repository;
|
||||
|
||||
use Doctrine\Common\Persistence\ObjectRepository;
|
||||
use Shlinkio\Shlink\Core\Entity\Visit;
|
||||
|
||||
interface VisitRepositoryInterface extends ObjectRepository
|
||||
{
|
||||
/**
|
||||
* @return Visit[]
|
||||
*/
|
||||
public function findUnlocatedVisits();
|
||||
}
|
@ -7,10 +7,10 @@ use Doctrine\ORM\ORMException;
|
||||
use GuzzleHttp\ClientInterface;
|
||||
use GuzzleHttp\Exception\GuzzleException;
|
||||
use Psr\Http\Message\UriInterface;
|
||||
use Shlinkio\Shlink\Common\Exception\RuntimeException;
|
||||
use Shlinkio\Shlink\Core\Entity\ShortUrl;
|
||||
use Shlinkio\Shlink\Core\Exception\InvalidShortCodeException;
|
||||
use Shlinkio\Shlink\Core\Exception\InvalidUrlException;
|
||||
use Shlinkio\Shlink\Core\Exception\RuntimeException;
|
||||
|
||||
class UrlShortener implements UrlShortenerInterface
|
||||
{
|
||||
|
@ -2,9 +2,9 @@
|
||||
namespace Shlinkio\Shlink\Core\Service;
|
||||
|
||||
use Psr\Http\Message\UriInterface;
|
||||
use Shlinkio\Shlink\Common\Exception\RuntimeException;
|
||||
use Shlinkio\Shlink\Core\Exception\InvalidShortCodeException;
|
||||
use Shlinkio\Shlink\Core\Exception\InvalidUrlException;
|
||||
use Shlinkio\Shlink\Core\Exception\RuntimeException;
|
||||
|
||||
interface UrlShortenerInterface
|
||||
{
|
||||
|
45
module/Core/src/Service/VisitService.php
Normal file
45
module/Core/src/Service/VisitService.php
Normal file
@ -0,0 +1,45 @@
|
||||
<?php
|
||||
namespace Shlinkio\Shlink\Core\Service;
|
||||
|
||||
use Acelaya\ZsmAnnotatedServices\Annotation\Inject;
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
use Shlinkio\Shlink\Core\Entity\Visit;
|
||||
use Shlinkio\Shlink\Core\Repository\VisitRepository;
|
||||
|
||||
class VisitService implements VisitServiceInterface
|
||||
{
|
||||
/**
|
||||
* @var EntityManagerInterface
|
||||
*/
|
||||
private $em;
|
||||
|
||||
/**
|
||||
* VisitService constructor.
|
||||
* @param EntityManagerInterface $em
|
||||
*
|
||||
* @Inject({"em"})
|
||||
*/
|
||||
public function __construct(EntityManagerInterface $em)
|
||||
{
|
||||
$this->em = $em;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Visit[]
|
||||
*/
|
||||
public function getUnlocatedVisits()
|
||||
{
|
||||
/** @var VisitRepository $repo */
|
||||
$repo = $this->em->getRepository(Visit::class);
|
||||
return $repo->findUnlocatedVisits();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Visit $visit
|
||||
*/
|
||||
public function saveVisit(Visit $visit)
|
||||
{
|
||||
$this->em->persist($visit);
|
||||
$this->em->flush();
|
||||
}
|
||||
}
|
17
module/Core/src/Service/VisitServiceInterface.php
Normal file
17
module/Core/src/Service/VisitServiceInterface.php
Normal file
@ -0,0 +1,17 @@
|
||||
<?php
|
||||
namespace Shlinkio\Shlink\Core\Service;
|
||||
|
||||
use Shlinkio\Shlink\Core\Entity\Visit;
|
||||
|
||||
interface VisitServiceInterface
|
||||
{
|
||||
/**
|
||||
* @return Visit[]
|
||||
*/
|
||||
public function getUnlocatedVisits();
|
||||
|
||||
/**
|
||||
* @param Visit $visit
|
||||
*/
|
||||
public function saveVisit(Visit $visit);
|
||||
}
|
@ -3,9 +3,9 @@ namespace Shlinkio\Shlink\Core\Service;
|
||||
|
||||
use Acelaya\ZsmAnnotatedServices\Annotation\Inject;
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
use Shlinkio\Shlink\Common\Exception\InvalidArgumentException;
|
||||
use Shlinkio\Shlink\Core\Entity\ShortUrl;
|
||||
use Shlinkio\Shlink\Core\Entity\Visit;
|
||||
use Shlinkio\Shlink\Core\Exception\InvalidArgumentException;
|
||||
use Zend\Paginator\Paginator;
|
||||
|
||||
class VisitsTracker implements VisitsTrackerInterface
|
||||
|
@ -65,7 +65,7 @@ class UrlShortenerTest extends TestCase
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @expectedException \Shlinkio\Shlink\Core\Exception\RuntimeException
|
||||
* @expectedException \Shlinkio\Shlink\Common\Exception\RuntimeException
|
||||
*/
|
||||
public function exceptionIsThrownWhenOrmThrowsException()
|
||||
{
|
||||
|
@ -4,7 +4,7 @@ namespace Shlinkio\Shlink\Rest\Action;
|
||||
use Acelaya\ZsmAnnotatedServices\Annotation\Inject;
|
||||
use Psr\Http\Message\ResponseInterface as Response;
|
||||
use Psr\Http\Message\ServerRequestInterface as Request;
|
||||
use Shlinkio\Shlink\Core\Exception\InvalidArgumentException;
|
||||
use Shlinkio\Shlink\Common\Exception\InvalidArgumentException;
|
||||
use Shlinkio\Shlink\Core\Service\VisitsTracker;
|
||||
use Shlinkio\Shlink\Core\Service\VisitsTrackerInterface;
|
||||
use Shlinkio\Shlink\Rest\Util\RestUtils;
|
||||
|
@ -1,7 +1,7 @@
|
||||
<?php
|
||||
namespace Shlinkio\Shlink\Rest\Exception;
|
||||
|
||||
use Shlinkio\Shlink\Core\Exception\ExceptionInterface;
|
||||
use Shlinkio\Shlink\Common\Exception\ExceptionInterface;
|
||||
|
||||
class AuthenticationException extends \RuntimeException implements ExceptionInterface
|
||||
{
|
||||
|
@ -4,7 +4,7 @@ namespace Shlinkio\Shlink\Rest\Middleware;
|
||||
use Acelaya\ZsmAnnotatedServices\Annotation\Inject;
|
||||
use Psr\Http\Message\ResponseInterface as Response;
|
||||
use Psr\Http\Message\ServerRequestInterface as Request;
|
||||
use Shlinkio\Shlink\Core\Exception\InvalidArgumentException;
|
||||
use Shlinkio\Shlink\Common\Exception\InvalidArgumentException;
|
||||
use Shlinkio\Shlink\Rest\Service\RestTokenService;
|
||||
use Shlinkio\Shlink\Rest\Service\RestTokenServiceInterface;
|
||||
use Shlinkio\Shlink\Rest\Util\RestUtils;
|
||||
|
@ -3,8 +3,8 @@ namespace Shlinkio\Shlink\Rest\Service;
|
||||
|
||||
use Acelaya\ZsmAnnotatedServices\Annotation\Inject;
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
use Shlinkio\Shlink\Common\Exception\InvalidArgumentException;
|
||||
use Shlinkio\Shlink\Core\Entity\RestToken;
|
||||
use Shlinkio\Shlink\Core\Exception\InvalidArgumentException;
|
||||
use Shlinkio\Shlink\Rest\Exception\AuthenticationException;
|
||||
|
||||
class RestTokenService implements RestTokenServiceInterface
|
||||
|
@ -1,8 +1,8 @@
|
||||
<?php
|
||||
namespace Shlinkio\Shlink\Rest\Service;
|
||||
|
||||
use Shlinkio\Shlink\Common\Exception\InvalidArgumentException;
|
||||
use Shlinkio\Shlink\Core\Entity\RestToken;
|
||||
use Shlinkio\Shlink\Core\Exception\InvalidArgumentException;
|
||||
use Shlinkio\Shlink\Rest\Exception\AuthenticationException;
|
||||
|
||||
interface RestTokenServiceInterface
|
||||
|
@ -1,6 +1,7 @@
|
||||
<?php
|
||||
namespace Shlinkio\Shlink\Rest\Util;
|
||||
|
||||
use Shlinkio\Shlink\Common\Exception as Common;
|
||||
use Shlinkio\Shlink\Core\Exception as Core;
|
||||
use Shlinkio\Shlink\Rest\Exception as Rest;
|
||||
|
||||
@ -13,7 +14,7 @@ class RestUtils
|
||||
const INVALID_AUTH_TOKEN_ERROR = 'INVALID_AUTH_TOKEN_ERROR';
|
||||
const UNKNOWN_ERROR = 'UNKNOWN_ERROR';
|
||||
|
||||
public static function getRestErrorCodeFromException(Core\ExceptionInterface $e)
|
||||
public static function getRestErrorCodeFromException(Common\ExceptionInterface $e)
|
||||
{
|
||||
switch (true) {
|
||||
case $e instanceof Core\InvalidShortCodeException:
|
||||
|
Loading…
Reference in New Issue
Block a user