Blog

Revise published content and add Workflow Support to revised content

Posted at 4:47 pm on Jan 30, 2014

 

Want to update published content WITHOUT taking the article offline?

Oasis Workflow has support for updating published content via workflow while keeping your current version of published content online.
You can revise an article, let the revised article flow through the workflow and finally when all the review is complete, Oasis Workflow will simply copy over the contents to the published article.

It not only copies the revised content, but also copies the various artifacts, like category changes, tag changes and all the post meta attributes to the revised article.

With Oasis Workflow Pro, it’s very simple to add workflow support for updating a published content while keeping your current content online.

Watch the video to see how it works.

Set your revision preferences

When you revise a post/page, you can set what the new title should look like. You can add a prefix or a suffix to easily identify a revision of an article.

make-revision-settings

Make revision

A new button will appear for all the published content. This button will essentially allow you to create a revision of the published article.

make revisionmake revision button

The plugin will copy most of the stuff out of the box, like content, metadata, attachments, taxonomies etc.

We also added a couple of hooks for you to extend the copy/make revision feature. You can use these hooks to copy other stuff from the article.

The revised item can now flow through the workflow in the same way as a normal article. However, we suggest to create a separate workflow (fast-track, smaller workflow), just so that updating a published article is faster. In other words, you may only need one-level review for updating published articles.

Publish a revised article

Now when you are about the published a revised article, the plugin will simply copy over the contents, attachments, taxonomies to the already published article from the revised article. While copying over the title it will strip off the prefix and the suffix from the revised article. It will also display a friendly message to indicate the copy action.

update-published-article

Moreover, the same hooks apply here too.

The “revised article” status is changed to “usedrev”, so that it’s not visible again. At the end, you are left with only one article (updated published article).

Other Features related to document revisioning

  • “Make Revision” is available for “Scheduled” articles also.
  • You can schedule a revision update – When you do the final sign off on a revised article, you can specify a date/time for this revision to update the original/published article.
  • Handling hierarchical post types – You can now configure if you wish to revise children articles when the parent article is being revised.
  • One Active Revision – The plugin will allow only one active revision for a given article.

You can now get the “Oasis Workflow Pro” from our site. What are you waiting for? Purchase a copy today!

22 comments on “Revise published content and add Workflow Support to revised content

  1. I have a question, if i use another plugin to create custom meta fields.
    These fields was copied too ?

    1. It depends. If the other plugin creates those meta fields in the same way wordpress does, the fields will get copied over. But if they store it in some other format/database table, then you need to use the hooks – http://www.oasisworkflow.com/hooks-and-filters to copy over the data.

      Here is an example for “custom field suite plugin“. This plugin stores the meta information in a custom table, so we need to use the hook to copy over the data.

      Here’s the hook/function which will do the trick in case of “custom field suite plugin”. This will be to copy the CFS data on the revised object.

      add_action('owf_duplicate_post', 'copy_cfs_values', 10, 2);
      function copy_cfs_values ($new_id, $post) {
            global $wpdb;
            $result = $wpdb->get_results( $wpdb->prepare( "SELECT distinct cfs.field_id, postmeta.meta_key FROM {$wpdb->base_prefix}cfs_values cfs
            	JOIN {$wpdb->prefix}postmeta postmeta ON cfs.meta_id = postmeta.meta_id
            	AND postmeta.post_id = %d ORDER BY cfs.field_id", $post->ID) );
      
            foreach ($result as $row) {
               // loop through each field id set
               $field_result = $wpdb->get_results( $wpdb->prepare( "SELECT * from {$wpdb->base_prefix}cfs_values
               		WHERE post_id = %d and field_id = %d ORDER BY meta_id", $post->ID, $row->field_id) );
      
               //get meta id for that key in the new post
               $new_meta = $wpdb->get_results( $wpdb->prepare( "SELECT * FROM {$wpdb->prefix}postmeta WHERE post_id = %d and meta_key = %s ORDER BY meta_id", $new_id, $row->meta_key ) );
      
               // the count of $field_result and $new_meta should be the same.
               for ($i = 0; $i < count($field_result); $i++) {
         			$cfs_data = array(
         						'field_id' => $field_result[$i]->field_id,
         						'meta_id' => $new_meta[$i]->meta_id,
         			         'post_id' => $new_id,
         			         'base_field_id' => $field_result[$i]->base_field_id,
         			         'hierarchy' => $field_result[$i]->hierarchy,
         			         'depth' => $field_result[$i]->depth,
         			         'weight' => $field_result[$i]->weight,
         			         'sub_weight' => $field_result[$i]->sub_weight
         					);
         			$table = $wpdb->base_prefix . "cfs_values";
         		   $result = $wpdb->insert($table, $cfs_data);
               }
            }
         }
      

      Then after the revised post has gone through the workflow, you need to use the “owf_update_published_post” hook to copy over the CFS data again back to the published post

      add_action('owf_update_published_post', 'update_cfs_values', 10, 2);
      
         function update_cfs_values ($original_post_id, $revised_post) {
            global $wpdb;
            $result = $wpdb->get_results( $wpdb->prepare( "SELECT distinct cfs.field_id, postmeta.meta_key FROM {$wpdb->base_prefix}cfs_values cfs
            	JOIN {$wpdb->prefix}postmeta postmeta ON cfs.meta_id = postmeta.meta_id
            	AND postmeta.post_id = %d ORDER BY cfs.field_id", $revised_post->ID) );
      
            //delete the original CFS values, since we will insert new ones from the revised post
            $wpdb->query( $wpdb->prepare( "DELETE FROM {$wpdb->base_prefix}cfs_values WHERE post_id = %d", $original_post_id) );
      
            foreach ($result as $row) {
               // loop through each field id set
               $field_result = $wpdb->get_results( $wpdb->prepare( "SELECT * from {$wpdb->base_prefix}cfs_values
               		WHERE post_id = %d and field_id = %d ORDER BY meta_id", $revised_post->ID, $row->field_id) );
      
               //get meta id for that key in the new post
               $original_meta = $wpdb->get_results( $wpdb->prepare( "SELECT * FROM {$wpdb->prefix}postmeta WHERE post_id = %d and meta_key = %s ORDER BY meta_id", $original_post_id, $row->meta_key ) );
      
               // the count of $field_result and $new_meta should be the same.
               for ($i = 0; $i < count($field_result); $i++) {
                  // double check if $original_meta exists
                  if (isset($original_meta) && $original_meta != null && isset($original_meta[$i])) {
                     $meta_id = $original_meta[$i]->meta_id;
                  }
                  else {
                     continue;
                  }
         			$cfs_data = array(
         						'field_id' => $field_result[$i]->field_id,
         						'meta_id' => $meta_id,
         			         'post_id' => $original_post_id,
         			         'base_field_id' => $field_result[$i]->base_field_id,
         			         'hierarchy' => $field_result[$i]->hierarchy,
         			         'depth' => $field_result[$i]->depth,
         			         'weight' => $field_result[$i]->weight,
         			         'sub_weight' => $field_result[$i]->sub_weight
         					);
         			$table = $wpdb->base_prefix . "cfs_values";
         		   $result = $wpdb->insert($table, $cfs_data);
               }
            }
         }
      

      Hope this helps.

  2. Hi Ravi,
    I’m using Workflow pro version and “custom field suite plugin“. use your example work fine with normal custom field (text, textarea …), but with custom field has type is “loop row”, it’s not work correctly. Please help me to fix it.
    thanks.

      1. The “loop row” worked for me with the above code.

        I tested with a simple field in the loop though. What type of field are you putting in the loop?

  3. Nevermind, I see the issue. It’s essentially copying the same value for all the loop fields.

    Let me look into it.

  4. I’ll soon be releasing an update (1.0.4 version) that will have multiple fixes for this particular feature.

    I’ll also release an updated code for the Custom Field Suite plugin, that will take care of copying over the “loop” attributes.

    In order to make it more modular, I’ll also be releasing a couple of hooks for “updating the published content”.

    There was a small regression in the “Make Revision” feature in 1.0.3. I’ll also add a fix for the same.

    The 1.0.4 release is targeted for March 13th.

    Stay tuned.

  5. I have released a new version of Oasis Workflow Pro which has the fixes for “make revision” and “updating published content”. I have also added two additional hooks to support the above.

    The above code to support Custom Fields Suite plugin (including the “loop” property) is also updated. We now need two functions to support the “make revision” and “update published content”. check out the above code and let me know.

  6. Hi Ravi, I used 2 action hook and your code above but it not work:

    //workflow
    add_action(‘owf_duplicate_post’, array(__CLASS__, ‘copy_cfs_values’), 10, 2);
    add_action(‘owf_duplicate_page’, array(__CLASS__, ‘copy_cfs_values’), 10, 2);

    add_action(‘owf_update_published_post’, array(__CLASS__, ‘update_cfs_values’), 10, 2);
    add_action(‘owf_update_published_page’, array(__CLASS__, ‘update_cfs_values’), 10, 2);

    with old version, I still duplicate new post/page with custom field. After update to 1.0.4 and using your code, even not duplicate page/post custom field.
    Please check it out, thanks

    1. That’s very interesting. I tested with the same code and it worked.

      Can you convert your function to a static function and see if that helps?

      Do you see any errors in the PHP log?

      1. BTW, I’m testing with Version 2.1.1 of Custom Fields Plugin and WordPress 3.8.1.

        Are you using a different version?

  7. Hi Ravi, I’ll check in your code and I see:

    foreach ($post_meta_keys as $meta_key) {
    $meta_key_trim = trim($meta_key);
    if ( ‘_’ == $meta_key_trim{0} || strpos($meta_key_trim,’oasis’) !== false ) //ignore keys like _edit_last, _edit_lock
    continue;
    $meta_values = get_post_custom_values($meta_key, $post->ID);
    foreach ($meta_values as $meta_value) {
    $meta_value = maybe_unserialize($meta_value);
    add_post_meta($new_id, $meta_key, $meta_value, false);
    }
    }

    in file: wp-content/plugins/oasis-workflow-pro/includes/workflow-duplicate-post.php, LINE 190.

    Because template page is stored in field has key “_wp_page_template”, so it was ingnored by your code.
    I think your test case only cover “default template”, not using custom template for page :(.

    Please check it.
    Thanks

    1. Did removing that underscore(_) check fix your issue? If so, I will fix the code and ignore specific keys.

      1. Here’s the code you can put/replace for that condition check.

                 if ( '_edit_lock' == $meta_key_trim
                    || '_edit_last' == $meta_key_trim
                    || strpos($meta_key_trim,'oasis') !== false ) //ignore keys like _edit_last, _edit_lock
                    continue;
        

        Make sure to put the same code in both copy_post_meta_info() and update_post_meta_info() functions

  8. Hi Ravi, I used this code and it copy good, but I wonder what’s ignore keys remaining ?. I think it has many risk :-s.

    Please re-check with custom template and file field in loop row (input type file)
    thank you.

    1. I’ll check with a custom template and let you know. BTW, did you try running the revision through the workflow and then updating the published content via workflow.

      The new code should handle all Adds/Deletes/Modifications to the CFS fields done on the revised post/page.

  9. Hi Ravi, your code have bug when I using duplicate key in loop row. Example, in loop row 1 I using key “thumbnail”, and I still using this key for loop row 2.
    Please check it, thanks

    1. I just tried using a loop attribute with file attachment and the key as “thumbnail” – See attached image..loop attribute with attachment

      Here’s how it looks in the database: loop-in-db

      When I “make revision”, I get the same set of values on my revised item. Are you not seeing a similar behavior? Let me know. If needed, send me a support message to run some analysis on your site directly.

  10. Hi Ravi, I found simple solution for this problem. I use cfs plugin API to copy/add custom field. Here is my code:

    add_action('owf_duplicate_post', array(__CLASS__, 'copy_cfs_values'), 10, 2);
                add_action('owf_duplicate_page', array(__CLASS__, 'copy_cfs_values'), 10, 2);
    public static function copy_cfs_values($new_id, $post)
        {
            global $cfs;
            //delete meta value copied by plugin
            $field_info = array_keys($cfs->get_field_info(false, $new_id));
            if (!empty($field_info)) {
                //delete meta data copied by plugin
                foreach ($field_info as $meta_key) {
                    delete_post_meta($new_id, $meta_key);
                }
            }
    
            $old_fields = $cfs->get(false, $post->ID);
            if (!empty($old_fields)) {
                //add new
                $cfs->save($old_fields, array('ID' => $new_id));
            }
        }
    

    It works fine for me, please check it,
    Thanks

Comments are closed.