SonataClassificationBundle
SonataClassificationBundle copied to clipboard
[5.x] Cannot create context with ContextAdmin
Environment
Clean install with upgraded data from [4.x]
Sonata packages
show
$ composer show --latest 'sonata-project/*'
# Put the result here.
Symfony packages
show
$ composer show --latest 'symfony/*'
# Put the result here.
PHP version
$ php -v
PHP 8.1.10 (cli) (built: Sep 1 2022 21:43:31) (NTS)
Copyright (c) The PHP Group
Zend Engine v4.1.10, Copyright (c) Zend Technologies
with Zend OPcache v8.1.10, Copyright (c), by Zend Technologies
Subject
Minimal repository with the bug
Steps to reproduce
Go to Context Admin and click on create new
Expected results
Create form of Context would appear
Actual results
with:
<?php
namespace App\Entity\Sonata;
use Doctrine\ORM\Mapping as ORM;
use Sonata\ClassificationBundle\Entity\BaseContext;
#[ORM\Table(name: 'classification__context')]
#[ORM\Entity]
class SonataClassificationContext extends BaseContext
{
#[ORM\Id]
#[ORM\GeneratedValue]
#[ORM\Column(type: 'integer')]
protected $id;
}
I get (stack trace):
Symfony\Component\ErrorHandler\Error\FatalError:
Compile Error: Type of App\Entity\Sonata\SonataClassificationContext::$id must be ?string (as in class Sonata\ClassificationBundle\Model\Context)
at src/Entity/Sonata/SonataClassificationContext.php:10
And All of the ClassificationAdmins are broken.
with:
<?php
namespace App\Entity\Sonata;
use Doctrine\ORM\Mapping as ORM;
use Sonata\ClassificationBundle\Entity\BaseContext;
#[ORM\Table(name: 'classification__context')]
#[ORM\Entity]
class SonataClassificationContext extends BaseContext
{
#[ORM\Id]
#[ORM\GeneratedValue]
#[ORM\Column(type: 'integer')]
protected ?string $id;
}
I get
Typed property App\Entity\Sonata\SonataClassificationContext::$id must not be accessed before initialization
Error:
Typed property App\Entity\Sonata\SonataClassificationContext::$id must not be accessed before initialization
at vendor/sonata-project/classification-bundle/src/Model/Context.php:85
at Sonata\ClassificationBundle\Model\Context->getId()
(vendor/sonata-project/classification-bundle/src/Admin/ContextAdmin.php:33)
at Sonata\ClassificationBundle\Admin\ContextAdmin->configureFormFields(object(FormMapper))
(vendor/sonata-project/admin-bundle/src/Admin/AbstractAdmin.php:821)
at Sonata\AdminBundle\Admin\AbstractAdmin->defineFormBuilder(object(FormBuilder))
(vendor/sonata-project/admin-bundle/src/Admin/AbstractAdmin.php:801)
at Sonata\AdminBundle\Admin\AbstractAdmin->getFormBuilder()
(vendor/sonata-project/admin-bundle/src/Admin/AbstractAdmin.php:2524)
at Sonata\AdminBundle\Admin\AbstractAdmin->buildForm()
(vendor/sonata-project/admin-bundle/src/Admin/AbstractAdmin.php:873)
at Sonata\AdminBundle\Admin\AbstractAdmin->getForm()
(vendor/sonata-project/admin-bundle/src/Controller/CRUDController.php:573)
at Sonata\AdminBundle\Controller\CRUDController->createAction(object(SiteRequest))
(vendor/symfony/http-kernel/HttpKernel.php:153)
at Symfony\Component\HttpKernel\HttpKernel->handleRaw(object(SiteRequest), 1)
(vendor/symfony/http-kernel/HttpKernel.php:75)
at Symfony\Component\HttpKernel\HttpKernel->handle(object(SiteRequest), 1, true)
(vendor/symfony/http-kernel/Kernel.php:202)
at Symfony\Component\HttpKernel\Kernel->handle(object(SiteRequest))
(public/index.php:22)
AFAIK this is a doctrine / PHP8 bug.
You need to add a default value here:
#[ORM\Id]
#[ORM\GeneratedValue]
#[ORM\Column(type: 'integer')]
protected ?string $id = null;
At least the install documentation should be fixed?
After that change it does work.
Id is well defined in our code https://github.com/sonata-project/SonataClassificationBundle/blob/4.x/src/Model/Context.php#L18
And type are not used in doc https://github.com/sonata-project/SonataClassificationBundle/blob/4.x/docs/reference/installation.rst
Both
protected ?string $id = null;
protected $id;
work.
So it just a misunderstanding of how PHP8 works.
Still, there is a bug in docs. Id is either integer, or string, can't be both.
Probably a lot of copy paste between bundles. but it looks like on some entities here, id is forced to be a string.
#[ORM\Column(type: 'integer')]
protected ?string $id = null;
This looks wrong.
protected $id;
Does not work.
Compile Error: Type of App\Entity\Sonata\SonataClassificationContext::$id must be ?string (as in class Sonata\ClassificationBundle\Model\Context)