Skip to content

Commit

Permalink
[EasyPagination] Clean up + Refactor pagination and paginators (#662)
Browse files Browse the repository at this point in the history
* [WIP][EasyPagination] Clean up + Refactor pagination and paginators

* [WIP][EasyPagination] Fix phpstan

* [WIP][EasyPagination] Fix phpstan - 1

* [WIP][EasyPagination] Fix phpstan - 2

* [EasyPagination] Implement bridges for new pagination provider

* [EasyPagination] Fix phpstan
  • Loading branch information
natepage authored Jul 20, 2021
1 parent ae7c081 commit 7f57614
Show file tree
Hide file tree
Showing 81 changed files with 3,841 additions and 47 deletions.
3 changes: 2 additions & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,8 @@
"illuminate/support": "^5.5 || ^6.0",
"bugsnag/bugsnag": "^3.19",
"elasticsearch/elasticsearch": "^7.8",
"psr/event-dispatcher": "^1.0"
"psr/event-dispatcher": "^1.0",
"laminas/laminas-uri": "^2.8"
},
"require-dev": {
"api-platform/core": "^2.5",
Expand Down
28 changes: 28 additions & 0 deletions packages/EasyPagination/src/Bridge/BridgeConstantsInterface.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<?php

declare(strict_types=1);

namespace EonX\EasyPagination\Bridge;

interface BridgeConstantsInterface
{
/**
* @var string
*/
public const PARAM_PAGE_ATTRIBUTE = 'easy_pagination.page_attribute';

/**
* @var string
*/
public const PARAM_PAGE_DEFAULT = 'easy_pagination.page_default';

/**
* @var string
*/
public const PARAM_PER_PAGE_ATTRIBUTE = 'easy_pagination.per_page_attribute';

/**
* @var string
*/
public const PARAM_PER_PAGE_DEFAULT = 'easy_pagination.per_page_default';
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@
use EonX\EasyPagination\Interfaces\LengthAwarePaginatorInterface;
use Illuminate\Contracts\Pagination\LengthAwarePaginator as LengthAwarePaginatorContract;

/**
* @deprecated since 3.2, will be removed in 4.0.
*/
final class LengthAwarePaginator implements LengthAwarePaginatorInterface
{
/**
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<?php

declare(strict_types=1);

namespace EonX\EasyPagination\Bridge\Laravel\Listeners;

use EonX\EasyPagination\Interfaces\PaginationProviderInterface;
use EonX\EasyPagination\Resolvers\FromHttpFoundationRequestResolver;
use Illuminate\Routing\Events\RouteMatched;

final class FromRequestPaginationListener
{
/**
* @var \EonX\EasyPagination\Interfaces\PaginationProviderInterface
*/
private $paginationProvider;

public function __construct(PaginationProviderInterface $paginationProvider)
{
$this->paginationProvider = $paginationProvider;
}

public function handle(RouteMatched $event): void
{
$resolver = new FromHttpFoundationRequestResolver(
$this->paginationProvider->getPaginationConfig(),
$event->request
);

$this->paginationProvider->setResolver($resolver);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
<?php

declare(strict_types=1);

namespace EonX\EasyPagination\Bridge\Laravel\Middleware;

use EonX\EasyPagination\Interfaces\PaginationProviderInterface;
use EonX\EasyPagination\Resolvers\FromHttpFoundationRequestResolver;
use Illuminate\Http\Request;

final class PaginationFromRequestMiddleware
{
/**
* @var \EonX\EasyPagination\Interfaces\PaginationProviderInterface
*/
private $paginationProvider;

public function __construct(PaginationProviderInterface $paginationProvider)
{
$this->paginationProvider = $paginationProvider;
}

/**
* @return mixed
*/
public function handle(Request $request, \Closure $next)
{
$resolver = new FromHttpFoundationRequestResolver(
$this->paginationProvider->getPaginationConfig(),
$request
);

$this->paginationProvider->setResolver($resolver);

return $next($request);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@
use Illuminate\Http\Request;
use Illuminate\Support\ServiceProvider;

/**
* @deprecated since 3.2, will be removed in 4.0. Use EasyPaginationServiceProvider instead.
*/
abstract class AbstractStartSizeEasyPaginationProvider extends ServiceProvider
{
/**
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
<?php

declare(strict_types=1);

namespace EonX\EasyPagination\Bridge\Laravel\Providers;

use EonX\EasyPagination\Bridge\Laravel\Listeners\FromRequestPaginationListener;
use EonX\EasyPagination\Bridge\Laravel\Middleware\PaginationFromRequestMiddleware;
use EonX\EasyPagination\Interfaces\PaginationInterface;
use EonX\EasyPagination\Interfaces\PaginationProviderInterface;
use EonX\EasyPagination\PaginationConfig;
use EonX\EasyPagination\PaginationProvider;
use Illuminate\Contracts\Container\Container;
use Illuminate\Routing\Events\RouteMatched;
use Illuminate\Support\ServiceProvider;
use Laravel\Lumen\Application as LumenApplication;

final class EasyPaginationServiceProvider extends ServiceProvider
{
public function boot(): void
{
$this->publishes([
__DIR__ . '/../config/easy-pagination.php' => \base_path('config/easy-pagination.php'),
]);
}

/**
* @throws \Illuminate\Contracts\Container\BindingResolutionException
*/
public function register(): void
{
$this->mergeConfigFrom(__DIR__ . '/../config/easy-pagination.php', 'easy-pagination');

$this->registerPaginationProvider();
$this->registerDefaultResolver();
}

/**
* @throws \Illuminate\Contracts\Container\BindingResolutionException
*/
private function registerDefaultResolver(): void
{
if (\config('easy-pagination.user_default_resolver', true) === false) {
return;
}

// Lumen
if ($this->app instanceof LumenApplication) {
$this->app->singleton(
PaginationFromRequestMiddleware::class,
static function (Container $app): PaginationFromRequestMiddleware {
return new PaginationFromRequestMiddleware($app->make(PaginationProviderInterface::class));
}
);
$this->app->middleware([PaginationFromRequestMiddleware::class]);

return;
}

// Laravel
$this->app->singleton(
FromRequestPaginationListener::class,
static function (Container $app): FromRequestPaginationListener {
return new FromRequestPaginationListener($app->make(PaginationProviderInterface::class));
}
);
$this->app->make('events')->listen(RouteMatched::class, FromRequestPaginationListener::class);
}

private function registerPaginationProvider(): void
{
$this->app->singleton(
PaginationProviderInterface::class,
static function (): PaginationProviderInterface {
$config = new PaginationConfig(
\config('easy-pagination.pagination.page_attribute'),
(int)\config('easy-pagination.pagination.page_default'),
\config('easy-pagination.pagination.per_page_attribute'),
(int)\config('easy-pagination.pagination.per_page_default')
);

return new PaginationProvider($config);
}
);

$this->app->singleton(PaginationInterface::class, static function (Container $app): PaginationInterface {
return $app->make(PaginationProviderInterface::class)->getPagination();
});
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@

use EonX\EasyPagination\Resolvers\StartSizeAsArrayInQueryResolver;

/**
* @deprecated since 3.2, will be removed in 4.0. Use EasyPaginationServiceProvider instead.
*/
final class StartSizeAsArrayInQueryEasyPaginationProvider extends AbstractStartSizeEasyPaginationProvider
{
/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@

use EonX\EasyPagination\Resolvers\StartSizeInQueryResolver;

/**
* @deprecated since 3.2, will be removed in 4.0. Use EasyPaginationServiceProvider instead.
*/
final class StartSizeInQueryEasyPaginationProvider extends AbstractStartSizeEasyPaginationProvider
{
protected function getResolverClosure(): \Closure
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<?php

declare(strict_types=1);

use EonX\EasyPagination\Bridge\BridgeConstantsInterface;

return [
'pagination' => [
'page_attribute' => \env('PAGINATION_PAGE_ATTRIBUTE', BridgeConstantsInterface::PARAM_PAGE_ATTRIBUTE),
'page_default' => \env('PAGINATION_PAGE_DEFAULT', BridgeConstantsInterface::PARAM_PAGE_DEFAULT),
'per_page_attribute' => \env('PAGINATION_PER_PAGE_ATTRIBUTE', BridgeConstantsInterface::PARAM_PER_PAGE_ATTRIBUTE),
'per_page_default' => \env('PAGINATION_PER_PAGE_DEFAULT', BridgeConstantsInterface::PARAM_PER_PAGE_DEFAULT),
],

'use_default_resolver' => \env('PAGINATION_USE_DEFAULT_RESOLVER', true),
];
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

namespace EonX\EasyPagination\Bridge\Symfony\DependencyInjection;

use EonX\EasyPagination\Interfaces\PaginationInterface;
use Symfony\Component\Config\Definition\Builder\TreeBuilder;
use Symfony\Component\Config\Definition\ConfigurationInterface;

Expand All @@ -15,7 +16,21 @@ public function getConfigTreeBuilder(): TreeBuilder

$treeBuilder->getRootNode()
->children()
->arrayNode('pagination')
->addDefaultsIfNotSet()
->children()
->scalarNode('page_attribute')->defaultValue(PaginationInterface::DEFAULT_PAGE_ATTRIBUTE)->end()
->integerNode('page_default')->defaultValue(PaginationInterface::DEFAULT_PAGE)->end()
->scalarNode('per_page_attribute')->defaultValue(PaginationInterface::DEFAULT_PER_PAGE_ATTRIBUTE)->end()
->integerNode('per_page_default')->defaultValue(PaginationInterface::DEFAULT_PER_PAGE)->end()
->end()
->end()
->booleanNode('use_default_resolver')
->defaultTrue()
->info('Resolve pagination from request by default')
->end()
->scalarNode('resolver')
->setDeprecated()
->defaultValue('in_query')
->info('Define which resolver to use. Available resolvers are: in_query, array_in_query.')
->validate()
Expand All @@ -24,20 +39,24 @@ public function getConfigTreeBuilder(): TreeBuilder
->end()
->end()
->scalarNode('array_in_query_attr')
->setDeprecated()
->defaultValue('page')
->info(
'This config is used to resolve the pagination data when it is expected in the query
parameters of the request as an array. This config is the name of the query parameter containing
'This config is used to resolve the pagination data when it is expected in the query
parameters of the request as an array. This config is the name of the query parameter containing
the pagination data array.'
)
->example(
'For this config as "page", the resolver will look in the query for:
'For this config as "page", the resolver will look in the query for:
"<your-url>?page[<number_attr>]=1&page[<size_attr>]=15"'
)
->end()
->arrayNode('start_size')
->setDeprecated(
'The child node "%node%" at path "%path%" is deprecated. Use pagination instead.'
)
->info(
'This config contains the names of the attributes to use to resolve the start_size
'This config contains the names of the attributes to use to resolve the start_size
pagination data, and also their default values if not set on the given request.'
)
->addDefaultsIfNotSet()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

namespace EonX\EasyPagination\Bridge\Symfony\DependencyInjection;

use EonX\EasyPagination\Bridge\BridgeConstantsInterface;
use EonX\EasyPagination\Interfaces\StartSizeDataResolverInterface;
use EonX\EasyPagination\Resolvers\StartSizeAsArrayInQueryResolver;
use EonX\EasyPagination\Resolvers\StartSizeInQueryResolver;
Expand All @@ -15,9 +16,19 @@
final class EasyPaginationExtension extends Extension
{
/**
* @var mixed[]
* @var string[]
*/
private static $resolvers = [
private const PAGINATION_PARAMS = [
'page_attribute' => BridgeConstantsInterface::PARAM_PAGE_ATTRIBUTE,
'page_default' => BridgeConstantsInterface::PARAM_PAGE_DEFAULT,
'per_page_attribute' => BridgeConstantsInterface::PARAM_PER_PAGE_ATTRIBUTE,
'per_page_default' => BridgeConstantsInterface::PARAM_PER_PAGE_DEFAULT,
];

/**
* @var string[]
*/
private const RESOLVERS = [
'array_in_query' => StartSizeAsArrayInQueryResolver::class,
'in_query' => StartSizeInQueryResolver::class,
];
Expand All @@ -29,13 +40,34 @@ final class EasyPaginationExtension extends Extension
*/
public function load(array $configs, ContainerBuilder $container): void
{
(new PhpFileLoader($container, new FileLocator(__DIR__ . '/../Resources/config')))->load('services.php');

$config = $this->processConfiguration(new Configuration(), $configs);
$loader = new PhpFileLoader($container, new FileLocator(__DIR__ . '/../Resources/config'));

$this->loadDeprecated($config, $container, $loader);

foreach (self::PAGINATION_PARAMS as $name => $param) {
$container->setParameter($param, $config['pagination'][$name]);
}

$loader->load('services.php');

if ($config['use_default_resolver'] ?? true) {
$loader->load('default_resolver.php');
}
}

/**
* @param mixed[] $config
*
* @throws \Exception
*/
private function loadDeprecated(array $config, ContainerBuilder $container, PhpFileLoader $loader): void
{
$loader->load('services_deprecated.php');

$container->setParameter('easy_pagination.start_size_config', $config['start_size']);
$container->setParameter('easy_pagination.array_in_query_attr', $config['array_in_query_attr']);

$container->setAlias(StartSizeDataResolverInterface::class, static::$resolvers[$config['resolver']]);
$container->setAlias(StartSizeDataResolverInterface::class, self::RESOLVERS[$config['resolver']]);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@

use EonX\EasyPagination\Resolvers\Config\StartSizeConfig;

/**
* @deprecated since 3.2, will be removed in 4.0.
*/
final class StartSizeConfigFactory
{
/**
Expand Down
Loading

0 comments on commit 7f57614

Please sign in to comment.