diff --git a/.github/workflows/php-checks.yaml b/.github/workflows/php-checks.yaml index 4984360..2ea7d72 100644 --- a/.github/workflows/php-checks.yaml +++ b/.github/workflows/php-checks.yaml @@ -12,10 +12,10 @@ jobs: strategy: matrix: - php-version: ['7.4', '8.0', '8.1'] + php-version: ['8.1'] dependencies: [''] include: - - { php-version: '7.4', dependencies: '--prefer-lowest --prefer-stable' } + - { php-version: '8.1', dependencies: '--prefer-lowest --prefer-stable' } name: Unit tests - PHP ${{ matrix.php-version }} ${{ matrix.dependencies }} @@ -68,7 +68,7 @@ jobs: - name: Setup PHP uses: shivammathur/setup-php@v2 with: - php-version: '7.4' + php-version: '8.1' extensions: mbstring, intl tools: composer:v2 diff --git a/CHANGELOG.md b/CHANGELOG.md index ad2f78e..c7de50e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,10 @@ Changelog ========= ## Unreleased +- Allow Symfony 6 +- Require php 8.1 + - [**BC**] Use php 8.1 features and types +- Add `FieldOption` Enum ## 5.1.0 - 2022-04-23 - Allow php ^8 diff --git a/README.md b/README.md index 70bca3e..c0738ff 100644 --- a/README.md +++ b/README.md @@ -62,7 +62,7 @@ You need to add the following lines in your deps : Add KitpagesChainBundle in your composer.json -``` +```json { "require": { "vysokeskoly/data-grid-bundle": "^5.0" @@ -72,17 +72,17 @@ Add KitpagesChainBundle in your composer.json Now tell composer to download the bundle by running the step: -``` bash +```bash $ php composer.phar update vysokeskoly/data-grid-bundle ``` AppKernel.php -``` php -$bundles = array( +```php +$bundles = [ ... new Kitpages\DataGridBundle\KitpagesDataGridBundle(), -); +]; ``` Configuration in config.yml @@ -120,10 +120,11 @@ Simple Usage example use Kitpages\DataGridBundle\Grid\GridConfig; use Kitpages\DataGridBundle\Grid\Field; use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\HttpFoundation\Response; class ContactController { - public function productListAction(Request $request) + public function productListAction(Request $request): Response { // create query builder $repository = $this->getDoctrine()->getRepository('AcmeStoreBundle:Product'); @@ -132,24 +133,22 @@ class ContactController ->setParameter('price', '19.90') ; - $gridConfig = new GridConfig(); + $gridConfig = new GridConfig($queryBuilder, 'item.id'); $gridConfig - ->setQueryBuilder($queryBuilder) - ->setCountFieldName('item.id') ->addField('item.id') - ->addField('item.slug', array('filterable' => true)) - ->addField('item.updatedAt', array( + ->addField('item.slug', ['filterable' => true]) + ->addField('item.updatedAt', [ 'sortable' => true, - 'formatValueCallback' => function($value) { return $value->format('Y/m/d'); } - )) + 'formatValueCallback' => fn ($value) => $value->format('Y/m/d') + ]) ; $gridManager = $this->get('kitpages_data_grid.grid_manager'); $grid = $gridManager->getGrid($gridConfig, $request); - return $this->render('AppSiteBundle:Default:productList.html.twig', array( + return $this->render('AppSiteBundle:Default:productList.html.twig', [ 'grid' => $grid - )); + ]); } } ``` @@ -193,11 +192,11 @@ More advanced usage use Kitpages\DataGridBundle\Grid\GridConfig; use Kitpages\DataGridBundle\Grid\Field; use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\HttpFoundation\Response; class AdminController extends Controller { - - public function listAction(Request $request, $state) + public function listAction(Request $request, $state): Response { // create query builder $em = $this->get('doctrine')->getEntityManager(); @@ -211,23 +210,21 @@ class AdminController extends Controller ->setParameter('state', $state) ; - $gridConfig = new GridConfig(); + $gridConfig = new GridConfig($queryBuilder, 'm.id'); $gridConfig - ->setQueryBuilder($queryBuilder) - ->setCountFieldName("m.id"); - ->addField('m.title', array('label' => 'title', 'filterable' => true)) - ->addField('m.country', array('filterable' => true)) - ->addField('c.corporation', array('filterable' => true)) - ->addField('e.lastname', array('filterable' => true)) - ->addField('e.email', array('filterable' => true)) + ->addField('m.title', ['label' => 'title', 'filterable' => true]) + ->addField('m.country', ['filterable' => true]) + ->addField('c.corporation', ['filterable' => true]) + ->addField('e.lastname', ['filterable' => true]) + ->addField('e.email', ['filterable' => true]) ; $gridManager = $this->get('kitpages_data_grid.grid_manager'); $grid = $gridManager->getGrid($gridConfig, $request); - return $this->render('KitappMissionBundle:Admin:list.html.twig', array( + return $this->render('KitappMissionBundle:Admin:list.html.twig', [ 'grid' => $grid - )); + ]); } } ``` @@ -241,12 +238,16 @@ Field "as" For request like - $queryBuilder->select("item, item.id * 3 as foo"); +```php +$queryBuilder->select("item, item.id * 3 as foo"); +``` You can display the foo field with - $gridConfig->addField("item.id"); - $gridConfig->addField("foo"); +```php +$gridConfig->addField("item.id"); +$gridConfig->addField("foo"); +``` Events @@ -264,18 +265,20 @@ Tag system is used to get some fields by tags. When you create a field, you can define some tags associated to this field. After that, in the grid config, you can find the fields that match this tag. - // add tag as the third parameter of the field - $gridConfig->addField("item.id", [], ['foo', 'bar']); - $gridConfig->addField("foo", [], ['myTag', 'foo']); +```php +// add tag as the third parameter of the field +$gridConfig->addField("item.id", [], ['foo', 'bar']); +$gridConfig->addField("foo", [], ['myTag', 'foo']); - // get fieldList matching 'bar' tag. There is only one result. - $fieldList = $gridConfig->getFieldListByTag('bar'); - $fieldList[0] // -> this is the first Field (which name is 'item.id') +// get fieldList matching 'bar' tag. There is only one result. +$fieldList = $gridConfig->getFieldListByTag('bar'); +$fieldList[0] // -> this is the first Field (which name is 'item.id') +``` Custom class for the $grid object ================================= -By default, the following line +By default, the following line ```php $grid = $gridManager->getGrid($gridConfig, $request); ``` @@ -294,7 +297,7 @@ $grid = $gridManager->getGrid($gridConfig, $request,$myCustomGrid); // now the $grid object is an instance of CustomGrid (it // is exactly the same object than $myCustomGrid, not cloned) ``` - + Reference guide =============== @@ -304,17 +307,32 @@ Reference guide when you add a field, you can set these parameters : ```php -$gridConfig->addField('slug', array( +$gridConfig->addField('slug', [ 'label' => 'Mon slug', 'sortable' => false, 'visible' => true, 'filterable' => true, 'translatable' => true, - 'formatValueCallback' => function($value) { return strtoupper($value); }, + 'formatValueCallback' => fn ($value) => strtoupper($value), 'autoEscape' => true, 'category' => null, // only used by you for checking this value in your events if you want to... 'nullIfNotExists' => false, // for leftJoin, if value is not defined, this can return null instead of an exception -)); +]); +``` + +TIP: Use `FieldOption` enum +```php +$gridConfig->addField('slug', [ + FieldOption::Label->value => 'Mon slug', + FieldOption::Sortable->value => false, + FieldOption::Visible->value => true, + FieldOption::Filterable->value => true, + FieldOption::Translatable->value => true, + FieldOption::FormatValueCallback->value => fn ($value) => strtoupper($value), + FieldOption::AutoEscape->value => true, + FieldOption::Category->value => null, // only used by you for checking this value in your events if you want to... + FieldOption::NullIfNotExists->value => false, // for leftJoin, if value is not defined, this can return null instead of an exception +]); ``` ## What can you personalize in your twig template diff --git a/composer.json b/composer.json index 3c0def4..3f77674 100644 --- a/composer.json +++ b/composer.json @@ -21,29 +21,29 @@ ], "homepage": "https://github.com/vysokeskoly/KitpagesDataGridBundle", "require": { - "php": "^7.4 || ^8.0", + "php": "^8.1", "ext-pdo": "*", "beberlei/assert": "^3.3", "doctrine/doctrine-bundle": "^2.5.7", "doctrine/orm": "^2.11.2", - "symfony/dependency-injection": "^5.0", - "symfony/framework-bundle": "^5.0", - "symfony/templating": "^5.0", - "symfony/translation": "^5.0", - "symfony/twig-bundle": "^5.0", + "symfony/dependency-injection": "^5.0 || ^6.0", + "symfony/framework-bundle": "^5.0 || ^6.0", + "symfony/templating": "^5.0 || ^6.0", + "symfony/translation": "^5.0 || ^6.0", + "symfony/twig-bundle": "^5.0 || ^6.0", "twig/twig": "^3.0" }, "require-dev": { "ergebnis/composer-normalize": "^2.24", - "lmc/coding-standard": "^3.2", + "lmc/coding-standard": "^3.3", "phpstan/extension-installer": "^1.1", "phpstan/phpstan": "^1.5", "phpstan/phpstan-beberlei-assert": "^1.0", "phpstan/phpstan-phpunit": "^1.0", - "phpunit/phpunit": "^9.5", - "symfony/browser-kit": "^5.0", - "symfony/finder": "^5.0", - "symfony/yaml": "^5.0" + "phpunit/phpunit": "^9.5.20", + "symfony/browser-kit": "^5.0 || ^6.0", + "symfony/finder": "^5.0 || ^6.0", + "symfony/yaml": "^5.0 || ^6.0" }, "autoload": { "psr-4": { diff --git a/ecs.php b/ecs.php index b8bbe8e..e50804e 100644 --- a/ecs.php +++ b/ecs.php @@ -4,6 +4,7 @@ use PHP_CodeSniffer\Standards\Generic\Sniffs\PHP\ForbiddenFunctionsSniff; use PhpCsFixer\Fixer\FunctionNotation\PhpdocToParamTypeFixer; +use SlevomatCodingStandard\Sniffs\TypeHints\ParameterTypeHintSniff; use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator; use Symplify\EasyCodingStandard\ValueObject\Option; @@ -14,14 +15,17 @@ Option::SKIP, [ ForbiddenFunctionsSniff::class => [ - __DIR__ . '/src/Grid/Grid.php', + 'src/Grid/Grid.php', ], PhpdocToParamTypeFixer::class => [ - __DIR__ . '/src/Hydrators/DataGridHydrator.php', + 'src/Hydrators/DataGridHydrator.php', ], - ] + ParameterTypeHintSniff::class . '.' . ParameterTypeHintSniff::CODE_MISSING_NATIVE_TYPE_HINT => [ + 'src/Hydrators/DataGridHydrator.php', + ], + ], ); $containerConfigurator->import(__DIR__ . '/vendor/lmc/coding-standard/ecs.php'); - $containerConfigurator->import(__DIR__ . '/vendor/lmc/coding-standard/ecs-7.4.php'); + $containerConfigurator->import(__DIR__ . '/vendor/lmc/coding-standard/ecs-8.1.php'); }; diff --git a/phpstan.neon b/phpstan.neon index 8ba0386..b4ab510 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -11,7 +11,3 @@ parameters: message: "#^Call to an undefined method object\\:\\:getManager\\(\\)\\.$#" count: 1 path: tests/BundleOrmTestCase.php - - - message: "#^Parameter \\#1 \\$field of method Kitpages\\\\DataGridBundle\\\\Grid\\\\GridConfig\\:\\:addField\\(\\) expects Kitpages\\\\DataGridBundle\\\\Grid\\\\Field\\|string, array\\|\\(Closure\\)\\|float\\|int\\|stdClass\\|true\\|null given\\.$#" - count: 1 - path: tests/Grid/GridConfigTest.php diff --git a/src/Event/AbstractEvent.php b/src/Event/AbstractEvent.php index f522ae1..bde023b 100644 --- a/src/Event/AbstractEvent.php +++ b/src/Event/AbstractEvent.php @@ -30,20 +30,12 @@ public function isPropagationStopped(): bool return $this->isPropagationStopped; } - /** - * @param mixed $key - * @param mixed $val - */ - public function set($key, $val): void + public function set(mixed $key, mixed $val): void { $this->data[$key] = $val; } - /** - * @param mixed $key - * @return mixed - */ - public function get($key) + public function get(mixed $key): mixed { if (!array_key_exists($key, $this->data)) { return null; diff --git a/src/Grid/Field.php b/src/Grid/Field.php index 4a7ab3a..52a79c5 100644 --- a/src/Grid/Field.php +++ b/src/Grid/Field.php @@ -6,7 +6,6 @@ class Field { - protected string $fieldName; protected string $label; protected bool $sortable = false; protected bool $filterable = false; @@ -26,27 +25,23 @@ class Field */ protected array $tagList = []; + /** + * @see FieldOption + * Field option usage: + * - currently it must be used by a ->value since Enum can not be used as a array key (yet?) + * + * new Field('name', [FieldOption::Label->value => 'label']) + * + * @phpstan-param array $optionList + */ public function __construct( - string $fieldName, + protected string $fieldName, array $optionList = [], - array $tagList = [] + array $tagList = [], ) { - $this->fieldName = $fieldName; $this->label = $fieldName; foreach ($optionList as $key => $val) { - if (\in_array($key, [ - 'label', - 'sortable', - 'filterable', - 'visible', - 'formatValueCallback', - 'autoEscape', - 'translatable', - 'category', - 'nullIfNotExists', - 'dataList', - 'uniqueId', - ], true)) { + if (FieldOption::tryFrom($key) !== null && property_exists($this, $key)) { $this->$key = $val; } else { throw new \InvalidArgumentException("key $key doesn't exist in option list"); @@ -162,7 +157,7 @@ public function getData(string $key): array { if (!array_key_exists($key, $this->dataList)) { throw new DataGridException( - "key [$key] is not defined in the data-list (should be defined in the dataList parameter in the new Field..." + "key [$key] is not defined in the data-list (should be defined in the dataList parameter in the new Field...", ); } diff --git a/src/Grid/FieldOption.php b/src/Grid/FieldOption.php new file mode 100644 index 0000000..a3364a8 --- /dev/null +++ b/src/Grid/FieldOption.php @@ -0,0 +1,18 @@ +urlTool = $urlTool; - $this->requestUri = $requestUri; - $this->dispatcher = $dispatcher; - $this->gridConfig = $gridConfig; } public function getSelectorUrl(string $selectorField, string $selectorValue): string @@ -46,7 +38,7 @@ public function getSelectorUrl(string $selectorField, string $selectorValue): st [ $this->getSelectorFieldFormName() => $selectorField, $this->getSelectorValueFormName() => $selectorValue, - ] + ], ); } else { $uri = $this->urlTool->changeRequestQueryString( @@ -54,7 +46,7 @@ public function getSelectorUrl(string $selectorField, string $selectorValue): st [ $this->getSelectorFieldFormName() => '', $this->getSelectorValueFormName() => '', - ] + ], ); } @@ -66,7 +58,7 @@ public function getSortUrl(string $fieldName): string $uri = $this->urlTool->changeRequestQueryString( $this->requestUri, $this->getSortFieldFormName(), - $fieldName + $fieldName, ); if ($fieldName == $this->getSortField()) { $order = ($this->getSortOrder() === 'ASC') ? 'DESC' : 'ASC'; @@ -77,7 +69,7 @@ public function getSortUrl(string $fieldName): string return $this->urlTool->changeRequestQueryString( $uri, $this->getSortOrderFormName(), - $order + $order, ); } @@ -92,8 +84,7 @@ public function getSortCssClass(string $fieldName): string return $css; } - /** @return mixed */ - public function displayGridValue(array $row, Field $field) + public function displayGridValue(array $row, Field $field): mixed { $value = null; $fieldName = $field->getFieldName(); diff --git a/src/Grid/GridConfig.php b/src/Grid/GridConfig.php index b807b1e..cc8b9a8 100644 --- a/src/Grid/GridConfig.php +++ b/src/Grid/GridConfig.php @@ -9,9 +9,6 @@ class GridConfig { protected string $name = 'grid'; - protected QueryBuilder $queryBuilder; - protected string $countFieldName; - protected ?PaginatorConfig $paginatorConfig = null; /** @@ -26,27 +23,25 @@ class GridConfig /** @var Selector[] */ protected array $selectorList = []; - public function __construct(QueryBuilder $queryBuilder, string $countFieldName) + public function __construct(protected QueryBuilder $queryBuilder, protected string $countFieldName) { - $this->queryBuilder = $queryBuilder; - $this->countFieldName = $countFieldName; } /** - * @param Field|string $field - * @param string[] $options list of tags - * @param mixed $tagList + * @see FieldOption + * Field option usage: + * - currently it must be used by a ->value since Enum can not be used as a array key (yet?) * - * @return GridConfig Fluent interface + * ->addField('name', [FieldOption::Label->value => 'label']) + * + * @phpstan-param array $options */ - public function addField($field, array $options = [], $tagList = []): self + public function addField(Field|string $field, array $options = [], mixed $tagList = []): self { - if (!(\is_string($field) || $field instanceof Field)) { - throw new \InvalidArgumentException('Argument $field should be string or instance of Kitpages\DataGridBundle\Grid\Field'); - } - if (\is_string($field)) { $field = new Field($field, $options, $tagList); + } elseif (!empty($options) || !empty($tagList)) { + throw new \InvalidArgumentException('Options and tags are only supported for field set by string.'); } $this->fieldList[] = $field; diff --git a/src/Grid/GridManager.php b/src/Grid/GridManager.php index 6442413..cbb451e 100644 --- a/src/Grid/GridManager.php +++ b/src/Grid/GridManager.php @@ -22,23 +22,14 @@ class GridManager { - protected EventDispatcherInterface $dispatcher; - protected PaginatorManager $paginatorManager; - protected NormalizerInterface $itemListNormalizer; protected string $hydratorClass; - /** - * @param mixed $hydratorClass - */ public function __construct( - EventDispatcherInterface $dispatcher, - PaginatorManager $paginatorManager, - NormalizerInterface $itemListNormalizer, - $hydratorClass + protected EventDispatcherInterface $dispatcher, + protected PaginatorManager $paginatorManager, + protected NormalizerInterface $itemListNormalizer, + mixed $hydratorClass, ) { - $this->dispatcher = $dispatcher; - $this->paginatorManager = $paginatorManager; - $this->itemListNormalizer = $itemListNormalizer; $this->hydratorClass = $hydratorClass; } @@ -54,7 +45,7 @@ public function __construct( public function getGrid( GridConfig $gridConfig, Request $request, - Grid $grid = null + Grid $grid = null, ): Grid { $queryBuilder = $gridConfig->getQueryBuilder(); @@ -64,7 +55,7 @@ public function getGrid( new UrlTool(), $request->getRequestUri(), $this->dispatcher, - $gridConfig + $gridConfig, ); } else { $grid->setGridConfig($gridConfig); @@ -132,11 +123,11 @@ public function getGrid( ? $this->itemListNormalizer->normalize( $event->get('query'), $event->get('gridQueryBuilder'), - $this->hydratorClass + $this->hydratorClass, ) : $this->itemListNormalizer->normalize( $event->get('query'), - $event->get('gridQueryBuilder') + $event->get('gridQueryBuilder'), ); // end normalization @@ -145,8 +136,7 @@ public function getGrid( return $grid; } - /** @param mixed $filter */ - protected function applyFilter(QueryBuilder $queryBuilder, Grid $grid, $filter): void + protected function applyFilter(QueryBuilder $queryBuilder, Grid $grid, mixed $filter): void { if (!$filter) { return; @@ -175,12 +165,11 @@ protected function applyFilter(QueryBuilder $queryBuilder, Grid $grid, $filter): $this->dispatcher->dispatch(new AfterApplyFilter($event)); } - /** @param mixed $selectorValue */ protected function applySelector( QueryBuilder $queryBuilder, Grid $grid, string $selectorField, - $selectorValue + mixed $selectorValue, ): void { if (empty($selectorField)) { return; @@ -206,7 +195,7 @@ protected function applySort( QueryBuilder $gridQueryBuilder, Grid $grid, string $sortField, - string $sortOrder + string $sortOrder, ): void { if (empty($sortField)) { return; diff --git a/src/Grid/Item.php b/src/Grid/Item.php index 335d3e4..af6393e 100644 --- a/src/Grid/Item.php +++ b/src/Grid/Item.php @@ -4,39 +4,25 @@ class Item { - /** @var mixed */ - protected $entity; - /** @var mixed */ - protected $row; + protected mixed $entity; + protected mixed $row; - /** - * @param mixed $entity - */ - public function setEntity($entity): void + public function setEntity(mixed $entity): void { $this->entity = $entity; } - /** - * @return mixed - */ - public function getEntity() + public function getEntity(): mixed { return $this->entity; } - /** - * @param mixed $row - */ - public function setRow($row): void + public function setRow(mixed $row): void { $this->row = $row; } - /** - * @return mixed - */ - public function getRow() + public function getRow(): mixed { return $this->row; } diff --git a/src/Paginator/Paginator.php b/src/Paginator/Paginator.php index 087ac97..3517222 100644 --- a/src/Paginator/Paginator.php +++ b/src/Paginator/Paginator.php @@ -6,9 +6,6 @@ class Paginator { - protected UrlTool $urlTool; - protected PaginatorConfig $paginatorConfig; - protected string $requestUri; protected ?int $totalPageCount = null; protected ?int $minPage = null; protected ?int $maxPage = null; @@ -17,11 +14,8 @@ class Paginator protected int $totalItemCount = 0; protected int $currentPage = 1; - public function __construct(PaginatorConfig $paginatorConfig, UrlTool $urlTool, string $requestUri) + public function __construct(protected PaginatorConfig $paginatorConfig, protected UrlTool $urlTool, protected string $requestUri) { - $this->paginatorConfig = $paginatorConfig; - $this->urlTool = $urlTool; - $this->requestUri = $requestUri; } public function getPageRange(): array @@ -34,13 +28,12 @@ public function getPageRange(): array return $tab; } - /** @param mixed $val */ - public function getUrl(string $key, $val): string + public function getUrl(string $key, mixed $val): string { return $this->urlTool->changeRequestQueryString( $this->requestUri, $this->paginatorConfig->getRequestQueryName($key), - $val + $val, ); } diff --git a/src/Paginator/PaginatorConfig.php b/src/Paginator/PaginatorConfig.php index 7c06bb0..c109809 100644 --- a/src/Paginator/PaginatorConfig.php +++ b/src/Paginator/PaginatorConfig.php @@ -7,15 +7,11 @@ class PaginatorConfig { protected string $name = 'paginator'; - protected QueryBuilder $queryBuilder; - protected string $countFieldName; protected ?int $itemCountInPage = null; protected ?int $visiblePageCountInPaginator = null; - public function __construct(QueryBuilder $queryBuilder, string $countFieldName) + public function __construct(protected QueryBuilder $queryBuilder, protected string $countFieldName) { - $this->queryBuilder = $queryBuilder; - $this->countFieldName = $countFieldName; } public function getRequestQueryName(string $key): string diff --git a/src/Paginator/PaginatorManager.php b/src/Paginator/PaginatorManager.php index 5cad5ac..29fc5f7 100644 --- a/src/Paginator/PaginatorManager.php +++ b/src/Paginator/PaginatorManager.php @@ -11,7 +11,6 @@ class PaginatorManager { - protected EventDispatcherInterface $dispatcher; protected array $paginatorParameterList; /** * @phpstan-var null|callable(PaginatorConfig): PaginatorConfig @@ -19,14 +18,10 @@ class PaginatorManager */ protected $configurePaginator; - /** - * @param mixed $paginatorParameterList - */ public function __construct( - EventDispatcherInterface $dispatcher, - $paginatorParameterList + protected EventDispatcherInterface $dispatcher, + mixed $paginatorParameterList, ) { - $this->dispatcher = $dispatcher; $this->paginatorParameterList = $paginatorParameterList; } @@ -58,7 +53,7 @@ public function getPaginator(PaginatorConfig $paginatorConfig, Request $request) sprintf( 'Configure Paginator function return %s instead of a PaginatorConfig.', gettype($configuredPaginator), - ) + ), ); } } @@ -117,7 +112,7 @@ public function getPaginator(PaginatorConfig $paginatorConfig, Request $request) $paginator->setTotalPageCount(0); } else { $paginator->setTotalPageCount( - (int) ((($paginator->getTotalItemCount() - 1) / $paginatorConfig->getItemCountInPage()) + 1) + (int) ((($paginator->getTotalItemCount() - 1) / $paginatorConfig->getItemCountInPage()) + 1), ); } diff --git a/src/Tool/UrlTool.php b/src/Tool/UrlTool.php index 67dbd9f..48c4ca7 100644 --- a/src/Tool/UrlTool.php +++ b/src/Tool/UrlTool.php @@ -6,11 +6,7 @@ class UrlTool { - /** - * @param string|array $mixedKey - * @param mixed $value - */ - public function changeRequestQueryString(string $url, $mixedKey = [], $value = null): string + public function changeRequestQueryString(string $url, string|array $mixedKey = [], mixed $value = null): string { if (is_string($mixedKey)) { $changeTab = ["$mixedKey" => $value]; diff --git a/src/Twig/GlobalsTwigExtension.php b/src/Twig/GlobalsTwigExtension.php index 7a8fe23..b40e257 100644 --- a/src/Twig/GlobalsTwigExtension.php +++ b/src/Twig/GlobalsTwigExtension.php @@ -7,15 +7,10 @@ class GlobalsTwigExtension extends AbstractExtension implements GlobalsInterface { - protected array $gridParameterList; - protected array $paginatorParameterList; - public function __construct( - array $gridParameterList, - array $paginatorParameterList + protected array $gridParameterList, + protected array $paginatorParameterList, ) { - $this->gridParameterList = $gridParameterList; - $this->paginatorParameterList = $paginatorParameterList; } public function getGlobals(): array diff --git a/tests/Functional/TwigExtensionTest.php b/tests/Functional/TwigExtensionTest.php index 14a5f86..5819bdb 100644 --- a/tests/Functional/TwigExtensionTest.php +++ b/tests/Functional/TwigExtensionTest.php @@ -18,7 +18,7 @@ public function testConfigParsing(): void $templating = $client->getContainer()->get('twig'); $this->assertEquals( '@KitpagesDataGrid/Grid/grid-standard.html.twig', - $templating->render('globals.html.twig') + $templating->render('globals.html.twig'), ); } } diff --git a/tests/Grid/CustomGrid.php b/tests/Grid/CustomGrid.php index c3e07ce..dfd796c 100644 --- a/tests/Grid/CustomGrid.php +++ b/tests/Grid/CustomGrid.php @@ -8,21 +8,14 @@ */ class CustomGrid extends Grid { - /** @var mixed */ - private $myCustomParamter; + private mixed $myCustomParamter; - /** - * @return mixed - */ - public function getMyCustomParamter() + public function getMyCustomParamter(): mixed { return $this->myCustomParamter; } - /** - * @param mixed $myCustomParamter - */ - public function setMyCustomParamter($myCustomParamter): void + public function setMyCustomParamter(mixed $myCustomParamter): void { $this->myCustomParamter = $myCustomParamter; } diff --git a/tests/Grid/FieldTest.php b/tests/Grid/FieldTest.php index c69fd6e..33db045 100644 --- a/tests/Grid/FieldTest.php +++ b/tests/Grid/FieldTest.php @@ -37,6 +37,37 @@ public function testConstructor(): void $this->assertFalse($field->getNullIfNotExists()); } + public function testConstructorWithEnums(): void + { + $field = new Field('id'); + $this->assertEquals($field->getFieldName(), 'id'); + + $field = new Field('phone', [ + FieldOption::Label->value => 'Phone', + FieldOption::Sortable->value => true, + FieldOption::Filterable->value => true, + FieldOption::Visible->value => false, + FieldOption::FormatValueCallback->value => function ($value) { + return mb_strtoupper($value); + }, + FieldOption::AutoEscape->value => true, + FieldOption::Translatable->value => true, + FieldOption::Category->value => 'my.category', + FieldOption::NullIfNotExists->value => true, + ]); + $this->assertEquals('Phone', $field->getLabel()); + $this->assertTrue($field->getSortable()); + $this->assertTrue($field->getFilterable()); + $this->assertFalse($field->getVisible()); + $this->assertNotNull($field->getFormatValueCallback()); + $this->assertTrue($field->getFilterable()); + $this->assertEquals('my.category', $field->getCategory()); + $this->assertTrue($field->getNullIfNotExists()); + + $field = new Field('test'); + $this->assertFalse($field->getNullIfNotExists()); + } + public function testWrongParameterConstructor(): void { try { @@ -69,7 +100,7 @@ public function testTagSystem(): void [ 'foo', 'bar', - ] + ], ); $this->assertTrue($field->hasTag('foo')); $this->assertFalse($field->hasTag('tutu')); diff --git a/tests/Grid/GridConfigTest.php b/tests/Grid/GridConfigTest.php index 8ddbf9a..0ad8dfc 100644 --- a/tests/Grid/GridConfigTest.php +++ b/tests/Grid/GridConfigTest.php @@ -14,7 +14,7 @@ protected function setUp(): void { $this->gridConfig = new GridConfig( $this->createMock(QueryBuilder::class), - 'node.id' + 'node.id', ); parent::setUp(); @@ -40,30 +40,39 @@ public function testCanAddAndRetrieveSingleFieldNewSyntax(): void $this->assertEquals($fieldName, $this->gridConfig->getFieldByName($fieldName)->getLabel()); } - public function testAddFieldWrongArgumentType(): void + public function testCanAddAndRetrieveSingleFieldNewSyntaxWithFieldOption(): void { - $arguments = [true, 1, 2.2, [], new \stdClass(), null, function (): void { }]; - - foreach ($arguments as $argument) { - try { - $this->gridConfig->addField($argument); - $this->fail(); - } catch (\InvalidArgumentException $e) { - $this->assertTrue(true); - } - } + $fieldName = uniqid('', true); + $this->gridConfig->addField($fieldName, [ + FieldOption::Label->value => $fieldName, + ]); + + $this->assertInstanceOf(Field::class, $this->gridConfig->getFieldByName($fieldName)); + $this->assertEquals($fieldName, $this->gridConfig->getFieldByName($fieldName)->getLabel()); + } + + public function testShouldNotAddFieldWithOptions(): void + { + $fieldName = uniqid('', true); + $field = new Field($fieldName, ['label' => $fieldName]); + + $this->expectException(\InvalidArgumentException::class); + + $this->gridConfig->addField($field, [ + 'label' => $fieldName, + ]); } public function testTags(): void { $this->gridConfig->addField( - new Field('f1', [], ['foo', 'bar']) + new Field('f1', [], ['foo', 'bar']), ); $this->gridConfig->addField( - new Field('f2', [], ['bar']) + new Field('f2', [], ['bar']), ); $this->gridConfig->addField( - new Field('f3', [], ['foo', 'bar', 'biz']) + new Field('f3', [], ['foo', 'bar', 'biz']), ); $this->assertCount(1, $this->gridConfig->getFieldListByTag('biz')); $this->assertCount(2, $this->gridConfig->getFieldListByTag('foo')); diff --git a/tests/Grid/GridManagerTest.php b/tests/Grid/GridManagerTest.php index 8d0697f..8457f90 100644 --- a/tests/Grid/GridManagerTest.php +++ b/tests/Grid/GridManagerTest.php @@ -51,7 +51,7 @@ public function getGridManager(): GridManager $this->dispatcher, new PaginatorManager($this->dispatcher, $parameters), $normalizer, - DataGridHydrator::class + DataGridHydrator::class, ); } @@ -77,7 +77,7 @@ public function initGridConfig(): GridConfig 'formatValueCallback' => function ($value) { return $value->format('Y/m/d'); }, - ] + ], )); $gridConfig->addField(new Field( 'node.content', @@ -85,7 +85,7 @@ public function initGridConfig(): GridConfig 'formatValueCallback' => function ($value, $row) { return $value . ':' . $row['createdAt']->format('Y'); }, - ] + ], )); $gridConfig->addField(new Field('node.user', [ 'filterable' => true, @@ -112,7 +112,7 @@ public function testGridBasic(): void 'formatValueCallback' => function ($value) { return $value->format('Y/m/d'); }, - ] + ], )); $gridConfig->addField(new Field( 'node.content', @@ -120,7 +120,7 @@ public function testGridBasic(): void 'formatValueCallback' => function ($value, $row) { return $value . ':' . $row['node.createdAt']->format('Y'); }, - ] + ], )); // get paginator @@ -143,7 +143,7 @@ public function testGridBasic(): void new UrlTool(), $request->getUri(), $this->dispatcher, - $gridConfig + $gridConfig, ); $myCustomGrid->setMyCustomParamter('my parameter value'); /** @var CustomGrid $grid */ diff --git a/tests/Grid/GridTest.php b/tests/Grid/GridTest.php index 91c18d7..25fccfc 100644 --- a/tests/Grid/GridTest.php +++ b/tests/Grid/GridTest.php @@ -13,7 +13,7 @@ class GridTest extends TestCase private \DateTime $now; private array $row; /** @var Field|MockObject */ - private $mockField; + private Field $mockField; protected function setUp(): void { @@ -23,7 +23,7 @@ protected function setUp(): void new UrlTool(), '', $dispatcher, - $this->createMock(GridConfig::class) + $this->createMock(GridConfig::class), ); $this->grid->setDispatcher($dispatcher); $this->now = new \DateTime(); diff --git a/tests/Tool/UrlToolTest.php b/tests/Tool/UrlToolTest.php index 1fba203..75aa939 100644 --- a/tests/Tool/UrlToolTest.php +++ b/tests/Tool/UrlToolTest.php @@ -14,7 +14,7 @@ public function testChangeRequestQueryString(): void $newUrl = $urlTool->changeRequestQueryString( $url, 'key1', - 'test' + 'test', ); $this->assertEquals('/titi?key1=test&key2=val2', $newUrl); @@ -23,14 +23,14 @@ public function testChangeRequestQueryString(): void [ 'key1' => 'test1', 'key2' => 'test2', - ] + ], ); $this->assertEquals('/titi?key1=test1&key2=test2', $newUrl); $newUrl = $urlTool->changeRequestQueryString( $url, 'key3', - 'val3' + 'val3', ); $this->assertEquals('/titi?key1=val1&key2=val2&key3=val3', $newUrl); } @@ -42,13 +42,13 @@ public function testChangeRequestUtf8QueryString(): void $newUrl = $urlTool->changeRequestQueryString( $url, 'key1', - 'fös' + 'fös', ); $this->assertEquals('/titi?key1=f%C3%B6s&key2=val2', $newUrl); $newUrl = $urlTool->changeRequestQueryString( $newUrl, 'key3', - 'mystring=-+ glou' + 'mystring=-+ glou', ); $this->assertEquals('/titi?key1=f%C3%B6s&key2=val2&key3=mystring%3D-%2B+glou', $newUrl); } @@ -61,14 +61,14 @@ public function testChangeRequestWithArray(): void $newUrl = $urlTool->changeRequestQueryString( $url, 'key2', - 'glou' + 'glou', ); $this->assertEquals('/titi?tab%5B0%5D=val_tab1&tab%5B1%5D=val_tab2&key2=glou', $newUrl); $newUrl = $urlTool->changeRequestQueryString( $url, 'tab', - ['newval1', 'newval2', 'newval3'] + ['newval1', 'newval2', 'newval3'], ); $this->assertEquals('/titi?tab%5B0%5D=newval1&tab%5B1%5D=newval2&tab%5B2%5D=newval3&key2=val2', $newUrl); @@ -77,14 +77,14 @@ public function testChangeRequestWithArray(): void $newUrl = $urlTool->changeRequestQueryString( $url, 'key2', - 'glou' + 'glou', ); $this->assertEquals('/titi?tab%5Bfield1%5D=val_tab1&tab%5Bfield2%5D=val_tab2&key2=glou', $newUrl); $newUrl = $urlTool->changeRequestQueryString( $url, 'tab', - ['field1' => 'newval1', 'field2' => 'newval2', 'newfield' => 'newval'] + ['field1' => 'newval1', 'field2' => 'newval2', 'newfield' => 'newval'], ); $this->assertEquals('/titi?tab%5Bfield1%5D=newval1&tab%5Bfield2%5D=newval2&tab%5Bnewfield%5D=newval&key2=val2', $newUrl); }