Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cannot completely remove object relation attribute #228

Open
SalvatorePollaci opened this issue Nov 7, 2019 · 3 comments
Open

Cannot completely remove object relation attribute #228

SalvatorePollaci opened this issue Nov 7, 2019 · 3 comments

Comments

@SalvatorePollaci
Copy link

I have run the following migration to remove the 'product_categories' object relation list attribute(list of 'product_category' content type objects) from my 'recipe' content type:

-
    type: content_type
    mode: update
    content_type_group: Content
    identifier: recipe
    remove_attributes: [product_categories]

Now if I view the 'recipe' content type definition from eZ's backoffice I no longer see the 'product_categories' object relation list attribute, BUT, from a recipe content objects 'Relations' tab I still see the relation with the previously associated product category.

recipe_product_category_related_objects

So now If I try to update such recipe content via eZ's ContentService(eZ\Publish\Core\Repository\ContentService) updateContent method I get the following notice 'Notice: Trying to get property of non-object' from
vendor/ezsystems/ezpublish-kernel/eZ/Publish/Core/Repository/RelationProcessor.php processFieldRelations method.

public function processFieldRelations(
        array $inputRelations,
        $sourceContentId,
        $sourceContentVersionNo,
        ContentType $contentType,
        array $existingRelations = array()
    ) {
        // Map existing relations for easier handling
        $mappedRelations = array();
        foreach ($existingRelations as $relation) {
            if ($relation->type === Relation::FIELD) {
                $fieldDefinitionId = $contentType->getFieldDefinition($relation->sourceFieldDefinitionIdentifier)->id;
                $mappedRelations[$relation->type][$fieldDefinitionId][$relation->destinationContentInfo->id] = $relation;
            }
            // Using bitwise AND as Legacy Stack stores COMMON, LINK and EMBED relation types
            // in the same entry using bitmask
            if ($relation->type & Relation::LINK) {
                $mappedRelations[Relation::LINK][$relation->destinationContentInfo->id] = $relation;
            }
            if ($relation->type & Relation::EMBED) {
                $mappedRelations[Relation::EMBED][$relation->destinationContentInfo->id] = $relation;
            }
        }

Simply put, the previous version of the 'recipe' content still contains the 'product_categories' relation, but now the relation's 'sourceFieldDefinitionIdentifier'

$relation->sourceFieldDefinitionIdentifier

is null, resulting in the highlighted notice.
On the other hand, if I re-publish the recipe content from eZ's backoffice, all goes well, and the relation is no longer visible from the 'Relations' tab.

Is this a bug in eZ Migration Bundle? If so, how can I programmatically re-publish the recipe contents without such notices?

@SalvatorePollaci
Copy link
Author

After a lot of debugging I found out that the sticky information was coming from the 'ezcontentobject_link' table. So after running the following query:

DELETE FROM ezcontentobject_link
WHERE contentclassattribute_id = XXX

the relation was no longer visible in the 'Relations tab', moreover I was able to programmatically re-publish the recipe contents without any notices.

Maybe such query should be automatically run my eZ Migration bundle when removing object relation list attributes?

@gggeek
Copy link
Member

gggeek commented Nov 8, 2019

I think that what you are experiencing might be a bug in the eZ kernel, and should be reported in the upstream bug tracker.

Of course it is entirely possible for you to add a 'sql' step to your yml migration definition that does the clean up of the ezcontentobject_link table after removing the object-relation field (I can provide an example of that if needed).

However, I am not sure that it is the duty of the migration bundle to execute that automatically:

a) is it really the correct thing to do? As far as I understand, the problem comes from current (as well as old) versions of objects having more data than they should have if matching the current ContentType definition. This seems to be a generic problem, that might happen for every field type which stores data in a custom table besides ezcontentobject_attribute or external system. Does the kernel already drop that custom data? If not, why? Are there performance implications (think about 10M objects)? Also, the reverse case can also happen: does the kernel allow one to add a new non-null field to a ContentType with existing contents? If so, existing contents will also be inconsistent with their current definition. Should the kernel disallow that, or maybe better allow to do that but set a default non-null value for all objects and their previous versions? Last but not least: what happens when an editor tries to preview/restore an old content version which did not have the new field?

b) assuming that it is the correct thing to do, it seems something that the kernel should do automatically

@gggeek gggeek added the bug label Nov 8, 2019
@gggeek
Copy link
Member

gggeek commented Oct 30, 2020

Ping @SalvatorePollaci any news about this? If you agree this is a kernel bug, I'd like to close this ticket...

@gggeek gggeek added upstream bug and removed bug labels Oct 30, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants