sonata-project / SonataPageBundle

This bundle provides a Site and Page management through container and block services
https://docs.sonata-project.org/projects/SonataPageBundle
MIT License
219 stars 210 forks source link

Saving a block deletes all children #1291

Closed gremo closed 2 years ago

gremo commented 3 years ago

Environment

Sonata packages

show

``` $ composer show --latest 'sonata-project/*' sonata-project/admin-bundle 3.96.0 3.96.0 The missing Symfony Admin Generator sonata-project/block-bundle 3.23.0 4.5.3 Symfony SonataBlockBundle sonata-project/cache 1.1.1 2.1.1 Cache library sonata-project/cache-bundle 2.4.2 3.3.0 This bundle provides caching services sonata-project/classification-bundle 3.16.0 3.16.0 Symfony SonataClassificationBundle sonata-project/datagrid-bundle 3.3.0 3.3.0 Symfony SonataDatagridBundle sonata-project/doctrine-extensions 1.12.0 1.12.0 Doctrine2 behavioral extensions sonata-project/doctrine-orm-admin-bundle 3.32.1 3.32.1 Integrate Doctrine ORM into the SonataAdminBundle sonata-project/easy-extends-bundle 2.5.0 2.5.0 Symfony SonataEasyExtendsBundle sonata-project/exporter 2.6.1 2.6.1 Lightweight Exporter library sonata-project/form-extensions 1.9.0 1.9.0 Symfony form extensions sonata-project/formatter-bundle 4.4.0 4.4.0 Symfony SonataFormatterBundle sonata-project/intl-bundle 2.10.1 2.10.1 Symfony SonataIntlBundle sonata-project/media-bundle 3.31.0 3.31.0 Symfony SonataMediaBundle sonata-project/notification-bundle 3.12.0 3.12.0 Symfony SonataNotificationBundle sonata-project/page-bundle 3.21.1 3.21.1 This bundle provides a Site and Page management through container and block services sonata-project/seo-bundle 2.13.0 2.13.0 Symfony SonataSeoBundle sonata-project/twig-extensions 1.5.1 1.5.1 Sonata twig extensions sonata-project/user-bundle 4.11.1 4.11.1 Symfony SonataUserBundle ```

Symfony packages

show

``` $ composer show --latest 'symfony/*' symfony/apache-pack v1.0.1 v1.0.1 A pack for Apache support in Symfony symfony/asset v4.4.20 v4.4.20 Manages URL generation and versioning of web assets such as CSS ... symfony/browser-kit v4.4.20 v4.4.20 Simulates the behavior of a web browser, allowing you to make re... symfony/cache v4.4.21 v4.4.21 Provides an extended PSR-6, PSR-16 (and tags) implementation symfony/cache-contracts v2.2.0 v2.2.0 Generic abstractions related to caching symfony/config v4.4.20 v4.4.20 Helps you find, load, combine, autofill and validate configurati... symfony/console v4.4.21 v4.4.21 Eases the creation of beautiful and testable command line interf... symfony/css-selector v4.4.20 v4.4.20 Converts CSS selectors to XPath expressions symfony/debug v4.4.20 v4.4.20 Provides tools to ease debugging PHP code symfony/debug-bundle v4.4.20 v4.4.20 Provides a tight integration of the Symfony Debug component into... symfony/debug-pack v1.0.9 v1.0.9 A debug pack for Symfony projects symfony/dependency-injection v4.4.21 v4.4.21 Allows you to standardize and centralize the way objects are con... symfony/deprecation-contracts v2.2.0 v2.2.0 A generic function and convention to trigger deprecation notices symfony/doctrine-bridge v4.4.21 v4.4.21 Provides integration for Doctrine with various Symfony components symfony/dom-crawler v4.4.20 v4.4.20 Eases DOM navigation for HTML and XML documents symfony/dotenv v4.4.20 v4.4.20 Registers environment variables from a .env file symfony/error-handler v4.4.21 v4.4.21 Provides tools to manage errors and ease debugging PHP code symfony/event-dispatcher v4.4.20 v4.4.20 Provides tools that allow your application components to communi... symfony/event-dispatcher-contracts v1.1.9 v2.2.0 Generic abstractions related to dispatching event symfony/expression-language v4.4.20 v4.4.20 Provides an engine that can compile and evaluate expressions symfony/filesystem v4.4.21 v4.4.21 Provides basic utilities for the filesystem symfony/finder v4.4.20 v4.4.20 Finds files and directories via an intuitive fluent interface symfony/flex v1.12.2 v1.12.2 Composer plugin for Symfony symfony/form v4.4.21 v4.4.21 Allows to easily create, process and reuse HTML forms symfony/framework-bundle v4.4.21 v4.4.21 Provides a tight integration between Symfony components and the ... symfony/http-client v4.4.21 v4.4.21 Provides powerful methods to fetch HTTP resources synchronously ... symfony/http-client-contracts v2.3.1 v2.3.1 Generic abstractions related to HTTP clients symfony/http-foundation v4.4.20 v4.4.20 Defines an object-oriented layer for the HTTP specification symfony/http-kernel v4.4.21 v4.4.21 Provides a structured process for converting a Request into a Re... symfony/inflector v4.4.21 v4.4.21 Converts words between their singular and plural forms (English ... symfony/intl v4.4.20 v4.4.20 Provides a PHP replacement layer for the C intl extension that i... symfony/mailer v4.4.21 v4.4.21 Helps sending emails symfony/maker-bundle v1.30.2 v1.30.2 Symfony Maker helps you create empty commands, controllers, form... symfony/mime v4.4.21 v4.4.21 Allows manipulating MIME messages symfony/monolog-bridge v4.4.21 v4.4.21 Provides integration for Monolog with various Symfony components symfony/monolog-bundle v3.7.0 v3.7.0 Symfony MonologBundle symfony/options-resolver v4.4.20 v4.4.20 Provides an improved replacement for the array_replace PHP function symfony/orm-pack v2.1.0 v2.1.0 A pack for the Doctrine ORM symfony/phpunit-bridge v5.2.6 v5.2.6 Provides utilities for PHPUnit, especially user deprecation noti... symfony/polyfill-intl-grapheme v1.22.1 v1.22.1 Symfony polyfill for intl's grapheme_* functions symfony/polyfill-intl-icu v1.22.1 v1.22.1 Symfony polyfill for intl's ICU-related data and classes symfony/polyfill-intl-idn v1.22.1 v1.22.1 Symfony polyfill for intl's idn_to_ascii and idn_to_utf8 functions symfony/polyfill-intl-normalizer v1.22.1 v1.22.1 Symfony polyfill for intl's Normalizer class and related functions symfony/polyfill-mbstring v1.22.1 v1.22.1 Symfony polyfill for the Mbstring extension symfony/polyfill-php72 v1.22.1 v1.22.1 Symfony polyfill backporting some PHP 7.2+ features to lower PHP... symfony/polyfill-php73 v1.22.1 v1.22.1 Symfony polyfill backporting some PHP 7.3+ features to lower PHP... symfony/polyfill-php80 v1.22.1 v1.22.1 Symfony polyfill backporting some PHP 8.0+ features to lower PHP... symfony/process v4.4.20 v4.4.20 Executes commands in sub-processes symfony/profiler-pack v1.0.5 v1.0.5 A pack for the Symfony web profiler symfony/property-access v4.4.20 v4.4.20 Provides functions to read and write from/to an object or array ... symfony/property-info v4.4.20 v4.4.20 Extracts information about PHP class' properties using metadata ... symfony/proxy-manager-bridge v4.4.18 v4.4.20 Symfony ProxyManager Bridge symfony/routing v4.4.20 v4.4.20 Maps an HTTP request to a set of configuration variables symfony/security-acl v3.1.1 v3.1.1 Symfony Security Component - ACL (Access Control List) symfony/security-bundle v4.4.21 v4.4.21 Provides a tight integration of the Security component into the ... symfony/security-core v4.4.21 v4.4.21 Symfony Security Component - Core Library symfony/security-csrf v4.4.20 v4.4.20 Symfony Security Component - CSRF Library symfony/security-guard v4.4.20 v4.4.20 Symfony Security Component - Guard symfony/security-http v4.4.21 v4.4.21 Symfony Security Component - HTTP Integration symfony/serializer v4.4.20 v4.4.20 Handles serializing and deserializing data structures, including... symfony/serializer-pack v1.0.4 v1.0.4 A pack for the Symfony serializer symfony/service-contracts v2.2.0 v2.2.0 Generic abstractions related to writing services symfony/stopwatch v4.4.20 v4.4.20 Provides a way to profile code symfony/string v5.2.6 v5.2.6 Provides an object-oriented API to strings and deals with bytes,... symfony/swiftmailer-bundle v3.5.2 v3.5.2 Symfony SwiftmailerBundle symfony/templating v4.4.20 v4.4.20 Provides all the tools needed to build any kind of template system symfony/test-pack v1.0.7 v1.0.7 A pack for functional and end-to-end testing within a Symfony app symfony/translation v4.4.21 v4.4.21 Provides tools to internationalize your application symfony/translation-contracts v2.3.0 v2.3.0 Generic abstractions related to translation symfony/twig-bridge v4.4.21 v4.4.21 Provides integration for Twig with various Symfony components symfony/twig-bundle v4.4.20 v4.4.20 Provides a tight integration of Twig into the Symfony full-stack... symfony/twig-pack v1.0.2 v1.0.1 A Twig pack for Symfony projects symfony/validator v4.4.21 v4.4.21 Provides tools to validate values symfony/var-dumper v4.4.21 v4.4.21 Provides mechanisms for walking through any arbitrary PHP variable symfony/var-exporter v4.4.20 v4.4.20 Allows exporting any serializable PHP data structure to plain PH... symfony/web-link v4.4.21 v4.4.21 Manages links between resources symfony/web-profiler-bundle v4.4.21 v4.4.21 Provides a development tool that gives detailed information abou... symfony/web-server-bundle v4.4.21 v4.4.21 Provides commands for running applications using the PHP built-i... symfony/webpack-encore-bundle v1.11.1 v1.11.1 Integration with your Symfony app & Webpack Encore! symfony/yaml v4.4.21 v4.4.21 Loads and dumps YAML files ```

PHP version

$ php -v
PHP 7.4.7 (cli) (built: Jun  9 2020 13:34:30) ( NTS Visual C++ 2017 x64 )
Copyright (c) The PHP Group
Zend Engine v3.4.0, Copyright (c) Zend Technologies
    with Zend OPcache v7.4.7, Copyright (c), by Zend Technologies

Subject

Serious issue here, saving a block deletes all children:

SonataPageBundle bug

Steps to reproduce

  1. Create a block inside any container of any page using page composer
  2. Switch to "Blocks" tab and edit that container
  3. Save changes

Expected results

Nothing should happen.

Actual results

All children blocks are deleted.

Hints

Probably due to to this assignment:

// fix weird bug with setter object not being call
$object->setChildren($object->getChildren());

AFAIK replacing the entire collection in this way... deletes all the children. It's a know issue / feature of Doctrine >= 2.5. I can remember that SonataMediaBundle did the same but was fixed at some point.

gremo commented 3 years ago

Any update on this? Right now, the workaround for me is a custom BlockAdmin class:

namespace App\Admin;

use Sonata\PageBundle\Model\PageInterface;
use Sonata\PageBundle\Admin\BlockAdmin as BaseBlockAdmin;

class BlockAdmin extends BaseBlockAdmin
{
    // TODO: rimuovere dopo fix https://github.com/sonata-project/SonataPageBundle/issues/1291
    /**
     * @param \Sonata\PageBundle\Entity\BaseBlock $object
     */
    public function prePersist($object)
    {
        /** @var \Sonata\PageBundle\Entity\BaseBlock $block */
        $block = $this->blockManager->get($object);
        if (\is_callable([$block, 'prePersist'])) {
            $block->prePersist($object);
        }

        if ($object->getPage() instanceof PageInterface) {
            $object->getPage()->setEdited(true);
        }
    }

    // TODO: rimuovere dopo fix https://github.com/sonata-project/SonataPageBundle/issues/1291
    /**
     * @param \Sonata\PageBundle\Entity\BaseBlock $object
     */
    public function preUpdate($object)
    {
        /** @var \Sonata\PageBundle\Entity\BaseBlock $block */
        $block = $this->blockManager->get($object);
        if (\is_callable([$block, 'preUpdate'])) {
            $block->preUpdate($object);
        }

        if ($object->getPage() instanceof PageInterface) {
            $object->getPage()->setEdited(true);
        }
    }
}

That is, the copy-paste of the original admin methods but without $object->setChildren($object->getChildren()).

gremo commented 3 years ago

@VincentLanglet or anyone? Can you replicate the issue?

VincentLanglet commented 3 years ago

It takes time to replicate such an issue. Could you provide a repository with the bug instead ?

Also I don't use this bundle.

gremo commented 3 years ago

Yes, I know. Sure, I can setup a custom repository... which bundle of the Sonata project should I include?

VincentLanglet commented 3 years ago

Yes, I know. Sure, I can setup a custom repository... which bundle of the Sonata project should I include?

I assume this bundle will be enough since it requires already multiple sonata bundles.

That is, the copy-paste of the original admin methods but without $object->setChildren($object->getChildren()).

If you think this is an error, you might try to open a PR without this line (and maybe some tests)

gremo commented 3 years ago

If you think this is an error, you might try to open a PR without this line (and maybe some tests)

Yes, that is the error. Removing that line results in the "normal" behaviour. I'm pretty sure I can also search for other bundles (maybe the SonataMedia one) that removed that line at some point in the past.

github-actions[bot] commented 2 years ago

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

haivala commented 2 years ago

I think this should not be closed..

VincentLanglet commented 2 years ago

I think this should not be closed..

Do you encounter the issue ? Can you provide a fix ?

gremo commented 2 years ago

@VincentLanglet I've provided a fix simple removing the call:

// fix weird bug with setter object not being call
$object->setChildren($object->getChildren());
VincentLanglet commented 2 years ago

@VincentLanglet I've provided a fix simple removing the call:

// fix weird bug with setter object not being call
$object->setChildren($object->getChildren());

I know nothing about this bundle and the previous issue you listed on MediaBundle. But if you think this is a good fix, please open a PR (with maybe a test if possible)

jordisala1991 commented 2 years ago

Should be fixed on 4.x: https://github.com/sonata-project/SonataPageBundle/pull/1452