Tuesday, October 11, 2011

Remove Duplicate Nodes based on title


Based on code from Robert Douglass.
I have added few lines to make it copy-paste-able to a module.
Simply copy this to dedupe.module, and create module named "dedupe". More info about creating modules can be found here.

<?php/**
* @file
* Remove Duplicate Nodes.
*/

/**
* Implementation of hook_menu().
*/
function dedupe_menu() {
   
$items['admin/content/dedupe'] = array(
       
'title' => 'Dedupe',
       
'description' => 'Delete Duplicate Nodes',
       
'page callback' => 'drupal_get_form',
       
'page arguments' => array('dedupe_content_command'),
       
'access arguments' => array('administer site configuration'),
       
'type' => MENU_NORMAL_ITEM,
    );
    return
$items;
}
/**
* Build Form
*/
function dedupe_content_command() {
   
$options = node_get_types('names');
   
$form['dedupe_node_types'] = array(
       
'#type' => 'select',
       
'#title' => t('You can select content type from which duplicates are removed.'),
       
'#options' => $options,
       
'#default_value' => variable_get('dedupe_node_types', array('page')),
       
'#description' => t('Duplicate content from the selected content types will be deleted.'),
    );
   
$form['submit'] = array(
       
'#type' => 'submit',
       
'#value' => t('Dedupe'),
    );
    return
$form;
}
/**
* Call delete function and set message.
*/
function dedupe_content_command_submit($form, $form_state) {
   
$type= $form_state['values']['dedupe_node_types'];
   
$dedupe_m = 'Duplicates deleted from content type '. $type;
   
dedupe_delete($type);
   
drupal_set_message(check_plain(t($dedupe_m)));
}
/**
* Delete duplicates from selected content type, based on title. By Robert Douglass.
* @see <a href="http://robshouse.net/blog-post/remove-duplicate-nodes-dedupe-based-title
" title="http://robshouse.net/blog-post/remove-duplicate-nodes-dedupe-based-title
" rel="nofollow">http://robshouse.net/blog-post/remove-duplicate-nodes-dedupe-based-title
</a> */
function dedupe_delete($type) {
   
$previous = array();
   
$result = db_query("SELECT nid, title FROM {node}
    WHERE title IN
      (SELECT title FROM {node}
        WHERE type = '%s'
        GROUP BY title HAVING count(*) > 1)
    ORDER BY title, created DESC"
, $type);
    while (
$row = db_fetch_array($result)) {
        if (
$row['title'] == $previous['title']) {
           
node_delete($previous['nid']);
        }
       
$previous = $row;
    }
}
?>

No comments:

Post a Comment