diff --git a/.gitignore b/.gitignore index d157f2c..6980ff2 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,4 @@ phpunit.xml composer.lock .php_cs .php_cs.cache +phpstan.neon \ No newline at end of file diff --git a/.travis.yml b/.travis.yml index 24d3263..4ea660a 100644 --- a/.travis.yml +++ b/.travis.yml @@ -43,6 +43,8 @@ matrix: env: TWIG_VERSION=1.* - php: 7.0 env: TWIG_VERSION=2.* + - php: 7.1 + env: PHPSTAN_VERSION=0.11.* before_install: - if [ -n "$GH_TOKEN" ]; then composer config github-oauth.github.com ${GH_TOKEN}; fi; @@ -52,9 +54,11 @@ before_script: - if [ "$DOCTRINE_VERSION" != "" ]; then composer require "doctrine/orm:${DOCTRINE_VERSION}" --dev --no-update; fi; - if [ "$TWIG_VERSION" != "" ]; then composer require "twig/twig:${TWIG_VERSION}" --dev --no-update; fi; - if [ "$PHPUNIT_VERSION" != "" ]; then composer require "phpunit/phpunit:${PHPUNIT_VERSION}" --dev --no-update; fi; + - if [ "$PHPSTAN_VERSION" != "" ]; then composer require "phpstan/phpstan:${PHPSTAN_VERSION}" --dev --no-update; fi; - COMPOSER_MEMORY_LIMIT=-1 composer install --prefer-dist --no-interaction --no-scripts --no-progress script: + - if [ "$PHPSTAN_VERSION" != "" ]; then ./vendor/bin/phpstan analyse; fi; - vendor/bin/phpunit --coverage-clover build/coverage-clover.xml after_script: diff --git a/phpstan.neon.dist b/phpstan.neon.dist new file mode 100644 index 0000000..1d5823a --- /dev/null +++ b/phpstan.neon.dist @@ -0,0 +1,4 @@ +parameters: + level: 7 + paths: + - src diff --git a/src/DependencyInjection/Configuration.php b/src/DependencyInjection/Configuration.php index 2faddc5..a8e8aee 100644 --- a/src/DependencyInjection/Configuration.php +++ b/src/DependencyInjection/Configuration.php @@ -10,6 +10,7 @@ namespace GpsLab\Bundle\PaginationBundle\DependencyInjection; +use Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition; use Symfony\Component\Config\Definition\Builder\TreeBuilder; use Symfony\Component\Config\Definition\ConfigurationInterface; @@ -30,19 +31,20 @@ public function getConfigTreeBuilder() $root = $tree_builder->root('gpslab_pagination'); } - $root - ->addDefaultsIfNotSet() - ->children() - ->scalarNode('max_navigate') - ->defaultValue(5) - ->end() - ->scalarNode('parameter_name') - ->defaultValue('page') - ->end() - ->scalarNode('template') - ->defaultValue('GpsLabPaginationBundle::pagination.html.twig') - ->end() - ->end(); + // @codeCoverageIgnoreStart + if (!$root instanceof ArrayNodeDefinition) { + throw new \RuntimeException(sprintf( + 'Config root node must be a "%s", given "%s".', + 'Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition', + get_class($root) + )); + } + // @codeCoverageIgnoreEnd + + $root->addDefaultsIfNotSet(); + $root->children()->scalarNode('max_navigate')->defaultValue(5); + $root->children()->scalarNode('parameter_name')->defaultValue('page'); + $root->children()->scalarNode('template')->defaultValue('GpsLabPaginationBundle::pagination.html.twig'); return $tree_builder; } diff --git a/src/Service/Builder.php b/src/Service/Builder.php index f28442b..4c05835 100644 --- a/src/Service/Builder.php +++ b/src/Service/Builder.php @@ -10,7 +10,6 @@ namespace GpsLab\Bundle\PaginationBundle\Service; -use Doctrine\ORM\NonUniqueResultException; use Doctrine\ORM\QueryBuilder; use GpsLab\Bundle\PaginationBundle\Exception\IncorrectPageNumberException; use GpsLab\Bundle\PaginationBundle\Exception\OutOfRangeException; @@ -70,8 +69,6 @@ public function paginate($total_pages = 1, $current_page = 1) * @param int $per_page Entities per page * @param int $current_page The current page number * - * @throws NonUniqueResultException - * * @return Configuration */ public function paginateQuery(QueryBuilder $query, $per_page, $current_page = 1) @@ -83,7 +80,7 @@ public function paginateQuery(QueryBuilder $query, $per_page, $current_page = 1) ->getSingleScalarResult() ; - $total_pages = ceil($total / $per_page); + $total_pages = (int) ceil($total / $per_page); $current_page = $this->validateCurrentPage($current_page, $total_pages); $query @@ -126,8 +123,6 @@ public function paginateRequest( * @param string $parameter_name Name of URL parameter for page number * @param int $reference_type The type of reference (one of the constants in UrlGeneratorInterface) * - * @throws NonUniqueResultException - * * @return Configuration */ public function paginateRequestQuery( @@ -159,12 +154,12 @@ private function validateCurrentPage($current_page, $total_pages) return 1; } - if (!is_numeric($current_page)) { + if (!is_int($current_page) && (!is_string($current_page) || !ctype_digit($current_page))) { throw IncorrectPageNumberException::incorrect($current_page); } if ($current_page < 1 || $current_page > $total_pages) { - throw OutOfRangeException::out($current_page, $total_pages); + throw OutOfRangeException::out((int) $current_page, $total_pages); } return (int) $current_page; @@ -185,7 +180,7 @@ private function configureFromRequest( $reference_type ) { $route = $request->get('_route'); - $route_params = array_merge($request->query->all(), $request->get('_route_params')); + $route_params = array_merge($request->query->all(), $request->get('_route_params', [])); unset($route_params[$parameter_name]); return $configuration diff --git a/src/Service/Configuration.php b/src/Service/Configuration.php index f25e3c7..17c3626 100644 --- a/src/Service/Configuration.php +++ b/src/Service/Configuration.php @@ -35,7 +35,7 @@ class Configuration private $current_page = 1; /** - * @var View + * @var View|null */ private $view; diff --git a/src/Service/NavigateRange.php b/src/Service/NavigateRange.php index 62b6cb2..89ceb24 100644 --- a/src/Service/NavigateRange.php +++ b/src/Service/NavigateRange.php @@ -81,9 +81,9 @@ private function definitionOffset() private function adjustmentLargeLeftOffset() { if ($this->config->getCurrentPage() - $this->left_offset < 1) { - $offset = (int) abs($this->config->getCurrentPage() - 1 - $this->left_offset); - $this->left_offset = $this->left_offset - $offset; - $this->right_offset = $this->right_offset + $offset; + $offset = abs($this->config->getCurrentPage() - 1 - $this->left_offset); + $this->left_offset -= $offset; + $this->right_offset += $offset; } } @@ -93,13 +93,13 @@ private function adjustmentLargeLeftOffset() private function adjustmentLargeRightOffset() { if ($this->config->getCurrentPage() + $this->right_offset > $this->config->getTotalPages()) { - $offset = (int) abs( + $offset = abs( $this->config->getTotalPages() - $this->config->getCurrentPage() - $this->right_offset ); - $this->left_offset = $this->left_offset + $offset; - $this->right_offset = $this->right_offset - $offset; + $this->left_offset += $offset; + $this->right_offset -= $offset; } } diff --git a/src/Service/View.php b/src/Service/View.php index 5968f80..af86d7d 100644 --- a/src/Service/View.php +++ b/src/Service/View.php @@ -36,7 +36,7 @@ class View implements \IteratorAggregate private $prev; /** - * @var Node + * @var Node|null */ private $current; @@ -144,7 +144,7 @@ public function getLast() } /** - * @return ArrayCollection + * @return ArrayCollection|Node[] */ public function getIterator() { diff --git a/tests/Service/BuilderTest.php b/tests/Service/BuilderTest.php index 3b0ed18..ec26ebb 100644 --- a/tests/Service/BuilderTest.php +++ b/tests/Service/BuilderTest.php @@ -15,7 +15,6 @@ use GpsLab\Bundle\PaginationBundle\Service\Builder; use GpsLab\Bundle\PaginationBundle\Tests\TestCase; use Symfony\Bundle\FrameworkBundle\Routing\Router; -use Symfony\Component\HttpFoundation\ParameterBag; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\Routing\Generator\UrlGeneratorInterface; @@ -26,11 +25,6 @@ class BuilderTest extends TestCase */ private $router; - /** - * @var \PHPUnit_Framework_MockObject_MockObject|Request - */ - private $request; - /** * @var \PHPUnit_Framework_MockObject_MockObject|AbstractQuery */ @@ -41,6 +35,11 @@ class BuilderTest extends TestCase */ private $query_builder; + /** + * @var Request + */ + private $request; + /** * @var array */ @@ -52,11 +51,10 @@ class BuilderTest extends TestCase protected function setUp() { $this->router = $this->getMockNoConstructor('Symfony\Bundle\FrameworkBundle\Routing\Router'); - $this->request = $this->getMockNoConstructor('Symfony\Component\HttpFoundation\Request'); $this->query = $this->getMockAbstract('Doctrine\ORM\AbstractQuery', ['getSingleScalarResult']); $this->query_builder = $this->getMockNoConstructor('Doctrine\ORM\QueryBuilder'); - $this->request->query = new ParameterBag($this->query_params); + $this->request = new Request($this->query_params); } public function testDefaultPageLink() @@ -158,7 +156,9 @@ public function testPaginateQueryOutOfRange() */ public function testPaginateRequestIncorrectPage() { - $this->currentPage('foo', 'page'); + $this->request = new Request(array_merge($this->query_params, [ + 'page' => 'foo', + ])); $builder = new Builder($this->router, 5, 'page'); $builder->paginateRequest($this->request, 10); @@ -169,7 +169,9 @@ public function testPaginateRequestIncorrectPage() */ public function testPaginateRequestLowPageNumber() { - $this->currentPage(0, 'p'); + $this->request = new Request(array_merge($this->query_params, [ + 'p' => 0, + ])); $builder = new Builder($this->router, 5, 'page'); $builder->paginateRequest($this->request, 10, 'p'); @@ -180,7 +182,9 @@ public function testPaginateRequestLowPageNumber() */ public function testPaginateRequestOutOfRange() { - $this->currentPage(150, 'p'); + $this->request = new Request(array_merge($this->query_params, [ + 'p' => 150, + ])); $builder = new Builder($this->router, 5, 'page'); $builder->paginateRequest($this->request, 10, 'p'); @@ -195,20 +199,12 @@ public function testPaginateRequest() $route_params = ['foo' => 'baz', '_route_params' => 123]; $all_params = array_merge($this->query_params, $route_params); $reference_type = UrlGeneratorInterface::ABSOLUTE_URL; - - $this->currentPage(null, 'p'); - $this->request - ->expects($this->at(1)) - ->method('get') - ->with('_route') - ->willReturn($route) - ; - $this->request - ->expects($this->at(2)) - ->method('get') - ->with('_route_params') - ->willReturn($route_params) - ; + $this->request = new Request(array_merge($this->query_params, [ + 'p' => null, + ]), [], [ + '_route' => $route, + '_route_params' => $route_params, + ]); $that = $this; $this->router @@ -247,7 +243,9 @@ public function testPaginateRequest() */ public function testPaginateRequesQuerytIncorrectPage() { - $this->currentPage('foo', 'page'); + $this->request = new Request(array_merge($this->query_params, [ + 'page' => 'foo', + ])); $this->countQuery(10); $builder = new Builder($this->router, 5, 'page'); @@ -259,7 +257,9 @@ public function testPaginateRequesQuerytIncorrectPage() */ public function testPaginateRequestQueryLowPageNumber() { - $this->currentPage(0, 'p'); + $this->request = new Request(array_merge($this->query_params, [ + 'p' => 0, + ])); $this->countQuery(10); $builder = new Builder($this->router, 5, 'page'); @@ -271,7 +271,9 @@ public function testPaginateRequestQueryLowPageNumber() */ public function testPaginateRequestQueryOutOfRange() { - $this->currentPage(150, 'p'); + $this->request = new Request(array_merge($this->query_params, [ + 'p' => 150, + ])); $this->countQuery(10); $builder = new Builder($this->router, 5, 'page'); @@ -289,20 +291,12 @@ public function testPaginateRequestQuery() $route_params = ['foo' => 'baz', '_route_params']; $all_params = array_merge($this->query_params, $route_params); $reference_type = UrlGeneratorInterface::ABSOLUTE_URL; - - $this->currentPage($current_page, 'p'); - $this->request - ->expects($this->at(1)) - ->method('get') - ->with('_route') - ->willReturn($route) - ; - $this->request - ->expects($this->at(2)) - ->method('get') - ->with('_route_params') - ->willReturn($route_params) - ; + $this->request = new Request(array_merge($this->query_params, [ + 'p' => $current_page, + ]), [], [ + '_route' => $route, + '_route_params' => $route_params, + ]); $this->countQuery($total); $this->query_builder @@ -356,20 +350,6 @@ public function testPaginateRequestQuery() ); } - /** - * @param int $current_page - * @param string $parameter_name - */ - private function currentPage($current_page, $parameter_name = 'page') - { - $this->request - ->expects($this->at(0)) - ->method('get') - ->with($parameter_name) - ->willReturn($current_page) - ; - } - /** * @param int $total */ diff --git a/tests/Service/ConfigurationTest.php b/tests/Service/ConfigurationTest.php index fc9b8ce..db24880 100644 --- a/tests/Service/ConfigurationTest.php +++ b/tests/Service/ConfigurationTest.php @@ -18,7 +18,7 @@ class ConfigurationTest extends TestCase /** * @var Configuration */ - protected $config; + private $config; protected function setUp() { diff --git a/tests/Service/NavigateRangeTest.php b/tests/Service/NavigateRangeTest.php index aec436d..de95a89 100644 --- a/tests/Service/NavigateRangeTest.php +++ b/tests/Service/NavigateRangeTest.php @@ -19,12 +19,12 @@ class NavigateRangeTest extends TestCase /** * @var \PHPUnit_Framework_MockObject_MockObject|Configuration */ - protected $config; + private $config; /** * @var NavigateRange */ - protected $range; + private $range; protected function setUp() { diff --git a/tests/Service/ViewTest.php b/tests/Service/ViewTest.php index fe0cd2d..a0d91b7 100644 --- a/tests/Service/ViewTest.php +++ b/tests/Service/ViewTest.php @@ -22,17 +22,17 @@ class ViewTest extends TestCase /** * @var \PHPUnit_Framework_MockObject_MockObject|Configuration */ - protected $config; + private $config; /** * @var \PHPUnit_Framework_MockObject_MockObject|NavigateRange */ - protected $range; + private $range; /** * @var View */ - protected $view; + private $view; protected function setUp() { diff --git a/tests/TestCase.php b/tests/TestCase.php index 44e3911..c48e8ea 100644 --- a/tests/TestCase.php +++ b/tests/TestCase.php @@ -23,8 +23,7 @@ protected function getMockNoConstructor($class_name) ->getMockBuilder($class_name) ->disableOriginalConstructor() ->disableOriginalClone() - ->getMock() - ; + ->getMock(); } /** @@ -39,7 +38,6 @@ protected function getMockAbstract($class_name, array $methods) ->getMockBuilder($class_name) ->disableOriginalConstructor() ->setMethods($methods) - ->getMockForAbstractClass() - ; + ->getMockForAbstractClass(); } } diff --git a/tests/Twig/Extension/PaginationExtensionTest.php b/tests/Twig/Extension/PaginationExtensionTest.php index aba496a..27727a6 100644 --- a/tests/Twig/Extension/PaginationExtensionTest.php +++ b/tests/Twig/Extension/PaginationExtensionTest.php @@ -19,12 +19,12 @@ class PaginationExtensionTest extends TestCase /** * @var PaginationExtension */ - protected $extension; + private $extension; /** * @var string */ - protected $template = 'foo'; + private $template = 'foo'; protected function setUp() {