⬆️ ⬇️

Writing a rating module for Joomla, or AJAX in Russian

image When working on the site, I had a need for an article rating system, and it had to be easy and simple. It was decided to abandon the five-point one immediately, and the “Like / Dislike” system was chosen. Unfortunately, a quick search did not find anything like this, and therefore it was decided to write a module from scratch.



Where to begin?


The module begins with a Hello World! Find it is not difficult, download and unpack into a folder. Since the module will work with the database, and the standard rating table does not suit us, we will create our own.

image



So, we have dealt with the database, now let's proceed to the module itself. Pedpolozhayu that you already know what AJAX is , what it is for. Since Joomla does not provide for the possibility of using AJAX modules, we will use the features offered by Leonid Touches , namely, we will create a file through which all requests will go. As a result, we now have 2 files in the module folder: ajax.php and mod_likerating (aka Hello World!). Now we write an xml file installer for them and install it.



<?xml version="1.0" encoding="utf-8"?> <install type="module" version="1.5.0"> <name>JLikeRating</name> <author>StyleT</author> <version>1.0</version> <description>   Joomla    / </description> <files> <filename module="mod_likerating">mod_likerating.php</filename> <filename module="mod_likerating">ajax.php</filename> </files> <params> <param name="suffix" type="text" default="" label="  " description="    " /> </params> </install> 




Writing the module code


We check the output of the module and go on. Since the module will be displayed in the full version of the news, then we will display it must have with the plugin Modules Anywhere with the required parameters Enable parameter overriding , Ignore module state and Enable in components .

Unfortunately, the module does not know the id of the material currently open, so we will pass it as a parameter using the Parameters overriding function of the Modules Anywhere plugin:

{module 65|newsid=<?php echo $this->article->id; ?>}

65 is the id of our module obtained after installation.

In total, the module code here has become:

 <?php defined('_JEXEC') or die('Restricted access'); $db = JFactory::getDBO();//  $user = JFactory::getUser();//  $suffix = $params->get("suffix");//   $newsid = $params->get("newsid");// id  if (JRequest::getVar('voteresult')) { //  AJAX echo 'hello from AJAX\n'.JRequest::getVar('voteresult'); } else{ //   ?> <script type="text/javascript"> function myAJAXSendRequest(voteres) { new Request({ method: 'get', url: '/modules/mod_likerating/ajax.php', data: { 'voteresult' : voteres}, onSuccess: function(responseText) { alert(responseText);}, onFailure: function() { alert('failed');} }).send(); } window.addEvent('domready', function() {//    $('likerating-like').addEvent('click', function(e) {myAJAXSendRequest('like');}); $('likerating-dislike').addEvent('click', function(e) {myAJAXSendRequest('dislike');}); }); </script> <DIV class="likerating<?php echo $suffix; ?>"> <button class="like" type="button" id="likerating-like" > <span class="label"></span> </button><button class="dislike" type="button" id="likerating-dislike"> <span class="label"> </span> </button> </div> <?php } ?> 


Everything worked out? Works? Ok, now let's take this code in steps:

1. The Modules Anywhere plugin calls the module and sends it the news id.

2. The module connects classes and receives parameters.

3. The “if (JRequest :: getVar ('voteresult'))” code gives false because there was no ajax request.

4. Output module to the user.

5. User presses the Like button.

6. Parameters specified in the data of the class Request are transmitted to the specified url

7. Called ajax.php calls module

8. The code “if (JRequest :: getVar ('voteresult'))” and only part of the ajax processing is executed, the server responds

9. OnSuccess is called and the server response is processed.

10. All this without reloading the page.

')

It is important to note that now we are transmitting data in text format, whereas new Request.JSON is already working with the JSON format, which is preferable if we accept several variables.



We write the actual voting


So below I give the full code of the voting module for which everything was started.

 <?php defined('_JEXEC') or die('Restricted access'); $db = JFactory::getDBO();//  $user = JFactory::getUser();//  $suffix = $params->get("suffix");//   $newsid = $params->get("newsid");// id  if (JRequest::getVar('voteresult')) { // true   ajax $voteres= JRequest::getVar('voteresult');//   $voted= JRequest::getVar('voted');//   ,   ,   0- 1- 2-  $newsid= JRequest::getVar('newsid');// id     Modules Anywhere     $query="UPDATE `#__likerating_news` SET "; if($voteres=='like') { switch($voted) { case 1: $query.="`like`=(SELECT REPLACE(`like`,',".$user->id."','')), `rate`=`rate`-'1'"; $answer= 0; break; case 2: $query.="`like`=(SELECT CONCAT_WS(',', `like`, '".$user->id."')), `rate`=`rate`+'2', `dislike`=(SELECT REPLACE(`dislike`,',".$user->id."',''))"; $answer= 1; break; case 0: $query.="`like`=(SELECT CONCAT_WS(',', `like`, '".$user->id."')), `rate`=`rate`+'1'"; $answer= 1; break; } }else if($voteres=='dislike') { switch($voted) { case 1: $query.="`dislike`=(SELECT CONCAT_WS(',', `dislike`, '".$user->id."')), `rate`=`rate`-'2', `like`=(SELECT REPLACE(`like`,',".$user->id."',''))"; $answer= 2; break; case 2: $query.="`dislike`=(SELECT REPLACE(`dislike`,',".$user->id."','')), `rate`=`rate`+'1'"; $answer= 0; break; case 0: $query.="`dislike`=(SELECT CONCAT_WS(',', `dislike`, '".$user->id."')), `rate`=`rate`-'1'"; $answer= 2; break; } } $query.=" WHERE `nid`='".$newsid."'"; $db->setQuery($query); $result = $db->loadResult(); echo $answer; } else{// AJAX    //            $db->setQuery("INSERT INTO #__likerating_news (`nid`, `like`, `dislike`, `rate`) VALUES ('".$newsid."', '0', '0', '0')"); $result = $db->loadResult(); //   ?      $db->setQuery("SELECT `like`, `dislike` FROM `#__likerating_news` WHERE `nid`='".$newsid."'"); $result = $db->loadRow(); if(strpos("t".$result[0], $user->id)) $voted= '1'; else if(strpos("t".$result[1], $user->id)) $voted= '2'; else $voted= '0'; ?> <script type="text/javascript"> var voted= '<?php echo $voted; ?>';//      JS var newsid= '<?php echo $newsid; ?>';//    ajax.php       function myAJAXSendRequest(voteres) { new Request({ method: 'get', url: '/modules/mod_likerating/ajax.php', data: { 'voteresult' : voteres , 'voted' : voted, 'newsid' : newsid}, onSuccess: function(responseText) { voted= responseText; if(voted==0){//    $('likeratingimg-like').setStyle('background-position', '0px -38px'); $('likeratingimg-dislike').setStyle('background-position', '0px 0px'); }else if(voted==1){ $('likeratingimg-like').setStyle('background-position', '0px -58px'); $('likeratingimg-dislike').setStyle('background-position', '0px 0px'); }else{ $('likeratingimg-like').setStyle('background-position', '0px -38px'); $('likeratingimg-dislike').setStyle('background-position', '0px -19px'); } //alert(voted); }, onFailure: function() {//    alert('failed'); } }).send(); } window.addEvent('domready', function() {//    $('likerating-like').addEvent('click', function(e) {myAJAXSendRequest('like');}); $('likerating-dislike').addEvent('click', function(e) {myAJAXSendRequest('dislike');}); }); </script> <DIV class="likerating<?php echo $suffix; ?>"> <button class="like" type="button" id="likerating-like" > <img id="likeratingimg-like" class="hand-image" style="<?php if($voted== '1'){echo 'background-position: 0px -58px;';}?>" src="/modules/mod_likerating/images/pixel.gif"> <span class="label"></span> </button><button class="dislike" type="button" id="likerating-dislike"> <img id="likeratingimg-dislike" class="hand-image" style="<?php if($voted== '2'){echo 'background-position: 0px -19px;';}?>" src="/modules/mod_likerating/images/pixel.gif"> </button> </div> <?php } ?> 


It is assumed that the background image consists of a sprite that is specified in the CSS style, but to write the actual CSS will be your task.

It is also important that you don’t need to touch ajax.php at all, just put it in the module folder and throw ajax requests at it.

Everyone probably noticed that the cell of the database's database is filled and taken into account, but the value does not go out of it anywhere, yes, it is, but nobody prevents you from using it.



Result


image

That's what ultimately happened to me, the functionality is completely similar to similar buttons on YouTube, I confess, the temporary design is also from there. If someone needs it, I can send an archive with files, now there is little time, to knock on Skype



Nothing works for me, what should I do?


The following is a list of useful links on this topic:

Temporarily. NO

Class: Request

My SQL String Functions

Basic AJAX Requests Using MooTools 1.2



From the author


This is my first topic on Habré, and I hope not the last. Perhaps everything is very detailed here, but there are few detailed descriptions and difficulties that I encountered in my time, and I think this article will help the newcomer save a couple of hours of life.

Source: https://habr.com/ru/post/113392/



All Articles