$ composer show --latest 'sonata-project/*'
sonata-project/admin-bundle dev-master 890ecee dev-master 8773923 The missing Symfony Admin Generator
sonata-project/block-bundle 4.4.0 4.4.0 Symfony SonataBlockBundle
sonata-project/cache 2.0.1 2.0.1 Cache library
sonata-project/doctrine-extensions 1.10.1 1.10.1 Doctrine2 behavioral extensions
sonata-project/doctrine-orm-admin-bundle dev-master a4391d3 dev-master a4391d3 Integrate Doctrine ORM into the Sona...
sonata-project/exporter 2.4.1 2.4.1 Lightweight Exporter library
sonata-project/form-extensions 1.6.0 1.6.0 Symfony form extensions
sonata-project/twig-extensions 1.4.1 1.4.1 Sonata twig extensions
$ composer show --latest 'symfony/*'
symfony/apache-pack v1.0.1 v1.0.1 A pack for Apache support in Symfony
symfony/asset v5.1.7 v5.1.7 Symfony Asset Component
symfony/browser-kit v5.1.7 v5.1.7 Symfony BrowserKit Component
symfony/cache v5.1.7 v5.1.7 Symfony Cache component with PSR-6, ...
symfony/cache-contracts v2.2.0 v2.2.0 Generic abstractions related to caching
symfony/config v5.1.7 v5.1.7 Symfony Config Component
symfony/console v5.1.7 v5.1.7 Symfony Console Component
symfony/css-selector v5.1.7 v5.1.7 Symfony CssSelector Component
symfony/debug-bundle v5.1.7 v5.1.7 Symfony DebugBundle
symfony/dependency-injection v5.1.7 v5.1.7 Symfony DependencyInjection Component
symfony/deprecation-contracts v2.2.0 v2.2.0 A generic function and convention to...
symfony/doctrine-bridge v5.1.7 v5.1.7 Symfony Doctrine Bridge
symfony/dom-crawler v5.1.7 v5.1.7 Symfony DomCrawler Component
symfony/dotenv v5.1.7 v5.1.7 Registers environment variables from...
symfony/error-handler v5.1.7 v5.1.7 Symfony ErrorHandler Component
symfony/event-dispatcher v5.1.7 v5.1.7 Symfony EventDispatcher Component
symfony/event-dispatcher-contracts v2.2.0 v2.2.0 Generic abstractions related to disp...
symfony/expression-language v5.1.7 v5.1.7 Symfony ExpressionLanguage Component
symfony/filesystem v5.1.7 v5.1.7 Symfony Filesystem Component
symfony/finder v5.1.7 v5.1.7 Symfony Finder Component
symfony/flex v1.9.10 v1.9.10 Composer plugin for Symfony
symfony/form v5.1.7 v5.1.7 Symfony Form Component
symfony/framework-bundle v5.1.7 v5.1.7 Symfony FrameworkBundle
symfony/http-client v5.1.7 v5.1.7 Symfony HttpClient component
symfony/http-client-contracts v2.3.1 v2.3.1 Generic abstractions related to HTTP...
symfony/http-foundation v5.1.7 v5.1.7 Symfony HttpFoundation Component
symfony/http-kernel v5.1.7 v5.1.7 Symfony HttpKernel Component
symfony/intl v5.1.7 v5.1.7 A PHP replacement layer for the C in...
symfony/mailer v5.1.7 v5.1.7 Symfony Mailer Component
symfony/maker-bundle v1.22.0 v1.22.0 Symfony Maker helps you create empty...
symfony/mime v5.1.7 v5.1.7 A library to manipulate MIME messages
symfony/monolog-bridge v5.1.7 v5.1.7 Symfony Monolog Bridge
symfony/monolog-bundle v3.6.0 v3.6.0 Symfony MonologBundle
symfony/notifier v5.1.7 v5.1.7 A library to notify messages
symfony/options-resolver v5.1.7 v5.1.7 Symfony OptionsResolver Component
symfony/phpunit-bridge v5.1.7 v5.1.7 Symfony PHPUnit Bridge
symfony/polyfill-intl-grapheme v1.18.1 v1.19.0 Symfony polyfill for intl's grapheme...
symfony/polyfill-intl-icu v1.18.1 v1.19.0 Symfony polyfill for intl's ICU-rela...
symfony/polyfill-intl-idn v1.18.1 v1.19.0 Symfony polyfill for intl's idn_to_a...
symfony/polyfill-intl-normalizer v1.18.1 v1.19.0 Symfony polyfill for intl's Normaliz...
symfony/polyfill-mbstring v1.18.1 v1.19.0 Symfony polyfill for the Mbstring ex...
symfony/polyfill-php73 v1.18.1 v1.19.0 Symfony polyfill backporting some PH...
symfony/polyfill-php80 v1.18.1 v1.19.0 Symfony polyfill backporting some PH...
symfony/process v5.1.7 v5.1.7 Symfony Process Component
symfony/property-access v5.1.7 v5.1.7 Symfony PropertyAccess Component
symfony/property-info v5.1.7 v5.1.7 Symfony Property Info Component
symfony/routing v5.1.7 v5.1.7 Symfony Routing Component
symfony/security-acl v3.1.0 v3.1.0 Symfony Security Component - ACL (Ac...
symfony/security-bundle v5.1.7 v5.1.7 Symfony SecurityBundle
symfony/security-core v5.1.7 v5.1.7 Symfony Security Component - Core Li...
symfony/security-csrf v5.1.7 v5.1.7 Symfony Security Component - CSRF Li...
symfony/security-guard v5.1.7 v5.1.7 Symfony Security Component - Guard
symfony/security-http v5.1.7 v5.1.7 Symfony Security Component - HTTP In...
symfony/serializer v5.1.7 v5.1.7 Symfony Serializer Component
symfony/service-contracts v2.2.0 v2.2.0 Generic abstractions related to writ...
symfony/stopwatch v5.1.7 v5.1.7 Symfony Stopwatch Component
symfony/string v5.1.7 v5.1.7 Symfony String component
symfony/translation v5.1.7 v5.1.7 Symfony Translation Component
symfony/translation-contracts v2.3.0 v2.3.0 Generic abstractions related to tran...
symfony/twig-bridge v5.1.7 v5.1.7 Symfony Twig Bridge
symfony/twig-bundle v5.1.7 v5.1.7 Symfony TwigBundle
symfony/validator v5.1.7 v5.1.7 Symfony Validator Component
symfony/var-dumper v5.1.7 v5.1.7 Symfony mechanism for exploring and ...
symfony/var-exporter v5.1.7 v5.1.7 A blend of var_export() + serialize(...
symfony/web-link v5.1.7 v5.1.7 Symfony WebLink Component
symfony/web-profiler-bundle v5.1.7 v5.1.7 Symfony WebProfilerBundle
symfony/webpack-encore-bundle v1.7.3 v1.7.3 Integration with your Symfony app & ...
symfony/yaml v5.1.7 v5.1.7 Symfony Yaml Component
$ php -v
PHP 7.3.12 (cli) (built: Nov 19 2019 13:58:02) ( ZTS MSVC15 (Visual C++ 2017) x64 )
Can not get the normalized identifier for App\Entity\BettingEventCategory since it is in state 2.
BettingEventCategory class
<?php
namespace App\Entity;
use App\Repository\BettingEventCategoryRepository;
use Doctrine\ORM\Mapping as ORM;
/**
* @ORM\Entity(repositoryClass=BettingEventCategoryRepository::class)
*/
class BettingEventCategory
{
/**
* @ORM\Id
* @ORM\GeneratedValue
* @ORM\Column(type="integer")
*/
private $id;
/**
* @ORM\Column(type="string", length=255)
*/
private $categoryName;
/**
* @ORM\Column(type="boolean")
*/
private $enabled;
public function getId(): ?int
{
return $this->id;
}
public function getCategoryName(): ?string
{
return $this->categoryName;
}
public function setCategoryName(string $categoryName): self
{
$this->categoryName = $categoryName;
return $this;
}
public function getEnabled(): ?bool
{
return $this->enabled;
}
public function setEnabled(bool $enabled): self
{
$this->enabled = $enabled;
return $this;
}
}
BettingEventCategoryAdmin class
<?php
namespace App\Admin;
use Sonata\AdminBundle\Admin\AbstractAdmin;
use Sonata\AdminBundle\Datagrid\DatagridMapper;
use Sonata\AdminBundle\Datagrid\ListMapper;
use Sonata\AdminBundle\Form\FormMapper;
use Sonata\Form\Type\BooleanType;
use Symfony\Component\Form\Extension\Core\Type\TextType;
class BettingEventCategoryAdmin extends AbstractAdmin
{
protected function configureFormFields(FormMapper $formMapper): void
{
$formMapper
->add('categoryName', TextType::class)
->add('enabled', BooleanType::class, array(
'label' => 'Enabled',
'transform' => true,
'required' => true,
));
}
protected function configureDataGridFilters(DatagridMapper $datagridMapper): void
{
$datagridMapper
->add('id')
->add('categoryName')
->add('enabled');
}
protected function configureListFields(ListMapper $listMapper): void
{
$listMapper
->addIdentifier('id')
->addIdentifier('categoryName')
->addIdentifier('enabled');
}
}
My service section
admin.betting_event_category:
class: App\Admin\BettingEventCategoryAdmin
arguments: [~, App\Entity\BettingEventCategory, ~]
tags:
- { name: sonata.admin, manager_type: orm, label: "Betting Event Category" }
Trying to create a new entity

The new entity should be created
Error received

InvalidArgumentException:
Can not get the normalized identifier for App\Entity\BettingEventCategory since it is in state 2.
at C:\xampp\htdocs\vendor\sonata-project\doctrine-orm-admin-bundle\src\Model\ModelManager.php:396
at Sonata\DoctrineORMAdminBundle\Model\ModelManager->getNormalizedIdentifier(object(BettingEventCategory))
(C:\xampp\htdocs\vendor\sonata-project\admin-bundle\src\Admin\AbstractAdmin.php:2001)
at Sonata\AdminBundle\Admin\AbstractAdmin->getNormalizedIdentifier(object(BettingEventCategory))
(C:\xampp\htdocs\vendor\sonata-project\admin-bundle\src\Admin\AbstractAdmin.php:2006)
at Sonata\AdminBundle\Admin\AbstractAdmin->id(object(BettingEventCategory))
(C:\xampp\htdocs\vendor\sonata-project\admin-bundle\src\Admin\AbstractAdmin.php:1984)
at Sonata\AdminBundle\Admin\AbstractAdmin->isGranted('CREATE', object(BettingEventCategory))
(C:\xampp\htdocs\vendor\sonata-project\admin-bundle\src\Admin\AbstractAdmin.php:2195)
at Sonata\AdminBundle\Admin\AbstractAdmin->checkAccess('create', object(BettingEventCategory))
(C:\xampp\htdocs\vendor\sonata-project\admin-bundle\src\Controller\CRUDController.php:549)
at Sonata\AdminBundle\Controller\CRUDController->createAction(object(Request))
(C:\xampp\htdocs\vendor\symfony\http-kernel\HttpKernel.php:157)
at Symfony\Component\HttpKernel\HttpKernel->handleRaw(object(Request), 1)
(C:\xampp\htdocs\vendor\symfony\http-kernel\HttpKernel.php:79)
at Symfony\Component\HttpKernel\HttpKernel->handle(object(Request), 1, true)
(C:\xampp\htdocs\vendor\symfony\http-kernel\Kernel.php:196)
at Symfony\Component\HttpKernel\Kernel->handle(object(Request))
(C:\xampp\htdocs\index.php:28)
I think we have 2 choices here:
ModelManagerInterface::hasNormalizedIdentifier();ModelManagerInterface::getNormalizedIdentifier() to return null for new or removed models.@sonata-project/contributors, WDYT?
I think we have 2 choices here:
- Add a
ModelManagerInterface::hasNormalizedIdentifier();- Let
ModelManagerInterface::getNormalizedIdentifier()to returnnullfor new or removed models.@sonata-project/contributors, WDYT?
getNormalizedIdentifier is used a lot:
In AbstractAdmin
public function getNormalizedIdentifier(object $model): string
{
return $this->getModelManager()->getNormalizedIdentifier($model);
}
public function id(object $model): string
{
return $this->getNormalizedIdentifier($model);
}
And then the id method is also use multiple times.
IMHO the simpler solution would be to allow null as a return value but I don't know the impact.
IMHO the simpler solution would be to allow null as a return value but I don't know the impact.
I think there is no critical impact. I've introduced this deprecation and exception in sonata-project/SonataDoctrineORMAdminBundle#1049, in order to narrow the API and avoid invalid values, but if this case can be considered legit, we could allow null as return type.
Does this mean that I am not able to create a new object until the milestone is reached?
I tried to allow null as return in the AbstractAdmin and the Interface, but this doesn't change anything. :/
Furthermore adding an id (in my case Uuid) in preValidate has no impact.
Does this mean that I am not able to create a new object until the milestone is reached?
Using the master branch is at your own risk, we provide stable 3.x branch and a unstable master.
We're putting a lot of effort working on Sonata 4. There is currently lot of BC-break on master, and some bug can appear. We appreciate a lot that you report the bugs you encounter with the master branch but can't guarantee to always solve quickly the bugs.
If you want to provide PR, I'll be happy to review it and merge it.
I tried to allow
nullas return in the AbstractAdmin and the Interface, but this doesn't change anything. :/Furthermore adding an id (in my case Uuid) in preValidate has no impact.
Your exception is thrown by
https://github.com/sonata-project/SonataDoctrineORMAdminBundle/blob/master/src/Model/ModelManager.php#L392
You can see that previously it was returning null
https://github.com/sonata-project/SonataDoctrineORMAdminBundle/blob/3.x/src/Model/ModelManager.php#L452
In your case, the state 2 is the state NEW.
The call is made by AbstractAdmin::id. The question is why ?
The answer is...
public function isGranted($name, ?object $object = null): bool
{
$objectRef = $object ? sprintf('/%s#%s', spl_object_hash($object), $this->id($object)) : '';
$key = md5(json_encode($name).$objectRef);
if (!\array_key_exists($key, $this->cacheIsGranted)) {
$this->cacheIsGranted[$key] = $this->securityHandler->isGranted($this, $name, $object ?: $this);
}
return $this->cacheIsGranted[$key];
}
We could add try/catch, default value, etc...
But when I look at getNormalizedIdentifiers I think it should never throw an exception. If no identifier can be determined, let's just return null or '' instead.
To me, null seems better. Does @sonata-project/contributors agree ?
So it requires a PR to change
getUrlSafeIdentifier
getNormalizedIdentifier
id
return type from string to ?string in AbstractAdmin and AdminInterface/UrlGeneratorInterface.
Then (in the same PR)
getUrlSafeIdentifier
getNormalizedIdentifier
return type from string to ?string in ModelManagerInterface
Then a PR in SonataDoctrineORM 3.x to remove the deprecation
https://github.com/sonata-project/SonataDoctrineORMAdminBundle/blob/3.x/src/Model/ModelManager.php#L456-L469
And a PR in SonataDoctrineORM master to remove the exception and return null instead.
You could add also the check
if (0 === \count($values)) {
return null;
}
again.
Using the master branch is at your own risk, we provide stable 3.x branch and a unstable master.
We're putting a lot of effort working on Sonata 4. There is currently lot of BC-break on master, and some bug can appear. We appreciate a lot that you report the bugs you encounter with the master branch but can't guarantee to always solve quickly the bugs.
You're totally right and I wanna say thank you for your effort explaining everything.
A PR is a good idea and I'll try to provide one.
Kind regards.
Most helpful comment
You're totally right and I wanna say thank you for your effort explaining everything.
A PR is a good idea and I'll try to provide one.
Kind regards.