To write plugin for Mighty Analytics is very simple. Reporter handle everything. You only need to create 4 events, onDrawChart, onChartData, onDrawTable, onGetTotals. I'll explain them one by one. But let me start with few points on installation XML file.
Powered by amCharts
The charts in this component use amCharts library. So to get documentation on how to create setting files and how to create data in XML format use their website. It is well documented. You do not need to use their files, everything needed already included in to Mighty Analytics component except Stock Type Charts as it is 1.0.0.0 Beta on the moment this component created. But this will be included in future versions or on first request from 3DP developer.
Installation XML
<?xml version="1.0" encoding="utf-8"?> <install version="1.5" type="plugin" group="analytics" method="upgrade"> <name>Plugin name</name> <author>MightyExtensions</author> <creationDate>May 2008</creationDate> <copyright>Copyright (C) 2005 - 2009 MightyExtensions. All rights reserved. </copyright> <license>Commercial</license> <authorEmail>support@mightyextensions.com</authorEmail> <authorUrl>www.mightyextensions.com</authorUrl> <version>1.0</version> <description>Your plugin description </description> <files> <filename plugin="plugin_name"> plugin_name.php</filename> <filename> plugin_name_settings1.xml</filename> </files> <params> <param name="height" type="text" label="Chart height (px)" default="400" size="5"/> <param name="date_range" type="hidden" default="1"/> <param name="groupby" type="hidden" default="0"/> Here you can add parameters you need to set up a report </params> <params group="Advanced params"> Here you can add parameters that will be available in front end to users <param name="limit" type="list" label="Rows on page" default="5" description=""> <option value="5">5</option> <option value="10">10</option> <option value="15">15</option> <option value="20">20</option> <option value="25">25</option> <option value="30">30</option> <option value="50">50</option> <option value="100">100</option> </param> </params> </install>
Installation file is usual as for any other plugins but you should note these points.
- Install to group analytics. Plugin will not work in any other groups.
- Line 14 - remember plugin name you set for plugin="" attribute. Later this name will be passed to every event to skip implementation if other plugin is called.
- Line 15 - you can place as many charts to report as you want as you will learn below, but every chart should have setting file. The setting file name constructed like [plugin-name]_settings[chart-key]
- <params> showld contain these parameters as default:
- Chart height (as text field)
- Date range (as hidden field with values 1/0)
- Group by (as hidden field with values 1/0)
- < params group="Advanced params"> - Advanced parameters are shown in the front-end to users and allow them to select parameters they need.
Plugin Construction
class plgAnalyticsPLUGIN_NAME extends JPlugin { function plgAnalyticsPLUGIN_NAME ( &amp;$subject, $params ) { parent::__construct( $subject, $params ); } }
Class name and construct function have usual structure plg[group name][plugin name]
onDrawChart
function onDrawChart(&amp;$data, $name, &amp;$params) { if($name != 'plugin_name') return; global $mainframe; // checking if the needed component is installed if(!JFolder::exists(JPATH_ADMINISTRATOR.DS.'components'.DS.'com_users')) { JError::raiseWarning(403, 'User Component Not Exists'); $mainframe->redirect('index.php?option=com_analytics'); } $mparams = clone($mainframe->getParams('com_analytics')); $chart = 1; $data[$chart]['width'] = $mparams->get('width', 600); $data[$chart]['height'] = $params->get('width', 400); $data[$chart]['bg'] = '#ffffff'; $data[$chart]['preloader_color'] = '#999999'; $data[$chart]['type'] = 'amcolumn'; // amline|ampie|amxy|amcolumn }
This event define how many charts are in report and what is their type and size. You can see chart definition lines 16 - 21. You can increase $chart++ and define another unlimited chart number. But I would suggest you to include only one chart per report unless it is very important to see few charts on one page to make some analysis.
$chart variable become the $key of the chart that is passed to every other event.
Line 3 - if($name != 'plugin_name') return; is the required line for every event.
Also if you create chart not for core Joomla component it is good to check if this component is installed like in line 7 - 11.
onChartData
This event create XML output for chart.
function onChartData(&amp;$data, $key, $name, $params) { if($name != 'plugin_name') return; $db = JFactory::getDBO(); $data = "<chart><series><value xid='1'>0</value></series><graphs></graphs></chart>"; $from = $params->get( 'start', strftime( '%Y-%m-%d 00:00:00', mktime( 0, 0, 0, date( 'm' ) - 1, date( 'd' ), date( 'Y' ) ) ) ); $to = $params->get( 'finish', strftime( '%Y-%m-%d 00:00:00', mktime( 23, 59, 59, date( 'm' ), date( 'd' ), date( 'Y' ) ) ) ); $from = strftime( '%Y-%m-%d 00:00:00', strtotime( $from ) ); $to = strftime( '%Y-%m-%d 00:00:00', strtotime( $to ) ); $user = JFactory::getUser(); $user_id = 0; if($params->get('user_stick')) { $user_id = $user->id; } $user_id = JRequest::getInt('user_id', $user_id); $sql = “SELECT * FROM table_name”; if(($params->get('user_stick') && $user_id) || ($user->gid == 25 && $user_id)) $sql .= " AND table.user_id = '$user_id'"; $db->setQuery($sql); $result = $db->loadObjectList(); foreach ( $result AS $key => $row ) { $res[$row->index_date] = $row->total; } if( !$result && !$bresult) return; if( !$bresult ) return; $date = $from; $key = 0; while( strtotime( $date ) <= strtotime( $to ) ) { $key ++; $index_date = strftime( $format_indexes, strtotime( $date ) ); $serie = strftime( $format_series, strtotime( $date ) ); $description = strftime( $format_description, strtotime( $date ) ); if( isset( $res[$index_date] ) ) { $value = $res[$index_date]; } else { $value = 0; } if( isset( $bres[$index_date] ) ) { $bvalue = $bres[$index_date]; } else { $bvalue = 0; } $series[] = "<value xid='{$key}'>".$serie."</value>"; $graph1[] = "<value xid='{$key}' description='{$description}'>{$value}</value>"; $graph2[] = "<value xid='{$key}' description='{$description}'>{$bvalue}</value>"; $date = $this->incrementDate( $date, $groupby ); } $out = "<chart><series>"; $out .= implode("", $series); $out .= "</series>"; $out .= "<graphs><graph gid='1' title='YOUR title'>"; $out .= implode("", $graph1).'</graph>'; $out .= "</graphs></chart>"; $data = $out; }
This event receive 4 arguments.
- $data = this is parameter you should set final XML to. You do not need to return anything.
- $key = Key of the chart defined by $chart in onDrawChart event.
- $name = name of the plugin
- $params = plugin parameters. Parameters contain all indexes you created in installation XML <prams> section and core parameters like start - date from, finish - date to, table - show table, xls - generate xls file.
In this function you do SQL query and build XML acording to amCharts format. I'll not exmplain it here. You can see example at the end of this article where I post all plugin source.
onDrawTable
function onDrawTable(&amp;$table, $key, $name, $params) { if($name != 'plugin_name') return; $db = JFactory::getDBO(); $user = JFactory::getUser(); $user_id = 0; if($params->get('user_stick')) { $user_id = $user->id; } $user_id = JRequest::getInt('user_id', $user_id); $limit = $params->get('limit', 0); $sort_by = $params->get('sort_by'); $groupby = $params->get('groupby', 'sday'); $sql = “SELECT * FROM table_name”; if(($params->get('user_stick') && $user_id) || ($user->gid == 25 && $user_id)) $sql .= " AND table.user_id = '$user_id'"; $sql .= "GROUP BY b.id, `{$groupby}` ORDER BY ".($sort_by ? $sort_by : 'table.ctime'); if($limit) $sql .= " LIMIT 0, $limit"; $table = ‘’; // you assign query result to $table variable // and at the end of this function you need to write this code if($params->get('rep_xls')) { $file = JPATH_ROOT.DS.'cache'.DS.$user->id.DS.$name.'_'.$key.'.xls'; JFile::write($file, $table); } }
This event is completely the same as previous instead of the first parameter. You also need to run SQL query here and build HTML table and set it to $table variable. You do not need to return anything. In this function there is a code that creates an XLS file that could be imported.
onGetTotals
function onGetTotals($key, $name, $params) { if($name != 'plugin_name') return; $db = JFactory::getDBO(); $user = JFactory::getUser(); $user_id = 0; if($params->get('user_stick')) { $user_id = $user->id; } $user_id = JRequest::getInt('user_id', $user_id); $limit = $params->get('limit', 0); $sort_by = $params->get('sort_by'); $groupby = $params->get('groupby', 'sday'); $sql = “SELECT COUNT(*) FROM table_name”; if(($params->get('user_stick') && $user_id) || ($user->gid == 25 && $user_id)) $sql .= " AND table.user_id = '$user_id'"; $db->setQuery($sql); if($res = $db->loadResult()) { $totals[0]['value'] = $res; $totals[0]['text'] = JText::_('Total amount'); } return $totals; }
This function receives 3 parameters. Here you run SQL query to get totals values (as many as you need) and set them into $totals variable. This event returns $totals array which includes value and text.
Whole plugin example
<?php defined( '_JEXEC' ) or die( 'Restricted access' ); jimport( 'joomla.plugin.plugin' ); class plgAnalyticsUser1 extends JPlugin { function plgAnalyticsUser1( &$subject, $params ) { parent::__construct( $subject, $params ); } function onDrawChart(&$data, $name, &$params) { if($name != 'user1') return; global $mainframe; if(!JFolder::exists(JPATH_ADMINISTRATOR.DS.'components'.DS.'com_users')) { JError::raiseWarning(403, 'User Component Not Exists'); $mainframe->redirect('index.php?option=com_analytics'); } $mparams = clone($mainframe->getParams('com_analytics')); $chart = 1; $data[$chart]['width'] = $mparams->get('width', 770); $data[$chart]['height'] = $params->get('height', 400); $data[$chart]['bg'] = '#ffffff'; $data[$chart]['preloader_color'] = '#999999'; $data[$chart]['type'] = 'amcolumn'; // amline|ampie|amxy|amcolumn } function onChartData(&$data, $key, $name, $params) { if( $name != 'user1' ) return; $data = "<chart><series><value xid='1'>0</value></series><graphs></graphs></chart>"; $db = JFactory::getDBO(); $from = $params->get( 'start', strftime( '%Y-%m-%d 00:00:00', mktime( 0, 0, 0, date( 'm' ) - 1, date( 'd' ), date( 'Y' ) ) ) ); $to = $params->get( 'finish', strftime( '%Y-%m-%d 00:00:00', mktime( 23, 59, 59, date( 'm' ), date( 'd' ), date( 'Y' ) ) ) ); $from = strftime( '%Y-%m-%d 00:00:00', strtotime( $from ) ); $to = strftime( '%Y-%m-%d 00:00:00', strtotime( $to ) ); $user = JFactory::getUser(); $user_id = 0; if($params->get('user_stick')) { $user_id = $user->id; } $user_id = JRequest::getInt('user_id', $user_id); $groupby = $params->get( 'groupby', 'sday' ); switch ( $groupby ) { case "sday": $format_description = '%Y %d %b'; $format_series = '%Yn%dn%b'; $format_indexes = '%Y %d %b'; break; case "sweek": $format_description = '%Y %U Week'; $format_series = '%Yn%UW'; $format_indexes = '%Y %U'; break; case "smonth": $format_description = '%Y %b'; $format_series = '%Yn%b'; $format_indexes = '%Y %b'; break; } $sql = " SELECT COUNT( u.id ) AS total, DATE_FORMAT( u.registerDate, '%Y, %m, %d' ) AS sday, DATE_FORMAT( u.registerDate, '%Y, %U' ) AS sweek, DATE_FORMAT( u.registerDate, '%Y, %m' ) AS smonth, DATE_FORMAT( u.registerDate, '$format_indexes' ) AS index_date FROM #__users AS u WHERE u.registerDate > '$from' AND u.registerDate < '$to' AND u.block = 1 "; if(($params->get('user_stick') && $user_id) || ($user->gid == 25 && $user_id)) $sql .= " AND u.id = '$user_id'"; $sql .= " GROUP BY `{$groupby}` ORDER BY u.registerDate ASC "; $db->setQuery($sql); $bresult = $db->loadObjectList(); foreach ( $bresult AS $key => $row ) { $bres[$row->index_date] = $row->total; } $sql = " SELECT COUNT( u.id ) AS total, DATE_FORMAT( u.registerDate, '%Y, %m, %d' ) AS sday, DATE_FORMAT( u.registerDate, '%Y, %U' ) AS sweek, DATE_FORMAT( u.registerDate, '%Y, %m' ) AS smonth, DATE_FORMAT( u.registerDate, '$format_indexes' ) AS index_date FROM #__users AS u WHERE u.registerDate > '$from' AND u.registerDate < '$to' AND u.block <> 1 GROUP BY `{$groupby}` ORDER BY u.registerDate ASC "; $db->setQuery($sql); $result = $db->loadObjectList(); foreach ( $result AS $key => $row ) { $res[$row->index_date] = $row->total; } if( !$result && !$bresult) return; if( !$bresult ) return; $date = $from; $key = 0; while( strtotime( $date ) <= strtotime( $to ) ) { $key ++; $index_date = strftime( $format_indexes, strtotime( $date ) ); $serie = strftime( $format_series, strtotime( $date ) ); $description = strftime( $format_description, strtotime( $date ) ); if( isset( $res[$index_date] ) ) { $value = $res[$index_date]; } else { $value = 0; } if( isset( $bres[$index_date] ) ) { $bvalue = $bres[$index_date]; } else { $bvalue = 0; } $series[] = "<value xid='{$key}'>".$serie."</value>"; $graph1[] = "<value xid='{$key}' description='{$description}'>{$value}</value>"; $graph2[] = "<value xid='{$key}' description='{$description}'>{$bvalue}</value>"; $date = $this->incrementDate( $date, $groupby ); } $out = "<chart><series>"; $out .= implode("", $series); $out .= "</series>"; $out .= "<graphs><graph gid='1' title='".JText::_( "Registered Users" )."'>"; $out .= implode("", $graph1).'</graph>'; if($params->get('block') == 0) { $out .= "<graph gid='2' title='".JText::_( "Registered Not Active Users" )."'>"; $out .= implode("", $graph2).'</graph>'; } $out .= "</graphs></chart>"; $data = $out; } function onDrawTable(&$table, $key, $name, $params) { if($name != 'user1') return; $db = JFactory::getDBO(); $user = JFactory::getUser(); $user_id = 0; if($params->get('user_stick')) { $user_id = $user->id; } $user_id = JRequest::getInt('user_id', $user_id); $from = $params->get( 'start', strftime( '%Y-%m-%d 00:00:00', mktime( 0, 0, 0, date( 'm' ) - 1, date( 'd' ), date( 'Y' ) ) ) ); $to = $params->get( 'finish', strftime( '%Y-%m-%d 00:00:00', mktime( 23, 59, 59, date( 'm' ), date( 'd' ), date( 'Y' ) ) ) ); $from = strftime( '%Y-%m-%d 00:00:00', strtotime( $from ) ); $to = strftime( '%Y-%m-%d 00:00:00', strtotime( $to ) ); $groupby = $params->get( 'groupby', 'sday' ); $sort_by = $params->get('sort_by'); $limit = $params->get('limit', 0); switch ( $groupby ) { case "sday": $format_indexes = '%Y %d %b'; break; case "sweek": $format_indexes = '%Y %U Week'; break; case "smonth": $format_indexes = '%Y %b'; break; } $sql = " SELECT COUNT( u.id ) AS total, DATE_FORMAT( u.registerDate, '%Y, %m, %d' ) AS sday, DATE_FORMAT( u.registerDate, '%Y, %U' ) AS sweek, DATE_FORMAT( u.registerDate, '%Y, %m' ) AS smonth, DATE_FORMAT( u.registerDate, '$format_indexes' ) AS index_date FROM #__users AS u WHERE u.registerDate > '$from' AND u.registerDate < '$to'". ( $params->get( 'block', 0 ) == 0 ? "" : "u.block = 0 " ); if(($params->get('user_stick') && $user_id) || ($user->gid == 25 && $user_id)) $sql .= " AND u.id = '$user_id'"; $sql .= " GROUP BY `$groupby` ORDER BY ".($sort_by ? $sort_by : 'u.registerDate ASC'); if($limit) $sql .= " LIMIT 0, $limit"; $db->setQuery($sql); $result = $db->loadObjectList(); if(!$result) return; $k = 0; $total = 0; $out[] = '<table class="adminlist">'; $out[] = '<thead>'; $out[] = '<tr>'; $out[] = '<th width="1%">#</th>'; $out[] = '<th class="title">'.JText::_('Date').'</th>'; $out[] = '<th width="1%">'.JText::_('Total').'</th>'; $out[] = '</tr>'; $out[] = '</thead>'; $out[] = '<tbody>'; foreach ( $result AS $var => $row ) { $k = 1 - $k; $out[] = "<tr class='row".$k."'><td>".( $var + 1 )."</td><td nowrap>". $row->index_date."</td><td>".$row->total."</td></tr>"; $total += $row->total; } $out[] = '<tr><td colspan="2" align="right"><b>'.JText::_('Total').'</b></td><td><b><big>'. $total.'</big></b></td></tr></tbody></table>'; $table = implode( "", $out ); if( $params->get( 'rep_xls' ) ) { jimport('joomla.filesystem.file'); $file = JPATH_ROOT.DS.'cache'.DS.$user->id.DS.$name.'_'.$key.'.xls'; JFile::write($file, $table); } } function onGetTotals($key, $name, $params) { if($name != 'user1') return; $db = JFactory::getDBO(); $user = JFactory::getUser(); $user_id = 0; if($params->get('user_stick')) { $user_id = $user->id; } if($user->gid == 25) $user_id = JRequest::getInt('user_id', $user_id); $db = JFactory::getDBO(); $from = $params->get('start', date('Y-m-d H:s:i', mktime(0,0,0, date('m')-1, date('d'), date('Y')))); $to = $params->get('finish', date('Y-m-d H:s:i', mktime(23,59,59, date('m'), date('d'), date('Y')))); $groupby = $params->get('groupby', 'sday'); $totals = array(); $sql = " SELECT COUNT( u.id ) AS total, block FROM #__users AS u WHERE u.registerDate > '$from' AND u.registerDate < '$to'". ( $params->get( 'block', 0 ) == 0 ? "" : "u.block = 0 " ); if(($params->get('user_stick') && $user_id) || ($user->gid == 25 && $user_id)) $sql .= " AND u.id = '$user_id'"; $sql .= " GROUP BY u.block ORDER by u.block"; $db->setQuery( $sql ); if($res = $db->loadObjectList()) { $all = 0; foreach($res as $i => $val) { $totals[$i]['value'] = $val->total; $totals[$i]['text'] = ($val->block == 1 ? JText::_( 'Total not active users registered') : JText::_( 'Total active users registered')) ; $all += $val->total; } $totals[$i + 1]['value'] = $all; $totals[$i + 1]['text'] = JText::_( 'Total users registered'); } return $totals; } function incrementDate( $date, $unit ) { $eDate = getDate( strtotime( $date ) ); switch ( $unit ) { case "sday": $eDate["mday"] ++; break; case "sweek": $eDate["mday"] += 7; break; case "smonth": $eDate["mon"] ++; break; } return date( 'Y-m-d H:s:i', mktime( $eDate["hours"], $eDate["minutes"], $eDate["seconds"], $eDate["mon"], $eDate["mday"], $eDate["year"] ) ); } } ?>


+1 (424) 201 06 56,