Kunstmaan / KunstmaanBundlesCMS

An advanced yet user-friendly content management system, based on the full stack Symfony framework combined with a whole host of community bundles. It provides a full featured, multi-language CMS system with an innovative page and form assembling process, versioning, workflow, translation and media managers and much more.
https://kunstmaancms.be
MIT License
403 stars 187 forks source link

[PagePartBundle] Delete nested (non-entity) sub-items #3423

Closed jverdeyen closed 3 months ago

jverdeyen commented 3 months ago
Q A
Bug fix? yes
New feature? no
BC breaks? no
Deprecations? no

When a pagepart has sub-items which are not entities (just a simple 'model') and you want to delete one or more items, the following error occures:

Kunstmaan\PagePartBundle\PagePartAdmin\PagePartAdmin::getObjectForDeletion(): Argument #2 ($deleteInfo) must be of type Kunstmaan\PagePartBundle\Dto\PagePartDeleteInfo, null given, called

This is normal as the regex which is used to find more information about the sub 'entity' (which is no entity in our case) does not match.

This is how the delete key is created. For an entity this could be delete_pagepartadmin_1653874_items_500 where 500 is the ID of the sub entity. For a model (plain php class) as sub item, this could be delete_pagepartadmin_1653874_items_testtitle where testtitle comes from {{ obj.vars.value }} in the snippet below.

src/Kunstmaan/AdminBundle/Resources/views/Form/fields.html.twig:180

data-delete-key="
{{ form.vars.id|replace({'form_': 'delete_'}) }}_
{% if obj.vars.value.id is defined %}
   {{ obj.vars.value.id }}
{% else %}
  {{ obj.vars.value }}
{% endif %}"

In the preBindRequest function of PagePartAdmin the $matches array of the preg_match_all should hold data like (in case of an entity sub item).

$matches = [
        0 => "items_500",    // Full match
        1 => "items",        // First capture group -> the form field name
        2 => "500"         // Second capture group -> the database id
    ]

In case of a model as subitem, $matches is an empty array, which is ok, as there should be no specific action on the list of subitems, Symfony form handling will delete this item from the array.

BUT since the $matches array is empty the preBindRequest function should not add this to the $subPagePartsToDelete array. This array is used to handle entity sub items.

src/Kunstmaan/PagePartBundle/PagePartAdmin/PagePartAdmin.php:152

preg_match('#^delete_pagepartadmin_(\d+)_(.*)#', $key, $ppInfo);
preg_match_all('#([a-zA-Z0-9]+)_(\\d+)#', $ppInfo[2], $matches, PREG_SET_ORDER);
acrobat commented 3 months ago

Thanks @jverdeyen!