Ajax and the Joomla Framework

242 views
Skip to first unread message

RonaldJ

unread,
Apr 13, 2012, 8:51:19 PM4/13/12
to Joomla! CMS Development
Hello all,

I have made a plus / minus counter for Kunena per post. This is a Ajax
script that plus by 1 the counter or minus 1. This is saved in the
database. Now I would like to use the Joomla Framework to connect to
the database and update the table. But since it is a Ajax script that
calls the php script I am out of the Framework.
Are there ways of doing this?

Thanks for any reply!

Ronald

Rouven Weßling

unread,
Apr 14, 2012, 10:00:30 AM4/14/12
to joomla-...@googlegroups.com
I don't completely understand your question. Why are you out of the framework? You can very easily write a JSON controller that you use with your JavaScript.

Rouven

> --
> You received this message because you are subscribed to the Google Groups "Joomla! CMS Development" group.
> To post to this group, send an email to joomla-...@googlegroups.com.
> To unsubscribe from this group, send email to joomla-dev-cm...@googlegroups.com.
> For more options, visit this group at http://groups.google.com/group/joomla-dev-cms?hl=en-GB.
>

Nils Rückmann

unread,
Apr 14, 2012, 12:33:11 PM4/14/12
to joomla-...@googlegroups.com

I have made a plus / minus counter for Kunena per post

How did you do that ? A plugin ? A Template override ? For questions like that a little bit of code would be very helpfull.
And like Rouven said: The prefered way should be a controller.

RonaldJ

unread,
Apr 15, 2012, 2:04:39 PM4/15/12
to Joomla! CMS Development
I made a template override where I include rating.php and I call
rating::showItem with the params in every post.
When you give a plus or a minus Ajax calls the rating.php again with
the _GET params.
That ( rating::update($rid,$uid,$cr,$uv); ) will call the update
function that updates the database and counter in the post.
That is basically all it does. Problem is that the database update is
called outside Joomla.

Here is the code:

"""
<?php

/*
* cr = current rate
* uv = update value
*/

include('database.php');

class rating
{
public function showItem($path,$rid,$uid)
{
$result = mysql_query("SELECT rating FROM rating WHERE rid = ".
$rid."");
$row = mysql_fetch_row($result);
$cr = $row[0];

// if no rating then add the new item
if (!is_numeric($cr)) {
mysql_query("INSERT INTO rating VALUES (".$rid.", 0)");
mysql_query("INSERT INTO rating_check VALUES (".$rid.",".
$uid.")");
$cr = 0;
}

$html = '
<script type="text/javascript">
function showUser(rid,uid,cr,uv)
{
if (cr==="")
{
document.getElementById("txtHint"+rid).innerHTML="";
return;
}
if (window.XMLHttpRequest)
{// code for IE7+, Firefox, Chrome, Opera, Safari
xmlhttp=new XMLHttpRequest();
}
else
{// code for IE6, IE5
xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
}
xmlhttp.onreadystatechange=function()
{
if (xmlhttp.readyState==4 && xmlhttp.status==200)
{

document.getElementById("txtHint"+rid).innerHTML=xmlhttp.responseText;
}
}
xmlhttp.open("GET","'.$path.'/rating/rating.php?rid="+rid
+"&uid="+uid+"&cr="+cr+"&uv="+uv,true);
xmlhttp.send();
}
</script>
<form>
<a style="float:left; padding:5px 3px 0 0;" name=""
onclick="showUser('.$rid.','.$uid.','.$cr.',1)"><img src="'.$path.'/
rating/images/plus.png" /></a>
<div style="float:left; color:#ffffff;" id="txtHint'.$rid.'"><b>'.
$cr.'</b></div>
<a style="float:right; padding:5px 0 0 3px;" name=""
onclick="showUser('.$rid.','.$uid.','.$cr.',-1)"><img src="'.$path.'/
rating/images/minus.png" /></a>
</form>
';
echo $html;
}


public function update($rid,$uid,$cr,$uv)
{
// Check if not allready rated
$result = mysql_query("SELECT uid FROM rating_check WHERE rid = '".
$rid."'");
$row = mysql_fetch_row($result);
//if(!empty($row))
//{
// print_r($row);
//}

$nr = $cr+$uv;
$sql="Update rating set rating = '".$nr."' WHERE rid = '".$rid."'";
$query = mysql_query($sql);
echo mysql_error();
return $nr;
}

}

// Ajax call
if(isset($_GET["rid"]))
{
// Set variables
$rid=$_GET["rid"];
$uid=$_GET["uid"];
$cr=$_GET["cr"];
$uv=$_GET["uv"];

$result = rating::update($rid,$uid,$cr,$uv);
echo $result;
}

?>

Nils Rückmann

unread,
Apr 15, 2012, 3:34:36 PM4/15/12
to joomla-...@googlegroups.com
You should really think about security issues .. http://docs.joomla.org/Secure_coding_guidelines


Lobos

unread,
Apr 15, 2012, 7:19:32 PM4/15/12
to Joomla! CMS Development
I think it would be best to do everything with the Joomla Framework.
Kuena supports plugin events - http://docs.kunena.org/index.php/Kunena_2.0_plugins_events
and it might be that you could use onKunenaContentPrepare to tie in
your code, or not. I think your best bet is to ask Kuena support about
this. It also looks like you might want to learn the basics of Joomla
Development as well, if you do everything within the framework and use
the correct api methods you won't need to worry so much about
security. search things like this:

Joomla Input Sanitization using JRequst
Joomla accessing the database
Joomla creating a plugin

Lobos

unread,
Apr 15, 2012, 7:26:38 PM4/15/12
to Joomla! CMS Development
Oh and if you want quick and dirty, you can also use a System Plugin
with the onAfterInitialise - you can put a condition in there say

if( !JRequest::getVar( 'save_counter' ) ) return; //if save_counter is
not present in the querystring do nothing else

//we know save_counter is present in the querystring - ie index.php?
save_counter=1&blah=blah, etc
//now save it

database stuff here to save

//now we exit out
exit();

The above is very quick and dirty and lazy way to do it and it is
better to use the correct even it Kuena offers it... it also depends
on you learning a bit about joomla first.

Happy coding :)

RonaldJ

unread,
Apr 16, 2012, 2:25:20 AM4/16/12
to Joomla! CMS Development
Thanks Lobos for your reply.

Kunena 2 is not there yet so I can not use that.
And as far as I know is it not possible to call functions inside a
plugin or such from ajax.
And it is not possible to update data on a page without reloading it
(ajax) from the framework.
Hopefully I'm very wrong here, but I don't see how your'e answer would
do that.

Greetings, RonaldJ

Cyber Pasta

unread,
Apr 16, 2012, 2:38:07 AM4/16/12
to joomla-...@googlegroups.com
Why not initialize joomla framework?:

define( 'DS', DIRECTORY_SEPARATOR );
require_once ( JOOMLA_BASE_PATH .DS.'includes'.DS.'framework.php' );
$mainframe = JFactory::getApplication('site');
$mainframe->initialise();

As I know, the only way to use ajax directly in joomla is through components. Ajax in modules or plugins needs to initialize the framework.
After you have initialized the framework you can access joomla API and user session data. As Nils said before, "You should really think about security issues .. http://docs.joomla.org/Secure_coding_guidelines".

Gary Mort

unread,
Apr 16, 2012, 8:50:13 AM4/16/12
to joomla-...@googlegroups.com
On 4/16/2012 2:25 AM, RonaldJ wrote:
> Thanks Lobos for your reply.
>
> Kunena 2 is not there yet so I can not use that.
> And as far as I know is it not possible to call functions inside a
> plugin or such from ajax.

Well, you can, but it's ugly. You can make a system plugin that checks
for your specific url, does something, spits out the json, and dies.

However, it's much CLEANER to do this via a component.
The summary:
Add &format=json&tmpl=raw in your query string
create the files view.json.php and default_json.php to do your special
processing
Everything works. Grab a beer.

-----
The long winded, ask me the time and I tell you how to build a clock,
commentary:

I assume you already now how to make a component which returns html. Ie
using the files
componentname/viewname/view.html.php
componentname/viewname/tmpl/default.tpl

Now the view.html.php is actually determined depending on what format
the browser says it wants the data in. If you add &format=ejs then the
file used would be view.ejs.php, if you add &format=json then the file
used is view.json.php. One exception, if you add &format=html5 because
you want a specific cool html5 format and to allow for fallback to
view.html.php for older browsers - your out of luck. If the first 4
charectors of the viewname are html, view.html.php is always used. So
you would have to use &format=5html to do it.

So now you have a view that can respond to ajax requests and will return
json data. But what about the template? No problem, format is used
there as well.
default.php
default_html.php
default_json.php

If default_html.php exists, it is used instead of default.php. Same
deal with default_json.php

So far so good. So now can create a component which returns json data.
But your still stuck with all the other modules and stuff. So how do
you get past that?
2 ways: add either tmpl=component or tmpl=raw to your query string.
tmpl=raw is safest.
tmpl=raw means no template will be loaded. Just the results of the
component plus any plugins which are called will be sent back, in
whatever way they are formatted.

tmpl=component instead will use the component.php file[if one exists] in
the template directory instead of the index.php file. Since most
templates do NOT have a component.php file the effect would be the
same...but if yours does...

Lobos

unread,
Apr 16, 2012, 12:38:52 PM4/16/12
to Joomla! CMS Development
Yeah I mentioned in my post, the system plugin would be a quick and
dirty way to do it. What Gary mentioned is the cleanest way to go
about it, but the thing is that if you update the Kunena component you
will lose your changes because you are effectively hacking it. With a
plugin you will not lose your changes when you need to update the
component (or have to reintegrate them).

I have always felt there is a need to be able to extend component
views and such in a non hack type of way, say like a plugin group that
can add new views without needing to hack the "core" of the component.
Just my two cents...

Chad Windnagle

unread,
Apr 16, 2012, 12:54:04 PM4/16/12
to joomla-...@googlegroups.com
Gary just want to thank you for your explanation on using the different view file types with the URL parameters. That is very useful information! It would be really cool if that were in the documentation somewhere. 

-Chad

Regards,
Chad Windnagle
Fight SOPA


Gary Mort

unread,
Apr 16, 2012, 1:00:08 PM4/16/12
to joomla-...@googlegroups.com
On 4/16/2012 12:38 PM, Lobos wrote:
> Yeah I mentioned in my post, the system plugin would be a quick and
> dirty way to do it. What Gary mentioned is the cleanest way to go
> about it, but the thing is that if you update the Kunena component you
> will lose your changes because you are effectively hacking it. With a
> plugin you will not lose your changes when you need to update the
> component (or have to reintegrate them).
>
> I have always felt there is a need to be able to extend component
> views and such in a non hack type of way, say like a plugin group that
> can add new views without needing to hack the "core" of the component.
> Just my two cents...
>

If the component is cleanly laid out and all the display is done in the
template file[default.tpl] then you can add an override to your
template. IE
templatename/html/com_kuenena/<viewfolder>/default.json.tpl

As long as it is using the native API's and not hardcoding the html
layout parameter, Joomla! should automatically use the override.

You can also create your own component:
components/com_kajax

And use a plugin to 'hijack' any requests for the kunena component which
have are ajax requests[aka set the format=json parameter].

Lastly, provided that the COMPONENT utilizes the Plugin system, if there
is a suitable view event you can call
$view->addTemplatePath(JPATH_BASE.'/libraries/mydisplayhacks/com_kunena/')
or some such variation and you can place your template overrides at the
head of the list. I think for the content component onContentPrepare
would be the appropriate one?

There probably are a couple more entry points into adding templates to
the view's Template Path depending on where it gets that array from[the
document?]

The more I dig, the more I find a lot of my "I wish Joomla! had a way"
wishes are in there already. It just takes digging through the code
line by line.

Gary Mort

unread,
Apr 16, 2012, 6:01:42 PM4/16/12
to joomla-...@googlegroups.com
On 4/16/2012 12:54 PM, Chad Windnagle wrote:
> Gary just want to thank you for your explanation on using the
> different view file types with the URL parameters. That is very useful
> information! It would be really cool if that were in the documentation
> somewhere.

I made a slight mistake, if you use $format=json as your keyword, you
should not have to specify &tmpl=...

In libraries/joomla/document there are SEVEN formats already defined for
you.
error, feed, html, json, opensearch, raw, and xml

If you use the json format, Joomla should use the JDocumentJSON class
instead of JDocumentHTML - and JDocumentJSON completely bypasses the
template and just returns the results from the component.

As for documented somewhere, feel free to take what I've written and
post it to Joomla!'s wiki a bit more coherently.... I'm switching
mental gears for the day.

Adam Stephen Docherty

unread,
Apr 17, 2012, 2:24:17 AM4/17/12
to Joomla! CMS Development
Each to there own, but with the template override you are still
"hacking" something.

> You can also create your own component:
> components/com_kajax
>
> And use a plugin to 'hijack' any requests for the kunena component which
> have are ajax requests[aka set the format=json parameter].

And this just seems wrong, I don't understand how you are going to
override Kunena's output my creating another component and plugin.

For something this simple I would use a system plugin with two
observers,

onAfterRender to manipulate the output and inject the html /js from
rating::showItem()

onAfterInitialise for rating::update()

Once you have done that the modification is completely standalone and
portable, so if you want to add it to another installation of Kuena it
is just a matter of installing the plugin and that is it, no need to
hack any files or muck around uploading assets, etc. You can even put
up on the J! extensions site to share with other users.

Anyways there are always many ways to skin a cat, and you will learn
more following Gary's instructions.

Adam Stephen Docherty

unread,
Apr 17, 2012, 2:27:54 AM4/17/12
to Joomla! CMS Development
> You can also create your own component:
> components/com_kajax

> And use a plugin to 'hijack' any requests for the kunena component which
> have are ajax requests[aka set the format=json parameter].

Sorry, this would indeed work, but again it is overkill to add such
simple functionality when you can do it with a system plugin and two
methods.

On Apr 17, 3:24 am, Adam Stephen Docherty <adam.doche...@gmail.com>
wrote:

RonaldJ

unread,
Apr 17, 2012, 4:13:32 AM4/17/12
to Joomla! CMS Development
Wow thanks for the great information!!! Thanks I will try it soon and
reply.
I guess I will have a hard time with this so give me some time :)

Thanks again!

On 17 apr, 07:27, Adam Stephen Docherty <adam.doche...@gmail.com>

garyamort

unread,
Apr 17, 2012, 12:12:02 PM4/17/12
to joomla-...@googlegroups.com


On Tuesday, April 17, 2012 2:27:54 AM UTC-4, Adam Stephen Docherty wrote:
> You can also create your own component:
> components/com_kajax

> And use a plugin to 'hijack' any requests for the kunena component which
> have are ajax requests[aka set the format=json parameter].

Sorry, this would indeed work, but again it is overkill to add such
simple functionality when you can do it with a system plugin and two
methods.


Oh certainly, I was just going through the various methods one can use.

For ONE mod, a system plugin is quick and clean.  If one becomes two, then three, then four it starts looking handier to have a component where you can enable and disable special functionality as needed.

The primary point is that "Joomla! allows for that".... which way someone wants to do it is up to them. 

Adam Stephen Docherty

unread,
Apr 17, 2012, 5:53:05 PM4/17/12
to Joomla! CMS Development
Oh yes you are completely right, anything even looking to be
moderately complex should be done in the correct MVC position. But
more to the point component devs should concentrate on making the
system observable so that it can be more easily extendible AND
documenting it - nothing worse than trolling thru reams of code
looking for access points lol!

Adam Stephen Docherty

unread,
Apr 17, 2012, 5:55:26 PM4/17/12
to Joomla! CMS Development
You just keep at it buddy, the best way to learn is via application.
This is a great way to start, ie integrating some small modifications
to existing systems. Have fun :)
Reply all
Reply to author
Forward
0 new messages