Skip to content

Conversation

@nfourtythree
Copy link
Contributor

@nfourtythree nfourtythree commented Mar 24, 2025

Description

Noticed a quirk/bug when creating an element using Craft::createObject() and setting data on a element relation custom field.

The test code for creating an entry is as follows:

$randomEntry = Entry::find()->orderBy('RAND()')->one();
$section = Craft::$app->getEntries()->getSectionByHandle('test');

$entry = Craft::createObject([
    'class' => Entry::class,
    'sectionId' => $section->id,
    'title' => 'My Test Entry',
    'enabled' => true,
    'myRelatedEntry' => [$randomEntry->id],
]);

Craft::$app->getElements()->saveElement($entry);

With this code the element saves and if you view the element in the CP or look at its content in the DB everything looks correct. The related element shows up in the field etc.

However, no rows are added to the relations DB table. This means that if you were to do an element query e.g. Entry::find()->relatedTo([123])->one() the entry would not be returned.

Tracked this issue down to two parts.

Because the element is being created with createObject() and mass assignment the $_initialized property on the element is still false when it hits the following bit of code, so the field is not marked as dirty.

cms/src/base/Element.php

Lines 5056 to 5058 in f48af60

if ($this->_initialized) {
$this->_dirtyFields[$fieldHandle] = true;
}

This however doesn't stop the content from saving, but in the case of a relationship field it prevents the relation from saving in the updateRelations() method when figuring out if the field should be included.

cms/src/base/Element.php

Lines 6199 to 6205 in f48af60

if (
($this->duplicateOf || $this->isFieldDirty($field->handle) || $field->forceUpdateRelations($this)) &&
(!$this->propagating || $localizeRelations)
) {
$include = true;
break;
}

To get the ball rolling on a solution for this I took the idea that if this element is a brand new element we can pass $isNew from the afterSave() to updateRelations(). As, in theory, if it is new we probably want to be trying to save all the data we can.

Related issues

craftcms/commerce#3931

@nfourtythree nfourtythree self-assigned this Mar 24, 2025
@brandonkelly brandonkelly changed the base branch from 5.x to 4.x March 24, 2025 18:27
@brandonkelly brandonkelly force-pushed the bugfix/element-create-object-not-saving-custom-field-relations branch from dc9f26b to e485b09 Compare March 24, 2025 18:41
[ci skip]
@brandonkelly brandonkelly merged commit cc176a6 into 4.x Mar 24, 2025
@brandonkelly brandonkelly deleted the bugfix/element-create-object-not-saving-custom-field-relations branch March 24, 2025 18:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants