Fixed all possible PHPStan errors

This commit is contained in:
Alejandro Celaya 2017-12-27 16:23:54 +01:00
parent 4f3995ea80
commit db956a1f40
21 changed files with 67 additions and 68 deletions

View file

@ -71,14 +71,6 @@ class ResolveUrlCommand extends Command
try {
$longUrl = $this->urlShortener->shortCodeToUrl($shortCode);
if (! isset($longUrl)) {
$output->writeln(sprintf(
'<error>' . $this->translator->translate('No URL found for short code "%s"') . '</error>',
$shortCode
));
return;
}
$output->writeln(sprintf('%s <info>%s</info>', $this->translator->translate('Long URL:'), $longUrl));
} catch (InvalidShortCodeException $e) {
$output->writeln(sprintf('<error>' . $this->translator->translate(

View file

@ -5,7 +5,7 @@ namespace Shlinkio\Shlink\Common\Exception;
class WrongIpException extends RuntimeException
{
public static function fromIpAddress($ipAddress, \Exception $prev = null)
public static function fromIpAddress($ipAddress, \Throwable $prev = null)
{
return new self(sprintf('Provided IP "%s" is invalid', $ipAddress), 0, $prev);
}

View file

@ -22,15 +22,17 @@ class IpLocationResolver implements IpLocationResolverInterface
}
/**
* @param $ipAddress
* @param string $ipAddress
* @return array
* @throws WrongIpException
*/
public function resolveIpLocation($ipAddress)
public function resolveIpLocation(string $ipAddress): array
{
try {
$response = $this->httpClient->get(sprintf(self::SERVICE_PATTERN, $ipAddress));
return json_decode((string) $response->getBody(), true);
} catch (GuzzleException $e) {
/** @var \Throwable $e */
throw WrongIpException::fromIpAddress($ipAddress, $e);
}
}

View file

@ -3,11 +3,14 @@ declare(strict_types=1);
namespace Shlinkio\Shlink\Common\Service;
use Shlinkio\Shlink\Common\Exception\WrongIpException;
interface IpLocationResolverInterface
{
/**
* @param $ipAddress
* @param string $ipAddress
* @return array
* @throws WrongIpException
*/
public function resolveIpLocation($ipAddress);
public function resolveIpLocation(string $ipAddress): array;
}

View file

@ -6,11 +6,11 @@ namespace Shlinkio\Shlink\Common\Util;
class DateRange
{
/**
* @var \DateTimeInterface
* @var \DateTimeInterface|null
*/
private $startDate;
/**
* @var \DateTimeInterface
* @var \DateTimeInterface|null
*/
private $endDate;
@ -21,7 +21,7 @@ class DateRange
}
/**
* @return \DateTimeInterface
* @return \DateTimeInterface|null
*/
public function getStartDate()
{
@ -29,7 +29,7 @@ class DateRange
}
/**
* @return \DateTimeInterface
* @return \DateTimeInterface|null
*/
public function getEndDate()
{
@ -39,8 +39,8 @@ class DateRange
/**
* @return bool
*/
public function isEmpty()
public function isEmpty(): bool
{
return is_null($this->startDate) && is_null($this->endDate);
return $this->startDate === null && $this->endDate === null;
}
}

View file

@ -49,12 +49,6 @@ class RedirectAction implements MiddlewareInterface
try {
$longUrl = $this->urlShortener->shortCodeToUrl($shortCode);
// If provided shortCode does not belong to a valid long URL, dispatch next middleware, which will trigger
// a not-found error
if ($longUrl === null) {
return $delegate->process($request);
}
// Track visit to this short code
$this->visitTracker->track($shortCode, $request);

View file

@ -7,9 +7,9 @@ use Shlinkio\Shlink\Common\Exception\RuntimeException;
class InvalidUrlException extends RuntimeException
{
public static function fromUrl($url, \Exception $previous = null)
public static function fromUrl($url, \Throwable $previous = null)
{
$code = isset($previous) ? $previous->getCode() : -1;
return new static(sprintf('Provided URL "%s" is not an exisitng and valid URL', $url), $code, $previous);
return new static(sprintf('Provided URL "%s" is not an existing and valid URL', $url), $code, $previous);
}
}

View file

@ -49,9 +49,9 @@ class ShortUrlService implements ShortUrlServiceInterface
* @return ShortUrl
* @throws InvalidShortCodeException
*/
public function setTagsByShortCode($shortCode, array $tags = [])
public function setTagsByShortCode($shortCode, array $tags = []): ShortUrl
{
/** @var ShortUrl $shortUrl */
/** @var ShortUrl|null $shortUrl */
$shortUrl = $this->em->getRepository(ShortUrl::class)->findOneBy([
'shortCode' => $shortCode,
]);

View file

@ -24,5 +24,5 @@ interface ShortUrlServiceInterface
* @return ShortUrl
* @throws InvalidShortCodeException
*/
public function setTagsByShortCode($shortCode, array $tags = []);
public function setTagsByShortCode($shortCode, array $tags = []): ShortUrl;
}

View file

@ -4,6 +4,7 @@ declare(strict_types=1);
namespace Shlinkio\Shlink\Core\Service\Tag;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\EntityManager;
use Doctrine\ORM\EntityManagerInterface;
use Shlinkio\Shlink\Core\Entity\Tag;
use Shlinkio\Shlink\Core\Exception\EntityDoesNotExistException;
@ -15,7 +16,7 @@ class TagService implements TagServiceInterface
use TagManagerTrait;
/**
* @var EntityManagerInterface
* @var EntityManager|EntityManagerInterface
*/
private $em;

View file

@ -90,6 +90,7 @@ class UrlShortener implements UrlShortenerInterface
int $maxVisits = null
): string {
// If the url already exists in the database, just return its short code
/** @var ShortUrl|null $shortUrl */
$shortUrl = $this->em->getRepository(ShortUrl::class)->findOneBy([
'originalUrl' => $url,
]);
@ -148,6 +149,7 @@ class UrlShortener implements UrlShortenerInterface
'max' => 15,
]]);
} catch (GuzzleException $e) {
/** @var \Throwable $e */
throw InvalidUrlException::fromUrl($url, $e);
}
}
@ -155,13 +157,13 @@ class UrlShortener implements UrlShortenerInterface
/**
* Generates the unique shortcode for an autoincrement ID
*
* @param int $id
* @param float $id
* @return string
*/
private function convertAutoincrementIdToShortCode($id): string
private function convertAutoincrementIdToShortCode(float $id): string
{
$id = ((int) $id) + 200000; // Increment the Id so that the generated shortcode is not too short
$length = strlen($this->chars);
$id += 200000; // Increment the Id so that the generated shortcode is not too short
$length = \strlen($this->chars);
$code = '';
while ($id > 0) {

View file

@ -15,7 +15,7 @@ use Shlinkio\Shlink\Core\Repository\VisitRepository;
class VisitsTracker implements VisitsTrackerInterface
{
/**
* @var EntityManagerInterface|EntityManager
* @var EntityManager|EntityManagerInterface
*/
private $em;
@ -66,14 +66,14 @@ class VisitsTracker implements VisitsTrackerInterface
/**
* Returns the visits on certain short code
*
* @param $shortCode
* @param string $shortCode
* @param DateRange $dateRange
* @return Visit[]
* @throws InvalidArgumentException
*/
public function info($shortCode, DateRange $dateRange = null): array
public function info(string $shortCode, DateRange $dateRange = null): array
{
/** @var ShortUrl $shortUrl */
/** @var ShortUrl|null $shortUrl */
$shortUrl = $this->em->getRepository(ShortUrl::class)->findOneBy([
'shortCode' => $shortCode,
]);

View file

@ -21,10 +21,10 @@ interface VisitsTrackerInterface
/**
* Returns the visits on certain short code
*
* @param $shortCode
* @param string $shortCode
* @param DateRange $dateRange
* @return Visit[]
* @throws InvalidArgumentException
*/
public function info($shortCode, DateRange $dateRange = null): array;
public function info(string $shortCode, DateRange $dateRange = null): array;
}

View file

@ -50,7 +50,7 @@ class CreateShortcodeAction extends AbstractRestAction
*/
public function process(Request $request, DelegateInterface $delegate)
{
$postData = $request->getParsedBody();
$postData = (array) $request->getParsedBody();
if (! isset($postData['longUrl'])) {
return new JsonResponse([
'error' => RestUtils::INVALID_ARGUMENT_ERROR,

View file

@ -75,10 +75,10 @@ class GetVisitsAction extends AbstractRestAction
/**
* @param Request $request
* @param $key
* @param string $key
* @return \DateTime|null
*/
protected function getDateQueryParam(Request $request, $key)
private function getDateQueryParam(Request $request, string $key)
{
$query = $request->getQueryParams();
if (! isset($query[$key]) || empty($query[$key])) {

View file

@ -27,7 +27,7 @@ class JWTService implements JWTServiceInterface
* @param int $lifetime
* @return string
*/
public function create(ApiKey $apiKey, $lifetime = self::DEFAULT_LIFETIME)
public function create(ApiKey $apiKey, $lifetime = self::DEFAULT_LIFETIME): string
{
$currentTimestamp = time();
@ -48,7 +48,7 @@ class JWTService implements JWTServiceInterface
* @return string
* @throws AuthenticationException If the token has expired
*/
public function refresh($jwt, $lifetime = self::DEFAULT_LIFETIME)
public function refresh(string $jwt, $lifetime = self::DEFAULT_LIFETIME): string
{
$payload = $this->getPayload($jwt);
$payload['exp'] = time() + $lifetime;
@ -61,7 +61,7 @@ class JWTService implements JWTServiceInterface
* @param string $jwt
* @return bool
*/
public function verify($jwt)
public function verify(string $jwt): bool
{
try {
// If no exception is thrown while decoding the token, it is considered valid
@ -79,7 +79,7 @@ class JWTService implements JWTServiceInterface
* @return array
* @throws AuthenticationException If the token has expired
*/
public function getPayload($jwt)
public function getPayload(string $jwt): array
{
try {
return $this->decode($jwt);
@ -92,16 +92,16 @@ class JWTService implements JWTServiceInterface
* @param array $data
* @return string
*/
protected function encode(array $data)
protected function encode(array $data): string
{
return JWT::encode($data, $this->appOptions->getSecretKey(), self::DEFAULT_ENCRYPTION_ALG);
}
/**
* @param $jwt
* @param string $jwt
* @return array
*/
protected function decode($jwt)
protected function decode(string $jwt): array
{
return (array) JWT::decode($jwt, $this->appOptions->getSecretKey(), [self::DEFAULT_ENCRYPTION_ALG]);
}

View file

@ -18,7 +18,7 @@ interface JWTServiceInterface
* @param int $lifetime
* @return string
*/
public function create(ApiKey $apiKey, $lifetime = self::DEFAULT_LIFETIME);
public function create(ApiKey $apiKey, $lifetime = self::DEFAULT_LIFETIME): string;
/**
* Refreshes a token and returns it with the new expiration
@ -28,7 +28,7 @@ interface JWTServiceInterface
* @return string
* @throws AuthenticationException If the token has expired
*/
public function refresh($jwt, $lifetime = self::DEFAULT_LIFETIME);
public function refresh(string $jwt, $lifetime = self::DEFAULT_LIFETIME): string;
/**
* Verifies that certain JWT is valid
@ -36,7 +36,7 @@ interface JWTServiceInterface
* @param string $jwt
* @return bool
*/
public function verify($jwt);
public function verify(string $jwt): bool;
/**
* Decodes certain token and returns the payload
@ -45,5 +45,5 @@ interface JWTServiceInterface
* @return array
* @throws AuthenticationException If the token has expired
*/
public function getPayload($jwt);
public function getPayload(string $jwt): array;
}

View file

@ -55,13 +55,14 @@ class CheckAuthenticationMiddleware implements MiddlewareInterface, StatusCodeIn
*
* @return Response
* @throws \InvalidArgumentException
* @throws \ErrorException
*/
public function process(Request $request, DelegateInterface $delegate)
{
// If current route is the authenticate route or an OPTIONS request, continue to the next middleware
/** @var RouteResult $routeResult */
/** @var RouteResult|null $routeResult */
$routeResult = $request->getAttribute(RouteResult::class);
if (! isset($routeResult)
if ($routeResult === null
|| $routeResult->isFailure()
|| $routeResult->getMatchedRouteName() === AuthenticateAction::class
|| $request->getMethod() === 'OPTIONS'

View file

@ -46,13 +46,9 @@ class ApiKeyService implements ApiKeyServiceInterface
*/
public function check($key)
{
/** @var ApiKey $apiKey */
/** @var ApiKey|null $apiKey */
$apiKey = $this->getByKey($key);
if (! isset($apiKey)) {
return false;
}
return $apiKey->isValid();
return $apiKey !== null && $apiKey->isValid();
}
/**
@ -60,12 +56,13 @@ class ApiKeyService implements ApiKeyServiceInterface
*
* @param string $key
* @return ApiKey
* @throws InvalidArgumentException
*/
public function disable($key)
{
/** @var ApiKey $apiKey */
/** @var ApiKey|null $apiKey */
$apiKey = $this->getByKey($key);
if (! isset($apiKey)) {
if ($apiKey === null) {
throw new InvalidArgumentException(sprintf('API key "%s" does not exist and can\'t be disabled', $key));
}
@ -75,7 +72,7 @@ class ApiKeyService implements ApiKeyServiceInterface
}
/**
* Lists all existing appi keys
* Lists all existing api keys
*
* @param bool $enabledOnly Tells if only enabled keys should be returned
* @return ApiKey[]
@ -94,8 +91,10 @@ class ApiKeyService implements ApiKeyServiceInterface
*/
public function getByKey($key)
{
return $this->em->getRepository(ApiKey::class)->findOneBy([
/** @var ApiKey|null $apiKey */
$apiKey = $this->em->getRepository(ApiKey::class)->findOneBy([
'key' => $key,
]);
return $apiKey;
}
}

View file

@ -3,6 +3,7 @@ declare(strict_types=1);
namespace Shlinkio\Shlink\Rest\Service;
use Shlinkio\Shlink\Common\Exception\InvalidArgumentException;
use Shlinkio\Shlink\Rest\Entity\ApiKey;
interface ApiKeyServiceInterface
@ -28,11 +29,12 @@ interface ApiKeyServiceInterface
*
* @param string $key
* @return ApiKey
* @throws InvalidArgumentException
*/
public function disable($key);
/**
* Lists all existing appi keys
* Lists all existing api keys
*
* @param bool $enabledOnly Tells if only enabled keys should be returned
* @return ApiKey[]

View file

@ -4,6 +4,7 @@ declare(strict_types=1);
namespace ShlinkioTest\Shlink\Rest\Action;
use PHPUnit\Framework\TestCase;
use Prophecy\Argument;
use Prophecy\Prophecy\ObjectProphecy;
use Shlinkio\Shlink\Rest\Action\AuthenticateAction;
use Shlinkio\Shlink\Rest\Authentication\JWTService;
@ -32,6 +33,8 @@ class AuthenticateActionTest extends TestCase
{
$this->apiKeyService = $this->prophesize(ApiKeyService::class);
$this->jwtService = $this->prophesize(JWTService::class);
$this->jwtService->create(Argument::cetera())->willReturn('');
$this->action = new AuthenticateAction(
$this->apiKeyService->reveal(),
$this->jwtService->reveal(),