When a new node is created, the created timestamp and changed timestamp are not the same. This is because of the function copyFormValuesToEntity in ContentEntityForm.php which copies values only from non-widget fields to the entity when the node is saved. Since 'changed' is a hidden field, even though it has the same timestamp as created until this function is executed , now gets a different time than the created.

I would assume that created and changed times should be the same for new nodes. Thoughts appreciated!

Thanks,
Sukanya

Members fund testing for the Drupal project. Drupal Association Learn more

Comments

sukanya.ramakrishnan created an issue. See original summary.

timmillwood’s picture

Maybe the created timestamp is when the form is first loaded and the changed timestamp is when the form is saved?

sukanya.ramakrishnan’s picture

Thats correct I believe!! when i debug the save functionality, i found that the created and updated time are being updated with the request time of the form save request, but since there is a possibility that the created time might have been changed in the authoring info widget, the value is not being copied over to the entity for the created field.

IMHO, the updated time should be set to the created time on node save only for new nodes (given that there is a possibility the created date can be changed in the form).

sukanya.ramakrishnan’s picture

This can definitely be done in a custom presave hook but this shud probably be fixed in core? Thoughts?

Thanks,
Sukanya

sukanya.ramakrishnan’s picture

Version: 8.2.x-dev » 8.4.x-dev
timmillwood’s picture

Version: 8.4.x-dev » 8.5.x-dev
Status: Active » Needs review

Thanks for the patches @sukanya.ramakrishnan, I think we should really be patching against 8.5.x only now.

I'm not sure how I feel about the solution, if we do want changed and created to be the same on new nodes I wonder if it should happen earlier in the save process. Also, I wonder if we need a more generic solution, for example do comments have the same issue? The Comment entity has both changed and created fields.

kevin.dutra’s picture

I think you're right Tim, this extends beyond nodes to virtually any type of content entity. If I'm reading things right, this is partly to do with the CreatedItem and ChangedItem field types and partly due to ContentEntityForm.

To populate the creation form, a new entity is created by the storage handler. The created and changedfields both receive a default value of the current request time via their field type plugins. So this new content entity has both dates set to the time the form was generated. (This is why the "Authored on" field is actually populated when creating a node, rather than being blank, which would allow it to use the submission time like you would expect.) Within the submission handler for ContentEntityForm, the changed field is specifically updated to the time of the form submission, which puts the fields out of alignment. (If the entity had been created via the API instead, you don't run into this issue because it's all done within the same request, so the dates align.)

Making changes to the changed field is a little safer because it's wrapped up in the EntityChangedTrait (and interface), so you're assured field naming and it's easy to check whether the entity is something that should be operated on. There does not appear to be a corresponding trait/interface for creation. Add to that the fact that Node (if not others) expose the created field to be edited, which means that creation time might actually be intentionally different.

So I think the best path forward here is to make an adjustment to ContentEntityForm::init() to check whether the entity is new and has a created field that is a CreatedItem type field and if so, wipe out that default value that was applied. This should cause the field to use the form submission time rather than the initial form generation time (except when a user manually changed that field value on the form). Does that sound kosher?

sukanya.ramakrishnan’s picture

Tim,

Can you please let me know what you think about @kevin.dutra's proposed solution? I will make changes per this approach if it sounds ok with you!

Thanks,
Sukanya

timmillwood’s picture

I'm not sure this should be part of the form.

It would be useful if we could take a TDD approach and have a functional AND kernel test for nodes and entity_test entities to show the issue exists when creating entities with and without the form.

kevin.dutra’s picture

That's the thing, this issue does not occur when creating an entity without the form. It only occurs when using the form because the entity is not created and saved within the same request. (It's created in one request when the form is generated and saved in another when the form is submitted.)

swentel’s picture

public function preSave() in CreatedItem might be an option too. (inspired by the fact that I'm currently doing this in a hook_node_presave() with the same isNew() check in custom code).

    if ($this->getEntity()->isNew()) {
      // Make sure it's NOW
    }

That saves the part where we'd have to iterated in init:: over all fields simply to check whether it's a CreatedItem.
And in case someone comes up with another way (decoupled ?) to temporarily store an entity before saving, the fix would be contained where it needs to be.

timmillwood’s picture

Another thought, is maybe the fix could be in \Drupal\Core\Field\Plugin\Field\FieldType\CreatedItem:onChange to update the ChangedItem field?

Version: 8.5.x-dev » 8.6.x-dev

Drupal 8.5.0-alpha1 will be released the week of January 17, 2018, which means new developments and disruptive changes should now be targeted against the 8.6.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.