Integrating the Comment Engine

From GeeklogWiki
Jump to: navigation, search

This section describes and documents how to enable your plugin to use the Geeklog comment engine. This is a key feature or plugin functionality for many developers and not very difficult to integrate into your project. The Geeklog developers have made this very straightforward and enabled the API calls into comment related core programs.

NOTE: You will need to use Geeklog version 1.3.7 or above. Otherwise you'd have to apply the new comment features yourself.


The functions

Displaying the commentbar within the plugin

The plugin simply needs to pass the right parameters to CMT_userComments. Until v1.3.0 it was called COM_userComments. For backward compatibility, COM_userComments still exists now as a redirect function. Nevertheless, CMT_userComments accepts one more parameter (comments allowed: yes/no/closed) than COM_userComments, so it's best to do:

    if (floatval (VERSION) < 1.4) {
        if ($this_plugin_accepts_comments) {
            if ($_PLG_MULTIFAQ['comments']) {
                $display .= COM_userComments(...);
            }
        }
    } else {
        require_once $_CONF['path_system'] . 'lib-comment.php';
        $display .= CMT_userComments(..., !$this_plugin_accepts_comments);
    }

V1.4.0-present

It is best to put the following code inside the already needed function plugin_displaycomment__<plugin name>, and just call that function from within the plugin - or better yet, function PLG_displayComment($plugin, ...) - whenever the following code is needed.


Saving/deleting/handling comments

V1.4.0-present

There are three (3) plugin functions that you need to have:

# Function Description of Function
1 function plugin_savecomment_<plugin name>($title, $comment, $id, $pid, $postmode) This function is called when Geeklog is asked to save a comment for this plugin.
2 function plugin_deletecomment_<plugin name>($cid, $id) This function is called when Geeklog is asked to delete a comment from this plugin.
3 function plugin_displaycomment__<plugin name>($id, $cid, $title, $order, $format, $page, $view) This function is called when Geeklog is asked to display a direct comment URL (when the user directly clicked a comment's link).

It can also be called upon by the plugin itself (see above) instead of having an additional internal function for Displaying the commentbar within the plugin.

Comment Submission Queue

As of Geeklog 1.6.0, comments may end up in the comment submission queue (if enabled) instead of being posted directly. In this case, plugins should display a message informing the user of this fact. Otherwise, users may wonder what happened to their comment and may try to post it again. Here's a code snippet demonstrating how to do that:

function plugin_savecomment_foo($title, $comment, $id, $pid, $postmode)
{
(...)
    $ret = CMT_saveComment($title, $comment, $id, $pid, 'foo', $postmode);
    if ($ret > 0) {
        // error handling goes here
        // On error we are returning to the comment page (this is needed if the Captcha plugin is used)
        if (!defined('COMMENT_ON_SAME_PAGE')) {
            $retval = COM_createHTMLDocument($retval, array('pagetitle' => $LANG03[1]));
        } else {
            if (!COMMENT_ON_SAME_PAGE) {
                $retval = COM_createHTMLDocument($retval, array('pagetitle' => $LANG03[1]));
            }
        }
    } else { // success
        $msg = '';
        if (isset($_CONF['commentsubmission']) &&
                ($_CONF['commentsubmission'] == 1) &&
                !SEC_hasRights('comment.submit')) {
            $msg = '&msg=15';
        }
        $retval = COM_refresh ($_CONF['site_url']
                               . "/foo/index.php?fooid=$id$msg");
    }

    return $retval;
}

This code assumes that there is a message text $PLG_foo_MESSAGE15 for your "foo" plugin that informs the user that their comment has been queued.

V1.3.7-1.3.X

There are three (3) plugin functions that you need to have plus one (1) optional function. The example functions that are used for explanation in this section and included in this kit are very complete. You should only need to edit them for your plugin name and table names. The following table summarizes the functions:

# Function Description of Function
1 plugin_commentsupport_<plugin name> This function does not take any parameters but simply returns true if this plugin supports comments. This call is made in Geeklog code (e.g. article.php) to determine if it should redirect execution to the plugin.
2 plugin_handlecomment_<plugin name> This function expects a parameter for the comment id and operation. The operation parameter is either 'save' or 'delete'. This function will update the plugin record with the total number of comments for this plugin item and then redirect the user back to the plugin instead of the main site page.
3 plugin_commentform_<plugin name> This function expects a number of parameters and is called from Geeklog article.php and comment.php. Parameters are: comment_id (primary key), comment_mode (nested, flat, threaded, none, order (Ascending or Descending) and reply (was the reply submit button used on the comment bar). Only comment_id is mandatory.
4 plugin_commentparent_<plugin name> Optional function which can be called from your plugin_commentform function to display the plugin parent record above the comments. This is how Geeklog articles are displayed with the story and then the comment bar and associated comments.


Note: this function is not called by the Geeklog core; use of it is solely within the plugin.

How to call the Comment Engine

After you implement the comment functions in your plugin, you will need to call the Geeklog comment engine or program to create the comment or view the comments. This can be done by adding a link or button which redirects the user to comment.php with the necessary parameters from your plugin.

The example below was used by the FileMgmt plugin, where there was a link under each file listed. The link to comment.php needs to be passed with two parameters to indicate the type and cid . The cid is a unique comment id. The following example is how to call the comment engine from your plugin. The variable $myretval is assigning the formatted link to a variable which will be displayed as a link in the plugin display.

$myretval = "<a href='" . $_CONF[site_url] . "/comment.php?type=filemgmt&id=" 
. $lid . "'>" . $LANG_FM01['ENTERCOMMENT'] . "</a>"

The variable type is assigned the plugin type and id is assigned a unique comment id which in this case is the plugin record id for this comment. In this example, the variable $lid is a unique record id in the filemgmt plugin for each file in the repository. You will want to use your plugin variable in place of $lid. We will actually be inserting the plugin comment ID into the SID field in the comment table. This is where you see the comment engine was initially designed around articles and stories; but no fear, the integration will be clean.  The ID that our plugin uses as a reference will be passed through comment.php to your plugin comment functions.

The following is a second example of enabling comment to the Journal Plugin. This was added to the display function for the journal entry where je_id is the primary key for the journal record.

$retval .= "</td></tr><tr><td><a 
href='" .$_CONF[site_url] ."/comment.php?type=journal&cid=" .$A['je_id']. "'>" . 
$LANG01[60] . "</a>"

The plugin API function PLG_callCommentForm is called in comment.php when the story-id sid is blank. This plugin API call in turns calls your plugin_commentform function if it exists. Additionally, the program article.php is called when the user presses reply on the comment bar or changes the comment view. In article.php PLG_callCommentForm is called with all the parameters such as mode, order and reply set. The sample completed plugin function in this kit shows how to pass these parameters on and in doing so your plugin will have full support for the comment bar.

Additional details on the comment table: The comment table has a unique primary key called cid that is an auto_increment date type. The field type will contain the name of our plugin. The field sid (story-id) is the identifier for the top level comment. We will update the sid field with the id that links to our plugin record for which we are adding this comment. The field pid is used to indicate the parent comment id and is 0 for the first comment or in the case of a threaded comment, it is set to the cid (the record id in the comment table) for the main comment that it is related to.

Plugin database changes

You will want to add a field in your plugin to keep track of the number of comments for this item. It is updated by the plugin_commentsave() and can be used to quickly check if there are any comments.

Function details and examples

This explanation of the plugin comment functions will use the FileMgmt plugin and step thru each function. The term comment bar will be used to describe the tool bar that appears above the comment thread and allows the user to change the comment view mode and order. There are four comment modes (Flat, Threaded, Nested and None) plus you can change the order comments are shown from Newest first to Oldest first. Using these plugin functions, you can easily support the comment bar and the various modes.

With Geeklog articles, you also will have seen how the article is shown above the comment bar and associated comments. You can optionally support this functionality as well by implementing the fourth function.

1) The commentsupport function is a basic function that returns a true or false to indicate to Geeklog if this plugin supports comments or not. This function is currently only called from article.php. When the comment bar is used, it will call article.php. At the beginning of article.php this Plugin API function is used to see if it is being called for a from a plugin related comment and if so, then redirect it to the plugin function to handle the comment.

function plugin_commentsupport_filemgmt()
{
    // Filemgmt Module will use comments
    return true;
}

2) The handlecomment function is called by comment.php to update your plugin record's field for total number of comments. You will need to add a field in your plugins record but this is useful to quickly determine if this record has any comments or not so it is advisable.

After the update, you want to redirect the program execution to a view of the single plugin record or another main page of your plugin.

The code to handle the save or delete may be the same but the API was designed to allow the developer to handle this differently if required.

function plugin_handlecomment_filemgmt($id, $operation)
{
    global $_CONF, $_FM_TABLES, $_TABLES;

    // Get the total number of comments now related to this comment id - which is also the plugin record id.
    $comments = DB_count($_TABLES['comments'], 'sid', $id);
    if ($operation == 'save') {
        // Update the the Filemgmt main record for this file with the number of related comments
        DB_change($_FM_TABLES['filemgmt_filedetail'], 'comments', $comments, lid', $id);
    } elseif ($operation == 'delete') {
        DB_change($_FM_TABLES['filemgmt_filedetail'], 'comments', $comments, 'lid', $id);
    } else {
        COM_errorLOG("Illegal Comment operation sent to FileMgmt Pugin:" . $operation);
    }
    // Now redirect the program flow to the view of the file and its comments
    echo COM_refresh($_CONF['site_url'] . "/filemgmt/singlefile.php?lid='$id'");
    }
}

3) The commentform function is the main function that is called to create the plugin comment. There are four (4) parameters of which only the comment id is mandatory. The other three parameters are passed automatically to set the comment view mode, display order and to indicate if the reply button was used on the comment bar.

The comment count for this plugin related record is retrieved to determine if this is the first comment for this plugin item.

  • If this is the first comment then redirect execution to comment.php and pass a valid sid set to the unique plugin item id, the plugin key for this comment and type set to the plugin name.
  • If this is not the first comment then you call COM_userComments. You can additionally call a function to display the plugin record above the comment bar and comments. In the example function, the return variable is being assigned the formatted HTML of the siteHeader, the plugin record and the results of the comments and finally the site footer. In the comment display, the user has access to the comment bar to start a new comment or use the reply links under any comment.
function plugin_commentform_filemgmt($id, $commentmode='', $order='', $reply='')
{
    global $_CONF, $_TABLES, $_FM_TABLES;

    $commentCount = DB_count($_TABLES['comments'],'sid',$id);
    $title = DB_getItem($_FM_TABLES['filemgmt_filedetail'], 'title', "lid='''$id'''");
    if ($commentmode == "") {
        $commentmode = $_CONF['comment_mode'];
    }
    if ($order == "") {
        $order="ASC";
    }
    $type="filemgmt";
    if ($commentCount == 0 || $reply != "") {
        $pid=0;
        $type="filemgmt"
        echo COM_refresh($_CONF['site_url'] . "/comment.php?sid='$id'&pid='$pid'&type='$type'");
    } else {
        $display = COM_siteHeader() . plugin_commentparent_filemgmt($id) . COM_userComments($id,$title,$type,$order,$commentmode);
        $display .= COM_siteFooter();
    }

    return $display;
}

4) The commentparent function is plugin specific and is really code that you likely already have to display a single record for your plugin. You may even call one of your existing plugin functions and not have to create it in the functions.inc file.

The following is a another example of the two main comment functions that were used for the Journal Plugin:

In this example, the commentparent function was not required as the existing Journal logic to display the Journal record was already written as a function - printjournalentry($id)

Ensure that you replace $type in the plugin_commentform() function with the plugin name.

function plugin_handlecomment_journal($id, $operation)
{
    global $_CONF, $_TABLES;

    // Get the total number of comments now related to this commment id - which is also the plugin record id.
    $comments = DB_count($_TABLES['comments'],'sid',$id);
    // Update the the Journal Entry record for this file with the number of related comments
    DB_change($_TABLES['journal_entry'],'je_comment', $comments, 'je_id',$id);
    // Now redirect the program flow to the view of the file and its comments
    echo COM_refresh($_CONF['site_url'] . "/journal/index.php?mode=read&type=entry&je_id=$id");
}

function plugin_commentform_journal($id,$commentmode='',$order='',$reply='')
{
    global $_CONF, $_TABLES;

    $commentCount = DB_count($_TABLES['comments'],'sid',$id);
    $title = DB_getItem($_TABLES['journal_entry'], 'je_summary', "je_id=$id");
    if ($commentmode == "") {
        $commentmode = $_CONF['comment_mode'];
    }
    if ($order == "") {
        $order="ASC";
    }
    $type="journal";
    if ($commentCount == 0 || $reply != "") {
        $pid=0;
        echo COM_refresh($_CONF['site_url'] . "/comment.php?sid=$id&amp;pid=$pid&amp;type=$type");
    } else {
        $display = COM_siteHeader() . printjournalentry($id) . COM_userComments($id,$title,$type,$order,$commentmode);
        $display .= COM_siteFooter();
    }

    return $display;
}

Outdated versions

In v1.3.7, Geeklog got the new API function PLG_callCommentForm in lib-plugins and had relevant changes in comment.php and article.php (all of which were dropped in v1.4.0 in favor of better API).

This section describes how to enable comment support manually if you want a plugin to have comments enabled in your Geeklog version that is below 1.3.7.

(anyone who reads this can feel free to add this part).