I'm working on a custom module to help out the moderators on my website by adding additional functionality, and one of these is simply adding a "Check IP" column with the comment's hostname on each field on the Comment Approval page. In addition, I will also be needing a way to alter the query to join the Comments table with my module's table later on, but that's not the concern for now.

Anyway, I can accomplish all of the above by making the following alterations to these two functions in the comment.admin.inc file in the core's Comment module...


function comment_admin_overview($type = 'new', $arg) {
  // build an 'Update options' form
  $form['options'] = array(
    '#type' => 'fieldset', '#title' => t('Update options'),
    '#prefix' => '<div class="container-inline">', '#suffix' => '</div>'
  );
  $options = array();
  foreach (comment_operations($arg == 'approval' ? 'publish' : 'unpublish') as $key => $value) {
    $options[$key] = $value[0];
  }
  $form['options']['operation'] = array('#type' => 'select', '#options' => $options, '#default_value' => 'publish');
  $form['options']['submit'] = array('#type' => 'submit', '#value' => t('Update'));

  // load the comments that we want to display
  $status = ($arg == 'approval') ? COMMENT_NOT_PUBLISHED : COMMENT_PUBLISHED;
  $form['header'] = array('#type' => 'value', '#value' => array(
    theme('table_select_header_cell'),
    array('data' => t('Subject'), 'field' => 'subject'),
    array('data' => t('Author'), 'field' => 'name'),
    array('data' => t('Hostname'), 'field' => 'hostname'),
    array('data' => t('Posted in'), 'field' => 'node_title'),
    array('data' => t('Time'), 'field' => 'timestamp', 'sort' => 'desc'),
    array('data' => t('Operations'))
  ));
  $result = pager_query('SELECT c.subject, c.nid, c.cid, c.comment, c.hostname, c.timestamp, c.status, c.name, c.homepage, u.name AS registered_name, u.uid, n.title as node_title FROM {comments} c INNER JOIN {users} u ON u.uid = c.uid INNER JOIN {node} n ON n.nid = c.nid WHERE c.status = %d'. tablesort_sql($form['header']['#value']), 50, 0, NULL, $status);

  // build a table listing the appropriate comments
  $destination = drupal_get_destination();
  while ($comment = db_fetch_object($result)) {
    $comments[$comment->cid] = '';
    $comment->name = $comment->uid ? $comment->registered_name : $comment->name;
    $form['subject'][$comment->cid] = array('#value' => l($comment->subject, 'node/'. $comment->nid, array('attributes' => array('title' => truncate_utf8($comment->comment, 128)), 'fragment' => 'comment-'. $comment->cid)));
    $form['username'][$comment->cid] = array('#value' => theme('username', $comment));
    $form['hostname'][$comment->cid] = array('#value' => l($comment->hostname, 'http://whatismyipaddress.com/ip/'. $comment->hostname));
    $form['node_title'][$comment->cid] = array('#value' => l($comment->node_title, 'node/'. $comment->nid));
    $form['timestamp'][$comment->cid] = array('#value' => format_date($comment->timestamp, 'small'));
    $form['operations'][$comment->cid] = array('#value' => l(t('edit'), 'comment/edit/'. $comment->cid, array('query' => $destination)));
  }
  $form['comments'] = array('#type' => 'checkboxes', '#options' => isset($comments) ? $comments: array());
  $form['pager'] = array('#value' => theme('pager', NULL, 50, 0));
  return $form;
}

function theme_comment_admin_overview($form) {
  $output = drupal_render($form['options']);
  if (isset($form['subject']) && is_array($form['subject'])) {
    foreach (element_children($form['subject']) as $key) {
      $row = array();
      $row[] = drupal_render($form['comments'][$key]);
      $row[] = drupal_render($form['subject'][$key]);
      $row[] = drupal_render($form['username'][$key]);
      $row[] = drupal_render($form['hostname'][$key]);
      $row[] = drupal_render($form['node_title'][$key]);
      $row[] = drupal_render($form['timestamp'][$key]);
      $row[] = drupal_render($form['operations'][$key]);
      $rows[] = $row;
    }
  }
  else {
    $rows[] = array(array('data' => t('No comments available.'), 'colspan' => '6'));
  }

  $output .= theme('table', $form['header']['#value'], $rows);
  if ($form['pager']['#value']) {
    $output .= drupal_render($form['pager']);
  }

  $output .= drupal_render($form);

  return $output;
}

Works perfectly, and I can even alter the sql query for the results and join my custom module's database with the comments later on. One flaw in this as any Drupal developer will immediately point out: "Hacking core is bad, mmmkay." So I copied the above code out of the core module and into my custom module, figuring I could override these two core functions with a "hook."

However, it is not working. Tried "mymodule_comment_admin_overview," "mymodule_preprocess_comment_admin_overview," and other combinations along with clearing the cache each time, but my custom module will not override core's output. Haven't tried it in the theme's template.php file, but I would really rather keep this in a custom module and out of the theme (easily reusable on other sites). What am I doing wrong?

Comments

Ashford’s picture

I am not a developer or a coder. I do not have a solution, but I can share some ideas with you.

http://simplersolutions.biz/content/overriding-module-functionality-drupal
You might find useful information in this web site article. One of the common mistakes they mention is when you have copied the function you need to your custom module, but there are other functions called by that function that you did not copy into your custom module. I'm not experienced enough to know if that is your problem, but it is a possibility.

I have also seen where the my-custom-module.info file has a line to list module dependencies. I would guess that allows you to use the functions from other modules.

I hope someone smarter than I am replies soon and gives you a direct answer to your question.

WebMaster’s picture

That article "may" have helped, thanks. When I slapped in some additional code (added a "$form = array(); inside my custom function), it completely disregarded the comment.module output and returned nothing at all. Which means perhaps I can get it to use my code instead with a little more work. Too inconclusive at this time, but will stay at it.

graysadler’s picture

WebMaster’s picture

Thanks for that, I'm now hooked into the function. I'm getting a little bit closer, but not quite yet. Here is the new code...

function mymodule_form_comment_admin_overview_alter(&$form, $form_state) {
   if ($form['#parameters'][2] == "approval") {

        // build an 'Update options' form
        $form['options'] = array(
            '#type' => 'fieldset', '#title' => t('Update options'),
            '#prefix' => '<div class="container-inline">', '#suffix' => '</div>'
        );
        $options = array();
        foreach (comment_operations($arg == 'approval' ? 'publish' : 'unpublish') as $key => $value) {
            $options[$key] = $value[0];
        }
        $form['options']['operation'] = array('#type' => 'select', '#options' => $options, '#default_value' => 'publish');
        $form['options']['submit'] = array('#type' => 'submit', '#value' => t('Update'));

        // load the comments that we want to display
        $status = ($arg == 'approval') ? COMMENT_NOT_PUBLISHED : COMMENT_PUBLISHED;
        $form['header'] = array('#type' => 'value', '#value' => array(
        theme('table_select_header_cell'),
            array('data' => t('Subject'), 'field' => 'subject'),
            array('data' => t('Author'), 'field' => 'name'),
            array('data' => t('Hostname'), 'field' => 'hostname'),
            array('data' => t('Posted in'), 'field' => 'node_title'),
            array('data' => t('Time'), 'field' => 'timestamp', 'sort' => 'desc'),
            array('data' => t('Operations'))
        ));

        $result = pager_query('SELECT c.subject, c.nid, c.cid, c.comment, c.hostname, c.timestamp, c.status, c.name, c.homepage, u.name AS registered_name, u.uid, n.title as node_title FROM {comments} c INNER JOIN {users} u ON u.uid = c.uid INNER JOIN {node} n ON n.nid = c.nid WHERE c.status = %d'. tablesort_sql($form['header']['#value']), 50, 0, NULL, $status);

        // build a table listing the appropriate comments
        $destination = drupal_get_destination();
        while ($comment = db_fetch_object($result)) {
            print_r($comments[$comement->cid]);
            $comments[$comment->cid] = '';
            $comment->name = $comment->uid ? $comment->registered_name : $comment->name;
            $form['subject'][$comment->cid] = array('#value' => l($comment->subject, 'node/'. $comment->nid, array('attributes' => array('title' => truncate_utf8($comment->comment, 128)), 'fragment' => 'comment-'. $comment->cid)));
            $form['username'][$comment->cid] = array('#value' => theme('username', $comment));
            $form['hostname'][$comment->cid] = array('#value' => l($comment->hostname, 'http://whatismyipaddress.com/ip/'. $comment->hostname));
            $form['node_title'][$comment->cid] = array('#value' => l($comment->node_title, 'node/'. $comment->nid));
            $form['timestamp'][$comment->cid] = array('#value' => format_date($comment->timestamp, 'small'));
            $form['operations'][$comment->cid] = array('#value' => l(t('edit'), 'comment/edit/'. $comment->cid, array('query' => $destination)));
        }
        $form['comments'] = array('#type' => 'checkboxes', '#options' => isset($comments) ? $comments: array());
        $form['pager'] = array('#value' => theme('pager', NULL, 50, 0));
        return $form;
    }
}

As I said, I'm hooked in; unfortunately the above function only seems to be paying attention to the theme('table_select_header_cell') reference. It adds the "Hostname" header just fine. But the rest of the code with the modified SQL query and the while output loop is completely ignored, so it doesn't grab the 'hostname' field and output the results.

I went into the "while" loop and tried to output / print_r the query results (to see if it's actually returning anything), but nada. Scratching my head on that one.

WebMaster’s picture

I hit this completely by accident. Apparently the $arg variable was being lost somewhere, so redefining that made the query in my module work.

function mymodule_form_comment_admin_overview_alter(&$form, $form_state) {
       if ($form['#parameters'][2] == "approval") {

        $arg = $form['#parameters'][2];
        $status = ($arg == 'approval') ? COMMENT_NOT_PUBLISHED : COMMENT_PUBLISHED;
        $form['header'] = array('#type' => 'value', '#value' => array(
        theme('table_select_header_cell'),
            array('data' => t('Subject'), 'field' => 'subject'),
            array('data' => t('Author'), 'field' => 'name'),
            array('data' => t('Hostname'), 'field' => 'hostname'),
            array('data' => t('Posted in'), 'field' => 'node_title'),
            array('data' => t('Time'), 'field' => 'timestamp', 'sort' => 'desc'),
            array('data' => t('Operations'))
        ));

        $result = pager_query('SELECT c.subject, c.nid, c.cid, c.comment, c.hostname, c.timestamp, c.status, c.name, c.homepage, u.name AS registered_name, u.uid, n.title as node_title FROM {comments} c INNER JOIN {users} u ON u.uid = c.uid INNER JOIN {node} n ON n.nid = c.nid WHERE c.status = %d'. tablesort_sql($form['header']['#value']), 50, 0, NULL, $status);

        // build a table listing the appropriate comments
        //$destination = drupal_get_destination();
        while ($comment = db_fetch_object($result)) {
            $comments[$comment->cid] = '';
            $comment->name = $comment->uid ? $comment->registered_name : $comment->name;
            $form['subject'][$comment->cid] = array('#value' => l($comment->subject, 'node/'. $comment->nid, array('attributes' => array('title' => truncate_utf8($comment->comment, 128)), 'fragment' => 'comment-'. $comment->cid)));
            $form['username'][$comment->cid] = array('#value' => theme('username', $comment));
            $form['hostname'][$comment->cid] = array('#value' => l($comment->hostname, 'http://whatismyipaddress.com/ip/'. $comment->hostname));
            $form['node_title'][$comment->cid] = array('#value' => l($comment->node_title, 'node/'. $comment->nid));
            $form['timestamp'][$comment->cid] = array('#value' => format_date($comment->timestamp, 'small'));
            $form['operations'][$comment->cid] = array('#value' => l(t('edit'), 'comment/edit/'. $comment->cid, array('query' => $destination)));
        }
        $form['comments'] = array('#type' => 'checkboxes', '#options' => isset($comments) ? $comments: array());
        $form['pager'] = array('#value' => theme('pager', NULL, 50, 0));
        return $form;
    }
}

It is now returning the hostname field, but not appearing in the table. That's because that part is defined in the second function from my original post, theme_comment_admin_overview. I thought for sure that 'mymodule_comment_admin_overview' would hook that one, but apparently it doesn't. Will try to see if the form_alter hook might work on that...

WebMaster’s picture

Here is what I needed to use in my module for the theme_comment_admin_overview override...

function phptemplate_comment_admin_overview($form) {
     [...]
}

For some reason, I thought phptemplate could only be used in the template.php file, but I was wrong. Now I should be able to bring this module to a completion.