0

I want to enable users to click a link to create a node of a specific content type. However, instead of going to /node/add/contenttype, which is the standard Drupal flow, I want the node of the relevant content type to automatically be created and saved, and then redirect the user to the newly created node's edit page.

In other words, when a user clicks "add a node," I want to create the node for the user and send the user to the edit page.

I want to do this because I have a very long, complicated form and I want to use the Autosave Form module to automatically save the form; however, this module can only save a node/entity that has already been saved once (entities with an entity ID).

What's the simplest way to implement this?

I'm thinking that I will need to define a custom route that checks permission, runs code to create the node, and then redirects to the node.

EDIT: Overriding the NodeController

As suggested by 4k4, I overrode the NodeController as follows. However, the problem is that when I go to /node/add/contenttype, the node is created and the form is shown, but it's an old form; when I try to save it, I get this error: "The content has either been modified by another user, or you have already submitted modifications. As a result, your changes cannot be saved."

class MymoduleNodeController extends NodeController {
  public function add(NodeTypeInterface $node_type) {
    $content_type = $node_type->id();
    if ($content_type == 'MYTYPE') {
      $node = $this->entityManager()->getStorage('node')->create([
        'type' => $node_type->id(),
      ]);
      $node->save();
      $form = $this->entityFormBuilder()->getForm($node);

      return $form;
    }
    else { // Default node creation behavior

1 Answer 1

1

I think the simplest way is to save the node right after you've created it in a custom version of NodeController::add():

  public function add(NodeTypeInterface $node_type) {
    $node = $this->entityManager()->getStorage('node')->create([
      'type' => $node_type->id(),
    ]);

    $form = $this->entityFormBuilder()->getForm($node);

    return $form;
  }

Edit:

Because building the form directly with the saved node doesn't work, return a redirect response for the node edit form:

    $node->save();
    return $this->redirect('entity.node.edit_form', ['node' => $node->id()]);
4
  • Thanks, but when I try using node->save() in my overriden controller, I get an old form: "The content has either been modified by another user, or you have already submitted modifications. As a result, your changes cannot be saved." Please see my updated question. Commented Dec 8, 2017 at 17:54
  • After you saved the node, what changed time is set? If it's the wrong time, try $node->changed->value = REQUEST_TIME;
    – 4uk4
    Commented Dec 8, 2017 at 18:06
  • After saving the node, created and changed are the exact same time, the moment I clicked the link. revision_timestamp is the same as well. I assume that all three of these should be the same, since all I did was immediately save the node. Still, the form that is loaded afterwards is stale for some reason. Commented Dec 8, 2017 at 19:18
  • 1
    The reason is probably, that we are still in a node add route. Seems confusing for the node form. So we need to redirect to get a new request, like you've already intended to do in the question. See the edit.
    – 4uk4
    Commented Dec 8, 2017 at 19:53

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.