Comments

coredumperror’s picture

This is just what I was looking for. With this code in place I can migrate the value returned by workbench_moderation_state_published() into this new workbench_moderation_state_new field, and Workbench Moderation will treat my migrated nodes as being Published, instead of Draft (which was happening to every node, even if I migrated it as status=1).

dixon_’s picture

Status: Needs review » Reviewed & tested by the community
StatusFileSize
new1.34 KB

Here's a rerolled patch. I noticed that I added the wrong path to the migrate file in .info.
No other changes.

This is a trivial addition. So I'll go against the rules and RTBC this myself.

les lim’s picture

Thanks! Works great.

darrenmothersele’s picture

darrenmothersele’s picture

Patch for 7.x-1.x

pvhee’s picture

#5 works like a charm.

in your migrate function, you can now write

    $this->addFieldMapping('workbench_moderation_state_new', 'workbench_moderation_state_new')->defaultValue('published');

which will make sure nodes imported via Migrate will by default by published, instead of being set to "draft".

Seems ready to be committed.

stevector’s picture

Status: Reviewed & tested by the community » Fixed

Status: Fixed » Closed (fixed)

Automatically closed -- issue fixed for 2 weeks with no activity.

myselfhimself’s picture

Hello,

Thank you very much for that awesome patch!

Example for migrate_d2d

Example class and field mapping

Just in case people were looking for more details on usage for this new possible mapping, here's an example with the migrate_d2d module, to migrate a Drupal site's nodes (for me D6) without workbench_moderation to another Drupal site (for me D7) having workbench_moderation. The possible destination workbench moderation states are 'published', 'needs_review' (omitted for this migration) and 'draft'.

Within a inheriting class of migrate_d2d's DrupalNodeMigration, in the __construct() method, one can use a field mapping as follows and a callback to convert source Drupal integer status to a destination Drupal Workbench moderation state string (note: those states strings can be retrieved easily in the database: select * from workbench_moderation_states):

class MyNodeMigration extends Drupal6NodeMigration {
  public function __construct($arguments) {
      //...
      $this->addFieldMapping('workbench_moderation_state_new', 'status')->callbacks(array($this, 'getWorkbenchModerationStateForNodeStatus'))->defaultValue('published');
  }

  /**
   * Translates a node published status 1 or 0 into a Workbench moderation state
   * value string.
   *
   * @param $status
   * @return string
   */
  public function getWorkbenchModerationStateForNodeStatus($status) {
    return ($status == '1') ? 'published' : 'draft';
  }
}

Evaluating correct migration Workbench moderation states

In case you were wondering if your Drupal published statuses are correctly mapped to workbench moderation states, you can lookup your source and destination databases as follows:

Counting states within the source database

-- Find number of published/unpublished nodes of my source content type
select count(status), status from node where type = 'src_content_type' group by status;

... which must yield the same numbers as in the source table:

 count | status 
-------+--------
    18 |      0
   393 |      1
(2 rows)

Counting states within the destination database

-- Find number of published/unpublished nodes of my destination content type
-- This query can be run during a migration and after, it is fun to see the digits changing :-D
select count(n.nid) as nb, h.state from node n inner join workbench_moderation_node_history h on n.vid = h.vid inner join migrate_map_{mymigrationname} r on r.destid1 = n.nid where n.type = 'dest_content_type' and h.current = 1 group by h.state;

which should yield the same numbers as in the source, with the mapped states values:

+-----+-----------+
| nb  | state     |
+-----+-----------+
|  18 | draft     |
| 392 | published |
+-----+-----------+
2 rows in set (0.01 sec)

What are regular node.status values migration ?

The migrate_d2d module takes care of migrating your nodes' regular node.status fields for you (see DrupalNodeMigration..); you may want to run the first query adapted for the destination and see you get the same numbers as in source (you may need to inner join on the migrate_map_{your migration name}.destid1 column if you had other nodes before your migrations).

Viva la vida!

jaxxed’s picture

Status: Closed (fixed) » Needs work

Technically this is incorrect code. The code works, but only when the auto-register functionality in migration is enabled. This functionality will likely (and should) be phased out.

Really the hook_migrate_api code should look like this:

--- a/workbench_moderation.module
+++ b/workbench_moderation.module
---   return array('api' => 2);
---
+++  return array(
+++     'api' => 2,
+++     'destination handlers' => array(
+++       'WorkbenchModerationMigrateDestinationHandler' => 'WorkbenchModerationMigrateDestinationHandler'
+++     )
+++   );
jaxxed’s picture

Here is a 7.x-1.x (origin/HEAD) patch that adds the explicit handler definition/registration.

There is no hook_migrate_api call in the 2.x branch (that I saw.)

jaxxed’s picture

Status: Needs work » Needs review

I always forget to mark review.

myselfhimself’s picture

@jaxxed
Thank you! Indeed, in my current install, I did not have to register anything for workbench_moderation migrate support; probably I already had that auto-register functionnality enabled. So thanks for patch #11 !

When setting the 'workbench_moderation_state_new' field for node-only migrations. The destination node does seem to migrate and display in the correct publishing state.

Subsequent Field collection migrations for some content type, however reverse or spoil the node.status value, which ends in migrated nodes with FCs displaying badly, having eg. node.status = 0 and their current workbench moderation state set to 'published'.

myselfhimself’s picture

Setting the 'workbench_moderation_state_new' property to 'published' does make Migrate Workbench-moderate the destination node. Though, it does not show within Views results anymore while the filtering does check for a workbench "published" status and the "moderate" tab does show a node moderation history with 1 step : "Draft => Published".

To me, that "workbench_moderation_state_new" property does not allow "full" publishing of a destination node. Has someone met that behaviour too ?

milesw’s picture

Issue summary: View changes

Had the same problem as #14. The moderation state was being migrated properly but Views refused to display any migrated nodes.

This was because the Views filter for moderation states adds:
INNER JOIN {workbench_moderation_node_history} workbench_moderation_node_history ON node_revision.vid = workbench_moderation_node_history.vid

But the migration didn't add anything to the workbench_moderation_node_history table.

Triggering a node revision during the migration seems to resolve this:

/**
 * Implements Migration::prepare().
 */
public function prepare($entity, $row) {
  $entity->revision = isset($entity->nid) ? FALSE : TRUE;
}
darrenmothersele’s picture

Just an FYI, Cross-referencing with work being done in this issue, where revisions are being worked on in case there's any incompatibility:

https://drupal.org/node/1298724

jmuzz’s picture

I do not have the problem mentioned by #14. I applied the patch in #11 to 7.x-1.3 and after migrating a node there is an entry for it in workbench_moderation_node_history and the view filter for it is working.

I believe this is the correct behavior and the information in the table should reflect how workbench moderation handles workbench_moderation_state_new without requiring an additional function in the migration. If that doesn't work in the development branch it should really be looked at... I don't see why the nodes affected by that would be limited to the ones being migrated.

one_orange_cat’s picture

I've just been struggling with the empty workbench_moderation_node_history problem mentioned in #14 and #15, as well as a number of the other migrate/workbench_moderation issues, and I think #14 in particular crops up when migrating data in fresh (not updating), combined with not having correct prepare code set up.
Depending on what you're doing in the migration process, you still need the patch in #11 (or auto-register on in Migrate) to make things work properly though.

In the end I solved all my problems (including the "I'm published but I'm not really!" gag) using a combination of the patch in https://www.drupal.org/node/1436260#comment-8927097, and a prepare function formed using https://www.drupal.org/node/1452016#comment-8503687 and the alteration in #15 above. My base version is 7.x-1.3+10-dev and my final working prepare code now looks like this:

<?php
    public function prepare($entity, $row) {
      /* check if this is a fresh import and set revision and is_new accordingly */
      $entity->revision = isset($entity->nid) ? FALSE : TRUE;
      $entity->is_new = !(isset($entity->nid) && ($entity->nid));
   
      /* set a current state to get a proper line in workbench_moderation_node_history */
      $entity->workbench_moderation_state_current = 'draft';
    
      /* and then I wanted to publish (or not) based on other migrate data as well */
      if ($row->{'Company:Agreement'} == 'Yes') {
        $entity->workbench_moderation_state_new = 'published';    
      } else {
        $entity->workbench_moderation_state_new = 'inactive';    
      }
    }
 ?>
mikeryan’s picture

Category: Feature request » Bug report
Priority: Major » Normal
StatusFileSize
new1.7 KB

Changing to a bug report - migration support is completely broken with current versions of Migrate without the handler registration.

In this version of the patch, in addition to @jaxxed's previous patch which registered the destination handler class:

  1. Moved hook_migrate_api() to the migrate.inc file, it doesn't need to be in .module.
  2. Switched to registerTypes() for register the entity type (node) this is valid for.
  3. Added a prepare() method to clear the revision field and initialize the current state from the new state.

I don't know enough about the workbench_moderation workflow to be sure that this prepare() code is right for all use cases, so this needs review by someone who does. It works fine in my case (only migrating published nodes), I just need to

    $this->addFieldMapping('workbench_moderation_state_new')
      ->defaultValue('published');

and everything seems to come out OK.

geerlingguy’s picture

Assigned: dixon_ » Unassigned

I'm testing this out the patch in #19; we had a situation where an update migration would cause all the updated nodes to be set into 'draft' status until a later Workbench process set the nodes back into 'published', thus some existing nodes were being unpublished and republished seemingly at random. I'll report back if it works, but this looks like exactly what we needed!

frosev’s picture

Experienced the same issues where nodes being imported were being set to a draft state until a subsequent workbench process would reset the node's status. I tested this patch on a local project and it correctly published the nodes. Will be testing on a dev/qa instance and will report back if it works on all instances.

geerlingguy’s picture

Status: Needs review » Reviewed & tested by the community

After a day's worth of testing, it looks like this patch allows migration to proceed normally without Workbench unpublishing/republishing everything that's updated. RTBC!

thijsvdanker’s picture

Status: Reviewed & tested by the community » Needs work
+++ b/workbench_moderation.migrate.inc
@@ -2,18 +2,33 @@
+      $node->revision = FALSE;

When $node->revision is set to FALSE, the workbench_moderation_node_history is not being populated. This causes views that depend on it to fail (as described in #15).

One option would be to incorporate #15 (set revision state depending on nid).
This would trigger the whole workbench_moderation_moderate() and workbench_moderation_store() flow and everything would be in sync.
This does however create a large overhead (all nodes will be resaved on shutdown, basically making migration take twice as long as mikeryan mentioned in https://www.drupal.org/node/1452016#comment-9254031).

Another option would be to update the workbench_moderation_node_history in the complete() function of the handler?
Something like this but with better checks for updating nodes and from -> to states.

 public function complete($node, $row) {
    global $user;

    // Build a history record.
    if (isset($node->workbench_moderation_state_new)) {
      $new_revision = (object) array(
        'from_state' => $node->workbench_moderation_state_current,
        'state' => $node->workbench_moderation_state_new,
        'nid' => $node->nid,
        'vid' => $node->vid,
        'uid' => $node->uid,
        'current' => 1,
        'published' => 1,
        'stamp' => $_SERVER['REQUEST_TIME'],
      );

      // Save the node history record.
      drupal_write_record('workbench_moderation_node_history', $new_revision);
    }
  }

This does make it harder to maintain as it adds a lot of (duplicate) logic to migration.

fluxsauce’s picture

Had the same problem as #23, so I've taken the best of #19 and #18 and combined them into a solution that's working for me.

fluxsauce’s picture

StatusFileSize
new1.73 KB

As mikeryan pointed out, setting is_new wasn't necessary.

mikeryan’s picture

Status: Needs review » Needs work

Well, with revision set, the history table does get written - unfortunately, we're back to resave-all-the-(published)-nodes in the shutdown function. The previous patch had avoided the workbench_moderation_moderate() call, which is where the history table is written - now it does get called, and we get this:

  if (!empty($node->workbench_moderation['published']) || !empty($node->workbench_moderation['current']->unpublishing)) {
    drupal_register_shutdown_function('workbench_moderation_store', clone $node);

I.e., all published nodes get resaved at shutdown.

So, has anyone thought about how to address the root problem - saving the node a second time? There must be some way for workbench_moderation to get all its state straight without that second node_save() and the shutdown hack...

mikeryan’s picture

Short of totally refactoring the node hooks, maybe it's time to try a patch with @thijsvdanker's suggestion at https://www.drupal.org/node/1445824#comment-9319109 (writing the history record ourselves).

mikeryan’s picture

Seems like this should address the root cause, eventually: #2376839: Rewrite to use the new Drafty module.

mikeryan’s picture

Status: Needs work » Needs review
StatusFileSize
new6.45 KB

For now, applying @thijsvdanker's idea. By separating the writing of the history record out into a separate function (which makes sense anyway), we avoid duplicating logic in the migration code.

mikeryan’s picture

I should say, testing on that is minimal so far... In my environment, the shutdown function is avoided and the history record looks good on a quick test.

mikeryan’s picture

StatusFileSize
new6.75 KB

Oops, lost the removal of hook_migrate_api() from the .module file (how did the testbot pass?), here we go.

fluxsauce’s picture

Status: Needs review » Reviewed & tested by the community

Patch #31 is working for me. Caveat: mikeryan and I are working on the same project, additional peer review would be appreciated.

kepford’s picture

Path #31 works for me as well.

fluxsauce’s picture

Status: Reviewed & tested by the community » Needs review
StatusFileSize
new6.83 KB
new567 bytes

Found a bug! Was trying to figure out why migrated content wasn't publicly visible. Turns out that the logic to make sure that there can only be one published workbench_moderation_node_history and node_revision was a bit too zealous. I added a condition to only update the old versions.

thijsvdanker’s picture

The patch in #34 caused errors on entities that don't have workbench moderation enabled for it.
I've added a check to see if it does in de prepareRow and complete functions.

fluxsauce’s picture

StatusFileSize
new9.15 KB

Good catch, thijsvdanker! I discovered another issue with https://www.drupal.org/project/workbench_path_revision - the tl;dr is that workbench_moderation_store is normally registered as a shutdown function, but that's not happening on migration.

fluxsauce’s picture

StatusFileSize
new7.04 KB

Now with 100% more correct patches!

fluxsauce’s picture

On further testing, my change isn't that good, let's stick with thijsvdanker's version.

gold’s picture

Status: Needs review » Reviewed & tested by the community

I've added the current patch from #35 to my make file and implemented this as per the example at #9. The current project is a migration of 318134 nodes and prior to this patch it took about 9.75 hours to run a full migration. After this patch was added the full run took 21.5 hours.

While, technically, the process is working and my nodes are now under workbench moderation the process is time consuming.

Personally I think the patch is RTBC. However, a separate issue could be created for optimising this process to strip out what workbench moderation is doing behind the scenes to mimic the results without the double node save.

hussainweb’s picture

StatusFileSize
new2.07 KB
new7.07 KB

I am just cleaning up the patch in #35 (which was RTBC'd) for comments and a bit of code as seen in interdiff.txt. It's only cosmetic changes and hence I think this can stay on RTBC. I am hoping this gets committed soon.

mstrelan’s picture

Not sure if this is in scope for this issue, but I need my migration to create new revisions if the content is to be updated. I'm running the patch in #40 which is setting the latest revision to the correct state, however I really need it to create a new revision and set that to the right state. Is this possible?

EDIT:
This is easily achieved with the following:

<?php
  public function prepare($entity, stdClass $current_row) {
    $entity->revision = isset($entity->nid) ? TRUE : FALSE;
  }
?>

Which is the exact opposite of #15 (and #18). It seems like there is a logic error in those two comments...

alan d.’s picture

Status: Reviewed & tested by the community » Needs review

We are running a migration with revisions flagged as per comment #42, but the node table is being set to the latest imported revision, rather than retaining the latest published revision, so any updated content becomes unpublished on the site.

i.e. node 54 had a published revision of 192, but after the migration, this was altered to the latest revision (from the import 193) and status was 0.

So can someone else test if this is correctly retaining published states, just in case it is something random to do with our migrations.

Steps to fail were:

  1. Migrate set to:
    - create revisions
    - non-published state (needs_review or similar)
  2. Import and publish a node
  3. Re-import that node
  4. Check that the main revision is still public and accessible to the public (issues may be hidden if you are logged in as admin user)

Flag RTBTC again if it passes.

  • stevector committed 3422c07 on 7.x-3.x
    Issue #1445824 by dixon_ and darrenmothersele: Migrate module support.
    
dxvargas’s picture

Does the commit mentioned in #43 solves this issue? Can we close it as Fixed?

jrb’s picture

What was committed appears to be the patch in #5 which included only minimal changes. I'm not sure why the later work was ignored. Maybe this was addressed with the switch to Drafty mentioned in #28?

crashtest_’s picture

I am wondering what the status is of this now that we have Content Moderation in core. Is there a migration path for Workbench Moderation (in D7) to Content Moderation in D8?