How to add image comments in eZcommunity 2.2.x


» Top level » Networking and web applications


This article outlines the easy method that a developer can extend eZcommunity (formerly eZpublish 2.2) forums to allow comments for different types of content.

A commenting capability is one of my favorite ways to add a simple collaborative capability to any site. Comments are powerful because they enable anyone to add an alternative perspective to the content published by the site owner. Philip Greenspun writes convincingly of the importance of a comment feature in chapter 6 (see the Comments on Articles section) of his online textbook "Software Engineering for Internet Applications".

One of the biggest advantages of developing with the eZcommunity toolkit is the consistent and structured framework that it offers through the use of object-oriented PHP code. For example, it is relatively easy to add comments to any type of content (images, products, surveys, and the like). These comments are simply an extension of the existing eZForum module, so that any comment is essentially a forum post, and stored in the same database table as any other forum message.

To begin with, anyone interested in learning more about using and developing the eZcommunity community toolkit should read Harry Fuecks' most excellent Sitepoint article, eZ publish: PHP's Killer App - Parts 1-3. This article is the best online source for basic installation and structural explanations of eZpublish 2.2, the framework upon which we built eZcommunity. For the purposes of this tutorial, pay particular attention to Harry's explanation of the eZpublish directory structure.

OK, assuming you are now familiar with the eZcommunity file structure, let's get started. The process of adding comments to images is relatively straightforward. We will need to take the following steps:
  • Create a new database table to store the new relationships
  • Add a new variable definition in the configuration file (site.ini)
  • Add two new methods to the eZImage class
  • Modify the eZImageCatalogue datasupplier.php (the module's "traffic cop", so to speak) file to display the comments for each image
First, we want to build a database table that will provide relationships between a given image and the forum we will create for each image. This forum be unique for each image, and will contain all the threaded comments for the image. Because eZForum already provides all of the mechanics for storing and displaying messages, all we have to do is build the linkage between the image and the forum. In MySQL, we can create the table like this:
CREATE TABLE 'eZImageCatalogue_ImageForumLink' (
  'ID' int(11) NOT NULL default '0',
  'ImageID' int(11) NOT NULL default '0',
  'ForumID' int(11) NOT NULL default '0',
  PRIMARY KEY  ('ID')
) TYPE=MyISAM;

Next, we will need to create a new forum category through the ezImageCatalogue admin interface that will contain all of our image comments. Record this category ID number. Edit your site.ini configuration file under the [eZImageCatalogueMain] heading. We need to set this category ID within the configuration file so that it is dynamic. Add this setting under [eZImageCatalogueMain] in site.ini as shown below (replace the number '6' with the category number you just created):
# Forum category used for image comments
# Leave blank to disable comments
ImageComments=6

Now we will need to add two methods to the eZImage class file. These methods will return or create a forum associated with the image object, and perform the reverse (return the image associated with a given forum). Add these two functions to the /ezimagecatalogue/classes/ezimage.php file somewhere at the bottom -- around line 1272 or so. Note that you can require user login to comment, or make the comments moderated if you would like (see comments in the code):
/*!
      Returns the comments for the image.
    */
    function forum( $as_object = true )
    {
        $db =& eZDB::globalDatabase();
        $db->array_query( $res, "SELECT ForumID FROM
                                            eZImageCatalogue_ImageForumLink
                                            WHERE ImageID='$this->ID'" );
        $forum = false;
        if ( count( $res ) == 1 )
        {
            if ( $as_object )
                $forum = new eZForum( $res[0][$db->fieldName( "ForumID" )] );
            else
                $forum = $res[0][$db->fieldName( "ForumID" )];
        }
        else
        {
	$forum = new eZForum();
	$forum->setName( $db->escapeString( $this->Name ) );

// NOTE:  Comment out the below line if you want to disable anonymous (not logged in) comments!!!
	$forum->setIsAnonymous(true);

// NOTE:  Comment out the below line if you want moderated comments!!!
	$forum->setIsModerated(false);

// NOTE:  Uncomment the below lines if you want moderated comments!!!
//		$forum->setIsModerated(true);
//	      $moderatorgroup = new eZUserGroup( 1 ); //should be a site.ini variable
//            $forum->setModerator( $moderatorgroup );

	$forum->store();
	$ini =& INIFile::globalINI();
				
	$category = new eZForumCategory( $ini->read_var( "eZForumMain", "ImageComments" ) );  
	$category->addForum( $forum );
	$forumID = $forum->id();
	$db->begin( );
	$db->lock( "eZImageCatalogue_ImageForumLink" );
	$nextID = $db->nextID( "eZImageCatalogue_ImageForumLink", "ID" );
	$res = $db->query( "INSERT INTO eZImageCatalogue_ImageForumLink
                                ( ID, ImageID, ForumID )
                                VALUES
                                ( '$nextID', '$this->ID', '$forumID' )" );
	$db->unlock();
	if ( $res == false )
		$db->rollback( );
	else
		$db->commit();
	if ( $as_object )
		$forum = new eZForum( $forumID );
	else
		$forum = $forumID;
        }
        return $forum;
    }

/*!
      Returns the image which a review is connected to.
     */
    function imageIDFromForum( $ForumID )
    {
        $db =& eZDB::globalDatabase();
        $ImageID = 0;
        $db->array_query( $result, "SELECT ImageID FROM
                                    eZImageCatalogue_ImageForumLink
                                    WHERE ForumID='$ForumID' GROUP BY ImageID" );
        if( count( $result ) > 0 )
        {
            $ImageID = $result[0][$db->fieldName("ImageID")];
        }
        return $ImageID;
    }


Finally, we will need to tell the presentation layer to display the comments list attached to each image. Again, eZForum already has this functionality built-in. We just need to modify /ezimagecatalogue/user/datasupplier.php so that it knows to display the comments. Find this code (around line 63):
case "imageview" :
	{
        $ImageID = $url_array[3];
        $VariationID = $url_array[4];
        include( "ezimagecatalogue/user/imageview.php" );
	}
break;

Modify the code to look like this:
case "imageview" :
	{
        $ImageID = $url_array[3];
        $VariationID = $url_array[4];
	$ImageComments = $ini->read_var( "eZForumMain", "ImageComments" );
        include( "ezimagecatalogue/user/imageview.php" );
	 if  (  ( $PrintableVersion != "enabled" ) &&  ( is_numeric($ImageComments) )
            {
		$RedirectURL = "/imagecatalogue/imageview/$ImageID/";
                $image = new eZImage ( $ImageID );
                if ( ( $image->id() >= 1 ) )
                {
                    for ( $i = 0; $i < count( $url_array ); $i++ )
                    {
                        if ( ( $url_array[$i] ) == "parent" )
                        {
                            $next = $i + 1;
                            $Offset = $url_array[$next];
                        }
                    }
                    $forum = $image->forum();
                    $ForumID = $forum->id();
                    include( "ezforum/user/messagesimplelist.php" );
                }
            }
	}
	break;

That's it! Notice how all we really had to do was establish the logic to build the relationship between an image and an associated category of forums. This modularity is what I really like about eZcommunity -- the ability to extend the functionality of one module to support another. The image gallery and forum modules already existed. We just had to link the two. You could conceivably add commenting to just about any content object by using almost identical code. For example, I changed this code around a little to add comments to eZTrade products as product reviews for another project.

Hope you find this modification useful. Please let me know how you implement it on your own site -- I am most interested in seeing your eZCommunity project or solution. Thanks to James Ward for inspiring this with his article (since unpublished) on adding comments to eZPoll surveys.




| Printer-friendly page | Send this article to a friend |

Comment List


Topic: Author:
Time:
Thanks for keeping up the fight ...
graham brookins 11.07.2005 15:18
Bob,

Subject says it all. I dropped a link (today) to this article in the eZ community, forums :: http://ezcommunity.net/

//graham
happy hacking,
leaving my shadow behind like yesterday

Non-Prophets - Fresh