Merge branch 'feature/11' into develop

This commit is contained in:
Alejandro Celaya 2016-07-19 18:34:02 +02:00
commit 0daa24739d
76 changed files with 506 additions and 252 deletions

View File

@ -1,7 +1,8 @@
{ {
"name": "acelaya/url-shortener", "name": "shlinkio/shlink",
"type": "project", "type": "project",
"homepage": "https://github.com/acelaya/url-shortener", "homepage": "http://shlink.io",
"description": "A PHP-based URL shortener application with analytics and management",
"license": "MIT", "license": "MIT",
"authors": [ "authors": [
{ {
@ -19,6 +20,8 @@
"zendframework/zend-stdlib": "^2.7", "zendframework/zend-stdlib": "^2.7",
"zendframework/zend-servicemanager": "^3.0", "zendframework/zend-servicemanager": "^3.0",
"zendframework/zend-paginator": "^2.6", "zendframework/zend-paginator": "^2.6",
"zendframework/zend-config": "^2.6",
"mtymek/expressive-config-manager": "^0.4",
"doctrine/orm": "^2.5", "doctrine/orm": "^2.5",
"guzzlehttp/guzzle": "^6.2", "guzzlehttp/guzzle": "^6.2",
"acelaya/zsm-annotated-services": "^0.2.0", "acelaya/zsm-annotated-services": "^0.2.0",
@ -34,12 +37,18 @@
}, },
"autoload": { "autoload": {
"psr-4": { "psr-4": {
"Acelaya\\UrlShortener\\": "src" "Shlinkio\\Shlink\\CLI\\": "module/CLI/src",
"Shlinkio\\Shlink\\Rest\\": "module/Rest/src",
"Shlinkio\\Shlink\\Core\\": "module/Core/src",
"Shlinkio\\Shlink\\Common\\": "module/Common/src"
} }
}, },
"autoload-dev": { "autoload-dev": {
"psr-4": { "psr-4": {
"AcelayaTest\\UrlShortener\\": "tests" "ShlinkioTest\\Shlink\\CLI\\": "module/CLI/test",
"ShlinkioTest\\Shlink\\Rest\\": "module/Rest/test",
"ShlinkioTest\\Shlink\\Core\\": "module/Core/test",
"ShlinkioTest\\Shlink\\Common\\": "module/Common/test"
} }
}, },
"scripts": { "scripts": {

View File

@ -1,5 +1,4 @@
<?php <?php
use Acelaya\UrlShortener\Middleware;
use Zend\Expressive\Container\ApplicationFactory; use Zend\Expressive\Container\ApplicationFactory;
use Zend\Expressive\Helper; use Zend\Expressive\Helper;
@ -20,15 +19,6 @@ return [
'priority' => 10, 'priority' => 10,
], ],
'rest' => [
'path' => '/rest',
'middleware' => [
Middleware\CheckAuthenticationMiddleware::class,
Middleware\CrossDomainMiddleware::class,
],
'priority' => 5,
],
'post-routing' => [ 'post-routing' => [
'middleware' => [ 'middleware' => [
Helper\UrlHelperMiddleware::class, Helper\UrlHelperMiddleware::class,

View File

@ -1,13 +1,4 @@
<?php <?php
use Acelaya\UrlShortener\CLI;
use Acelaya\UrlShortener\Factory\CacheFactory;
use Acelaya\UrlShortener\Factory\EntityManagerFactory;
use Acelaya\UrlShortener\Middleware;
use Acelaya\UrlShortener\Service;
use Acelaya\ZsmAnnotatedServices\Factory\V3\AnnotatedFactory;
use Doctrine\Common\Cache\Cache;
use Doctrine\ORM\EntityManager;
use Symfony\Component\Console;
use Zend\Expressive; use Zend\Expressive;
use Zend\Expressive\Container; use Zend\Expressive\Container;
use Zend\Expressive\Helper; use Zend\Expressive\Helper;
@ -21,7 +12,6 @@ return [
'services' => [ 'services' => [
'factories' => [ 'factories' => [
Expressive\Application::class => Container\ApplicationFactory::class, Expressive\Application::class => Container\ApplicationFactory::class,
Console\Application::class => CLI\Factory\ApplicationFactory::class,
// Url helpers // Url helpers
Helper\UrlHelper::class => Helper\UrlHelperFactory::class, Helper\UrlHelper::class => Helper\UrlHelperFactory::class,
@ -33,38 +23,10 @@ return [
// View // View
'Zend\Expressive\FinalHandler' => Container\TemplatedErrorHandlerFactory::class, 'Zend\Expressive\FinalHandler' => Container\TemplatedErrorHandlerFactory::class,
Template\TemplateRendererInterface::class => Twig\TwigRendererFactory::class, Template\TemplateRendererInterface::class => Twig\TwigRendererFactory::class,
// Services
EntityManager::class => EntityManagerFactory::class,
GuzzleHttp\Client::class => InvokableFactory::class,
Service\UrlShortener::class => AnnotatedFactory::class,
Service\VisitsTracker::class => AnnotatedFactory::class,
Service\ShortUrlService::class => AnnotatedFactory::class,
Service\RestTokenService::class => AnnotatedFactory::class,
Cache::class => CacheFactory::class,
// Cli commands
CLI\Command\GenerateShortcodeCommand::class => AnnotatedFactory::class,
CLI\Command\ResolveUrlCommand::class => AnnotatedFactory::class,
CLI\Command\ListShortcodesCommand::class => AnnotatedFactory::class,
CLI\Command\GetVisitsCommand::class => AnnotatedFactory::class,
// Middleware
Middleware\Routable\RedirectMiddleware::class => AnnotatedFactory::class,
Middleware\Rest\AuthenticateMiddleware::class => AnnotatedFactory::class,
Middleware\Rest\CreateShortcodeMiddleware::class => AnnotatedFactory::class,
Middleware\Rest\ResolveUrlMiddleware::class => AnnotatedFactory::class,
Middleware\Rest\GetVisitsMiddleware::class => AnnotatedFactory::class,
Middleware\Rest\ListShortcodesMiddleware::class => AnnotatedFactory::class,
Middleware\CrossDomainMiddleware::class => InvokableFactory::class,
Middleware\CheckAuthenticationMiddleware::class => AnnotatedFactory::class,
], ],
'aliases' => [ 'aliases' => [
'em' => EntityManager::class,
'httpClient' => GuzzleHttp\Client::class,
Router\RouterInterface::class => Router\FastRouteRouter::class, Router\RouterInterface::class => Router\FastRouteRouter::class,
AnnotatedFactory::CACHE_SERVICE => Cache::class, ],
]
], ],
]; ];

View File

@ -2,12 +2,6 @@
return [ return [
'templates' => [
'paths' => [
'templates'
],
],
'twig' => [ 'twig' => [
'cache_dir' => 'data/cache/twig', 'cache_dir' => 'data/cache/twig',
'extensions' => [ 'extensions' => [

View File

@ -1,14 +1,8 @@
<?php <?php
return [ return [
'debug' => false, 'debug' => false,
'config_cache_enabled' => true,
'config_cache_enabled' => false,
'zend-expressive' => [
'error_handler' => [
'template_404' => 'error/404.html.twig',
'template_error' => 'error/error.html.twig',
],
],
]; ];

View File

@ -4,7 +4,7 @@ use Doctrine\ORM\Tools\Console\ConsoleRunner;
use Interop\Container\ContainerInterface; use Interop\Container\ContainerInterface;
/** @var ContainerInterface $container */ /** @var ContainerInterface $container */
$container = include __DIR__ . '/config/container.php'; $container = include __DIR__ . '/container.php';
/** @var EntityManager $em */ /** @var EntityManager $em */
$em = $container->get(EntityManager::class); $em = $container->get(EntityManager::class);

View File

@ -1,6 +1,10 @@
<?php <?php
use Zend\Stdlib\ArrayUtils; use Shlinkio\Shlink\CLI;
use Zend\Stdlib\Glob; use Shlinkio\Shlink\Common;
use Shlinkio\Shlink\Core;
use Shlinkio\Shlink\Rest;
use Zend\Expressive\ConfigManager\ConfigManager;
use Zend\Expressive\ConfigManager\ZendConfigProvider;
/** /**
* Configuration files are loaded in a specific order. First ``global.php``, then ``*.global.php``. * Configuration files are loaded in a specific order. First ``global.php``, then ``*.global.php``.
@ -11,22 +15,14 @@ use Zend\Stdlib\Glob;
* Obviously, if you use closures in your config you can't cache it. * Obviously, if you use closures in your config you can't cache it.
*/ */
$cachedConfigFile = 'data/cache/app_config.php'; return call_user_func(function () {
$configManager = new ConfigManager([
new ZendConfigProvider('config/autoload/{{,*.}global,{,*.}local}.php'),
Common\ConfigProvider::class,
Core\ConfigProvider::class,
CLI\ConfigProvider::class,
Rest\ConfigProvider::class,
], 'data/cache/app_config.php');
$config = []; return $configManager->getMergedConfig();
if (is_file($cachedConfigFile)) { });
// Try to load the cached config
$config = include $cachedConfigFile;
} else {
// Load configuration from autoload path
foreach (Glob::glob('config/autoload/{{,*.}global,{,*.}local}.php', Glob::GLOB_BRACE) as $file) {
$config = ArrayUtils::merge($config, include $file);
}
// Cache config if enabled
if (isset($config['config_cache_enabled']) && $config['config_cache_enabled'] === true) {
file_put_contents($cachedConfigFile, '<?php return ' . var_export($config, true) . ';');
}
}
return $config;

View File

@ -1,5 +1,5 @@
<?php <?php
use Acelaya\UrlShortener\CLI\Command; use Shlinkio\Shlink\CLI\Command;
return [ return [

View File

@ -0,0 +1,19 @@
<?php
use Acelaya\ZsmAnnotatedServices\Factory\V3\AnnotatedFactory;
use Shlinkio\Shlink\CLI;
use Symfony\Component\Console;
return [
'services' => [
'factories' => [
Console\Application::class => CLI\Factory\ApplicationFactory::class,
CLI\Command\GenerateShortcodeCommand::class => AnnotatedFactory::class,
CLI\Command\ResolveUrlCommand::class => AnnotatedFactory::class,
CLI\Command\ListShortcodesCommand::class => AnnotatedFactory::class,
CLI\Command\GetVisitsCommand::class => AnnotatedFactory::class,
],
],
];

View File

@ -1,16 +1,15 @@
<?php <?php
namespace Acelaya\UrlShortener\CLI\Command; namespace Shlinkio\Shlink\CLI\Command;
use Acelaya\UrlShortener\Exception\InvalidUrlException;
use Acelaya\UrlShortener\Service\UrlShortener;
use Acelaya\UrlShortener\Service\UrlShortenerInterface;
use Acelaya\ZsmAnnotatedServices\Annotation\Inject; use Acelaya\ZsmAnnotatedServices\Annotation\Inject;
use Shlinkio\Shlink\Core\Exception\InvalidUrlException;
use Shlinkio\Shlink\Core\Service\UrlShortener;
use Shlinkio\Shlink\Core\Service\UrlShortenerInterface;
use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Helper\QuestionHelper; use Symfony\Component\Console\Helper\QuestionHelper;
use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface; use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Question\ChoiceQuestion;
use Symfony\Component\Console\Question\Question; use Symfony\Component\Console\Question\Question;
use Zend\Diactoros\Uri; use Zend\Diactoros\Uri;

View File

@ -1,9 +1,9 @@
<?php <?php
namespace Acelaya\UrlShortener\CLI\Command; namespace Shlinkio\Shlink\CLI\Command;
use Acelaya\UrlShortener\Service\VisitsTracker;
use Acelaya\UrlShortener\Service\VisitsTrackerInterface;
use Acelaya\ZsmAnnotatedServices\Annotation\Inject; use Acelaya\ZsmAnnotatedServices\Annotation\Inject;
use Shlinkio\Shlink\Core\Service\VisitsTracker;
use Shlinkio\Shlink\Core\Service\VisitsTrackerInterface;
use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Helper\QuestionHelper; use Symfony\Component\Console\Helper\QuestionHelper;
use Symfony\Component\Console\Helper\Table; use Symfony\Component\Console\Helper\Table;

View File

@ -1,11 +1,11 @@
<?php <?php
namespace Acelaya\UrlShortener\CLI\Command; namespace Shlinkio\Shlink\CLI\Command;
use Acelaya\UrlShortener\Paginator\Adapter\PaginableRepositoryAdapter;
use Acelaya\UrlShortener\Paginator\Util\PaginatorUtilsTrait;
use Acelaya\UrlShortener\Service\ShortUrlService;
use Acelaya\UrlShortener\Service\ShortUrlServiceInterface;
use Acelaya\ZsmAnnotatedServices\Annotation\Inject; use Acelaya\ZsmAnnotatedServices\Annotation\Inject;
use Shlinkio\Shlink\Common\Paginator\Adapter\PaginableRepositoryAdapter;
use Shlinkio\Shlink\Common\Paginator\Util\PaginatorUtilsTrait;
use Shlinkio\Shlink\Core\Service\ShortUrlService;
use Shlinkio\Shlink\Core\Service\ShortUrlServiceInterface;
use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Helper\QuestionHelper; use Symfony\Component\Console\Helper\QuestionHelper;
use Symfony\Component\Console\Helper\Table; use Symfony\Component\Console\Helper\Table;

View File

@ -1,10 +1,10 @@
<?php <?php
namespace Acelaya\UrlShortener\CLI\Command; namespace Shlinkio\Shlink\CLI\Command;
use Acelaya\UrlShortener\Exception\InvalidShortCodeException;
use Acelaya\UrlShortener\Service\UrlShortener;
use Acelaya\UrlShortener\Service\UrlShortenerInterface;
use Acelaya\ZsmAnnotatedServices\Annotation\Inject; use Acelaya\ZsmAnnotatedServices\Annotation\Inject;
use Shlinkio\Shlink\Core\Exception\InvalidShortCodeException;
use Shlinkio\Shlink\Core\Service\UrlShortener;
use Shlinkio\Shlink\Core\Service\UrlShortenerInterface;
use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Helper\QuestionHelper; use Symfony\Component\Console\Helper\QuestionHelper;
use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputArgument;

View File

@ -0,0 +1,13 @@
<?php
namespace Shlinkio\Shlink\CLI;
use Zend\Config\Factory;
use Zend\Stdlib\Glob;
class ConfigProvider
{
public function __invoke()
{
return Factory::fromFiles(Glob::glob(__DIR__ . '/../config/{,*.}config.php', Glob::GLOB_BRACE));
}
}

View File

@ -1,5 +1,5 @@
<?php <?php
namespace Acelaya\UrlShortener\CLI\Factory; namespace Shlinkio\Shlink\CLI\Factory;
use Interop\Container\ContainerInterface; use Interop\Container\ContainerInterface;
use Interop\Container\Exception\ContainerException; use Interop\Container\Exception\ContainerException;

View File

@ -0,0 +1,60 @@
<?php
namespace ShlinkioTest\Shlink\CLI\Factory;
use PHPUnit_Framework_TestCase as TestCase;
use Shlinkio\Shlink\CLI\Factory\ApplicationFactory;
use Symfony\Component\Console\Application;
use Symfony\Component\Console\Command\Command;
use Zend\ServiceManager\ServiceManager;
class ApplicationFactoryTest extends TestCase
{
/**
* @var ApplicationFactory
*/
protected $factory;
public function setUp()
{
$this->factory = new ApplicationFactory();
}
/**
* @test
*/
public function serviceIsCreated()
{
$instance = $this->factory->__invoke($this->createServiceManager(), '');
$this->assertInstanceOf(Application::class, $instance);
}
/**
* @test
*/
public function allCommandsWhichAreServicesAreAdded()
{
$sm = $this->createServiceManager([
'commands' => [
'foo',
'bar',
'baz',
],
]);
$sm->setService('foo', $this->prophesize(Command::class)->reveal());
$sm->setService('baz', $this->prophesize(Command::class)->reveal());
/** @var Application $instance */
$instance = $this->factory->__invoke($sm, '');
$this->assertInstanceOf(Application::class, $instance);
$this->assertCount(2, $instance->all());
}
protected function createServiceManager($config = [])
{
return new ServiceManager(['services' => [
'config' => [
'cli' => $config,
],
]]);
}
}

View File

@ -0,0 +1,24 @@
<?php
use Acelaya\ZsmAnnotatedServices\Factory\V3\AnnotatedFactory;
use Doctrine\Common\Cache\Cache;
use Doctrine\ORM\EntityManager;
use Shlinkio\Shlink\Common\Factory\CacheFactory;
use Shlinkio\Shlink\Common\Factory\EntityManagerFactory;
use Zend\ServiceManager\Factory\InvokableFactory;
return [
'services' => [
'factories' => [
EntityManager::class => EntityManagerFactory::class,
GuzzleHttp\Client::class => InvokableFactory::class,
Cache::class => CacheFactory::class,
],
'aliases' => [
'em' => EntityManager::class,
'httpClient' => GuzzleHttp\Client::class,
AnnotatedFactory::CACHE_SERVICE => Cache::class,
],
],
];

View File

@ -0,0 +1,13 @@
<?php
namespace Shlinkio\Shlink\Common;
use Zend\Config\Factory;
use Zend\Stdlib\Glob;
class ConfigProvider
{
public function __invoke()
{
return Factory::fromFiles(Glob::glob(__DIR__ . '/../config/{,*.}config.php', Glob::GLOB_BRACE));
}
}

View File

@ -1,5 +1,5 @@
<?php <?php
namespace Acelaya\UrlShortener\Entity; namespace Shlinkio\Shlink\Common\Entity;
use Doctrine\ORM\Mapping as ORM; use Doctrine\ORM\Mapping as ORM;

View File

@ -1,5 +1,5 @@
<?php <?php
namespace Acelaya\UrlShortener\Factory; namespace Shlinkio\Shlink\Common\Factory;
use Doctrine\Common\Cache\ApcuCache; use Doctrine\Common\Cache\ApcuCache;
use Doctrine\Common\Cache\ArrayCache; use Doctrine\Common\Cache\ArrayCache;

View File

@ -1,5 +1,5 @@
<?php <?php
namespace Acelaya\UrlShortener\Factory; namespace Shlinkio\Shlink\Common\Factory;
use Doctrine\Common\Cache\ArrayCache; use Doctrine\Common\Cache\ArrayCache;
use Doctrine\Common\Cache\Cache; use Doctrine\Common\Cache\Cache;
@ -33,7 +33,7 @@ class EntityManagerFactory implements FactoryInterface
$dbConfig = isset($globalConfig['database']) ? $globalConfig['database'] : []; $dbConfig = isset($globalConfig['database']) ? $globalConfig['database'] : [];
return EntityManager::create($dbConfig, Setup::createAnnotationMetadataConfiguration( return EntityManager::create($dbConfig, Setup::createAnnotationMetadataConfiguration(
['src/Entity'], ['module/Core/src/Entity'],
$isDevMode, $isDevMode,
'data/proxies', 'data/proxies',
$cache, $cache,

View File

@ -1,7 +1,7 @@
<?php <?php
namespace Acelaya\UrlShortener\Paginator\Adapter; namespace Shlinkio\Shlink\Common\Paginator\Adapter;
use Acelaya\UrlShortener\Repository\PaginableRepositoryInterface; use Shlinkio\Shlink\Common\Repository\PaginableRepositoryInterface;
use Zend\Paginator\Adapter\AdapterInterface; use Zend\Paginator\Adapter\AdapterInterface;
class PaginableRepositoryAdapter implements AdapterInterface class PaginableRepositoryAdapter implements AdapterInterface

View File

@ -1,5 +1,5 @@
<?php <?php
namespace Acelaya\UrlShortener\Paginator\Util; namespace Shlinkio\Shlink\Common\Paginator\Util;
use Zend\Paginator\Paginator; use Zend\Paginator\Paginator;
use Zend\Stdlib\ArrayUtils; use Zend\Stdlib\ArrayUtils;

View File

@ -1,5 +1,5 @@
<?php <?php
namespace Acelaya\UrlShortener\Repository; namespace Shlinkio\Shlink\Common\Repository;
interface PaginableRepositoryInterface interface PaginableRepositoryInterface
{ {

View File

@ -1,5 +1,5 @@
<?php <?php
namespace Acelaya\UrlShortener\Util; namespace Shlinkio\Shlink\Common\Util;
trait StringUtilsTrait trait StringUtilsTrait
{ {

View File

@ -1,10 +1,10 @@
<?php <?php
namespace AcelayaTest\UrlShortener\Factory; namespace ShlinkioTest\Shlink\Common\Factory;
use Acelaya\UrlShortener\Factory\CacheFactory;
use Doctrine\Common\Cache\ApcuCache; use Doctrine\Common\Cache\ApcuCache;
use Doctrine\Common\Cache\ArrayCache; use Doctrine\Common\Cache\ArrayCache;
use PHPUnit_Framework_TestCase as TestCase; use PHPUnit_Framework_TestCase as TestCase;
use Shlinkio\Shlink\Common\Factory\CacheFactory;
use Zend\ServiceManager\ServiceManager; use Zend\ServiceManager\ServiceManager;
class CacheFactoryTest extends TestCase class CacheFactoryTest extends TestCase

View File

@ -1,9 +1,9 @@
<?php <?php
namespace AcelayaTest\UrlShortener\Factory; namespace ShlinkioTest\Shlink\Common\Factory;
use Acelaya\UrlShortener\Factory\EntityManagerFactory;
use Doctrine\ORM\EntityManager; use Doctrine\ORM\EntityManager;
use PHPUnit_Framework_TestCase as TestCase; use PHPUnit_Framework_TestCase as TestCase;
use Shlinkio\Shlink\Common\Factory\EntityManagerFactory;
use Zend\ServiceManager\ServiceManager; use Zend\ServiceManager\ServiceManager;
class EntityManagerFactoryTest extends TestCase class EntityManagerFactoryTest extends TestCase

View File

@ -0,0 +1,15 @@
<?php
use Shlinkio\Shlink\Core\Action\RedirectMiddleware;
return [
'routes' => [
[
'name' => 'long-url-redirect',
'path' => '/{shortCode}',
'middleware' => RedirectMiddleware::class,
'allowed_methods' => ['GET'],
],
],
];

View File

@ -0,0 +1,20 @@
<?php
use Acelaya\ZsmAnnotatedServices\Factory\V3\AnnotatedFactory;
use Shlinkio\Shlink\Core\Action\RedirectMiddleware;
use Shlinkio\Shlink\Core\Service;
return [
'services' => [
'factories' => [
// Services
Service\UrlShortener::class => AnnotatedFactory::class,
Service\VisitsTracker::class => AnnotatedFactory::class,
Service\ShortUrlService::class => AnnotatedFactory::class,
// Middleware
RedirectMiddleware::class => AnnotatedFactory::class,
],
],
];

View File

@ -0,0 +1,11 @@
<?php
return [
'templates' => [
'paths' => [
'module/Core/templates',
],
],
];

View File

@ -0,0 +1,12 @@
<?php
return [
'zend-expressive' => [
'error_handler' => [
'template_404' => 'core/error/404.html.twig',
'template_error' => 'core/error/error.html.twig',
],
],
];

View File

@ -1,13 +1,13 @@
<?php <?php
namespace Acelaya\UrlShortener\Middleware\Routable; namespace Shlinkio\Shlink\Core\Action;
use Acelaya\UrlShortener\Service\UrlShortener;
use Acelaya\UrlShortener\Service\UrlShortenerInterface;
use Acelaya\UrlShortener\Service\VisitsTracker;
use Acelaya\UrlShortener\Service\VisitsTrackerInterface;
use Acelaya\ZsmAnnotatedServices\Annotation\Inject; use Acelaya\ZsmAnnotatedServices\Annotation\Inject;
use Psr\Http\Message\ResponseInterface as Response; use Psr\Http\Message\ResponseInterface as Response;
use Psr\Http\Message\ServerRequestInterface as Request; use Psr\Http\Message\ServerRequestInterface as Request;
use Shlinkio\Shlink\Core\Service\UrlShortener;
use Shlinkio\Shlink\Core\Service\UrlShortenerInterface;
use Shlinkio\Shlink\Core\Service\VisitsTracker;
use Shlinkio\Shlink\Core\Service\VisitsTrackerInterface;
use Zend\Diactoros\Response\RedirectResponse; use Zend\Diactoros\Response\RedirectResponse;
use Zend\Stratigility\MiddlewareInterface; use Zend\Stratigility\MiddlewareInterface;

View File

@ -0,0 +1,13 @@
<?php
namespace Shlinkio\Shlink\Core;
use Zend\Config\Factory;
use Zend\Stdlib\Glob;
class ConfigProvider
{
public function __invoke()
{
return Factory::fromFiles(Glob::glob(__DIR__ . '/../config/{,*.}config.php', Glob::GLOB_BRACE));
}
}

View File

@ -1,8 +1,9 @@
<?php <?php
namespace Acelaya\UrlShortener\Entity; namespace Shlinkio\Shlink\Core\Entity;
use Acelaya\UrlShortener\Util\StringUtilsTrait;
use Doctrine\ORM\Mapping as ORM; use Doctrine\ORM\Mapping as ORM;
use Shlinkio\Shlink\Common\Entity\AbstractEntity;
use Shlinkio\Shlink\Common\Util\StringUtilsTrait;
/** /**
* Class RestToken * Class RestToken

View File

@ -1,16 +1,17 @@
<?php <?php
namespace Acelaya\UrlShortener\Entity; namespace Shlinkio\Shlink\Core\Entity;
use Doctrine\Common\Collections\ArrayCollection; use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection; use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM; use Doctrine\ORM\Mapping as ORM;
use Shlinkio\Shlink\Common\Entity\AbstractEntity;
/** /**
* Class ShortUrl * Class ShortUrl
* @author * @author
* @link * @link
* *
* @ORM\Entity(repositoryClass="Acelaya\UrlShortener\Repository\ShortUrlRepository") * @ORM\Entity(repositoryClass="Shlinkio\Shlink\Core\Repository\ShortUrlRepository")
* @ORM\Table(name="short_urls") * @ORM\Table(name="short_urls")
*/ */
class ShortUrl extends AbstractEntity implements \JsonSerializable class ShortUrl extends AbstractEntity implements \JsonSerializable

View File

@ -1,7 +1,8 @@
<?php <?php
namespace Acelaya\UrlShortener\Entity; namespace Shlinkio\Shlink\Core\Entity;
use Doctrine\ORM\Mapping as ORM; use Doctrine\ORM\Mapping as ORM;
use Shlinkio\Shlink\Common\Entity\AbstractEntity;
/** /**
* Class Visit * Class Visit

View File

@ -0,0 +1,6 @@
<?php
namespace Shlinkio\Shlink\Core\Exception;
interface ExceptionInterface
{
}

View File

@ -1,5 +1,5 @@
<?php <?php
namespace Acelaya\UrlShortener\Exception; namespace Shlinkio\Shlink\Core\Exception;
class InvalidArgumentException extends \InvalidArgumentException implements ExceptionInterface class InvalidArgumentException extends \InvalidArgumentException implements ExceptionInterface
{ {

View File

@ -1,5 +1,5 @@
<?php <?php
namespace Acelaya\UrlShortener\Exception; namespace Shlinkio\Shlink\Core\Exception;
class InvalidShortCodeException extends RuntimeException class InvalidShortCodeException extends RuntimeException
{ {

View File

@ -1,5 +1,5 @@
<?php <?php
namespace Acelaya\UrlShortener\Exception; namespace Shlinkio\Shlink\Core\Exception;
class InvalidUrlException extends RuntimeException class InvalidUrlException extends RuntimeException
{ {

View File

@ -1,5 +1,5 @@
<?php <?php
namespace Acelaya\UrlShortener\Exception; namespace Shlinkio\Shlink\Core\Exception;
class RuntimeException extends \RuntimeException implements ExceptionInterface class RuntimeException extends \RuntimeException implements ExceptionInterface
{ {

View File

@ -1,9 +1,8 @@
<?php <?php
namespace Acelaya\UrlShortener\Repository; namespace Shlinkio\Shlink\Core\Repository;
use Acelaya\UrlShortener\Entity\ShortUrl;
use Doctrine\ORM\EntityRepository; use Doctrine\ORM\EntityRepository;
use Doctrine\ORM\QueryBuilder; use Shlinkio\Shlink\Core\Entity\ShortUrl;
class ShortUrlRepository extends EntityRepository implements ShortUrlRepositoryInterface class ShortUrlRepository extends EntityRepository implements ShortUrlRepositoryInterface
{ {

View File

@ -1,7 +1,8 @@
<?php <?php
namespace Acelaya\UrlShortener\Repository; namespace Shlinkio\Shlink\Core\Repository;
use Doctrine\Common\Persistence\ObjectRepository; use Doctrine\Common\Persistence\ObjectRepository;
use Shlinkio\Shlink\Common\Repository\PaginableRepositoryInterface;
interface ShortUrlRepositoryInterface extends ObjectRepository, PaginableRepositoryInterface interface ShortUrlRepositoryInterface extends ObjectRepository, PaginableRepositoryInterface
{ {

View File

@ -1,11 +1,11 @@
<?php <?php
namespace Acelaya\UrlShortener\Service; namespace Shlinkio\Shlink\Core\Service;
use Acelaya\UrlShortener\Entity\ShortUrl;
use Acelaya\UrlShortener\Paginator\Adapter\PaginableRepositoryAdapter;
use Acelaya\UrlShortener\Repository\ShortUrlRepository;
use Acelaya\ZsmAnnotatedServices\Annotation\Inject; use Acelaya\ZsmAnnotatedServices\Annotation\Inject;
use Doctrine\ORM\EntityManagerInterface; use Doctrine\ORM\EntityManagerInterface;
use Shlinkio\Shlink\Common\Paginator\Adapter\PaginableRepositoryAdapter;
use Shlinkio\Shlink\Core\Entity\ShortUrl;
use Shlinkio\Shlink\Core\Repository\ShortUrlRepository;
use Zend\Paginator\Paginator; use Zend\Paginator\Paginator;
class ShortUrlService implements ShortUrlServiceInterface class ShortUrlService implements ShortUrlServiceInterface

View File

@ -1,7 +1,7 @@
<?php <?php
namespace Acelaya\UrlShortener\Service; namespace Shlinkio\Shlink\Core\Service;
use Acelaya\UrlShortener\Entity\ShortUrl; use Shlinkio\Shlink\Core\Entity\ShortUrl;
use Zend\Paginator\Paginator; use Zend\Paginator\Paginator;
interface ShortUrlServiceInterface interface ShortUrlServiceInterface

View File

@ -1,16 +1,16 @@
<?php <?php
namespace Acelaya\UrlShortener\Service; namespace Shlinkio\Shlink\Core\Service;
use Acelaya\UrlShortener\Entity\ShortUrl;
use Acelaya\UrlShortener\Exception\InvalidShortCodeException;
use Acelaya\UrlShortener\Exception\InvalidUrlException;
use Acelaya\UrlShortener\Exception\RuntimeException;
use Acelaya\ZsmAnnotatedServices\Annotation\Inject; use Acelaya\ZsmAnnotatedServices\Annotation\Inject;
use Doctrine\ORM\EntityManagerInterface; use Doctrine\ORM\EntityManagerInterface;
use Doctrine\ORM\ORMException; use Doctrine\ORM\ORMException;
use GuzzleHttp\ClientInterface; use GuzzleHttp\ClientInterface;
use GuzzleHttp\Exception\GuzzleException; use GuzzleHttp\Exception\GuzzleException;
use Psr\Http\Message\UriInterface; use Psr\Http\Message\UriInterface;
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 class UrlShortener implements UrlShortenerInterface
{ {
@ -44,7 +44,7 @@ class UrlShortener implements UrlShortenerInterface
) { ) {
$this->httpClient = $httpClient; $this->httpClient = $httpClient;
$this->em = $em; $this->em = $em;
$this->chars = $chars; $this->chars = empty($chars) ? self::DEFAULT_CHARS : $chars;
} }
/** /**

View File

@ -1,10 +1,10 @@
<?php <?php
namespace Acelaya\UrlShortener\Service; namespace Shlinkio\Shlink\Core\Service;
use Acelaya\UrlShortener\Exception\InvalidShortCodeException;
use Acelaya\UrlShortener\Exception\InvalidUrlException;
use Acelaya\UrlShortener\Exception\RuntimeException;
use Psr\Http\Message\UriInterface; use Psr\Http\Message\UriInterface;
use Shlinkio\Shlink\Core\Exception\InvalidShortCodeException;
use Shlinkio\Shlink\Core\Exception\InvalidUrlException;
use Shlinkio\Shlink\Core\Exception\RuntimeException;
interface UrlShortenerInterface interface UrlShortenerInterface
{ {

View File

@ -1,12 +1,11 @@
<?php <?php
namespace Acelaya\UrlShortener\Service; namespace Shlinkio\Shlink\Core\Service;
use Acelaya\UrlShortener\Entity\ShortUrl;
use Acelaya\UrlShortener\Entity\Visit;
use Acelaya\UrlShortener\Exception\InvalidArgumentException;
use Acelaya\UrlShortener\Exception\InvalidShortCodeException;
use Acelaya\ZsmAnnotatedServices\Annotation\Inject; use Acelaya\ZsmAnnotatedServices\Annotation\Inject;
use Doctrine\ORM\EntityManagerInterface; use Doctrine\ORM\EntityManagerInterface;
use Shlinkio\Shlink\Core\Entity\ShortUrl;
use Shlinkio\Shlink\Core\Entity\Visit;
use Shlinkio\Shlink\Core\Exception\InvalidArgumentException;
use Zend\Paginator\Paginator; use Zend\Paginator\Paginator;
class VisitsTracker implements VisitsTrackerInterface class VisitsTracker implements VisitsTrackerInterface

View File

@ -1,7 +1,7 @@
<?php <?php
namespace Acelaya\UrlShortener\Service; namespace Shlinkio\Shlink\Core\Service;
use Acelaya\UrlShortener\Entity\Visit; use Shlinkio\Shlink\Core\Entity\Visit;
use Zend\Paginator\Paginator; use Zend\Paginator\Paginator;
interface VisitsTrackerInterface interface VisitsTrackerInterface

View File

@ -1,4 +1,4 @@
{% extends 'layout/default.html.twig' %} {% extends 'core/layout/default.html.twig' %}
{% block title %}URL Not Found{% endblock %} {% block title %}URL Not Found{% endblock %}

View File

@ -1,4 +1,4 @@
{% extends 'layout/default.html.twig' %} {% extends 'core/layout/default.html.twig' %}
{% block title %}{{ status }} {{ reason }}{% endblock %} {% block title %}{{ status }} {{ reason }}{% endblock %}

View File

@ -1,13 +1,13 @@
<?php <?php
namespace AcelayaTest\UrlShortener\Service; namespace ShlinkioTest\Shlink\Core\Service;
use Acelaya\UrlShortener\Entity\ShortUrl;
use Acelaya\UrlShortener\Repository\ShortUrlRepository;
use Acelaya\UrlShortener\Service\ShortUrlService;
use Doctrine\ORM\EntityManagerInterface; use Doctrine\ORM\EntityManagerInterface;
use PHPUnit_Framework_TestCase as TestCase; use PHPUnit_Framework_TestCase as TestCase;
use Prophecy\Argument; use Prophecy\Argument;
use Prophecy\Prophecy\ObjectProphecy; use Prophecy\Prophecy\ObjectProphecy;
use Shlinkio\Shlink\Core\Entity\ShortUrl;
use Shlinkio\Shlink\Core\Repository\ShortUrlRepository;
use Shlinkio\Shlink\Core\Service\ShortUrlService;
class ShortUrlServiceTest extends TestCase class ShortUrlServiceTest extends TestCase
{ {

View File

@ -1,8 +1,6 @@
<?php <?php
namespace AcelayaTest\UrlShortener\Service; namespace ShlinkioTest\Shlink\Core\Service;
use Acelaya\UrlShortener\Entity\ShortUrl;
use Acelaya\UrlShortener\Service\UrlShortener;
use Doctrine\Common\Persistence\ObjectRepository; use Doctrine\Common\Persistence\ObjectRepository;
use Doctrine\DBAL\Connection; use Doctrine\DBAL\Connection;
use Doctrine\ORM\EntityManagerInterface; use Doctrine\ORM\EntityManagerInterface;
@ -10,10 +8,11 @@ use Doctrine\ORM\ORMException;
use GuzzleHttp\ClientInterface; use GuzzleHttp\ClientInterface;
use GuzzleHttp\Exception\ClientException; use GuzzleHttp\Exception\ClientException;
use GuzzleHttp\Psr7\Request; use GuzzleHttp\Psr7\Request;
use GuzzleHttp\Psr7\Response;
use PHPUnit_Framework_TestCase as TestCase; use PHPUnit_Framework_TestCase as TestCase;
use Prophecy\Argument; use Prophecy\Argument;
use Prophecy\Prophecy\ObjectProphecy; use Prophecy\Prophecy\ObjectProphecy;
use Shlinkio\Shlink\Core\Entity\ShortUrl;
use Shlinkio\Shlink\Core\Service\UrlShortener;
use Zend\Diactoros\Uri; use Zend\Diactoros\Uri;
class UrlShortenerTest extends TestCase class UrlShortenerTest extends TestCase
@ -66,7 +65,7 @@ class UrlShortenerTest extends TestCase
/** /**
* @test * @test
* @expectedException \Acelaya\UrlShortener\Exception\RuntimeException * @expectedException \Shlinkio\Shlink\Core\Exception\RuntimeException
*/ */
public function exceptionIsThrownWhenOrmThrowsException() public function exceptionIsThrownWhenOrmThrowsException()
{ {
@ -82,7 +81,7 @@ class UrlShortenerTest extends TestCase
/** /**
* @test * @test
* @expectedException \Acelaya\UrlShortener\Exception\InvalidUrlException * @expectedException \Shlinkio\Shlink\Core\Exception\InvalidUrlException
*/ */
public function exceptionIsThrownWhenUrlDoesNotExist() public function exceptionIsThrownWhenUrlDoesNotExist()
{ {
@ -127,7 +126,7 @@ class UrlShortenerTest extends TestCase
/** /**
* @test * @test
* @expectedException \Acelaya\UrlShortener\Exception\InvalidShortCodeException * @expectedException \Shlinkio\Shlink\Core\Exception\InvalidShortCodeException
*/ */
public function invalidCharSetThrowsException() public function invalidCharSetThrowsException()
{ {

View File

@ -1,12 +1,12 @@
<?php <?php
namespace AcelayaTest\UrlShortener\Service; namespace ShlinkioTest\Shlink\Core\Service;
use Acelaya\UrlShortener\Entity\ShortUrl;
use Acelaya\UrlShortener\Service\VisitsTracker;
use Doctrine\ORM\EntityManager; use Doctrine\ORM\EntityManager;
use Doctrine\ORM\EntityRepository; use Doctrine\ORM\EntityRepository;
use PHPUnit_Framework_TestCase as TestCase; use PHPUnit_Framework_TestCase as TestCase;
use Prophecy\Argument; use Prophecy\Argument;
use Shlinkio\Shlink\Core\Entity\ShortUrl;
use Shlinkio\Shlink\Core\Service\VisitsTracker;
class VisitsTrackerTest extends TestCase class VisitsTrackerTest extends TestCase
{ {

View File

@ -0,0 +1,16 @@
<?php
use Shlinkio\Shlink\Rest\Middleware;
return [
'middleware_pipeline' => [
'rest' => [
'path' => '/rest',
'middleware' => [
Middleware\CheckAuthenticationMiddleware::class,
Middleware\CrossDomainMiddleware::class,
],
'priority' => 5,
],
],
];

View File

@ -1,46 +1,37 @@
<?php <?php
use Acelaya\UrlShortener\Middleware\Routable; use Shlinkio\Shlink\Rest\Action;
use Acelaya\UrlShortener\Middleware\Rest;
return [ return [
'routes' => [ 'routes' => [
[
'name' => 'long-url-redirect',
'path' => '/{shortCode}',
'middleware' => Routable\RedirectMiddleware::class,
'allowed_methods' => ['GET'],
],
// Rest
[ [
'name' => 'rest-authenticate', 'name' => 'rest-authenticate',
'path' => '/rest/authenticate', 'path' => '/rest/authenticate',
'middleware' => Rest\AuthenticateMiddleware::class, 'middleware' => Action\AuthenticateMiddleware::class,
'allowed_methods' => ['POST', 'OPTIONS'], 'allowed_methods' => ['POST', 'OPTIONS'],
], ],
[ [
'name' => 'rest-create-shortcode', 'name' => 'rest-create-shortcode',
'path' => '/rest/short-codes', 'path' => '/rest/short-codes',
'middleware' => Rest\CreateShortcodeMiddleware::class, 'middleware' => Action\CreateShortcodeMiddleware::class,
'allowed_methods' => ['POST', 'OPTIONS'], 'allowed_methods' => ['POST', 'OPTIONS'],
], ],
[ [
'name' => 'rest-resolve-url', 'name' => 'rest-resolve-url',
'path' => '/rest/short-codes/{shortCode}', 'path' => '/rest/short-codes/{shortCode}',
'middleware' => Rest\ResolveUrlMiddleware::class, 'middleware' => Action\ResolveUrlMiddleware::class,
'allowed_methods' => ['GET', 'OPTIONS'], 'allowed_methods' => ['GET', 'OPTIONS'],
], ],
[ [
'name' => 'rest-list-shortened-url', 'name' => 'rest-lActionist-shortened-url',
'path' => '/rest/short-codes', 'path' => '/rest/short-codes',
'middleware' => Rest\ListShortcodesMiddleware::class, 'middleware' => Action\ListShortcodesMiddleware::class,
'allowed_methods' => ['GET'], 'allowed_methods' => ['GET'],
], ],
[ [
'name' => 'rest-get-visits', 'name' => 'rest-get-visits',
'path' => '/rest/visits/{shortCode}', 'path' => '/rest/visits/{shortCode}',
'middleware' => Rest\GetVisitsMiddleware::class, 'middleware' => Action\GetVisitsMiddleware::class,
'allowed_methods' => ['GET', 'OPTIONS'], 'allowed_methods' => ['GET', 'OPTIONS'],
], ],
], ],

View File

@ -0,0 +1,25 @@
<?php
use Acelaya\ZsmAnnotatedServices\Factory\V3\AnnotatedFactory;
use Shlinkio\Shlink\Rest\Action;
use Shlinkio\Shlink\Rest\Middleware;
use Shlinkio\Shlink\Rest\Service;
use Zend\ServiceManager\Factory\InvokableFactory;
return [
'services' => [
'factories' => [
Service\RestTokenService::class => AnnotatedFactory::class,
Action\AuthenticateMiddleware::class => AnnotatedFactory::class,
Action\CreateShortcodeMiddleware::class => AnnotatedFactory::class,
Action\ResolveUrlMiddleware::class => AnnotatedFactory::class,
Action\GetVisitsMiddleware::class => AnnotatedFactory::class,
Action\ListShortcodesMiddleware::class => AnnotatedFactory::class,
Middleware\CrossDomainMiddleware::class => InvokableFactory::class,
Middleware\CheckAuthenticationMiddleware::class => AnnotatedFactory::class,
],
],
];

View File

@ -1,5 +1,5 @@
<?php <?php
namespace Acelaya\UrlShortener\Middleware\Rest; namespace Shlinkio\Shlink\Rest\Action;
use Psr\Http\Message\ResponseInterface as Response; use Psr\Http\Message\ResponseInterface as Response;
use Psr\Http\Message\ServerRequestInterface as Request; use Psr\Http\Message\ServerRequestInterface as Request;

View File

@ -1,13 +1,13 @@
<?php <?php
namespace Acelaya\UrlShortener\Middleware\Rest; namespace Shlinkio\Shlink\Rest\Action;
use Acelaya\UrlShortener\Exception\AuthenticationException;
use Acelaya\UrlShortener\Service\RestTokenService;
use Acelaya\UrlShortener\Service\RestTokenServiceInterface;
use Acelaya\UrlShortener\Util\RestUtils;
use Acelaya\ZsmAnnotatedServices\Annotation\Inject; use Acelaya\ZsmAnnotatedServices\Annotation\Inject;
use Psr\Http\Message\ResponseInterface as Response; use Psr\Http\Message\ResponseInterface as Response;
use Psr\Http\Message\ServerRequestInterface as Request; use Psr\Http\Message\ServerRequestInterface as Request;
use Shlinkio\Shlink\Rest\Exception\AuthenticationException;
use Shlinkio\Shlink\Rest\Service\RestTokenService;
use Shlinkio\Shlink\Rest\Service\RestTokenServiceInterface;
use Shlinkio\Shlink\Rest\Util\RestUtils;
use Zend\Diactoros\Response\JsonResponse; use Zend\Diactoros\Response\JsonResponse;
class AuthenticateMiddleware extends AbstractRestMiddleware class AuthenticateMiddleware extends AbstractRestMiddleware

View File

@ -1,13 +1,13 @@
<?php <?php
namespace Acelaya\UrlShortener\Middleware\Rest; namespace Shlinkio\Shlink\Rest\Action;
use Acelaya\UrlShortener\Exception\InvalidUrlException;
use Acelaya\UrlShortener\Service\UrlShortener;
use Acelaya\UrlShortener\Service\UrlShortenerInterface;
use Acelaya\UrlShortener\Util\RestUtils;
use Acelaya\ZsmAnnotatedServices\Annotation\Inject; use Acelaya\ZsmAnnotatedServices\Annotation\Inject;
use Psr\Http\Message\ResponseInterface as Response; use Psr\Http\Message\ResponseInterface as Response;
use Psr\Http\Message\ServerRequestInterface as Request; use Psr\Http\Message\ServerRequestInterface as Request;
use Shlinkio\Shlink\Core\Exception\InvalidUrlException;
use Shlinkio\Shlink\Core\Service\UrlShortener;
use Shlinkio\Shlink\Core\Service\UrlShortenerInterface;
use Shlinkio\Shlink\Rest\Util\RestUtils;
use Zend\Diactoros\Response\JsonResponse; use Zend\Diactoros\Response\JsonResponse;
use Zend\Diactoros\Uri; use Zend\Diactoros\Uri;

View File

@ -1,13 +1,13 @@
<?php <?php
namespace Acelaya\UrlShortener\Middleware\Rest; namespace Shlinkio\Shlink\Rest\Action;
use Acelaya\UrlShortener\Exception\InvalidArgumentException;
use Acelaya\UrlShortener\Service\VisitsTracker;
use Acelaya\UrlShortener\Service\VisitsTrackerInterface;
use Acelaya\UrlShortener\Util\RestUtils;
use Acelaya\ZsmAnnotatedServices\Annotation\Inject; use Acelaya\ZsmAnnotatedServices\Annotation\Inject;
use Psr\Http\Message\ResponseInterface as Response; use Psr\Http\Message\ResponseInterface as Response;
use Psr\Http\Message\ServerRequestInterface as Request; use Psr\Http\Message\ServerRequestInterface as Request;
use Shlinkio\Shlink\Core\Exception\InvalidArgumentException;
use Shlinkio\Shlink\Core\Service\VisitsTracker;
use Shlinkio\Shlink\Core\Service\VisitsTrackerInterface;
use Shlinkio\Shlink\Rest\Util\RestUtils;
use Zend\Diactoros\Response\JsonResponse; use Zend\Diactoros\Response\JsonResponse;
class GetVisitsMiddleware extends AbstractRestMiddleware class GetVisitsMiddleware extends AbstractRestMiddleware

View File

@ -1,15 +1,14 @@
<?php <?php
namespace Acelaya\UrlShortener\Middleware\Rest; namespace Shlinkio\Shlink\Rest\Action;
use Acelaya\UrlShortener\Paginator\Util\PaginatorUtilsTrait;
use Acelaya\UrlShortener\Service\ShortUrlService;
use Acelaya\UrlShortener\Service\ShortUrlServiceInterface;
use Acelaya\UrlShortener\Util\RestUtils;
use Acelaya\ZsmAnnotatedServices\Annotation\Inject; use Acelaya\ZsmAnnotatedServices\Annotation\Inject;
use Psr\Http\Message\ResponseInterface as Response; use Psr\Http\Message\ResponseInterface as Response;
use Psr\Http\Message\ServerRequestInterface as Request; use Psr\Http\Message\ServerRequestInterface as Request;
use Shlinkio\Shlink\Common\Paginator\Util\PaginatorUtilsTrait;
use Shlinkio\Shlink\Core\Service\ShortUrlService;
use Shlinkio\Shlink\Core\Service\ShortUrlServiceInterface;
use Shlinkio\Shlink\Rest\Util\RestUtils;
use Zend\Diactoros\Response\JsonResponse; use Zend\Diactoros\Response\JsonResponse;
use Zend\Stdlib\ArrayUtils;
class ListShortcodesMiddleware extends AbstractRestMiddleware class ListShortcodesMiddleware extends AbstractRestMiddleware
{ {

View File

@ -1,13 +1,13 @@
<?php <?php
namespace Acelaya\UrlShortener\Middleware\Rest; namespace Shlinkio\Shlink\Rest\Action;
use Acelaya\UrlShortener\Exception\InvalidShortCodeException;
use Acelaya\UrlShortener\Service\UrlShortener;
use Acelaya\UrlShortener\Service\UrlShortenerInterface;
use Acelaya\UrlShortener\Util\RestUtils;
use Acelaya\ZsmAnnotatedServices\Annotation\Inject; use Acelaya\ZsmAnnotatedServices\Annotation\Inject;
use Psr\Http\Message\ResponseInterface as Response; use Psr\Http\Message\ResponseInterface as Response;
use Psr\Http\Message\ServerRequestInterface as Request; use Psr\Http\Message\ServerRequestInterface as Request;
use Shlinkio\Shlink\Core\Exception\InvalidShortCodeException;
use Shlinkio\Shlink\Core\Service\UrlShortener;
use Shlinkio\Shlink\Core\Service\UrlShortenerInterface;
use Shlinkio\Shlink\Rest\Util\RestUtils;
use Zend\Diactoros\Response\JsonResponse; use Zend\Diactoros\Response\JsonResponse;
class ResolveUrlMiddleware extends AbstractRestMiddleware class ResolveUrlMiddleware extends AbstractRestMiddleware

View File

@ -0,0 +1,13 @@
<?php
namespace Shlinkio\Shlink\Rest;
use Zend\Config\Factory;
use Zend\Stdlib\Glob;
class ConfigProvider
{
public function __invoke()
{
return Factory::fromFiles(Glob::glob(__DIR__ . '/../config/{,*.}config.php', Glob::GLOB_BRACE));
}
}

View File

@ -1,5 +1,7 @@
<?php <?php
namespace Acelaya\UrlShortener\Exception; namespace Shlinkio\Shlink\Rest\Exception;
use Shlinkio\Shlink\Core\Exception\ExceptionInterface;
class AuthenticationException extends \RuntimeException implements ExceptionInterface class AuthenticationException extends \RuntimeException implements ExceptionInterface
{ {

View File

@ -1,13 +1,13 @@
<?php <?php
namespace Acelaya\UrlShortener\Middleware; namespace Shlinkio\Shlink\Rest\Middleware;
use Acelaya\UrlShortener\Exception\InvalidArgumentException;
use Acelaya\UrlShortener\Service\RestTokenService;
use Acelaya\UrlShortener\Service\RestTokenServiceInterface;
use Acelaya\UrlShortener\Util\RestUtils;
use Acelaya\ZsmAnnotatedServices\Annotation\Inject; use Acelaya\ZsmAnnotatedServices\Annotation\Inject;
use Psr\Http\Message\ResponseInterface as Response; use Psr\Http\Message\ResponseInterface as Response;
use Psr\Http\Message\ServerRequestInterface as Request; use Psr\Http\Message\ServerRequestInterface as Request;
use Shlinkio\Shlink\Core\Exception\InvalidArgumentException;
use Shlinkio\Shlink\Rest\Service\RestTokenService;
use Shlinkio\Shlink\Rest\Service\RestTokenServiceInterface;
use Shlinkio\Shlink\Rest\Util\RestUtils;
use Zend\Diactoros\Response\JsonResponse; use Zend\Diactoros\Response\JsonResponse;
use Zend\Expressive\Router\RouteResult; use Zend\Expressive\Router\RouteResult;
use Zend\Stratigility\MiddlewareInterface; use Zend\Stratigility\MiddlewareInterface;

View File

@ -1,5 +1,5 @@
<?php <?php
namespace Acelaya\UrlShortener\Middleware; namespace Shlinkio\Shlink\Rest\Middleware;
use Psr\Http\Message\ResponseInterface as Response; use Psr\Http\Message\ResponseInterface as Response;
use Psr\Http\Message\ServerRequestInterface as Request; use Psr\Http\Message\ServerRequestInterface as Request;

View File

@ -1,11 +1,11 @@
<?php <?php
namespace Acelaya\UrlShortener\Service; namespace Shlinkio\Shlink\Rest\Service;
use Acelaya\UrlShortener\Entity\RestToken;
use Acelaya\UrlShortener\Exception\AuthenticationException;
use Acelaya\UrlShortener\Exception\InvalidArgumentException;
use Acelaya\ZsmAnnotatedServices\Annotation\Inject; use Acelaya\ZsmAnnotatedServices\Annotation\Inject;
use Doctrine\ORM\EntityManagerInterface; use Doctrine\ORM\EntityManagerInterface;
use Shlinkio\Shlink\Core\Entity\RestToken;
use Shlinkio\Shlink\Core\Exception\InvalidArgumentException;
use Shlinkio\Shlink\Rest\Exception\AuthenticationException;
class RestTokenService implements RestTokenServiceInterface class RestTokenService implements RestTokenServiceInterface
{ {

View File

@ -1,9 +1,9 @@
<?php <?php
namespace Acelaya\UrlShortener\Service; namespace Shlinkio\Shlink\Rest\Service;
use Acelaya\UrlShortener\Entity\RestToken; use Shlinkio\Shlink\Core\Entity\RestToken;
use Acelaya\UrlShortener\Exception\AuthenticationException; use Shlinkio\Shlink\Core\Exception\InvalidArgumentException;
use Acelaya\UrlShortener\Exception\InvalidArgumentException; use Shlinkio\Shlink\Rest\Exception\AuthenticationException;
interface RestTokenServiceInterface interface RestTokenServiceInterface
{ {

View File

@ -1,7 +1,8 @@
<?php <?php
namespace Acelaya\UrlShortener\Util; namespace Shlinkio\Shlink\Rest\Util;
use Acelaya\UrlShortener\Exception; use Shlinkio\Shlink\Core\Exception as Core;
use Shlinkio\Shlink\Rest\Exception as Rest;
class RestUtils class RestUtils
{ {
@ -12,16 +13,16 @@ class RestUtils
const INVALID_AUTH_TOKEN_ERROR = 'INVALID_AUTH_TOKEN_ERROR'; const INVALID_AUTH_TOKEN_ERROR = 'INVALID_AUTH_TOKEN_ERROR';
const UNKNOWN_ERROR = 'UNKNOWN_ERROR'; const UNKNOWN_ERROR = 'UNKNOWN_ERROR';
public static function getRestErrorCodeFromException(Exception\ExceptionInterface $e) public static function getRestErrorCodeFromException(Core\ExceptionInterface $e)
{ {
switch (true) { switch (true) {
case $e instanceof Exception\InvalidShortCodeException: case $e instanceof Core\InvalidShortCodeException:
return self::INVALID_SHORTCODE_ERROR; return self::INVALID_SHORTCODE_ERROR;
case $e instanceof Exception\InvalidUrlException: case $e instanceof Core\InvalidUrlException:
return self::INVALID_URL_ERROR; return self::INVALID_URL_ERROR;
case $e instanceof Exception\InvalidArgumentException: case $e instanceof Core\InvalidArgumentException:
return self::INVALID_ARGUMENT_ERROR; return self::INVALID_ARGUMENT_ERROR;
case $e instanceof Exception\AuthenticationException: case $e instanceof Rest\AuthenticationException:
return self::INVALID_CREDENTIALS_ERROR; return self::INVALID_CREDENTIALS_ERROR;
default: default:
return self::UNKNOWN_ERROR; return self::UNKNOWN_ERROR;

View File

@ -0,0 +1,54 @@
<?php
namespace ShlinkioTest\Shlink\Rest\Middleware;
use PHPUnit_Framework_TestCase as TestCase;
use Shlinkio\Shlink\Rest\Middleware\CrossDomainMiddleware;
use Zend\Diactoros\Response;
use Zend\Diactoros\ServerRequestFactory;
class CrossDomainMiddlewareTest extends TestCase
{
/**
* @var CrossDomainMiddleware
*/
protected $middleware;
public function setUp()
{
$this->middleware = new CrossDomainMiddleware();
}
/**
* @test
*/
public function anyRequestIncludesTheAllowAccessHeader()
{
$response = $this->middleware->__invoke(
ServerRequestFactory::fromGlobals(),
new Response(),
function ($req, $resp) {
return $resp;
}
);
$headers = $response->getHeaders();
$this->assertArrayHasKey('Access-Control-Allow-Origin', $headers);
$this->assertArrayNotHasKey('Access-Control-Allow-Headers', $headers);
}
/**
* @test
*/
public function optionsRequestIncludesMoreHeaders()
{
$request = ServerRequestFactory::fromGlobals(['REQUEST_METHOD' => 'OPTIONS']);
$response = $this->middleware->__invoke($request, new Response(), function ($req, $resp) {
return $resp;
});
$headers = $response->getHeaders();
$this->assertArrayHasKey('Access-Control-Allow-Origin', $headers);
$this->assertArrayHasKey('Access-Control-Allow-Headers', $headers);
}
}

View File

@ -16,8 +16,7 @@
</rule> </rule>
<!-- Paths to check --> <!-- Paths to check -->
<file>src</file> <file>module</file>
<file>tests</file>
<file>config</file> <file>config</file>
<file>public/index.php</file> <file>public/index.php</file>
</ruleset> </ruleset>

View File

@ -1,7 +1,16 @@
<phpunit bootstrap="./vendor/autoload.php" colors="true"> <phpunit bootstrap="./vendor/autoload.php" colors="true">
<testsuites> <testsuites>
<testsuite name="AcelayaTest"> <testsuite name="Common">
<directory>./tests</directory> <directory>./module/Common/test</directory>
</testsuite>
<testsuite name="Core">
<directory>./module/Core/test</directory>
</testsuite>
<testsuite name="Rest">
<directory>./module/Rest/test</directory>
</testsuite>
<testsuite name="CLI">
<directory>./module/CLI/test</directory>
</testsuite> </testsuite>
</testsuites> </testsuites>

View File

@ -1,6 +0,0 @@
<?php
namespace Acelaya\UrlShortener\Exception;
interface ExceptionInterface
{
}