mirror of
https://github.com/Part-DB/Part-DB-server.git
synced 2025-07-03 23:14:36 +02:00
Show a proper error message to user when he is not allowed to create a new element using a StructuralEntityType
This fixes issue #391
This commit is contained in:
parent
f53c98312e
commit
7a2928e202
3 changed files with 45 additions and 7 deletions
|
@ -20,6 +20,7 @@ declare(strict_types=1);
|
||||||
* You should have received a copy of the GNU Affero General Public License
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
namespace App\Form\Type\Helper;
|
namespace App\Form\Type\Helper;
|
||||||
|
|
||||||
use App\Entity\Base\AbstractNamedDBElement;
|
use App\Entity\Base\AbstractNamedDBElement;
|
||||||
|
@ -28,7 +29,10 @@ use App\Repository\StructuralDBElementRepository;
|
||||||
use App\Services\Trees\NodesListBuilder;
|
use App\Services\Trees\NodesListBuilder;
|
||||||
use Doctrine\ORM\EntityManagerInterface;
|
use Doctrine\ORM\EntityManagerInterface;
|
||||||
use Symfony\Component\Form\ChoiceList\Loader\AbstractChoiceLoader;
|
use Symfony\Component\Form\ChoiceList\Loader\AbstractChoiceLoader;
|
||||||
|
use Symfony\Component\Form\FormError;
|
||||||
|
use Symfony\Component\Form\FormInterface;
|
||||||
use Symfony\Component\OptionsResolver\Options;
|
use Symfony\Component\OptionsResolver\Options;
|
||||||
|
use Symfony\Contracts\Translation\TranslatorInterface;
|
||||||
|
|
||||||
class StructuralEntityChoiceLoader extends AbstractChoiceLoader
|
class StructuralEntityChoiceLoader extends AbstractChoiceLoader
|
||||||
{
|
{
|
||||||
|
@ -36,8 +40,14 @@ class StructuralEntityChoiceLoader extends AbstractChoiceLoader
|
||||||
|
|
||||||
private ?AbstractNamedDBElement $starting_element = null;
|
private ?AbstractNamedDBElement $starting_element = null;
|
||||||
|
|
||||||
public function __construct(private readonly Options $options, private readonly NodesListBuilder $builder, private readonly EntityManagerInterface $entityManager)
|
private ?FormInterface $form = null;
|
||||||
{
|
|
||||||
|
public function __construct(
|
||||||
|
private readonly Options $options,
|
||||||
|
private readonly NodesListBuilder $builder,
|
||||||
|
private readonly EntityManagerInterface $entityManager,
|
||||||
|
private readonly TranslatorInterface $translator
|
||||||
|
) {
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function loadChoices(): iterable
|
protected function loadChoices(): iterable
|
||||||
|
@ -67,14 +77,22 @@ class StructuralEntityChoiceLoader extends AbstractChoiceLoader
|
||||||
if ($this->starting_element !== null
|
if ($this->starting_element !== null
|
||||||
&& $this->starting_element->getID() === null //Element must not be persisted yet
|
&& $this->starting_element->getID() === null //Element must not be persisted yet
|
||||||
&& $this->options['choice_value']($this->starting_element) === $value) {
|
&& $this->options['choice_value']($this->starting_element) === $value) {
|
||||||
|
|
||||||
//Then reuse the starting element
|
//Then reuse the starting element
|
||||||
$this->entityManager->persist($this->starting_element);
|
$this->entityManager->persist($this->starting_element);
|
||||||
return [$this->starting_element];
|
return [$this->starting_element];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (!$this->options['allow_add']) {
|
if (!$this->options['allow_add']) {
|
||||||
throw new \RuntimeException('Cannot create new entity, because allow_add is not enabled!');
|
//If we have a form, add an error to it, to improve the user experience
|
||||||
|
if ($this->form !== null) {
|
||||||
|
$this->form->addError(
|
||||||
|
new FormError($this->translator->trans('entity.select.creating_new_entities_not_allowed')
|
||||||
|
)
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
throw new \RuntimeException('Cannot create new entity, because allow_add is not enabled!');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$class = $this->options['class'];
|
$class = $this->options['class'];
|
||||||
|
@ -85,10 +103,13 @@ class StructuralEntityChoiceLoader extends AbstractChoiceLoader
|
||||||
|
|
||||||
$results = [];
|
$results = [];
|
||||||
|
|
||||||
foreach($entities as $entity) {
|
foreach ($entities as $entity) {
|
||||||
//If the entity is newly created (ID null), add it as result and persist it.
|
//If the entity is newly created (ID null), add it as result and persist it.
|
||||||
if ($entity->getID() === null) {
|
if ($entity->getID() === null) {
|
||||||
$this->entityManager->persist($entity);
|
//Only persist the entities if it is allowed
|
||||||
|
if ($this->options['allow_add']) {
|
||||||
|
$this->entityManager->persist($entity);
|
||||||
|
}
|
||||||
$results[] = $entity;
|
$results[] = $entity;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -115,6 +136,16 @@ class StructuralEntityChoiceLoader extends AbstractChoiceLoader
|
||||||
return $this->starting_element;
|
return $this->starting_element;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the form that this loader is bound to.
|
||||||
|
* @param FormInterface|null $form
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function setForm(?FormInterface $form): void
|
||||||
|
{
|
||||||
|
$this->form = $form;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the initial value used to populate the field. This will always be an allowed value.
|
* Sets the initial value used to populate the field. This will always be an allowed value.
|
||||||
* @param AbstractNamedDBElement|null $starting_element
|
* @param AbstractNamedDBElement|null $starting_element
|
||||||
|
|
|
@ -67,6 +67,7 @@ class StructuralEntityType extends AbstractType
|
||||||
$choice_loader = $options['choice_loader'];
|
$choice_loader = $options['choice_loader'];
|
||||||
if ($choice_loader instanceof StructuralEntityChoiceLoader) {
|
if ($choice_loader instanceof StructuralEntityChoiceLoader) {
|
||||||
$choice_loader->setAdditionalElement($data);
|
$choice_loader->setAdditionalElement($data);
|
||||||
|
$choice_loader->setForm($form);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -83,7 +84,7 @@ class StructuralEntityType extends AbstractType
|
||||||
'subentities_of' => null, //Only show entities with the given parent class
|
'subentities_of' => null, //Only show entities with the given parent class
|
||||||
'disable_not_selectable' => false, //Disable entries with not selectable property
|
'disable_not_selectable' => false, //Disable entries with not selectable property
|
||||||
'choice_value' => fn(?AbstractNamedDBElement $element) => $this->choice_helper->generateChoiceValue($element), //Use the element id as option value and for comparing items
|
'choice_value' => fn(?AbstractNamedDBElement $element) => $this->choice_helper->generateChoiceValue($element), //Use the element id as option value and for comparing items
|
||||||
'choice_loader' => fn(Options $options) => new StructuralEntityChoiceLoader($options, $this->builder, $this->em),
|
'choice_loader' => fn(Options $options) => new StructuralEntityChoiceLoader($options, $this->builder, $this->em, $this->translator),
|
||||||
'choice_label' => fn(Options $options) => fn($choice, $key, $value) => $this->choice_helper->generateChoiceLabel($choice),
|
'choice_label' => fn(Options $options) => fn($choice, $key, $value) => $this->choice_helper->generateChoiceLabel($choice),
|
||||||
'choice_attr' => fn(Options $options) => fn($choice, $key, $value) => $this->choice_helper->generateChoiceAttr($choice, $options),
|
'choice_attr' => fn(Options $options) => fn($choice, $key, $value) => $this->choice_helper->generateChoiceAttr($choice, $options),
|
||||||
'group_by' => fn(AbstractNamedDBElement $element) => $this->choice_helper->generateGroupBy($element),
|
'group_by' => fn(AbstractNamedDBElement $element) => $this->choice_helper->generateGroupBy($element),
|
||||||
|
|
|
@ -11801,5 +11801,11 @@ Please note, that you can not impersonate a disabled user. If you try you will g
|
||||||
<target>Ends with</target>
|
<target>Ends with</target>
|
||||||
</segment>
|
</segment>
|
||||||
</unit>
|
</unit>
|
||||||
|
<unit id="SgLdhCl" name="entity.select.creating_new_entities_not_allowed">
|
||||||
|
<segment>
|
||||||
|
<source>entity.select.creating_new_entities_not_allowed</source>
|
||||||
|
<target>You are not allowed to create new entities of this type! Please choose a pre-existing one.</target>
|
||||||
|
</segment>
|
||||||
|
</unit>
|
||||||
</file>
|
</file>
|
||||||
</xliff>
|
</xliff>
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue