Rainforest

Sankuru

Implementeren, customiseren, uitbreiden, en troubleshooten van Joomla/Virtuemart

Views: 2822

Wij helpen met ...

Virtuemart
Joomfish
Andere extensies
SocialTwist Tell-a-Friend

Automatische vertaling

English Arabic Chinese (Simplified) German Japanese Russian Spanish



Hergebruik open source

Datgene wat U nodig hebt, bestaat vaak al, en dekt 80% van Uw behoeften. Wij zorgen voor de ontbrekende 20%.

Gratis offerte

Vraag vandaag nog gratis een offerte aan.

Excluding categories of content articles from the DISQUS commenting system PDF Afdrukken E-mail
Waardering: / 2
SlechtZeer goed 
Geschreven door erik   
zaterdag 04 april 2009 04:50
There are no translations available.

In my previous blog post on modifying the DISQUS commenting plugin for Joomla, I explained how to apply a rapid modification to the plugin's source in order to exclude particular content articles. One of the comments to my post, raised the question of how to modify the plugin's source in order to exclude categories.

To tell you the truth, when I start modifying source code, I usually do not know from the start, how it actually works. In fact, there is too much source code around for anybody to know all of it from the top of his hat.The secret for acquiring the ability to modify any source code, consists in using methods of discoverability.

First, we start by adopting reasonable assumptions.

As I mentioned in my previous post, two of the events for which a plugin can register functions to trigger, are the onBeforeDisplayContent and onAfterDisplayContent events.  If you look carefully at what signature these functions should have, you can see that the Joomla plugin system will call them with the function parameters $article, $params, and $limitstart:

function onBeforeDisplayContent( &$article, &$params, $limitstart )  { /* ... */ }

function onAfterDisplayContent( &$article, &$params, $limitstart ) { /* ... */  }

Even though I do not really trust source code comments that much, they may push discovery efforts in the right direction (as they may not ...). The comments say the following about the function parameters:

@param     object        The article object.  Note $article->text is also available
@param     object        The article params
@param     int            The 'page' number

The $article object is most likely just a memory copy of the article record in the database. From experience I know that Joomla heavily -- if not almost exclusively -- uses its O/R (Object/Relational) mapping system to drag database records in and out of memory.

Articles are stored in the jos_content table. The $article object can therefore be expected to be an instance of a subclass of JTable, representing a jos_content record.

Let us first have a look at the fields in the jos_content table:

SHOW FULL COLUMNS FROM jos_content

id, title, alias, title_alias, introtext, fulltext, state, sectionid, mask, catid, created, created_by, created_by_alias, modified, modified_by, checked_out, checked_out_time, publish_up, publish_down, images, urls, attribs, version, parentid, ordering, metakey, metadesc, access, hits, metadata       

The standard design guideline says that the first column in a Joomla table must be its primary key, called id, which must be an integer. Content articles -- as any other records in Joomla -- are therefore fully identified by their id.

According to the Joomla database design, a content article can belong to one category only. Of course, in accordance with the design guidelines, a Joomla category must also be identified by its id field.

Therefore, standard relational database design guidelines (Codd) insist that the joomla content article record contain a field ("foreign key" principle) with the category id to which the content article belongs. Consequently, the presence of the field catid in the jos_content record is completely in accordance with our expectations. We knew the catid field had to be there, and the SHOW COLUMNS query simply confirms our intuition.

Content articles belong to one category, and categories belong to one section. Therefore, we can reasonably expect the presence of a section id in the category record. Articles only indirectly belong to a section, that is, through their category. Therefore, we do not expect a section id in the article record. As you can see from the query results above, the article record does unexpectedly and redundantly contain the section id for the section to which the article belongs.

Note: I tend to flag such redundant section id field in the article record as suspicious. In every piece of source code where articles are being created, the author of the source code must remember not to forget to fill out that redundant section id.  This is obviously a potential source of bugs. I suspect the Joomla core database designers added the section id to the article record, because of performance considerations -- which are probably somehow valid, as this practice may indeed speed up queries -- but in my opinion, application correctness must take precedence on performance considerations.

Now, let us verify our assumptions and ascertain that the variable $article is indeed the O/R memory representation of an article record. We can use the source for any published (active) content plugin to validate our assumption. We can use, for example, the pagenavigation.php plugin, which is activated by default in Joomla. As you can see in the source code, the plugin registers the plgContentNavigation() function onBeforeDisplayContent:

$mainframe->registerEvent( 'onBeforeDisplayContent', 'plgContentNavigation' );

Every time an article is about to be displayed, Joomla will therefore trigger the plgContentNavigation() function. The variable $row (aka $article) will according to our assumptions contain an O/R copy of the article record in the jos_content table.

Let's investigate the variable $row, by dumping its content and then die(), that is, stop the execution of the script:

function plgContentNavigation( &$row, &$params, $page=0 )
{
print_r($row);
die("stop here");
...

}

Any attempt to display an article in the front end should now crash just after dumping the article record:

stdClass Object ( [id] => 25 [title] => <...> [title_alias] => [introtext] => <...>[fulltext] => [state] => 1 [sectionid] => 3 [mask] => 0 [catid] => 31 [created] => 2008-08-11 00:42:31 [created_by] => 62 [created_by_alias] => [modified] => 2008-08-11 00:42:31 [modified_by] => 62 [checked_out] => 0 [checked_out_time] => 0000-00-00 00:00:00 [publish_up] => 2006-10-10 06:00:00 [publish_down] => Never [images] => [urls] => [attribs] => <...> [version] => 6 [parentid] => 0 [ordering] => 5 [metakey] => [metadesc] => [access] => 0 [hits] => 28 [metadata] => robots= author= [author] => Administrator [usertype] => Super Administrator [category] => General [section] => FAQs [slug] <...> [catslug] => 31:general [groups] => Public [sec_pub] => 1 [cat_pub] => 1 [sec_access] => 0 [cat_access] => 0 [rating_count] => 0 [rating] => 0 [text] => <...> [parameters] => JParameter Object (<...>) stop here

Note: You'd probably better take out this debug code after inspecting the dump, because the front end will otherwise keep crashing every time it tries to display an article.

As we can see, the $row variable is indeed mostly an O/R memory copy of the corresponding jos_content record in the database. However, it apparently also embeds a JParameter object. Therefore, something in the framework will first enrich the O/R copy of the record, before sending it on to the plugin's function.

Note: If you want to know what part exactly of the source code does this, you should have a look at the JPlugin class and other upstream source code, and figure out where exactly it is being done. (That will of course not tell you why exactly it is being done ...)

So, now we can confirm that $row->catid will indeed contain the category id for the article. All our reasonable assumptions mostly hold true.

Therefore, this investigation gives us enough information to improve the source code modification in my previous blog post, and allow us to exclude particular categories from the DISQUS Commenting System, in addition to excluding particular articles:

function noCommentsForThisCategory($id)
{
$disabled=array(1,3,9);
if(in_array($id,$disabled)) return true;
else return false;
}

We must make sure that the functions registered for the events, call this function first, in addition to the function preventing comments to particular articles, prior to entering the actual code:

function plgJWDisqus_onBeforeDisplayContent( &$row, &$params, $limitstart ){
if (noCommentsForThisArticle($row->id)) return;
if (noCommentsForThisCategory($row->catid)) return;
global $mainframe; 

...}

function plgJWDisqus_onAfterDisplayContent( &$row, &$params, $limitstart ){
if (noCommentsForThisArticle($row->id)) return;
if (noCommentsForThisCategory($row->catid)) return;
global $mainframe;

...}

Of course, this is again a hack. Categories excluded from the DISQUS Commenting System would have their ids hardcoded in the plugin's source. That is obviously not a very gracious nor a very elegant solution; but it would work.

I guess a truly user-friendly solution would consist in slightly modifying the Category Manager source code in the Joomla backend, by adding a tickbox to the Edit Category form: Exclude from DISQUS Comments (Y/N).

So, in conclusion, do you need to be familiar, know, or have prior understanding of the source code, in order to modify it? No. Not at all. You just need to have a firm grip on the principles of discoverability and reasonable assumptions.


blog comments powered by Disqus
 
 
Joomla 1.5 Templates by Joomlashack