diff --git a/tjreports/administrator/access.xml b/tjreports/administrator/access.xml
index 2e45095..85ca516 100755
--- a/tjreports/administrator/access.xml
+++ b/tjreports/administrator/access.xml
@@ -13,6 +13,7 @@
+
diff --git a/tjreports/administrator/models/tjreport.php b/tjreports/administrator/models/tjreport.php
index ece6446..5ed7eeb 100644
--- a/tjreports/administrator/models/tjreport.php
+++ b/tjreports/administrator/models/tjreport.php
@@ -173,6 +173,8 @@ public function getReportPluginData($pluginId, $pluginName = null)
JModelLegacy::addIncludePath(JPATH_SITE . '/plugins/tjreports/' . $pluginName);
$plgModel = JModelLegacy::getInstance($pluginName, 'TjreportsModel');
+ $defaultColToHide = $plgModel->getState('defaultColToHide');
+
$params = array();
$params['filter_order'] = $plgModel->getState('list.ordering');
$params['filter_order_Dir'] = $plgModel->getState('list.direction');
@@ -180,7 +182,16 @@ public function getReportPluginData($pluginId, $pluginName = null)
$params['emailColumn'] = $plgModel->getState('emailColumn');
$params['colToshow'] = $plgModel->getState('colToshow');
$params['colToshow'] = array_combine($params['colToshow'], array_fill(0, count($params['colToshow']), true));
+
+ /* Here merge colToshow (array value is true) with defaultColToHide (array value is false) column -
+ * so false value column not display on report by default.*/
+ if (!empty($defaultColToHide))
+ {
+ $params['colToshow'] = array_merge($params['colToshow'], $defaultColToHide);
+ }
+
$params['showHideColumns'] = $plgModel->showhideCols;
+ $params['piiColumns'] = $plgModel->getState('piiColumns');
$report->param = json_encode($params);
}
diff --git a/tjreports/administrator/sql/install.mysql.utf8.sql b/tjreports/administrator/sql/install.mysql.utf8.sql
index 26a7e86..70bd55f 100755
--- a/tjreports/administrator/sql/install.mysql.utf8.sql
+++ b/tjreports/administrator/sql/install.mysql.utf8.sql
@@ -12,4 +12,4 @@ CREATE TABLE IF NOT EXISTS `#__tj_reports` (
`datadenyset` int(11),
`param` text NOT NULL,
PRIMARY KEY (`id`)
-) AUTO_INCREMENT=1 ;
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 DEFAULT COLLATE=utf8mb4_unicode_ci AUTO_INCREMENT=1;
diff --git a/tjreports/administrator/sql/uninstall.mysql.utf8.sql b/tjreports/administrator/sql/uninstall.mysql.utf8.sql
index d31a636..94f5d88 100755
--- a/tjreports/administrator/sql/uninstall.mysql.utf8.sql
+++ b/tjreports/administrator/sql/uninstall.mysql.utf8.sql
@@ -1,2 +1 @@
-
-DELETE FROM `#__content_types` WHERE (type_alias LIKE 'com_tjreports.%');
\ No newline at end of file
+-- DELETE FROM `#__content_types` WHERE (type_alias LIKE 'com_tjreports.%');
diff --git a/tjreports/administrator/sql/updates/mysql/1.1.2.sql b/tjreports/administrator/sql/updates/mysql/1.1.2.sql
new file mode 100644
index 0000000..0908242
--- /dev/null
+++ b/tjreports/administrator/sql/updates/mysql/1.1.2.sql
@@ -0,0 +1,9 @@
+-- Change engine
+ALTER TABLE `#__tj_reports` ENGINE = InnoDB;
+
+-- Change charset, collation for table #__tj_reports
+ALTER TABLE `#__tj_reports` CHANGE `title` `title` VARCHAR(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL;
+ALTER TABLE `#__tj_reports` CHANGE `alias` `alias` VARCHAR(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL,
+ALTER TABLE `#__tj_reports` CHANGE `plugin` `plugin` VARCHAR(255) CHARACTER SET utf8 COLLATE utf8mb4_unicode_ci NOT NULL,
+ALTER TABLE `#__tj_reports` CHANGE `client` `client` VARCHAR(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL,
+ALTER TABLE `#__tj_reports` CHANGE `param` `param` TEXT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL;
diff --git a/tjreports/languages/administrator/en-GB/en-GB.com_tjreports.ini b/tjreports/languages/administrator/en-GB/en-GB.com_tjreports.ini
index c57d742..cfbb861 100755
--- a/tjreports/languages/administrator/en-GB/en-GB.com_tjreports.ini
+++ b/tjreports/languages/administrator/en-GB/en-GB.com_tjreports.ini
@@ -111,6 +111,8 @@ COM_TJREPORTS_ACCESS_VIEW_SUBSCRIBE_DESC="Allow user to view only subscribed rep
JACTION_VIEW="View"
JACTION_VIEW_COMPONENT_DESC="Allow user to view reports in this extension"
JACTION_EXPORT="Export"
+COM_TJREPORTS_ACCESS_PIIDATA="View PII Data"
+COM_TJREPORTS_ACCESS_PIIDATA_COMPONENT_DESC="Allow user to see Personally Identifiable Information (PII) data on the report."
JACTION_EXPORT_COMPONENT_DESC="Allow user to export report data in this extension"
;tjreport lms
diff --git a/tjreports/plugins/actionlog/tjreports/tjreports.xml b/tjreports/plugins/actionlog/tjreports/tjreports.xml
index 314baeb..cf61054 100644
--- a/tjreports/plugins/actionlog/tjreports/tjreports.xml
+++ b/tjreports/plugins/actionlog/tjreports/tjreports.xml
@@ -2,12 +2,12 @@
plg_actionlog_tjreports
Techjoomla
- 12th Jul 2019
+ 22nd Oct 2019
Copyright (C) 2016 - 2019 Techjoomla. All rights reserved.
http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL
extensions@techjoomla.com
https://techjoomla.com
- 1.1.1
+ 1.1.2
PLG_ACTIONLOG_TJREPORTS_XML_DESCRIPTION
tjreports.php
diff --git a/tjreports/plugins/content/tjreportsfields/tjreportsfields.xml b/tjreports/plugins/content/tjreportsfields/tjreportsfields.xml
index f7f33d5..4357cea 100644
--- a/tjreports/plugins/content/tjreportsfields/tjreportsfields.xml
+++ b/tjreports/plugins/content/tjreportsfields/tjreportsfields.xml
@@ -5,10 +5,10 @@
Techjoomla
extensions@techjoomla.com
https://techjoomla.com
- 12th Jul 2019
+ 22nd Oct 2019
Copyright (C) 2016 - 2019 Techjoomla. All rights reserved.
http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL
- 1.1.1
+ 1.1.2
tjreportsfields.php
diff --git a/tjreports/plugins/privacy/tjreports/tjreports.xml b/tjreports/plugins/privacy/tjreports/tjreports.xml
index 45d6501..ab37f09 100644
--- a/tjreports/plugins/privacy/tjreports/tjreports.xml
+++ b/tjreports/plugins/privacy/tjreports/tjreports.xml
@@ -1,8 +1,8 @@
plg_privacy_tjreports
- 1.1.1
- 12th Jul 2019
+ 1.1.2
+ 22nd Oct 2019
Techjoomla
extensions@techjoomla.com
https://techjoomla.com
diff --git a/tjreports/plugins/user/tjreportsindexer/sql/tjreportsindexer.install.sql b/tjreports/plugins/user/tjreportsindexer/sql/tjreportsindexer.install.sql
index 4e64539..d79fa56 100755
--- a/tjreports/plugins/user/tjreportsindexer/sql/tjreportsindexer.install.sql
+++ b/tjreports/plugins/user/tjreportsindexer/sql/tjreportsindexer.install.sql
@@ -1,3 +1,5 @@
CREATE TABLE IF NOT EXISTS `#__tjreports_com_users_user` (
- `record_id` int(11) NOT NULL
+ `record_id` int(11) NOT NULL,
+ `username_hash` VARCHAR(100) NOT NULL,
+ `email_hash` VARCHAR(100) NOT NULL
)ENGINE=InnoDB DEFAULT CHARSET=utf8;
diff --git a/tjreports/plugins/user/tjreportsindexer/sql/updates/mysql/1.1.2.sql b/tjreports/plugins/user/tjreportsindexer/sql/updates/mysql/1.1.2.sql
new file mode 100644
index 0000000..7977427
--- /dev/null
+++ b/tjreports/plugins/user/tjreportsindexer/sql/updates/mysql/1.1.2.sql
@@ -0,0 +1,2 @@
+ALTER TABLE `#__tjreports_com_users_user` ADD username_hash VARCHAR(100) NOT NULL AFTER record_id;
+ALTER TABLE `#__tjreports_com_users_user` ADD email_hash VARCHAR(100) NOT NULL AFTER username_hash;
diff --git a/tjreports/plugins/user/tjreportsindexer/tjreportsindexer.php b/tjreports/plugins/user/tjreportsindexer/tjreportsindexer.php
index 533eab9..e43c79d 100644
--- a/tjreports/plugins/user/tjreportsindexer/tjreportsindexer.php
+++ b/tjreports/plugins/user/tjreportsindexer/tjreportsindexer.php
@@ -48,17 +48,6 @@ class PlgUserTjreportsindexer extends JPlugin
*/
public function onUserAfterSave($user, $isNew, $success, $msg)
{
- /*
- [com_fields] => Array
- (
- [job-position] => Developer
- )*/
-
- if (empty($user['com_fields']))
- {
- return;
- }
-
// Delete existing user-data entry
// Here record_id = user_id
$this->deleteIndexerEntry($user['id']);
@@ -153,6 +142,10 @@ protected function addIndexerEntry($user)
$values[] = $db->quote($value);
}
+ // Add username & email hash values
+ array_push($columns, 'username_hash', 'email_hash');
+ array_push($values, "'" . md5($user['username']) . "'", "'" . md5($user['email']) . "'");
+
// Prepare the insert query
$query = $db->getQuery(true);
$query
diff --git a/tjreports/plugins/user/tjreportsindexer/tjreportsindexer.xml b/tjreports/plugins/user/tjreportsindexer/tjreportsindexer.xml
index 568f885..4ee72f8 100644
--- a/tjreports/plugins/user/tjreportsindexer/tjreportsindexer.xml
+++ b/tjreports/plugins/user/tjreportsindexer/tjreportsindexer.xml
@@ -5,10 +5,10 @@
Techjoomla
extensions@techjoomla.com
https://techjoomla.com
- 12th Jul 2019
+ 22nd Oct 2019
Copyright (C) 2016 - 2019 Techjoomla. All rights reserved.
http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL
- 1.1.1
+ 1.1.2
sql/tjreportsindexer.install.sql
diff --git a/tjreports/site/assets/js/tjrContentUI.js b/tjreports/site/assets/js/tjrContentUI.js
index 5c16ad2..9927292 100755
--- a/tjreports/site/assets/js/tjrContentUI.js
+++ b/tjreports/site/assets/js/tjrContentUI.js
@@ -49,11 +49,11 @@ jQuery.extend(tjrContentUI.report, {
// If sendEmail plug is enabled then try to add a column of checkboxes
if (
- typeof tjutilitysendemail != 'undefined' &&
+ typeof window.tjSendEmail.UI != 'undefined' &&
jQuery('body').find('.td-sendemail').length > 0
)
{
- tjutilitysendemail.addColumn('report-table');
+ window.tjemail = new window.tjSendEmail.UI("report-table", "td-sendemail", "cid");
}
// Reinitialze some js like for calandar, tooltip, chosen
diff --git a/tjreports/site/models/reports.php b/tjreports/site/models/reports.php
index 5614ff4..a224fc4 100755
--- a/tjreports/site/models/reports.php
+++ b/tjreports/site/models/reports.php
@@ -14,6 +14,7 @@
// Load TJReports db helper
JLoader::import('database', JPATH_SITE . '/components/com_tjreports/helpers');
+JLoader::import('components.com_tjreports.helpers.tjreports', JPATH_ADMINISTRATOR);
/**
* Methods supporting a list of Tjreports records.
@@ -37,6 +38,9 @@ class TjreportsModelReports extends JModelList
// Columns array contain columns data
public $columns = array();
+ // Columns array contain PII columns
+ private $piiColumns = array();
+
// Columns array contain email columns
private $emailColumn = '';
@@ -46,6 +50,9 @@ class TjreportsModelReports extends JModelList
// Columns which will be displayed by default
private $defaultColToShow = array();
+ // Columns which will be hide by default
+ private $defaultColToHide = array();
+
// Columns which are sortable with or without query statement
public $sortableColumns = array();
@@ -72,6 +79,14 @@ class TjreportsModelReports extends JModelList
protected $tjreportsDbHelper;
+ private $piiPermission;
+
+ private $filterShowhideCols = array();
+
+ private $filterPiiColumns = array();
+
+ private $filterParamColToshow = array();
+
/**
* Constructor.
*
@@ -95,7 +110,19 @@ public function __construct($config = array())
}
// Get email column
- $this->emailColumn = array_search(1, array_map(function ($ar) {return $ar['emailColumn'];}, $this->columns));
+ $this->emailColumn = array_search(
+ 1, array_map(
+ function ($ar) {
+ if (!empty($ar['emailColumn']))
+ {
+ return $ar['emailColumn'];
+ }
+ }, $this->columns
+ )
+ );
+
+ // Check PII data permission
+ $this->piiPermission = $this->canViewPiiData();
$this->initData();
@@ -148,15 +175,8 @@ protected function setCustomFieldsColumns()
// Set columns from custom fields table into tjreports plugin's column list
foreach ($columnNames as $columnName)
{
- // Skip primary key, record_id of indexed table
- // As those are not part of custom fields
- if (!isset($columnLabels[$columnName]))
- {
- continue;
- }
-
$customField = array (
- 'title' => $columnLabels[$columnName],
+ 'title' => ($columnLabels[$columnName]) ? $columnLabels[$columnName] : $columnName,
'table_column' => $this->customFieldsTableAlias . '.' . $columnName
// , 'disable_sorting' => true
@@ -347,7 +367,9 @@ private function initData()
if ((isset($column['not_show_hide']) && $column['not_show_hide'] === true)
|| (strpos($key, '::') !== false && !isset($column['not_show_hide'])))
{
+ // If column not_show_hide = true then this column hide from show/hide list as well as on the report
unset($this->showhideCols[$key]);
+ unset($this->defaultColToShow[$key]);
}
if ((isset($column['disable_sorting']) && $column['disable_sorting'])
@@ -356,6 +378,11 @@ private function initData()
unset($this->sortableColumns[$key]);
}
+ if (isset($column['isPiiColumn']) && $column['isPiiColumn'] === true)
+ {
+ array_push($this->piiColumns, $key);
+ }
+
if (!isset($column['disable_sorting']) && (!isset($column['table_column']) || !in_array($key, $this->sortableColumns)))
{
array_push($this->sortableWoQuery, $key);
@@ -364,15 +391,19 @@ private function initData()
if (!isset($column['title']) || (strpos($key, '::') !== false)
|| (isset($column['not_show_hide']) && $column['not_show_hide'] === false))
{
+ /* If column not_show_hide = false then column does not show on the report
+ * but shows on Hide / show column list dropdown with unchecking the checkbox.*/
+ array_push($this->defaultColToHide, $key);
unset($this->defaultColToShow[$key]);
}
}
+ $this->piiColumns = array_values($this->piiColumns);
$this->showhideCols = array_values($this->showhideCols);
$this->sortableColumns = array_values($this->sortableColumns);
$this->sortableWoQuery = array_values($this->sortableWoQuery);
$this->defaultColToShow = array_values($this->defaultColToShow);
-
+ $this->defaultColToHide = array_values($this->defaultColToHide);
}
/**
@@ -511,6 +542,12 @@ protected function populateState($ordering = '', $direction = 'ASC')
$reportParams = $this->getReportParams($reportId);
$colToshow = $reportParams->get("colToshow");
+ $piiColumns = array_flip($reportParams->get("piiColumns"));
+
+ if (!empty($piiColumns))
+ {
+ $colToshow = (object) array_diff_key((array) $colToshow, $piiColumns);
+ }
}
$this->filterReportColumns($reportId, $colToshow);
@@ -532,11 +569,23 @@ protected function populateState($ordering = '', $direction = 'ASC')
$value = $input->get('limitstart', 0, 'uint');
$this->setState('list.start', $value);
+ if (!empty($this->piiColumns))
+ {
+ $this->setState('piiColumns', $this->piiColumns);
+ }
+
if ($this->emailColumn)
{
$this->setState('emailColumn', $this->emailColumn);
}
+ if ($this->defaultColToHide)
+ {
+ // Array set hide column in param as false value
+ $defaultColToHide = array_combine($this->defaultColToHide, array_fill(0, count($this->defaultColToHide), false));
+ $this->setState('defaultColToHide', $defaultColToHide);
+ }
+
// Ordering
$this->default_order = $input->get('filter_order', $this->default_order, 'STRING');
@@ -943,6 +992,21 @@ public function getreportoptions()
return $options;
}
+ /**
+ * Check for permissions
+ *
+ * @return boolean
+ *
+ * @since 1.0
+ */
+
+ public function canViewPiiData()
+ {
+ $canDo = TjreportsHelper::getActions();
+
+ return $canDo->get('core.view.piidata');
+ }
+
/**
* Check for permissions
*
@@ -1062,8 +1126,8 @@ public function loadLanguage($name, $type = 'tjreports', $extension = '', $baseP
/**
* Method to Process parent Report columns
*
- * @param string $queryId Query Id
- * @param ARRAY &$selColToshow Columns to show
+ * @param INT $queryId Query Id
+ * @param ARRAY &$selColToshow Columns to show
*
* @return Void
*
@@ -1077,56 +1141,61 @@ private function filterReportColumns($queryId, &$selColToshow)
}
$query = $this->_db->getQuery(true);
- $showhideCols = $paramColToshow = array();
+ $this->filterShowhideCols = $this->filterPiiColumns = $this->filterParamColToshow = array();
+
+ // $this->filterSelColToshow = $selColToshow;
// Process plugin params
- $parentId = $this->processSavedReportColumns($queryId, $showhideCols, $paramColToshow, $selColToshow);
+ $parentId = $this->processSavedReportColumns($queryId, $selColToshow);
// Process if user has saved query is for a plugin
if (!empty($parentId))
{
- $this->processSavedReportColumns($parentId, $showhideCols, $paramColToshow, $selColToshow);
+ $this->processSavedReportColumns($parentId, $selColToshow);
}
// If plugin has save any column assign that otherwise default plugin param will be applied
- if ($paramColToshow)
+ if ($this->filterParamColToshow)
{
// If show hide column changes, check if there is any must to hide column
if ($selColToshow)
{
- $selColToshow = array_intersect($selColToshow, $paramColToshow);
- $selColToshow = $selColToshow ? $selColToshow : $paramColToshow;
+ $selColToshow = array_intersect($selColToshow, $this->filterParamColToshow);
+ $selColToshow = $selColToshow ? $selColToshow : $this->filterParamColToshow;
}
else
{
- $selColToshow = $paramColToshow;
+ $selColToshow = $this->filterParamColToshow;
}
}
- if (!empty($showhideCols))
+ if (!empty($this->filterShowhideCols))
{
- $this->showhideCols = $showhideCols;
+ $this->showhideCols = $this->filterShowhideCols;
}
if (!empty($emailColumn))
{
$this->emailColumn = $emailColumn;
}
+
+ if (!empty($this->filterPiiColumns))
+ {
+ $this->piiColumns = $this->filterPiiColumns;
+ }
}
/**
* Method to Process parent Report columns
*
- * @param INT $queryId Query Id
- * @param ARRAY &$showhideCols Show Hide columns
- * @param ARRAY &$colToshow Columns to show
- * @param ARRAY &$selColToshow Selected Cols
+ * @param INT $queryId Query Id
+ * @param ARRAY &$selColToshow Selected Cols
*
- * @return Void
+ * @return INTEGER
*
* @since 3.0
*/
- private function processSavedReportColumns($queryId, &$showhideCols, &$colToshow, &$selColToshow)
+ private function processSavedReportColumns($queryId, &$selColToshow)
{
$query = $this->_db->getQuery(true);
$query->select(array('param', 'parent'))
@@ -1142,13 +1211,25 @@ private function processSavedReportColumns($queryId, &$showhideCols, &$colToshow
if (isset($param['showHideColumns']))
{
- if (empty($showhideCols))
+ if (empty($this->filterShowhideCols))
+ {
+ $this->filterShowhideCols = (array) $param['showHideColumns'];
+ }
+ else
+ {
+ $this->filterShowhideCols = array_intersect($this->filterShowhideCols, (array) $param['showHideColumns']);
+ }
+ }
+
+ if (isset($param['piiColumns']))
+ {
+ if (empty($this->filterPiiColumns))
{
- $showhideCols = (array) $param['showHideColumns'];
+ $this->filterPiiColumns = (array) $param['piiColumns'];
}
else
{
- $showhideCols = array_intersect($showhideCols, (array) $param['showHideColumns']);
+ $this->filterPiiColumns = array_intersect($this->filterPiiColumns, (array) $param['piiColumns']);
}
}
@@ -1158,20 +1239,36 @@ private function processSavedReportColumns($queryId, &$showhideCols, &$colToshow
{
if ($show !== false || in_array($cols, $selColToshow))
{
- $colToshow[$cols] = $cols;
+ $this->filterParamColToshow[$cols] = $cols;
}
if (!empty($param['showHideColumns']) && !in_array($cols, $param['showHideColumns']) && !empty($selColToshow))
{
array_splice($selColToshow, $i, 0, $cols);
$i++;
- $colToshow[$cols] = $cols;
+ $this->filterParamColToshow[$cols] = $cols;
}
}
}
+ // Check PII permission
+ if (!empty($param['piiColumns']) && !$this->piiPermission)
+ {
+ $this->filterParamColToshow = array_diff($this->filterParamColToshow, $param['piiColumns']);
+ $this->filterShowhideCols = array_diff($this->filterShowhideCols, $param['piiColumns']);
+ }
+
$parent = $queryData->parent;
}
+ else
+ {
+ // Check PII permission if load params not set
+ if (!empty($this->piiColumns) && !$this->piiPermission)
+ {
+ $this->defaultColToShow = array_diff($this->defaultColToShow, $this->piiColumns);
+ $this->showhideCols = array_diff($this->showhideCols, $this->piiColumns);
+ }
+ }
return $parent;
}
diff --git a/tjreports/site/views/reports/view.base.php b/tjreports/site/views/reports/view.base.php
index d8809a9..bb25a18 100644
--- a/tjreports/site/views/reports/view.base.php
+++ b/tjreports/site/views/reports/view.base.php
@@ -159,13 +159,28 @@ public function processData($type = 'html')
$this->pagination = $this->get('pagination');
$this->headerLevel = $this->model->headerLevel;
+
+ // Array_key - defaultColToHide column are present then get the key as value.
+ $this->defaultColToHide = array_keys($this->model->getState('defaultColToHide'));
$this->columns = $this->model->columns;
+
+ /* Array_merge - here colToshow means get all true value array so want to mearg defaultColToHide column and then using
+ * array_intersect - only remove those column which is force fully added in load param in showhideCols config
+ */
$this->showHideColumns = $this->model->showhideCols;
+
+ if (!empty($this->defaultColToHide))
+ {
+ $this->showHideColumns = array_intersect($this->model->showhideCols, array_merge($this->model->getState('colToshow'), $this->defaultColToHide));
+ }
+
$this->sortable = $this->model->sortableColumns;
$this->emailColumn = $this->model->getState('emailColumn');
$this->srButton = $this->model->showSearchResetButton;
- $this->colToshow = $this->model->getState('colToshow');
+ // Array_intersect - if column present in colToshow as true/false but not in showHideColumns then remove it
+ $this->colToshow = array_intersect($this->model->getState('colToshow'), $this->model->showhideCols);
+
$this->filterValues = $this->model->getState('filters');
$this->userFilters = $this->model->displayFilters();
diff --git a/tjreports/tjreports.xml b/tjreports/tjreports.xml
index 3ddde42..ba4cd46 100644
--- a/tjreports/tjreports.xml
+++ b/tjreports/tjreports.xml
@@ -6,8 +6,8 @@
https://techjoomla.com
Copyright (C) 2016 - 2019 Techjoomla. All rights reserved.
http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL
- 12th Jul 2019
- 1.1.1
+ 22nd Oct 2019
+ 1.1.2
This component is used to access all the report at single place.