diff --git a/config/autoload/routes.global.php b/config/autoload/routes.global.php index 680a195d..b2976df5 100644 --- a/config/autoload/routes.global.php +++ b/config/autoload/routes.global.php @@ -25,6 +25,12 @@ return [ 'middleware' => Rest\ResolveUrlMiddleware::class, 'allowed_methods' => ['GET'], ], + [ + 'name' => 'rest-list-shortened-url', + 'path' => '/rest/short-codes', + 'middleware' => Rest\ListShortcodesMiddleware::class, + 'allowed_methods' => ['GET'], + ], [ 'name' => 'rest-get-visits', 'path' => '/rest/visits/{shortCode}', diff --git a/config/autoload/services.global.php b/config/autoload/services.global.php index 8dada5e8..92a4adce 100644 --- a/config/autoload/services.global.php +++ b/config/autoload/services.global.php @@ -37,6 +37,7 @@ return [ GuzzleHttp\Client::class => InvokableFactory::class, Service\UrlShortener::class => AnnotatedFactory::class, Service\VisitsTracker::class => AnnotatedFactory::class, + Service\ShortUrlService::class => AnnotatedFactory::class, Cache::class => CacheFactory::class, // Cli commands @@ -47,6 +48,7 @@ return [ Middleware\Rest\CreateShortcodeMiddleware::class => AnnotatedFactory::class, Middleware\Rest\ResolveUrlMiddleware::class => AnnotatedFactory::class, Middleware\Rest\GetVisitsMiddleware::class => AnnotatedFactory::class, + Middleware\Rest\ListShortcodesMiddleware::class => AnnotatedFactory::class, ], 'aliases' => [ 'em' => EntityManager::class, diff --git a/src/Entity/ShortUrl.php b/src/Entity/ShortUrl.php index d1d5c4f7..fe96d651 100644 --- a/src/Entity/ShortUrl.php +++ b/src/Entity/ShortUrl.php @@ -13,7 +13,7 @@ use Doctrine\ORM\Mapping as ORM; * @ORM\Entity * @ORM\Table(name="short_urls") */ -class ShortUrl extends AbstractEntity +class ShortUrl extends AbstractEntity implements \JsonSerializable { /** * @var string @@ -117,4 +117,21 @@ class ShortUrl extends AbstractEntity $this->visits = $visits; return $this; } + + /** + * 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 json_encode, + * which is a value of any type other than a resource. + * @since 5.4.0 + */ + public function jsonSerialize() + { + return [ + 'shortCode' => $this->shortCode, + 'originalUrl' => $this->originalUrl, + 'dateCreated' => isset($this->dateCreated) ? $this->dateCreated->format(\DateTime::ISO8601) : null, + 'visitsCount' => count($this->visits), + ]; + } } diff --git a/src/Middleware/Rest/ListShortcodesMiddleware.php b/src/Middleware/Rest/ListShortcodesMiddleware.php new file mode 100644 index 00000000..d437b742 --- /dev/null +++ b/src/Middleware/Rest/ListShortcodesMiddleware.php @@ -0,0 +1,74 @@ +shortUrlService = $shortUrlService; + } + + /** + * Process an incoming request and/or response. + * + * Accepts a server-side request and a response instance, and does + * something with them. + * + * If the response is not complete and/or further processing would not + * interfere with the work done in the middleware, or if the middleware + * wants to delegate to another process, it can use the `$out` callable + * if present. + * + * If the middleware does not return a value, execution of the current + * request is considered complete, and the response instance provided will + * be considered the response to return. + * + * Alternately, the middleware may return a response instance. + * + * Often, middleware will `return $out();`, with the assumption that a + * later middleware will return a response. + * + * @param Request $request + * @param Response $response + * @param null|callable $out + * @return null|Response + */ + public function __invoke(Request $request, Response $response, callable $out = null) + { + try { + $shortUrls = $this->shortUrlService->listShortUrls(); + + return new JsonResponse([ + 'shortUrls' => [ + 'data' => $shortUrls, +// 'pagination' => [], + ] + ]); + } catch (\Exception $e) { + return new JsonResponse([ + 'error' => RestUtils::UNKNOWN_ERROR, + 'message' => 'Unexpected error occured', + ], 500); + } + } +} diff --git a/src/Service/ShortUrlService.php b/src/Service/ShortUrlService.php new file mode 100644 index 00000000..f6dc57fa --- /dev/null +++ b/src/Service/ShortUrlService.php @@ -0,0 +1,33 @@ +em = $em; + } + + /** + * @return ShortUrl[] + */ + public function listShortUrls() + { + return $this->em->getRepository(ShortUrl::class)->findAll(); + } +} diff --git a/src/Service/ShortUrlServiceInterface.php b/src/Service/ShortUrlServiceInterface.php new file mode 100644 index 00000000..5a943ba0 --- /dev/null +++ b/src/Service/ShortUrlServiceInterface.php @@ -0,0 +1,12 @@ +em = $this->prophesize(EntityManagerInterface::class); + $this->service = new ShortUrlService($this->em->reveal()); + } + + /** + * @test + */ + public function listedUrlsAreReturnedFromEntityManager() + { + $repo = $this->prophesize(EntityRepository::class); + $repo->findAll()->willReturn([ + new ShortUrl(), + new ShortUrl(), + new ShortUrl(), + new ShortUrl(), + ])->shouldBeCalledTimes(1); + $this->em->getRepository(ShortUrl::class)->willReturn($repo->reveal()); + + $list = $this->service->listShortUrls(); + $this->assertCount(4, $list); + } +}