diff --git a/composer.json b/composer.json index b425fe4d..9cec64bd 100644 --- a/composer.json +++ b/composer.json @@ -34,6 +34,7 @@ "nelmio/cors-bundle": "^1.5", "ocramius/proxy-manager": "^2.1.1", "onelogin/php-saml": "^3.4", + "pagerfanta/pagerfanta": "^2.1", "phpoffice/phpspreadsheet": "^1.10", "phpoffice/phpword": "^0.17", "psr/log": "^1.1", @@ -59,8 +60,7 @@ "symfony/yaml": "^4.0", "twig/extra-bundle": "^3.0", "twig/intl-extra": "^3.0", - "twig/string-extra": "^3.0", - "white-october/pagerfanta-bundle": "^1.1" + "twig/string-extra": "^3.0" }, "require-dev": { "dama/doctrine-test-bundle": "^6.0", diff --git a/composer.lock b/composer.lock index e26339b8..48966314 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "937e678d15c03f8508dd269116d57d82", + "content-hash": "b2981837e799c1f3dc53a03fb19ba617", "packages": [ { "name": "beberlei/doctrineextensions", @@ -9216,67 +9216,6 @@ ], "time": "2019-11-24T13:36:37+00:00" }, - { - "name": "white-october/pagerfanta-bundle", - "version": "v1.3.2", - "source": { - "type": "git", - "url": "https://github.com/whiteoctober/WhiteOctoberPagerfantaBundle.git", - "reference": "6df560869b5e09a3acf920890ab40598998b30ae" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/whiteoctober/WhiteOctoberPagerfantaBundle/zipball/6df560869b5e09a3acf920890ab40598998b30ae", - "reference": "6df560869b5e09a3acf920890ab40598998b30ae", - "shasum": "" - }, - "require": { - "pagerfanta/pagerfanta": "^1.1.0|^2.0.0", - "php": ">=5.3.3", - "symfony/framework-bundle": "~2.3|~3.0|~4.0", - "symfony/property-access": "~2.3|~3.0|~4.0", - "symfony/translation": "~2.3|~3.0|~4.0", - "symfony/twig-bundle": "~2.3|~3.0|~4.0" - }, - "conflict": { - "twig/twig": "<1.34|>=2.0,<2.4" - }, - "require-dev": { - "phpunit/phpunit": "~3.7|~4.0|^5.0", - "symfony/symfony": "~2.3|~3.0|~4.0" - }, - "type": "symfony-bundle", - "extra": { - "branch-alias": { - "dev-master": "1.0.x-dev" - } - }, - "autoload": { - "psr-4": { - "WhiteOctober\\PagerfantaBundle\\": "" - }, - "exclude-from-classmap": [ - "Tests/", - "TestsProject/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Pablo Díez", - "email": "pablodip@gmail.com" - } - ], - "description": "Bundle to use Pagerfanta with Symfony2", - "keywords": [ - "page", - "paging" - ], - "time": "2019-12-02T14:19:37+00:00" - }, { "name": "willdurand/jsonp-callback-validator", "version": "v1.1.0", diff --git a/config/bundles.php b/config/bundles.php index 42cae898..331f3d08 100644 --- a/config/bundles.php +++ b/config/bundles.php @@ -11,7 +11,6 @@ return [ Symfony\Bundle\TwigBundle\TwigBundle::class => ['all' => true], Symfony\Bundle\SecurityBundle\SecurityBundle::class => ['all' => true], Symfony\Bundle\SwiftmailerBundle\SwiftmailerBundle::class => ['all' => true], - WhiteOctober\PagerfantaBundle\WhiteOctoberPagerfantaBundle::class => ['all' => true], Symfony\Bundle\MakerBundle\MakerBundle::class => ['dev' => true], Symfony\Bundle\DebugBundle\DebugBundle::class => ['dev' => true, 'test' => true], DAMA\DoctrineTestBundle\DAMADoctrineTestBundle::class => ['test' => true], diff --git a/src/Twig/PaginationExtension.php b/src/Twig/PaginationExtension.php new file mode 100644 index 00000000..ad909b10 --- /dev/null +++ b/src/Twig/PaginationExtension.php @@ -0,0 +1,101 @@ +view = new TwitterBootstrap3View(); + $this->router = $router; + } + + /** + * {@inheritdoc} + */ + public function getFunctions() + { + return [ + new TwigFunction('pagerfanta', [$this, 'renderPagerfanta'], ['is_safe' => ['html']]), + new TwigFunction('pagination', [$this, 'renderPagination'], ['is_safe' => ['html']]), + ]; + } + + /** + * @deprecated since 1.8 + */ + public function renderPagerfanta(Pagerfanta $pagerfanta, $viewName = null, array $options = []) + { + @trigger_error('Twig function pagerfanta() is deprecated and will be removed with 2.0, use pagination() instead', E_USER_DEPRECATED); + + if (is_array($viewName)) { + $options = $viewName; + } + + return $this->renderPagination($pagerfanta, $options); + } + + public function renderPagination(Pagerfanta $pagerfanta, array $options = []) + { + $routeGenerator = $this->createRouteGenerator($options); + + $options['proximity'] = 1; + //$options['prev_message'] = '←'; + //$options['next_message'] = '→'; + $options['prev_message'] = ''; + $options['next_message'] = ''; + + return $this->view->render($pagerfanta, $routeGenerator, $options); + } + + private function createRouteGenerator(array $options = []) + { + $options = array_replace([ + 'routeName' => null, + 'routeParams' => [], + 'pageParameter' => '[page]', + ], $options); + + $router = $this->router; + + if (null === $options['routeName']) { + throw new \Exception('Pagination is missing the "routeName" option'); + } + + $routeName = $options['routeName']; + $routeParams = $options['routeParams']; + $pagePropertyPath = new PropertyPath($options['pageParameter']); + + return function ($page) use ($router, $routeName, $routeParams, $pagePropertyPath) { + $propertyAccessor = PropertyAccess::createPropertyAccessor(); + $propertyAccessor->setValue($routeParams, $pagePropertyPath, $page); + + return $router->generate($routeName, $routeParams); + }; + } +} diff --git a/src/Utils/Translator.php b/src/Utils/Translator.php index 81d27111..56f9073f 100644 --- a/src/Utils/Translator.php +++ b/src/Utils/Translator.php @@ -13,17 +13,10 @@ use Symfony\Bundle\FrameworkBundle\Translation\Translator as BaseTranslator; use Symfony\Component\Translation\Exception\InvalidArgumentException; use Symfony\Component\Translation\MessageCatalogueInterface; use Symfony\Component\Translation\TranslatorBagInterface; -use Symfony\Component\Translation\TranslatorInterface as LegacyTranslatorInterface; use Symfony\Contracts\Translation\LocaleAwareInterface; use Symfony\Contracts\Translation\TranslatorInterface; -/** - * Should be: - * class Translator implements TranslatorInterface, TranslatorBagInterface, LocaleAwareInterface - * - * But this is not compatible with PagerFanta yet. - */ -class Translator implements LegacyTranslatorInterface, TranslatorInterface, TranslatorBagInterface +class Translator implements TranslatorInterface, TranslatorBagInterface, LocaleAwareInterface { /** * @var BaseTranslator diff --git a/symfony.lock b/symfony.lock index b420912e..e103f948 100644 --- a/symfony.lock +++ b/symfony.lock @@ -271,7 +271,7 @@ "version": "3.4.1" }, "pagerfanta/pagerfanta": { - "version": "v1.0.5" + "version": "v2.1.3" }, "paragonie/random_compat": { "version": "v2.0.17" @@ -735,9 +735,6 @@ "webmozart/assert": { "version": "1.2.0" }, - "white-october/pagerfanta-bundle": { - "version": "v1.1.2" - }, "willdurand/jsonp-callback-validator": { "version": "v1.1.0" }, diff --git a/templates/customer/embed_projects.html.twig b/templates/customer/embed_projects.html.twig index 855faeb3..6346a40e 100644 --- a/templates/customer/embed_projects.html.twig +++ b/templates/customer/embed_projects.html.twig @@ -7,7 +7,7 @@ id="project_list_box" data-href="{{ path('customer_projects', {'id': customer.id}) }}" data-reload="kimai.projectUpdate" {% endblock %} {% block box_tools %} - {{ pagerfanta(projects, 'twitter_bootstrap3_translated', { proximity: 1, css_container_class: 'pagination pagination-sm inline', routeName: 'customer_projects', routeParams: {'id': customer.id} }) }} + {{ pagination(projects, { css_container_class: 'pagination pagination-sm inline', routeName: 'customer_projects', routeParams: {'id': customer.id} }) }} {% endblock %} {% block box_body_class %}no-padding{% endblock %} {% block box_tools_attributes %}data-page="{{ page }}"{% endblock %} diff --git a/templates/macros/datatables.html.twig b/templates/macros/datatables.html.twig index 07036bc3..cdafd5f3 100644 --- a/templates/macros/datatables.html.twig +++ b/templates/macros/datatables.html.twig @@ -206,7 +206,7 @@ {% endif %} {% if route is not empty and entries is not null%}
{% endif %} {% endmacro %} diff --git a/templates/project/embed_activities.html.twig b/templates/project/embed_activities.html.twig index 6fc8fd9f..1e29d6a9 100644 --- a/templates/project/embed_activities.html.twig +++ b/templates/project/embed_activities.html.twig @@ -6,7 +6,7 @@ id="activity_list_box" data-href="{{ path('project_activities', {'id': project.id}) }}" data-reload="kimai.activityUpdate" {% endblock %} {% block box_tools %} - {{ pagerfanta(activities, 'twitter_bootstrap3_translated', { proximity: 1, css_container_class: 'pagination pagination-sm inline', routeName: 'project_activities', routeParams: {'id': project.id} }) }} + {{ pagination(activities, { css_container_class: 'pagination pagination-sm inline', routeName: 'project_activities', routeParams: {'id': project.id} }) }} {% endblock %} {% block box_body_class %}no-padding{% endblock %} {% block box_tools_attributes %}data-page="{{ page }}"{% endblock %} diff --git a/tests/Twig/PaginationExtensionTest.php b/tests/Twig/PaginationExtensionTest.php new file mode 100644 index 00000000..623efc4f --- /dev/null +++ b/tests/Twig/PaginationExtensionTest.php @@ -0,0 +1,140 @@ +getMockBuilder(UrlGeneratorInterface::class)->getMock(); + $urlGenerator + ->expects($this->any()) + ->method('generate') + ->will($this->returnCallback(function ($name, $parameters = []) { + $params = []; + foreach ($parameters as $k => $v) { + $params[] = $k . '=' . $v; + } + + return (string) $name . '?' . implode('&', $params); + })) + ; + + return $urlGenerator; + } + + protected function getSut(): PaginationExtension + { + return new PaginationExtension($this->getUrlGenerator()); + } + + public function testGetFunctions() + { + $functions = ['pagerfanta', 'pagination']; + $sut = $this->getSut(); + $twigFunctions = $sut->getFunctions(); + self::assertCount(count($functions), $twigFunctions); + $i = 0; + /** @var TwigFunction $filter */ + foreach ($twigFunctions as $filter) { + self::assertInstanceOf(TwigFunction::class, $filter); + self::assertEquals($functions[$i++], $filter->getName()); + } + } + + /** + * @group legacy + */ + public function testDeprecatedRenderPagerfanta() + { + $sut = $this->getSut(); + + $values = array_fill(0, 151, 'blub'); + $pagerfanta = new Pagerfanta(new ArrayAdapter($values)); + $result = $sut->renderPagerfanta($pagerfanta, 'twitter_bootstrap3_translated', [ + 'css_container_class' => 'pagination pagination-sm inline', + 'routeName' => 'project_activities', + 'routeParams' => ['id' => 137] + ]); + $this->assertPaginationHtml($result); + } + + /** + * @group legacy + */ + public function testDeprecatedRenderPagerfantaWithoutTemplateName() + { + $sut = $this->getSut(); + + $values = array_fill(0, 151, 'blub'); + $pagerfanta = new Pagerfanta(new ArrayAdapter($values)); + $result = $sut->renderPagerfanta($pagerfanta, [ + 'css_container_class' => 'pagination pagination-sm inline', + 'routeName' => 'project_activities', + 'routeParams' => ['id' => 137] + ]); + $this->assertPaginationHtml($result); + } + + protected function assertPaginationHtml($result) + { + $expected = + ''; + + self::assertEquals($expected, $result); + } + + public function testRenderPagination() + { + $sut = $this->getSut(); + + $values = array_fill(0, 151, 'blub'); + $pagerfanta = new Pagerfanta(new ArrayAdapter($values)); + $result = $sut->renderPagination($pagerfanta, [ + 'css_container_class' => 'pagination pagination-sm inline', + 'routeName' => 'project_activities', + 'routeParams' => ['id' => 137] + ]); + $this->assertPaginationHtml($result); + } + + public function testRenderPaginationWithoutRouteName() + { + $this->expectException(\Exception::class); + $this->expectExceptionMessage('Pagination is missing the "routeName" option'); + + $sut = $this->getSut(); + + $values = array_fill(0, 151, 'blub'); + $pagerfanta = new Pagerfanta(new ArrayAdapter($values)); + $result = $sut->renderPagination($pagerfanta, [ + 'css_container_class' => 'pagination pagination-sm inline', + 'routeParams' => ['id' => 137] + ]); + $this->assertPaginationHtml($result); + } +} diff --git a/translations/pagerfanta.ar.xlf b/translations/pagerfanta.ar.xlf deleted file mode 100755 index c178679e..00000000 --- a/translations/pagerfanta.ar.xlf +++ /dev/null @@ -1,15 +0,0 @@ - -