The non-drupal site from which I am migrating has a hopeless menu structure which will not be duplicated. So we are migrating the nodes and requiring our editors to rebuild the menus structure by hand.

So far so good.

However, content is still being edited on the source system and I would like to be able to perform periodic updates. This, of course, would destroy any menu structure that the editors had created in the destination site. I have already tried setting the systemOfRecord to DESTINATION. However, every update still destroys the menu links.

What am I misunderstanding, and is there some way to prevent this? My Google-fu is failing me.

Comments

mikeryan’s picture

Status: Active » Postponed (maintainer needs more info)
Related issues: +#983290: Importing an existing node removes it from the menu

See #983290: Importing an existing node removes it from the menu for previous discussion. The odd thing is that this would happen in the DESTINATION case - with DESTINATION, only fields you map should overwrite the original node data, the menu links should be preserved. Can you do some debugging and see what $node looks like in the prepare() method?

mikeryan’s picture

Actually, you might try the prepare() trick that's in the linked issue...

wayneloftus’s picture

In the prepare method, the $node looks like:

stdClass Object
(
    [body] => Array
        (
            [und] => Array
                (
                    [0] => Array
                        (
                            [value_format] => full_html
                            [format] => full_html
                            [value] => ...
                        )
                )
        )
    [uid] => 149
    [title] => Budget Reports
    [nid] => 5263
    [changed] => 2015-02-12 19:43:53
    [status] => 1
    [created] => 1328306714
    [vid] => 5437
    [migrate] => Array
        (
            [machineName] => OperationsUpdate
        )
    [path] => Array
        (
            [pathauto] => 0
            [alias] =>
        )
)

And, for what it's worth, $this->systemOfRecord = 2.

I saw the other ticket earlier with the prepare() trick, but as you can see, $node->menu isn't there, so the expression is evaluating as false.

wayneloftus’s picture

Looking at \MigrateDestinationNode::import I'm not seeing where the menu links get assigned to $node.

migrate/plugins/destinations/node.inc:158:

  if ($migration->getSystemOfRecord() == Migration::DESTINATION) {
      if (!isset($node->nid)) {
        throw new MigrateException(t('System-of-record is DESTINATION, but no destination nid provided'));
      }
      $old_node = node_load($node->nid);
      if (empty($old_node)) {
        throw new MigrateException(t('System-of-record is DESTINATION, but node !nid does not exist',
                                   array('!nid' => $node->nid)));
      }
      if (!isset($node->created)) {
        $node->created = $old_node->created;
      }
      if (!isset($node->vid)) {
        $node->vid = $old_node->vid;
      }
      if (!isset($node->status)) {
        $node->status = $old_node->status;
      }
      if (!isset($node->uid)) {
        $node->uid = $old_node->uid;
      }
    }
    elseif (!isset($node->type)) {
      // Default the type to our designated destination bundle (by doing this
      // conditionally, we permit some flexibility in terms of implementing
      // migrations which can affect more than one type).
      $node->type = $this->bundle;
    }

So I see $node->created, $node->vid, $node->status, and $node->uid being assigned, but not $node->menu_node_links. Is that right?

mikeryan’s picture

Status: Postponed (maintainer needs more info) » Active

When providing more info to an issue marked "Postponed (maintainer needs more info)", be sure to reset the status to "Active".

mikeryan’s picture

Status: Active » Postponed (maintainer needs more info)

Farther down in MigrateDestinationNode::import, you'll see a loop over $old_node that copies unmapped fields from the old node to the new node, that should be copying the existing menu into $node, unless for some reason coming in $node->menu exists and contains NULL (as opposed to not existing). But, you dumped $node in prepare() and the menu wasn't there... And now that I look, I realize prepare() is too soon for you to look for it - the old menu wouldn't be added to $node until after prepare() is called - I would dump $node and look for the menu just before the node_save().

mikeryan’s picture

Status: Postponed (maintainer needs more info) » Closed (cannot reproduce)