Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 10 additions & 1 deletion .github/workflows/test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@ jobs:

continue-on-error: ${{ matrix.allowed-to-fail }}

env:
SYMFONY_REQUIRE: ${{matrix.symfony-require}}

strategy:
matrix:
php-version:
Expand All @@ -27,6 +30,7 @@ jobs:
- '8.0'
dependencies: [highest]
allowed-to-fail: [false]
symfony-require: [""]
variant: [normal]
include:
- php-version: '7.3'
Expand All @@ -36,6 +40,7 @@ jobs:
- php-version: '8.0'
dependencies: highest
allowed-to-fail: false
symfony-require: 4.4.*
variant: 'symfony/symfony:"4.4.*"'
- php-version: '8.0'
dependencies: highest
Expand All @@ -57,8 +62,12 @@ jobs:
- name: Add PHPUnit matcher
run: echo "::add-matcher::${{ runner.tool_cache }}/phpunit.json"

- name: "Globally install symfony/flex"
if: matrix.symfony-require != ''
run: "composer global require --no-progress --no-scripts --no-plugins symfony/flex"

- name: Install variant
if: matrix.variant != 'normal'
if: matrix.variant != 'normal' && !startsWith(matrix.variant, 'symfony/symfony')
run: composer require ${{ matrix.variant }} --no-update

- name: "Install Composer dependencies (${{ matrix.dependencies }})"
Expand Down
15 changes: 15 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,21 @@
All notable changes to this project will be documented in this file.
This project adheres to [Semantic Versioning](http://semver.org/).

## [3.33.0](https://github.com/sonata-project/SonataDoctrineORMAdminBundle/compare/3.32.1...3.33.0) - 2021-04-19
### Added
- [[#1416](https://github.com/sonata-project/SonataDoctrineORMAdminBundle/pull/1416)] "force_case_insensitivity" option to `StringFilter` in order to force the database to ignore the case sensitivity when matching filters. ([@phansys](https://github.com/phansys))

### Changed
- [[#1395](https://github.com/sonata-project/SonataDoctrineORMAdminBundle/pull/1395)] Default value for the "case_sensitive" option from `true` to `null` in `StringFilter`. ([@phansys](https://github.com/phansys))

### Deprecated
- [[#1416](https://github.com/sonata-project/SonataDoctrineORMAdminBundle/pull/1416)] "case_sensitive" option in `StringFilter`. ([@phansys](https://github.com/phansys))

### Fixed
- [[#1408](https://github.com/sonata-project/SonataDoctrineORMAdminBundle/pull/1408)] Allow to decorate EntityManager ([@michkinn](https://github.com/michkinn))
- [[#1414](https://github.com/sonata-project/SonataDoctrineORMAdminBundle/pull/1414)] Return type for `ModelManager::getModelIdentifier()`. ([@phansys](https://github.com/phansys))
- [[#1399](https://github.com/sonata-project/SonataDoctrineORMAdminBundle/pull/1399)] Fixed triggering always deprecation when calling `ModelManager::getDefaultSortValues()` method ([@franmomu](https://github.com/franmomu))

## [3.32.1](https://github.com/sonata-project/SonataDoctrineORMAdminBundle/compare/3.32.0...3.32.1) - 2021-04-06
### Fixed
- [[#1393](https://github.com/sonata-project/SonataDoctrineORMAdminBundle/pull/1393)] Added missing filter declaration in the config ([@VincentLanglet](https://github.com/VincentLanglet))
Expand Down
9 changes: 9 additions & 0 deletions UPGRADE-3.x.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,15 @@ UPGRADE 3.x
UPGRADE FROM 3.x to 3.x
=======================

### Sonata\DoctrineORMAdminBundle\Filter\CallbackFilter

Not adding `Sonata\AdminBundle\Filter\Model\FilterData` as type declaration of argument 4 of the callable passed to
`Sonata\DoctrineORMAdminBundle\Filter\CallbackFilter` is deprecated. In version 4.0 this argument will be an instance
of `Sonata\AdminBundle\Filter\Model\FilterData`.

UPGRADE FROM 3.32 to 3.33
=========================

### Sonata\DoctrineORMAdminBundle\Filter\StringFilter

The option "case_sensitive" is deprecated in favor of "force_case_insensitivity".
Expand Down
11 changes: 7 additions & 4 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,11 @@
],
"require": {
"php": "^7.3 || ^8.0",
"doctrine/dbal": "^2.13",
"doctrine/doctrine-bundle": "^2.3",
"doctrine/orm": "^2.5",
"doctrine/persistence": "^2.0",
"sonata-project/admin-bundle": "^4.0@alpha",
"doctrine/orm": "^2.8",
"doctrine/persistence": "^2.1",
"sonata-project/admin-bundle": "^4.0@dev",
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you will also need to conflict with previous alphas

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"sonata-project/admin-bundle": "<=4.0.0-alpha-1" ?

"sonata-project/exporter": "^2.0",
"sonata-project/form-extensions": "^1.4",
"symfony/config": "^4.4 || ^5.2",
Expand All @@ -47,6 +48,7 @@
},
"conflict": {
"simplethings/entity-audit-bundle": ">=2.0",
"sonata-project/admin-bundle": "<=4.0.0-alpha-1",
"sonata-project/block-bundle": "<4.2"
},
"provide": {
Expand All @@ -67,7 +69,8 @@
"symfony/phpunit-bridge": "^5.2",
"symfony/templating": "^4.4 || ^5.2",
"symfony/yaml": "^4.4 || ^5.2",
"vimeo/psalm": "^4.1.1"
"vimeo/psalm": "^4.1.1",
"weirdan/doctrine-psalm-plugin": "^1.0"
},
"suggest": {
"sonata-project/entity-audit-bundle": "If you want to support for versioning of entities and their associations."
Expand Down
1 change: 1 addition & 0 deletions docs/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ The ``Doctrine ORM Admin`` provides services to work with the ``Admin Bundle`` a
reference/templates
reference/audit
reference/query_proxy
reference/data_source
reference/troubleshootings

.. toctree::
Expand Down
52 changes: 52 additions & 0 deletions docs/reference/data_source.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
.. index::
double: Reference; Export / DataSource

Export / DataSource
===================

When using an admins export feature you might want to modify how dates and times are exported.
This is done by calling ``setDateTimeFormat`` on the data source iterator.

Here's one way to do it:

1. Decorate the default Sonata\DoctrineORMAdminBundle\Exporter\DataSource with your own and call ``setDateTimeFormat`` there.::

<?php

namespace App\Service\Admin;

use Sonata\AdminBundle\Datagrid\ProxyQueryInterface;
use Sonata\AdminBundle\Exporter\DataSourceInterface;
use Sonata\DoctrineORMAdminBundle\Exporter\DataSource;
use Sonata\Exporter\Source\DoctrineORMQuerySourceIterator;
use Sonata\Exporter\Source\SourceIteratorInterface;

class DecoratingDataSource implements DataSourceInterface
{
private DataSource $dataSource;

public function __construct(DataSource $dataSource)
{
$this->dataSource = $dataSource;
}

public function createIterator(ProxyQueryInterface $query, array $fields): SourceIteratorInterface
{
/** @var DoctrineORMQuerySourceIterator $iterator */
$iterator = $this->dataSource->createIterator($query, $fields);

$iterator->setDateTimeFormat('Y-m-d H:i:s');

return $iterator;
}
}


2. Add the your service in the ``config/services.yaml`` definition.::

services:
...
App\Service\Admin\DecoratingDataSource:
decorates: 'sonata.admin.data_source.orm'


3 changes: 0 additions & 3 deletions phpstan-baseline.neon
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,6 @@ parameters:
- # https://github.com/phpstan/phpstan-phpunit/issues/87
message: '#^Trying to mock an undefined method [a-zA-Z]*\(\) on class stdClass\.$#'
path: tests/
- # https://github.com/phpstan/phpstan/issues/4650 & https://github.com/phpstan/phpstan-src/pull/476
message: '#^Strict comparison using === between array\(\) and array<int\|string>\&nonEmpty will always evaluate to false.$#'
path: src/Model/ModelManager.php
- # https://github.com/doctrine/persistence/pull/163
message: '#Parameter \#1 \$class of method Sonata\\DoctrineORMAdminBundle\\FieldDescription\\FieldDescriptionFactory\:\:getMetadata\(\) expects class-string, string given.$#'
path: src/FieldDescription/FieldDescriptionFactory.php
18 changes: 14 additions & 4 deletions psalm-baseline.xml
Original file line number Diff line number Diff line change
@@ -1,8 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
<files psalm-version="3.16@d03e5ef057d6adc656c0ff7e166c50b73b4f48f3">
<file src="src/Builder/FormContractor.php">
<UndefinedClass occurrences="1">
<code>[CollectionType::class, 'Sonata\CoreBundle\Form\Type\CollectionType']</code>
</UndefinedClass>
<!-- https://github.com/vimeo/psalm/issues/5643 -->
<file src="src/Model/ModelManager.php">
<TypeDoesNotContainType occurrences="1">
<code>[] === $idx</code>
</TypeDoesNotContainType>
</file>
<!-- https://github.com/vimeo/psalm/issues/5551 -->
<file src="tests/Filter/FilterTest.php">
<UndefinedPropertyFetch occurrences="1">
<code>static::$groupedOrExpressions</code>
</UndefinedPropertyFetch>
<UndefinedPropertyAssignment occurrences="1">
<code>static::$groupedOrExpressions</code>
</UndefinedPropertyAssignment>
</file>
</files>
3 changes: 2 additions & 1 deletion psalm.xml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<psalm xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="https://getpsalm.org/schema/config" errorLevel="7" resolveFromConfigFile="true" xsi:schemaLocation="https://getpsalm.org/schema/config vendor/vimeo/psalm/config.xsd" autoloader="vendor/bin/.phpunit/phpunit/vendor/autoload.php" errorBaseline="psalm-baseline.xml">
<psalm xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="https://getpsalm.org/schema/config" errorLevel="4" resolveFromConfigFile="true" xsi:schemaLocation="https://getpsalm.org/schema/config vendor/vimeo/psalm/config.xsd" autoloader="vendor/bin/.phpunit/phpunit/vendor/autoload.php" errorBaseline="psalm-baseline.xml">
<projectFiles>
<directory name="src"/>
<directory name="tests"/>
Expand All @@ -10,5 +10,6 @@
<plugins>
<pluginClass class="Psalm\SymfonyPsalmPlugin\Plugin"/>
<pluginClass class="Psalm\PhpUnitPlugin\Plugin"/>
<pluginClass class="Weirdan\DoctrinePsalmPlugin\Plugin"/>
</plugins>
</psalm>
11 changes: 10 additions & 1 deletion src/Builder/DatagridBuilder.php
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,9 @@
use Symfony\Component\Form\Extension\Core\Type\FormType;
use Symfony\Component\Form\FormFactoryInterface;

/**
* @phpstan-implements DatagridBuilderInterface<ProxyQueryInterface>
*/
final class DatagridBuilder implements DatagridBuilderInterface
{
/**
Expand Down Expand Up @@ -115,6 +118,7 @@ public function addFilter(DatagridInterface $datagrid, ?string $type, FieldDescr
));
}

/** @phpstan-var class-string $type */
$type = $guessType->getType();
$fieldDescription->setType($type);

Expand Down Expand Up @@ -147,7 +151,12 @@ public function getBaseDatagrid(AdminInterface $admin, array $values = []): Data

$formBuilder = $this->formFactory->createNamedBuilder('filter', FormType::class, [], $defaultOptions);

return new Datagrid($admin->createQuery(), $admin->getList(), $pager, $formBuilder, $values);
$query = $admin->createQuery();
if (!$query instanceof ProxyQueryInterface) {
throw new \TypeError(sprintf('The admin query MUST implement %s.', ProxyQueryInterface::class));
}

return new Datagrid($query, $admin->getList(), $pager, $formBuilder, $values);
}

/**
Expand Down
38 changes: 5 additions & 33 deletions src/Datagrid/Pager.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@

namespace Sonata\DoctrineORMAdminBundle\Datagrid;

use Doctrine\ORM\Tools\Pagination\Paginator;
use Sonata\AdminBundle\Datagrid\Pager as BasePager;

/**
Expand All @@ -33,25 +32,11 @@ final class Pager extends BasePager
public function getCurrentPageResults(): iterable
{
$query = $this->getQuery();
if (!$query instanceof ProxyQueryInterface) {
throw new \TypeError(sprintf(
'The pager query MUST implement %s.',
ProxyQueryInterface::class,
));
if (null === $query) {
throw new \LogicException('The pager need a query to display results');
}

$identifierFieldNames = $query
->getQueryBuilder()
->getEntityManager()
->getMetadataFactory()
->getMetadataFor(current($query->getQueryBuilder()->getRootEntities()))
->getIdentifierFieldNames();

// Paginator with fetchJoinCollection doesn't work with composite primary keys
// https://github.com/doctrine/orm/issues/2910
$paginator = new Paginator($query->getDoctrineQuery(), 1 === \count($identifierFieldNames));

return $paginator->getIterator();
return $query->execute();
}

public function countResults(): int
Expand All @@ -61,13 +46,13 @@ public function countResults(): int

public function init(): void
{
$this->resultsCount = $this->computeResultsCount();

$query = $this->getQuery();
if (null === $query) {
throw new \LogicException('The pager need a query to be initialised');
}

$this->resultsCount = \count($query->execute());

$query->setFirstResult(null);
$query->setMaxResults(null);

Expand All @@ -82,17 +67,4 @@ public function init(): void
$query->setMaxResults($this->getMaxPerPage());
}
}

private function computeResultsCount(): int
{
$query = $this->getQuery();

if (!$query instanceof ProxyQueryInterface) {
throw new \TypeError(sprintf('The pager query MUST implement %s.', ProxyQueryInterface::class));
}

$paginator = new Paginator($query->getDoctrineQuery());

return \count($paginator);
}
}
15 changes: 14 additions & 1 deletion src/Datagrid/ProxyQuery.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
use Doctrine\ORM\EntityManager;
use Doctrine\ORM\Query;
use Doctrine\ORM\QueryBuilder;
use Doctrine\ORM\Tools\Pagination\Paginator;
use Sonata\AdminBundle\Datagrid\ProxyQueryInterface as BaseProxyQueryInterface;

/**
Expand Down Expand Up @@ -137,6 +138,9 @@ public function __clone()
$this->queryBuilder = clone $this->queryBuilder;
}

/**
* @return Paginator<object>
*/
public function execute()
{
$query = $this->getDoctrineQuery();
Expand All @@ -145,7 +149,16 @@ public function execute()
$query->setHint($name, $value);
}

return $query->execute();
$identifierFieldNames = $this
->getQueryBuilder()
->getEntityManager()
->getMetadataFactory()
->getMetadataFor(current($this->getQueryBuilder()->getRootEntities()))
->getIdentifierFieldNames();

// Paginator with fetchJoinCollection doesn't work with composite primary keys
// https://github.com/doctrine/orm/issues/2910
return new Paginator($query, 1 === \count($identifierFieldNames));
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@
use Symfony\Component\DependencyInjection\ContainerBuilder;

/**
* @internal
*
* @author Thomas Rabaix <thomas.rabaix@sonata-project.org>
*/
final class AddAuditEntityCompilerPass implements CompilerPassInterface
Expand All @@ -28,7 +30,9 @@ public function process(ContainerBuilder $container): void
}

$auditedEntities = $container->getParameter('simplethings.entityaudit.audited_entities');
\assert(\is_array($auditedEntities));
$force = $container->getParameter('sonata_doctrine_orm_admin.audit.force');
\assert(\is_bool($force));

foreach ($container->findTaggedServiceIds('sonata.admin') as $id => $attributes) {
if ('orm' !== $attributes[0]['manager_type']) {
Expand Down
2 changes: 2 additions & 0 deletions src/DependencyInjection/Compiler/AddGuesserCompilerPass.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@
use Symfony\Component\DependencyInjection\Reference;

/**
* @internal
*
* @author Thomas Rabaix <thomas.rabaix@sonata-project.org>
*/
final class AddGuesserCompilerPass implements CompilerPassInterface
Expand Down
Loading