| Current Path : /home/digilove/www/41423/ |
| Current File : /home/digilove/www/41423/actionlogs.tar |
forms/actionlogs.xml 0000644 00000001537 15234453245 0010573 0 ustar 00 <?xml version="1.0" encoding="UTF-8"?>
<form>
<fieldset name="actionlogs" label="PLG_SYSTEM_ACTIONLOGS_OPTIONS" addfieldpath="/administrator/components/com_actionlogs/models/fields">
<fields name="actionlogs">
<field
name="actionlogsNotify"
type="radio"
label="PLG_SYSTEM_ACTIONLOGS_NOTIFICATIONS"
description="PLG_SYSTEM_ACTIONLOGS_NOTIFICATIONS_DESC"
class="btn-group btn-group-yesno"
default="0"
filter="integer"
required="true"
>
<option value="1">JYES</option>
<option value="0">JNO</option>
</field>
<field
name="actionlogsExtensions"
type="logtype"
label="PLG_SYSTEM_ACTIONLOGS_EXTENSIONS_NOTIFICATIONS"
description="PLG_SYSTEM_ACTIONLOGS_EXTENSIONS_NOTIFICATIONS_DESC"
multiple="true"
validate="options"
showon="actionlogsNotify:1"
/>
</fields>
</fieldset>
</form>
forms/information.xml 0000644 00000000617 15234453245 0010754 0 ustar 00 <?xml version="1.0" encoding="UTF-8"?>
<form>
<fields name="params">
<fieldset name="information" label="PLG_SYSTEM_ACTIONLOGS_OPTIONS" addfieldpath="/administrator/components/com_actionlogs/models/fields">
<field
name="Information"
type="plugininfo"
label="PLG_SYSTEM_ACTIONLOGS_INFO_LABEL"
description="PLG_SYSTEM_ACTIONLOGS_INFO_DESC"
/>
</fieldset>
</fields>
</form>
actionlogs.php 0000644 00000027672 15234453245 0007444 0 ustar 00 <?php
/**
* @package Joomla.Plugins
* @subpackage System.actionlogs
*
* @copyright (C) 2018 Open Source Matters, Inc. <https://www.joomla.org>
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
defined('_JEXEC') or die;
use Joomla\CMS\Cache\Cache;
use Joomla\CMS\Factory;
use Joomla\CMS\Form\Form;
use Joomla\CMS\HTML\HTMLHelper;
use Joomla\CMS\Language\Text;
use Joomla\CMS\Plugin\PluginHelper;
use Joomla\CMS\User\User;
/**
* Joomla! Users Actions Logging Plugin.
*
* @since 3.9.0
*/
class PlgSystemActionLogs extends JPlugin
{
/**
* Application object.
*
* @var JApplicationCms
* @since 3.9.0
*/
protected $app;
/**
* Database object.
*
* @var JDatabaseDriver
* @since 3.9.0
*/
protected $db;
/**
* Load plugin language file automatically so that it can be used inside component
*
* @var boolean
* @since 3.9.0
*/
protected $autoloadLanguage = true;
/**
* Constructor.
*
* @param object &$subject The object to observe.
* @param array $config An optional associative array of configuration settings.
*
* @since 3.9.0
*/
public function __construct(&$subject, $config)
{
parent::__construct($subject, $config);
// Import actionlog plugin group so that these plugins will be triggered for events
PluginHelper::importPlugin('actionlog');
}
/**
* Adds additional fields to the user editing form for logs e-mail notifications
*
* @param JForm $form The form to be altered.
* @param mixed $data The associated data for the form.
*
* @return boolean
*
* @since 3.9.0
*/
public function onContentPrepareForm($form, $data)
{
if (!$form instanceof Form)
{
$this->subject->setError('JERROR_NOT_A_FORM');
return false;
}
$formName = $form->getName();
$allowedFormNames = array(
'com_users.profile',
'com_admin.profile',
'com_users.user',
);
if (!in_array($formName, $allowedFormNames))
{
return true;
}
/**
* We only allow users who has Super User permission change this setting for himself or for other users
* who has same Super User permission
*/
$user = Factory::getUser();
if (!$user->authorise('core.admin'))
{
return true;
}
// If we are on the save command, no data is passed to $data variable, we need to get it directly from request
$jformData = $this->app->input->get('jform', array(), 'array');
if ($jformData && !$data)
{
$data = $jformData;
}
if (is_array($data))
{
$data = (object) $data;
}
if (empty($data->id) || !User::getInstance($data->id)->authorise('core.admin'))
{
return true;
}
Form::addFormPath(__DIR__ . '/forms');
if ((!PluginHelper::isEnabled('actionlog', 'joomla')) && (Factory::getApplication()->isClient('administrator')))
{
$form->loadFile('information', false);
return true;
}
if (!PluginHelper::isEnabled('actionlog', 'joomla'))
{
return true;
}
$form->loadFile('actionlogs', false);
}
/**
* Runs on content preparation
*
* @param string $context The context for the data
* @param object $data An object containing the data for the form.
*
* @return boolean
*
* @since 3.9.0
*/
public function onContentPrepareData($context, $data)
{
if (!in_array($context, array('com_users.profile', 'com_admin.profile', 'com_users.user')))
{
return true;
}
if (is_array($data))
{
$data = (object) $data;
}
if (!User::getInstance($data->id)->authorise('core.admin'))
{
return true;
}
$query = $this->db->getQuery(true)
->select($this->db->quoteName(array('notify', 'extensions')))
->from($this->db->quoteName('#__action_logs_users'))
->where($this->db->quoteName('user_id') . ' = ' . (int) $data->id);
try
{
$values = $this->db->setQuery($query)->loadObject();
}
catch (JDatabaseExceptionExecuting $e)
{
return false;
}
if (!$values)
{
return true;
}
$data->actionlogs = new StdClass;
$data->actionlogs->actionlogsNotify = $values->notify;
$data->actionlogs->actionlogsExtensions = $values->extensions;
if (!HTMLHelper::isRegistered('users.actionlogsNotify'))
{
HTMLHelper::register('users.actionlogsNotify', array(__CLASS__, 'renderActionlogsNotify'));
}
if (!HTMLHelper::isRegistered('users.actionlogsExtensions'))
{
HTMLHelper::register('users.actionlogsExtensions', array(__CLASS__, 'renderActionlogsExtensions'));
}
return true;
}
/**
* Runs after the HTTP response has been sent to the client and delete log records older than certain days
*
* @return void
*
* @since 3.9.0
*/
public function onAfterRespond()
{
$daysToDeleteAfter = (int) $this->params->get('logDeletePeriod', 0);
if ($daysToDeleteAfter <= 0)
{
return;
}
// The delete frequency will be once per day
$deleteFrequency = 3600 * 24;
// Do we need to run? Compare the last run timestamp stored in the plugin's options with the current
// timestamp. If the difference is greater than the cache timeout we shall not execute again.
$now = time();
$last = (int) $this->params->get('lastrun', 0);
if (abs($now - $last) < $deleteFrequency)
{
return;
}
// Update last run status
$this->params->set('lastrun', $now);
$db = $this->db;
$query = $db->getQuery(true)
->update($db->qn('#__extensions'))
->set($db->qn('params') . ' = ' . $db->q($this->params->toString('JSON')))
->where($db->qn('type') . ' = ' . $db->q('plugin'))
->where($db->qn('folder') . ' = ' . $db->q('system'))
->where($db->qn('element') . ' = ' . $db->q('actionlogs'));
try
{
// Lock the tables to prevent multiple plugin executions causing a race condition
$db->lockTable('#__extensions');
}
catch (Exception $e)
{
// If we can't lock the tables it's too risky to continue execution
return;
}
try
{
// Update the plugin parameters
$result = $db->setQuery($query)->execute();
$this->clearCacheGroups(array('com_plugins'), array(0, 1));
}
catch (Exception $exc)
{
// If we failed to execute
$db->unlockTables();
$result = false;
}
try
{
// Unlock the tables after writing
$db->unlockTables();
}
catch (Exception $e)
{
// If we can't lock the tables assume we have somehow failed
$result = false;
}
// Abort on failure
if (!$result)
{
return;
}
$daysToDeleteAfter = (int) $this->params->get('logDeletePeriod', 0);
$now = $db->quote(Factory::getDate()->toSql());
if ($daysToDeleteAfter > 0)
{
$conditions = array($db->quoteName('log_date') . ' < ' . $query->dateAdd($now, -1 * $daysToDeleteAfter, ' DAY'));
$query->clear()
->delete($db->quoteName('#__action_logs'))->where($conditions);
$db->setQuery($query);
try
{
$db->execute();
}
catch (RuntimeException $e)
{
// Ignore it
return;
}
}
}
/**
* Utility method to act on a user after it has been saved.
*
* @param array $user Holds the new user data.
* @param boolean $isNew True if a new user is stored.
* @param boolean $success True if user was successfully stored in the database.
* @param string $msg Message.
*
* @return boolean
*
* @since 3.9.0
*/
public function onUserAfterSave($user, $isNew, $success, $msg)
{
if (!$success)
{
return false;
}
// Clear access rights in case user groups were changed.
$userObject = new User($user['id']);
$userObject->clearAccessRights();
$authorised = $userObject->authorise('core.admin');
$query = $this->db->getQuery(true)
->select('COUNT(*)')
->from($this->db->quoteName('#__action_logs_users'))
->where($this->db->quoteName('user_id') . ' = ' . (int) $user['id']);
try
{
$exists = (bool) $this->db->setQuery($query)->loadResult();
}
catch (JDatabaseExceptionExecuting $e)
{
return false;
}
// If preferences don't exist, insert.
if (!$exists && $authorised && isset($user['actionlogs']))
{
$values = array((int) $user['id'], (int) $user['actionlogs']['actionlogsNotify']);
$columns = array('user_id', 'notify');
if (isset($user['actionlogs']['actionlogsExtensions']))
{
$values[] = $this->db->quote(json_encode($user['actionlogs']['actionlogsExtensions']));
$columns[] = 'extensions';
}
$query = $this->db->getQuery(true)
->insert($this->db->quoteName('#__action_logs_users'))
->columns($this->db->quoteName($columns))
->values(implode(',', $values));
}
elseif ($exists && $authorised && isset($user['actionlogs']))
{
// Update preferences.
$values = array($this->db->quoteName('notify') . ' = ' . (int) $user['actionlogs']['actionlogsNotify']);
if (isset($user['actionlogs']['actionlogsExtensions']))
{
$values[] = $this->db->quoteName('extensions') . ' = ' . $this->db->quote(json_encode($user['actionlogs']['actionlogsExtensions']));
}
$query = $this->db->getQuery(true)
->update($this->db->quoteName('#__action_logs_users'))
->set($values)
->where($this->db->quoteName('user_id') . ' = ' . (int) $user['id']);
}
elseif ($exists && !$authorised)
{
// Remove preferences if user is not authorised.
$query = $this->db->getQuery(true)
->delete($this->db->quoteName('#__action_logs_users'))
->where($this->db->quoteName('user_id') . ' = ' . (int) $user['id']);
}
try
{
$this->db->setQuery($query)->execute();
}
catch (JDatabaseExceptionExecuting $e)
{
return false;
}
return true;
}
/**
* Removes user preferences
*
* Method is called after user data is deleted from the database
*
* @param array $user Holds the user data
* @param boolean $success True if user was successfully stored in the database
* @param string $msg Message
*
* @return boolean
*
* @since 3.9.0
*/
public function onUserAfterDelete($user, $success, $msg)
{
if (!$success)
{
return false;
}
$query = $this->db->getQuery(true)
->delete($this->db->quoteName('#__action_logs_users'))
->where($this->db->quoteName('user_id') . ' = ' . (int) $user['id']);
try
{
$this->db->setQuery($query)->execute();
}
catch (JDatabaseExceptionExecuting $e)
{
return false;
}
return true;
}
/**
* Clears cache groups. We use it to clear the plugins cache after we update the last run timestamp.
*
* @param array $clearGroups The cache groups to clean
* @param array $cacheClients The cache clients (site, admin) to clean
*
* @return void
*
* @since 3.9.0
*/
private function clearCacheGroups(array $clearGroups, array $cacheClients = array(0, 1))
{
$conf = Factory::getConfig();
foreach ($clearGroups as $group)
{
foreach ($cacheClients as $clientId)
{
try
{
$options = array(
'defaultgroup' => $group,
'cachebase' => $clientId ? JPATH_ADMINISTRATOR . '/cache' :
$conf->get('cache_path', JPATH_SITE . '/cache')
);
$cache = Cache::getInstance('callback', $options);
$cache->clean();
}
catch (Exception $e)
{
// Ignore it
}
}
}
}
/**
* Method to render a value.
*
* @param integer|string $value The value (0 or 1).
*
* @return string The rendered value.
*
* @since 3.9.16
*/
public static function renderActionlogsNotify($value)
{
return Text::_($value ? 'JYES' : 'JNO');
}
/**
* Method to render a list of extensions.
*
* @param array|string $extensions Array of extensions or an empty string if none selected.
*
* @return string The rendered value.
*
* @since 3.9.16
*/
public static function renderActionlogsExtensions($extensions)
{
// No extensions selected.
if (!$extensions)
{
return Text::_('JNONE');
}
// Load the helper.
JLoader::register('ActionlogsHelper', JPATH_ADMINISTRATOR . '/components/com_actionlogs/helpers/actionlogs.php');
foreach ($extensions as &$extension)
{
// Load extension language files and translate extension name.
ActionlogsHelper::loadTranslationFiles($extension);
$extension = Text::_($extension);
}
return implode(', ', $extensions);
}
}
actionlogs.xml 0000644 00000002363 15234453245 0007443 0 ustar 00 <?xml version="1.0" encoding="UTF-8"?>
<extension version="3.9" type="plugin" group="system" method="upgrade">
<name>PLG_SYSTEM_ACTIONLOGS</name>
<author>Joomla! Project</author>
<creationDate>May 2018</creationDate>
<copyright>(C) 2018 Open Source Matters, Inc.</copyright>
<license>GNU General Public License version 2 or later; see LICENSE.txt</license>
<authorEmail>admin@joomla.org</authorEmail>
<authorUrl>www.joomla.org</authorUrl>
<version>3.9.0</version>
<description>PLG_SYSTEM_ACTIONLOGS_XML_DESCRIPTION</description>
<files>
<filename plugin="actionlogs">actionlogs.php</filename>
<folder>forms</folder>
</files>
<languages>
<language tag="en-GB">en-GB.plg_system_actionlogs.ini</language>
<language tag="en-GB">en-GB.plg_system_actionlogs.sys.ini</language>
</languages>
<config>
<fields name="params">
<fieldset name="basic">
<field
name="logDeletePeriod"
type="number"
label="PLG_SYSTEM_ACTIONLOGS_LOG_DELETE_PERIOD"
description="PLG_SYSTEM_ACTIONLOGS_LOG_DELETE_PERIOD_DESC"
default="0"
min="0"
filter="int"
validate="number"
/>
<field
name="lastrun"
type="hidden"
default="0"
filter="integer"
/>
</fieldset>
</fields>
</config>
</extension>
tmpl/default.php 0000644 00000011360 15235426425 0007666 0 ustar 00 <?php
/**
* @package Joomla.Administrator
* @subpackage com_actionlogs
*
* @copyright (C) 2018 Open Source Matters, Inc. <https://www.joomla.org>
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
defined('_JEXEC') or die;
use Joomla\CMS\Factory;
use Joomla\CMS\HTML\HTMLHelper;
use Joomla\CMS\Language\Text;
use Joomla\CMS\Layout\LayoutHelper;
use Joomla\CMS\Router\Route;
/** @var ActionlogsViewActionlogs $this */
JLoader::register('ActionlogsHelper', JPATH_ADMINISTRATOR . '/components/com_actionlogs/helpers/actionlogs.php');
HTMLHelper::_('bootstrap.tooltip');
HTMLHelper::_('behavior.multiselect');
HTMLHelper::_('formbehavior.chosen', 'select');
$listOrder = $this->escape($this->state->get('list.ordering'));
$listDirn = $this->escape($this->state->get('list.direction'));
Factory::getDocument()->addScriptDeclaration('
Joomla.submitbutton = function(task)
{
if (task == "actionlogs.exportLogs")
{
Joomla.submitform(task, document.getElementById("exportForm"));
return;
}
if (task == "actionlogs.exportSelectedLogs")
{
// Get id of selected action logs item and pass it to export form hidden input
var cids = [];
jQuery("input[name=\'cid[]\']:checked").each(function() {
cids.push(jQuery(this).val());
});
document.exportForm.cids.value = cids.join(",");
Joomla.submitform(task, document.getElementById("exportForm"));
return;
}
Joomla.submitform(task);
};
');
?>
<form action="<?php echo Route::_('index.php?option=com_actionlogs&view=actionlogs'); ?>" method="post" name="adminForm" id="adminForm">
<div id="j-main-container">
<?php echo LayoutHelper::render('joomla.searchtools.default', array('view' => $this)); ?>
<?php if (empty($this->items)) : ?>
<div class="alert alert-no-items">
<?php echo Text::_('JGLOBAL_NO_MATCHING_RESULTS'); ?>
</div>
<?php else : ?>
<table class="table table-striped table-hover" id="logsList">
<thead>
<th width="1%" class="center">
<?php echo HTMLHelper::_('grid.checkall'); ?>
</th>
<th>
<?php echo HTMLHelper::_('searchtools.sort', 'COM_ACTIONLOGS_ACTION', 'a.message', $listDirn, $listOrder); ?>
</th>
<th width="15%" class="nowrap">
<?php echo HTMLHelper::_('searchtools.sort', 'COM_ACTIONLOGS_EXTENSION', 'a.extension', $listDirn, $listOrder); ?>
</th>
<th width="15%" class="nowrap">
<?php echo HTMLHelper::_('searchtools.sort', 'COM_ACTIONLOGS_DATE', 'a.log_date', $listDirn, $listOrder); ?>
</th>
<th width="10%" class="nowrap">
<?php echo HTMLHelper::_('searchtools.sort', 'COM_ACTIONLOGS_NAME', 'a.user_id', $listDirn, $listOrder); ?>
</th>
<?php if ($this->showIpColumn) : ?>
<th width="10%" class="nowrap">
<?php echo HTMLHelper::_('searchtools.sort', 'COM_ACTIONLOGS_IP_ADDRESS', 'a.ip_address', $listDirn, $listOrder); ?>
</th>
<?php endif; ?>
<th width="1%" class="nowrap hidden-phone">
<?php echo HTMLHelper::_('searchtools.sort', 'JGRID_HEADING_ID', 'a.id', $listDirn, $listOrder); ?>
</th>
</thead>
<tfoot>
<tr>
<td colspan="7">
<?php echo $this->pagination->getListFooter(); ?>
</td>
</tr>
</tfoot>
<tbody>
<?php foreach ($this->items as $i => $item) :
$extension = strtok($item->extension, '.');
ActionlogsHelper::loadTranslationFiles($extension); ?>
<tr class="row<?php echo $i % 2; ?>">
<td class="center">
<?php echo HTMLHelper::_('grid.id', $i, $item->id); ?>
</td>
<td>
<?php echo ActionlogsHelper::getHumanReadableLogMessage($item); ?>
</td>
<td>
<?php echo $this->escape(Text::_($extension)); ?>
</td>
<td>
<span class="hasTooltip" title="<?php echo HTMLHelper::_('date', $item->log_date, Text::_('DATE_FORMAT_LC6')); ?>">
<?php echo HTMLHelper::_('date.relative', $item->log_date); ?>
</span>
</td>
<td>
<?php echo $this->escape($item->name); ?>
</td>
<?php if ($this->showIpColumn) : ?>
<td>
<?php echo Text::_($this->escape($item->ip_address)); ?>
</td>
<?php endif;?>
<td class="hidden-phone">
<?php echo (int) $item->id; ?>
</td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
<?php endif;?>
<input type="hidden" name="task" value="" />
<input type="hidden" name="boxchecked" value="0" />
<?php echo HTMLHelper::_('form.token'); ?>
</div>
</form>
<form action="<?php echo Route::_('index.php?option=com_actionlogs&view=actionlogs'); ?>" method="post" name="exportForm" id="exportForm">
<input type="hidden" name="task" value="" />
<input type="hidden" name="cids" value="" />
<?php echo HTMLHelper::_('form.token'); ?>
</form>
tmpl/default.xml 0000644 00000000307 15235426425 0007676 0 ustar 00 <?xml version="1.0" encoding="utf-8"?>
<metadata>
<layout title="COM_ACTIONLOGS_VIEW_DEFAULT_TITLE">
<message>
<![CDATA[COM_ACTIONLOGS_VIEW_DEFAULT_DESC]]>
</message>
</layout>
</metadata>
view.html.php 0000644 00000005237 15235426425 0007211 0 ustar 00 <?php
/**
* @package Joomla.Administrator
* @subpackage com_actionlogs
*
* @copyright (C) 2018 Open Source Matters, Inc. <https://www.joomla.org>
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
defined('_JEXEC') or die;
use Joomla\CMS\Component\ComponentHelper;
use Joomla\CMS\Language\Text;
use Joomla\CMS\Toolbar\Toolbar;
use Joomla\CMS\Toolbar\ToolbarHelper;
JLoader::register('ActionlogsHelper', JPATH_ADMINISTRATOR . '/components/com_actionlogs/helpers/actionlogs.php');
/**
* View class for a list of logs.
*
* @since 3.9.0
*/
class ActionlogsViewActionlogs extends JViewLegacy
{
/**
* An array of items.
*
* @var array
* @since 3.9.0
*/
protected $items;
/**
* The model state
*
* @var array
* @since 3.9.0
*/
protected $state;
/**
* The pagination object
*
* @var JPagination
* @since 3.9.0
*/
protected $pagination;
/**
* The active search filters
*
* @var array
* @since 3.9.0
*/
public $activeFilters;
/**
* Method to display the view.
*
* @param string $tpl A template file to load. [optional]
*
* @return mixed A string if successful, otherwise an Error object.
*
* @since 3.9.0
*/
public function display($tpl = null)
{
$params = ComponentHelper::getParams('com_actionlogs');
$this->items = $this->get('Items');
$this->state = $this->get('State');
$this->filterForm = $this->get('FilterForm');
$this->activeFilters = $this->get('ActiveFilters');
$this->pagination = $this->get('Pagination');
$this->showIpColumn = (bool) $params->get('ip_logging', 0);
if (count($errors = $this->get('Errors')))
{
JError::raiseError(500, implode("\n", $errors));
return false;
}
$this->addToolBar();
// Load all actionlog plugins language files
ActionlogsHelper::loadActionLogPluginsLanguage();
return parent::display($tpl);
}
/**
* Add the page title and toolbar.
*
* @return void
*
* @since 3.9.0
*/
protected function addToolbar()
{
ToolbarHelper::title(Text::_('COM_ACTIONLOGS_MANAGER_USERLOGS'), 'list-2');
ToolbarHelper::deleteList('JGLOBAL_CONFIRM_DELETE', 'actionlogs.delete');
$bar = Toolbar::getInstance('toolbar');
$bar->appendButton('Confirm', 'COM_ACTIONLOGS_PURGE_CONFIRM', 'delete', 'COM_ACTIONLOGS_TOOLBAR_PURGE', 'actionlogs.purge', false);
ToolbarHelper::preferences('com_actionlogs');
ToolbarHelper::help('JHELP_COMPONENTS_ACTIONLOGS');
ToolBarHelper::custom('actionlogs.exportSelectedLogs', 'download', '', 'COM_ACTIONLOGS_EXPORT_CSV', true);
ToolBarHelper::custom('actionlogs.exportLogs', 'download', '', 'COM_ACTIONLOGS_EXPORT_ALL_CSV', false);
}
}