Score:1

Programmatically loading and saving nodes is not updating my field but editing and saving manually does. Why the difference?

ng flag

I have migrated D7 date fields to D9 Smart Date (with recurring). During the migration, I've parsed the legacy repeat rules and populated them into the new D9 Smart Date field.

However, the repeating dates do not show up in Views unless I first manually edit and save the node (without making any changes).

The problem is that I have hundreds of nodes that need to be resaved and none of the progratic methods work. Only manually editing and saving is forcing the repeat rule to do what needs to be done to show up.

I've tried using Views Bulks Action's Save Node function. I've tried using the Save All module. I've tried creating a PHP script to load and save the node.

None of these work. My script is below. Any ideas why only manually saving works?

enter image description here

Jaypan avatar
de flag
Node's generally won't do anything when saved if no values have changed.
quantumized avatar
ng flag
I just modified the script to change the sticky to true and it's still not working. So the node is saving but whatever the Smart Date field needs to do is only working when the node is saved manually. Is there a way to mimick saving the node manually through code? Not sure where the discrepancy is coming from.
Jaypan avatar
de flag
It's possible that the module has some functionality that is being performed on form save, rather than entity save. I'd go through the module and look at the form definition and/or any form alter hooks to see if they're doing something that way.
quantumized avatar
ng flag
Thank you. That makes sense. Is there a way to do a form save programmatically?
Jaypan avatar
de flag
In Drupal 7, you could use drupal_form_submit(). This change record (https://www.drupal.org/node/2121003) says that you can use `\Drupal::formBuilder()->submitForm()`. I don't know the mechanics of it though
Score:1
cn flag

Any ideas why only manually saving works?

As Jaypan mentioned in the comments, this is because Drupal won't save the node if nothing has changed.

When you submit the form for an entity which has a created/changed date (i.e. implements EntityChangedInterface), it does this:

if ($entity instanceof EntityChangedInterface) {
  $entity->setChangedTime($this->time->getRequestTime());
}

Which changes a field value, forcing the entity to save.

You could use the same method to force a save in your code.

quantumized avatar
ng flag
Thank you for the info @Clive. I was hoping it would be something simple like you suggested but when I change the sticky from false to true and resave the Smart Date is still not doing it's magic that occurs when manually saving. It was suggested that perhaps the module is doing something special that only occurs during a node form edit/save but I can't figure out how to save the form programmatically.
cn flag
There's an example here: https://drupal.stackexchange.com/questions/253009/how-to-call-submit-form-from-another-page-in-custom-module - problem is it's an entity form, so not exactly simple to populate the submission values. There will be another API method for that too, but forms are a bit tricky to work with programatically (from the outside at least). It might be less effort to look through the code in the smart date module and see if it's doing something unusual
Jaypan avatar
de flag
Yeah, you may just need to pull the code out of their module and put it in a hook_update_N() or make a drush script that does the same thing.
mangohost

Post an answer

Most people don’t grasp that asking a lot of questions unlocks learning and improves interpersonal bonding. In Alison’s studies, for example, though people could accurately recall how many questions had been asked in their conversations, they didn’t intuit the link between questions and liking. Across four studies, in which participants were engaged in conversations themselves or read transcripts of others’ conversations, people tended not to realize that question asking would influence—or had influenced—the level of amity between the conversationalists.