Server IP : 195.201.23.43 / Your IP : 3.14.8.164 Web Server : Apache System : Linux webserver2.vercom.be 5.4.0-192-generic #212-Ubuntu SMP Fri Jul 5 09:47:39 UTC 2024 x86_64 User : kdecoratie ( 1041) PHP Version : 7.1.33-63+ubuntu20.04.1+deb.sury.org+1 Disable Function : pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wifcontinued,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_get_handler,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,pcntl_async_signals, MySQL : OFF | cURL : ON | WGET : ON | Perl : ON | Python : OFF | Sudo : ON | Pkexec : ON Directory : /home/kdecoratie/public_html/plugins/system/actionlogs/ |
Upload File : |
<?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); } }Private